Skip to content

Commit 31b0007

Browse files
dylanmckaydylanmckay
authored andcommitted
[AVR] Use the generic branch relaxer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307617 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 776e4f2 commit 31b0007

File tree

7 files changed

+181
-12
lines changed

7 files changed

+181
-12
lines changed

lib/Target/AVR/AVRInstrInfo.cpp

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
402402
ArrayRef<MachineOperand> Cond,
403403
const DebugLoc &DL,
404404
int *BytesAdded) const {
405-
assert(!BytesAdded && "code size not handled");
405+
if (BytesAdded) *BytesAdded = 0;
406406

407407
// Shouldn't be a fall through.
408408
assert(TBB && "insertBranch must not be told to insert a fallthrough");
@@ -411,19 +411,24 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
411411

412412
if (Cond.empty()) {
413413
assert(!FBB && "Unconditional branch with multiple successors!");
414-
BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
414+
auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
415+
if (BytesAdded)
416+
*BytesAdded += getInstSizeInBytes(MI);
415417
return 1;
416418
}
417419

418420
// Conditional branch.
419421
unsigned Count = 0;
420422
AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
421-
BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
423+
auto &CondMI = *BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
424+
425+
if (BytesAdded) *BytesAdded += getInstSizeInBytes(CondMI);
422426
++Count;
423427

424428
if (FBB) {
425429
// Two-way Conditional branch. Insert the second branch.
426-
BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
430+
auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
431+
if (BytesAdded) *BytesAdded += getInstSizeInBytes(MI);
427432
++Count;
428433
}
429434

@@ -432,7 +437,7 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
432437

433438
unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
434439
int *BytesRemoved) const {
435-
assert(!BytesRemoved && "code size not handled");
440+
if (BytesRemoved) *BytesRemoved = 0;
436441

437442
MachineBasicBlock::iterator I = MBB.end();
438443
unsigned Count = 0;
@@ -450,6 +455,7 @@ unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
450455
}
451456

452457
// Remove the branch.
458+
if (BytesRemoved) *BytesRemoved += getInstSizeInBytes(*I);
453459
I->eraseFromParent();
454460
I = MBB.end();
455461
++Count;
@@ -494,5 +500,61 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
494500
}
495501
}
496502

503+
MachineBasicBlock *
504+
AVRInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
505+
switch (MI.getOpcode()) {
506+
default:
507+
llvm_unreachable("unexpected opcode!");
508+
case AVR::JMPk:
509+
case AVR::CALLk:
510+
case AVR::RCALLk:
511+
case AVR::RJMPk:
512+
case AVR::BREQk:
513+
case AVR::BRNEk:
514+
case AVR::BRSHk:
515+
case AVR::BRLOk:
516+
case AVR::BRMIk:
517+
case AVR::BRPLk:
518+
case AVR::BRGEk:
519+
case AVR::BRLTk:
520+
return MI.getOperand(0).getMBB();
521+
case AVR::BRBSsk:
522+
case AVR::BRBCsk:
523+
return MI.getOperand(1).getMBB();
524+
case AVR::SBRCRrB:
525+
case AVR::SBRSRrB:
526+
case AVR::SBICAb:
527+
case AVR::SBISAb:
528+
llvm_unreachable("unimplemented branch instructions");
529+
}
530+
}
531+
532+
bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
533+
int64_t BrOffset) const {
534+
535+
switch (BranchOp) {
536+
default:
537+
llvm_unreachable("unexpected opcode!");
538+
case AVR::JMPk:
539+
case AVR::CALLk:
540+
assert(BrOffset >= 0 && "offset must be absolute address");
541+
return isUIntN(16, BrOffset);
542+
case AVR::RCALLk:
543+
case AVR::RJMPk:
544+
return isIntN(13, BrOffset);
545+
case AVR::BRBSsk:
546+
case AVR::BRBCsk:
547+
case AVR::BREQk:
548+
case AVR::BRNEk:
549+
case AVR::BRSHk:
550+
case AVR::BRLOk:
551+
case AVR::BRMIk:
552+
case AVR::BRPLk:
553+
case AVR::BRGEk:
554+
case AVR::BRLTk:
555+
return isIntN(7, BrOffset);
556+
}
557+
}
558+
497559
} // end of namespace llvm
498560

lib/Target/AVR/AVRInstrInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class AVRInstrInfo : public AVRGenInstrInfo {
103103
bool
104104
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
105105

106+
MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
107+
108+
bool isBranchOffsetInRange(unsigned BranchOpc,
109+
int64_t BrOffset) const override;
106110
private:
107111
const AVRRegisterInfo RI;
108112
};

lib/Target/AVR/AVRTargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class AVRPassConfig : public TargetPassConfig {
6666

6767
bool addInstSelector() override;
6868
void addPreSched2() override;
69+
void addPreEmitPass() override;
6970
void addPreRegAlloc() override;
7071
};
7172
} // namespace
@@ -115,4 +116,9 @@ void AVRPassConfig::addPreSched2() {
115116
addPass(createAVRExpandPseudoPass());
116117
}
117118

119+
void AVRPassConfig::addPreEmitPass() {
120+
// Must run branch selection immediately preceding the asm printer.
121+
addPass(&BranchRelaxationPassID);
122+
}
123+
118124
} // end of namespace llvm

test/CodeGen/AVR/branch-relaxation.ll

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
; RUN: llc < %s -march=avr | FileCheck %s
2+
3+
; CHECKC-LABEL: relax_breq
4+
; CHECK: cpi r{{[0-9]+}}, 0
5+
; CHECK: brne LBB0_1
6+
; CHECK: rjmp LBB0_2
7+
; LBB0_1:
8+
9+
define i8 @relax_breq(i1 %a) {
10+
entry-block:
11+
br i1 %a, label %hello, label %finished
12+
13+
hello:
14+
call void asm sideeffect "nop", ""()
15+
call void asm sideeffect "nop", ""()
16+
call void asm sideeffect "nop", ""()
17+
call void asm sideeffect "nop", ""()
18+
call void asm sideeffect "nop", ""()
19+
call void asm sideeffect "nop", ""()
20+
call void asm sideeffect "nop", ""()
21+
call void asm sideeffect "nop", ""()
22+
call void asm sideeffect "nop", ""()
23+
call void asm sideeffect "nop", ""()
24+
call void asm sideeffect "nop", ""()
25+
call void asm sideeffect "nop", ""()
26+
call void asm sideeffect "nop", ""()
27+
call void asm sideeffect "nop", ""()
28+
call void asm sideeffect "nop", ""()
29+
call void asm sideeffect "nop", ""()
30+
call void asm sideeffect "nop", ""()
31+
call void asm sideeffect "nop", ""()
32+
call void asm sideeffect "nop", ""()
33+
call void asm sideeffect "nop", ""()
34+
call void asm sideeffect "nop", ""()
35+
call void asm sideeffect "nop", ""()
36+
call void asm sideeffect "nop", ""()
37+
call void asm sideeffect "nop", ""()
38+
call void asm sideeffect "nop", ""()
39+
call void asm sideeffect "nop", ""()
40+
call void asm sideeffect "nop", ""()
41+
call void asm sideeffect "nop", ""()
42+
call void asm sideeffect "nop", ""()
43+
call void asm sideeffect "nop", ""()
44+
call void asm sideeffect "nop", ""()
45+
call void asm sideeffect "nop", ""()
46+
call void asm sideeffect "nop", ""()
47+
call void asm sideeffect "nop", ""()
48+
call void asm sideeffect "nop", ""()
49+
call void asm sideeffect "nop", ""()
50+
call void asm sideeffect "nop", ""()
51+
call void asm sideeffect "nop", ""()
52+
call void asm sideeffect "nop", ""()
53+
call void asm sideeffect "nop", ""()
54+
call void asm sideeffect "nop", ""()
55+
call void asm sideeffect "nop", ""()
56+
call void asm sideeffect "nop", ""()
57+
call void asm sideeffect "nop", ""()
58+
call void asm sideeffect "nop", ""()
59+
call void asm sideeffect "nop", ""()
60+
call void asm sideeffect "nop", ""()
61+
call void asm sideeffect "nop", ""()
62+
call void asm sideeffect "nop", ""()
63+
call void asm sideeffect "nop", ""()
64+
br label %finished
65+
finished:
66+
ret i8 3
67+
}
68+
69+
; CHECKC-LABEL: no_relax_breq
70+
; CHECK: cpi r{{[0-9]+}}, 0
71+
; CHECK: breq [[END_BB:LBB[0-9]+_[0-9]+]]
72+
; CHECK: nop
73+
; ...
74+
; LBB0_1:
75+
define i8 @no_relax_breq(i1 %a) {
76+
entry-block:
77+
br i1 %a, label %hello, label %finished
78+
79+
hello:
80+
; There are not enough NOPs to require relaxation.
81+
call void asm sideeffect "nop", ""()
82+
call void asm sideeffect "nop", ""()
83+
call void asm sideeffect "nop", ""()
84+
call void asm sideeffect "nop", ""()
85+
call void asm sideeffect "nop", ""()
86+
call void asm sideeffect "nop", ""()
87+
call void asm sideeffect "nop", ""()
88+
call void asm sideeffect "nop", ""()
89+
call void asm sideeffect "nop", ""()
90+
call void asm sideeffect "nop", ""()
91+
call void asm sideeffect "nop", ""()
92+
br label %finished
93+
finished:
94+
ret i8 3
95+
}
96+

test/CodeGen/AVR/ctlz.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ declare i8 @llvm.ctlz.i8(i8)
1010

1111
; CHECK-LABEL: count_leading_zeros:
1212
; CHECK: cpi [[RESULT:r[0-9]+]], 0
13-
; CHECK: breq LBB0_1
13+
; CHECK: brne LBB0_1
14+
; CHECK: rjmp LBB0_2
1415
; CHECK: mov [[SCRATCH:r[0-9]+]], {{.*}}[[RESULT]]
1516
; CHECK: lsr {{.*}}[[SCRATCH]]
1617
; CHECK: or {{.*}}[[SCRATCH]], {{.*}}[[RESULT]]
@@ -43,6 +44,6 @@ declare i8 @llvm.ctlz.i8(i8)
4344
; CHECK: add {{.*}}[[RESULT]], {{.*}}[[SCRATCH]]
4445
; CHECK: andi {{.*}}[[RESULT]], 15
4546
; CHECK: ret
46-
; CHECK: LBB0_1:
47+
; CHECK: LBB0_2:
4748
; CHECK: ldi {{.*}}[[RESULT]], 8
4849
; CHECK: ret

test/CodeGen/AVR/cttz.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare i8 @llvm.cttz.i8(i8)
1010

1111
; CHECK-LABEL: count_trailing_zeros:
1212
; CHECK: cpi [[RESULT:r[0-9]+]], 0
13-
; CHECK: breq LBB0_1
13+
; CHECK: breq [[END_BB:LBB[0-9]+_[0-9]+]]
1414
; CHECK: mov [[SCRATCH:r[0-9]+]], {{.*}}[[RESULT]]
1515
; CHECK: dec {{.*}}[[SCRATCH]]
1616
; CHECK: com {{.*}}[[RESULT]]
@@ -34,7 +34,7 @@ declare i8 @llvm.cttz.i8(i8)
3434
; CHECK: andi {{.*}}[[SCRATCH]], 15
3535
; CHECK: mov {{.*}}[[RESULT]], {{.*}}[[SCRATCH]]
3636
; CHECK: ret
37-
; CHECK: LBB0_1:
37+
; CHECK: [[END_BB]]:
3838
; CHECK: ldi {{.*}}[[SCRATCH]], 8
3939
; CHECK: mov {{.*}}[[RESULT]], {{.*}}[[SCRATCH]]
4040
; CHECK: ret

test/CodeGen/AVR/select-mbb-placement-bug.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ define internal fastcc void @loopy() {
88
;
99
; https://github.com/avr-rust/rust/issues/49
1010

11-
; CHECK: LBB0_1:
12-
; CHECK: LBB0_2:
13-
; CHECK-NOT: LBB0_3:
11+
; CHECK: LBB0_{{[0-9]+}}:
12+
; CHECK: LBB0_{{[0-9]+}}:
13+
; CHECK-NOT: LBB0_{{[0-9]+}}:
1414
start:
1515
br label %bb7.preheader
1616

0 commit comments

Comments
 (0)