@@ -27,63 +27,84 @@ using namespace llvm;
27
27
28
28
#define DEBUG_TYPE " msp430-branch-select"
29
29
30
+ static cl::opt<bool >
31
+ BranchSelectEnabled (" msp430-branch-select" , cl::Hidden, cl::init(true ),
32
+ cl::desc(" Expand out of range branches" ));
33
+
34
+ STATISTIC (NumSplit, " Number of machine basic blocks split" );
30
35
STATISTIC (NumExpanded, " Number of branches expanded to long format" );
31
36
32
37
namespace {
33
- struct MSP430BSel : public MachineFunctionPass {
34
- static char ID;
35
- MSP430BSel () : MachineFunctionPass(ID) {}
38
+ class MSP430BSel : public MachineFunctionPass {
36
39
37
- // / BlockSizes - The sizes of the basic blocks in the function.
38
- std::vector<unsigned > BlockSizes;
40
+ typedef SmallVector<int , 16 > OffsetVector;
39
41
40
- bool runOnMachineFunction (MachineFunction &Fn) override ;
42
+ MachineFunction *MF;
43
+ const MSP430InstrInfo *TII;
41
44
42
- MachineFunctionProperties getRequiredProperties () const override {
43
- return MachineFunctionProperties ().set (
44
- MachineFunctionProperties::Property::AllVRegsAllocated);
45
- }
45
+ unsigned measureFunction (OffsetVector &BlockOffsets,
46
+ MachineBasicBlock *FromBB = nullptr );
47
+ bool expandBranches (OffsetVector &BlockOffsets);
46
48
47
- const char *getPassName () const override {
48
- return " MSP430 Branch Selector" ;
49
- }
50
- };
51
- char MSP430BSel::ID = 0 ;
49
+ public:
50
+ static char ID;
51
+ MSP430BSel () : MachineFunctionPass(ID) {}
52
+
53
+ bool runOnMachineFunction (MachineFunction &MF) override ;
54
+
55
+ MachineFunctionProperties getRequiredProperties () const override {
56
+ return MachineFunctionProperties ().set (
57
+ MachineFunctionProperties::Property::AllVRegsAllocated);
58
+ }
59
+
60
+ const char *getPassName () const override { return " MSP430 Branch Selector" ; }
61
+ };
62
+ char MSP430BSel::ID = 0 ;
52
63
}
53
64
54
- // / createMSP430BranchSelectionPass - returns an instance of the Branch
55
- // / Selection Pass
56
- // /
57
- FunctionPass *llvm::createMSP430BranchSelectionPass () {
58
- return new MSP430BSel ();
65
+ static bool isInRage (int DistanceInBytes) {
66
+ // According to CC430 Family User's Guide, Section 4.5.1.3, branch
67
+ // instructions have the signed 10-bit word offset field, so first we need to
68
+ // convert the distance from bytes to words, then check if it fits in 10-bit
69
+ // signed integer.
70
+ const int WordSize = 2 ;
71
+
72
+ assert ((DistanceInBytes % WordSize == 0 ) &&
73
+ " Branch offset should be word aligned!" );
74
+
75
+ int Words = DistanceInBytes / WordSize;
76
+ return isInt<10 >(Words);
59
77
}
60
78
61
- bool MSP430BSel::runOnMachineFunction (MachineFunction &Fn) {
62
- const MSP430InstrInfo *TII =
63
- static_cast <const MSP430InstrInfo *>(Fn.getSubtarget ().getInstrInfo ());
79
+ // / Measure each basic block, fill the BlockOffsets, and return the size of
80
+ // / the function, starting with BB
81
+ unsigned MSP430BSel::measureFunction (OffsetVector &BlockOffsets,
82
+ MachineBasicBlock *FromBB) {
64
83
// Give the blocks of the function a dense, in-order, numbering.
65
- Fn.RenumberBlocks ();
66
- BlockSizes.resize (Fn.getNumBlockIDs ());
67
-
68
- // Measure each MBB and compute a size for the entire function.
69
- unsigned FuncSize = 0 ;
70
- for (MachineBasicBlock &MBB : Fn) {
71
- unsigned BlockSize = 0 ;
72
- for (MachineInstr &MI : MBB)
73
- BlockSize += TII->GetInstSizeInBytes (MI);
74
-
75
- BlockSizes[MBB.getNumber ()] = BlockSize;
76
- FuncSize += BlockSize;
84
+ MF->RenumberBlocks (FromBB);
85
+
86
+ MachineFunction::iterator Begin;
87
+ if (FromBB == nullptr ) {
88
+ Begin = MF->begin ();
89
+ } else {
90
+ Begin = FromBB->getIterator ();
77
91
}
78
92
79
- // If the entire function is smaller than the displacement of a branch field,
80
- // we know we don't need to shrink any branches in this function. This is a
81
- // common case.
82
- if (FuncSize < (1 << 9 )) {
83
- BlockSizes.clear ();
84
- return false ;
93
+ BlockOffsets.resize (MF->getNumBlockIDs ());
94
+
95
+ unsigned TotalSize = BlockOffsets[Begin->getNumber ()];
96
+ for (auto &MBB : make_range (Begin, MF->end ())) {
97
+ BlockOffsets[MBB.getNumber ()] = TotalSize;
98
+ for (MachineInstr &MI : MBB) {
99
+ TotalSize += TII->GetInstSizeInBytes (MI);
100
+ }
85
101
}
102
+ return TotalSize;
103
+ }
86
104
105
+ // / Do expand branches and split the basic blocks if necessary.
106
+ // / Returns true if made any change.
107
+ bool MSP430BSel::expandBranches (OffsetVector &BlockOffsets) {
87
108
// For each conditional branch, if the offset to its destination is larger
88
109
// than the offset field allows, transform it into a long branch sequence
89
110
// like this:
@@ -93,91 +114,144 @@ bool MSP430BSel::runOnMachineFunction(MachineFunction &Fn) {
93
114
// b!CC $PC+6
94
115
// b MBB
95
116
//
96
- bool MadeChange = true ;
97
- bool EverMadeChange = false ;
98
- while (MadeChange) {
99
- // Iteratively expand branches until we reach a fixed point.
100
- MadeChange = false ;
101
-
102
- for (MachineFunction::iterator MFI = Fn.begin (), E = Fn.end (); MFI != E;
103
- ++MFI) {
104
- MachineBasicBlock &MBB = *MFI;
105
- unsigned MBBStartOffset = 0 ;
106
- for (MachineBasicBlock::iterator I = MBB.begin (), E = MBB.end ();
107
- I != E; ++I) {
108
- if ((I->getOpcode () != MSP430::JCC || I->getOperand (0 ).isImm ()) &&
109
- I->getOpcode () != MSP430::JMP) {
110
- MBBStartOffset += TII->GetInstSizeInBytes (*I);
111
- continue ;
112
- }
117
+ bool MadeChange = false ;
118
+ for (auto MBB = MF->begin (), E = MF->end (); MBB != E; ++MBB) {
119
+ unsigned MBBStartOffset = 0 ;
120
+ for (auto MI = MBB->begin (), EE = MBB->end (); MI != EE; ++MI) {
121
+ MBBStartOffset += TII->GetInstSizeInBytes (*MI);
113
122
114
- // Determine the offset from the current branch to the destination
115
- // block.
116
- MachineBasicBlock *Dest = I->getOperand (0 ).getMBB ();
117
-
118
- int BranchSize;
119
- if (Dest->getNumber () <= MBB.getNumber ()) {
120
- // If this is a backwards branch, the delta is the offset from the
121
- // start of this block to this branch, plus the sizes of all blocks
122
- // from this block to the dest.
123
- BranchSize = MBBStartOffset;
124
-
125
- for (unsigned i = Dest->getNumber (), e = MBB.getNumber (); i != e; ++i)
126
- BranchSize += BlockSizes[i];
127
- } else {
128
- // Otherwise, add the size of the blocks between this block and the
129
- // dest to the number of bytes left in this block.
130
- BranchSize = -MBBStartOffset;
131
-
132
- for (unsigned i = MBB.getNumber (), e = Dest->getNumber (); i != e; ++i)
133
- BranchSize += BlockSizes[i];
134
- }
123
+ // If this instruction is not a short branch then skip it.
124
+ if (MI->getOpcode () != MSP430::JCC && MI->getOpcode () != MSP430::JMP) {
125
+ continue ;
126
+ }
135
127
136
- // If this branch is in range, ignore it.
137
- if (isInt<10 >(BranchSize)) {
138
- MBBStartOffset += 2 ;
139
- continue ;
140
- }
128
+ MachineBasicBlock *DestBB = MI->getOperand (0 ).getMBB ();
129
+ // Determine the distance from the current branch to the destination
130
+ // block. MBBStartOffset already includes the size of the current branch
131
+ // instruction.
132
+ int BlockDistance =
133
+ BlockOffsets[DestBB->getNumber ()] - BlockOffsets[MBB->getNumber ()];
134
+ int BranchDistance = BlockDistance - MBBStartOffset;
135
+
136
+ // If this branch is in range, ignore it.
137
+ if (isInRage (BranchDistance)) {
138
+ continue ;
139
+ }
140
+
141
+ DEBUG (dbgs () << " Found a branch that needs expanding, BB#"
142
+ << DestBB->getNumber () << " , Distance " << BranchDistance
143
+ << " \n " );
144
+
145
+ // If JCC is not the last instruction we need to split the MBB.
146
+ if (MI->getOpcode () == MSP430::JCC && std::next (MI) != EE) {
147
+
148
+ DEBUG (dbgs () << " Found a basic block that needs to be split, BB#"
149
+ << MBB->getNumber () << " \n " );
150
+
151
+ // Create a new basic block.
152
+ MachineBasicBlock *NewBB =
153
+ MF->CreateMachineBasicBlock (MBB->getBasicBlock ());
154
+ MF->insert (std::next (MBB), NewBB);
141
155
142
- // Otherwise, we have to expand it to a long branch.
143
- unsigned NewSize;
144
- MachineInstr &OldBranch = *I;
145
- DebugLoc dl = OldBranch.getDebugLoc ();
146
-
147
- if (I->getOpcode () == MSP430::JMP) {
148
- NewSize = 4 ;
149
- } else {
150
- // The BCC operands are:
151
- // 0. MSP430 branch predicate
152
- // 1. Target MBB
153
- SmallVector<MachineOperand, 1 > Cond;
154
- Cond.push_back (I->getOperand (1 ));
155
-
156
- // Jump over the uncond branch inst (i.e. $+6) on opposite condition.
157
- TII->ReverseBranchCondition (Cond);
158
- BuildMI (MBB, I, dl, TII->get (MSP430::JCC))
159
- .addImm (4 ).addOperand (Cond[0 ]);
160
-
161
- NewSize = 6 ;
156
+ // Splice the instructions following MI over to the NewBB.
157
+ NewBB->splice (NewBB->end (), &*MBB, std::next (MI), MBB->end ());
158
+
159
+ // Update the successor lists.
160
+ for (MachineBasicBlock *Succ : MBB->successors ()) {
161
+ if (Succ == DestBB) {
162
+ continue ;
163
+ }
164
+ MBB->replaceSuccessor (Succ, NewBB);
165
+ NewBB->addSuccessor (Succ);
162
166
}
163
- // Uncond branch to the real destination.
164
- I = BuildMI (MBB, I, dl, TII->get (MSP430::Bi)).addMBB (Dest);
165
167
166
- // Remove the old branch from the function.
167
- OldBranch.eraseFromParent ();
168
+ // We introduced a new MBB so all following blocks should be numbered
169
+ // and measured again.
170
+ measureFunction (BlockOffsets, &*MBB);
168
171
169
- // Remember that this instruction is NewSize bytes, increase the size of the
170
- // block by NewSize-2, remember to iterate.
171
- BlockSizes[MBB.getNumber ()] += NewSize-2 ;
172
- MBBStartOffset += NewSize;
172
+ ++NumSplit;
173
173
174
- ++NumExpanded;
175
- MadeChange = true ;
174
+ // It may be not necessary to start all over at this point, but it's
175
+ // safer do this anyway.
176
+ return true ;
176
177
}
178
+
179
+ MachineInstr &OldBranch = *MI;
180
+ DebugLoc dl = OldBranch.getDebugLoc ();
181
+ int InstrSizeDiff = -TII->GetInstSizeInBytes (OldBranch);
182
+
183
+ if (MI->getOpcode () == MSP430::JCC) {
184
+ MachineBasicBlock *NextMBB = &*std::next (MBB);
185
+ assert (MBB->isSuccessor (NextMBB) &&
186
+ " This block must have a layout successor!" );
187
+
188
+ // The BCC operands are:
189
+ // 0. Target MBB
190
+ // 1. MSP430 branch predicate
191
+ SmallVector<MachineOperand, 1 > Cond;
192
+ Cond.push_back (MI->getOperand (1 ));
193
+
194
+ // Jump over the long branch on the opposite condition
195
+ TII->ReverseBranchCondition (Cond);
196
+ MI = BuildMI (*MBB, MI, dl, TII->get (MSP430::JCC))
197
+ .addMBB (NextMBB)
198
+ .addOperand (Cond[0 ]);
199
+ InstrSizeDiff += TII->GetInstSizeInBytes (*MI);
200
+ ++MI;
201
+ }
202
+
203
+ // Unconditional branch to the real destination.
204
+ MI = BuildMI (*MBB, MI, dl, TII->get (MSP430::Bi)).addMBB (DestBB);
205
+ InstrSizeDiff += TII->GetInstSizeInBytes (*MI);
206
+
207
+ // Remove the old branch from the function.
208
+ OldBranch.eraseFromParent ();
209
+
210
+ // The size of a new instruction is different from the old one, so we need
211
+ // to correct all block offsets.
212
+ for (int i = MBB->getNumber () + 1 , e = BlockOffsets.size (); i < e; ++i) {
213
+ BlockOffsets[i] += InstrSizeDiff;
214
+ }
215
+ MBBStartOffset += InstrSizeDiff;
216
+
217
+ ++NumExpanded;
218
+ MadeChange = true ;
177
219
}
178
- EverMadeChange |= MadeChange;
179
220
}
221
+ return MadeChange;
222
+ }
223
+
224
+ bool MSP430BSel::runOnMachineFunction (MachineFunction &mf) {
225
+ MF = &mf;
226
+ TII = static_cast <const MSP430InstrInfo *>(MF->getSubtarget ().getInstrInfo ());
227
+
228
+ // If the pass is disabled, just bail early.
229
+ if (!BranchSelectEnabled)
230
+ return false ;
231
+
232
+ DEBUG (dbgs () << " \n ********** " << getPassName () << " **********\n " );
233
+
234
+ // BlockOffsets - Contains the distance from the beginning of the function to
235
+ // the beginning of each basic block.
236
+ OffsetVector BlockOffsets;
237
+
238
+ unsigned FunctionSize = measureFunction (BlockOffsets);
239
+ // If the entire function is smaller than the displacement of a branch field,
240
+ // we know we don't need to expand any branches in this
241
+ // function. This is a common case.
242
+ if (isInRage (FunctionSize)) {
243
+ return false ;
244
+ }
245
+
246
+ // Iteratively expand branches until we reach a fixed point.
247
+ bool MadeChange = false ;
248
+ while (expandBranches (BlockOffsets))
249
+ MadeChange = true ;
250
+
251
+ return MadeChange;
252
+ }
180
253
181
- BlockSizes.clear ();
182
- return true ;
254
+ // / Returns an instance of the Branch Selection Pass
255
+ FunctionPass *llvm::createMSP430BranchSelectionPass () {
256
+ return new MSP430BSel ();
183
257
}
0 commit comments