@@ -36,7 +36,7 @@ class ARMBlockPlacement : public MachineFunctionPass {
36
36
ARMBlockPlacement () : MachineFunctionPass(ID) {}
37
37
38
38
bool runOnMachineFunction (MachineFunction &MF) override ;
39
- void moveBasicBlock (MachineBasicBlock *BB, MachineBasicBlock *After );
39
+ void moveBasicBlock (MachineBasicBlock *BB, MachineBasicBlock *Before );
40
40
bool blockIsBefore (MachineBasicBlock *BB, MachineBasicBlock *Other);
41
41
bool fixBackwardsWLS (MachineLoop *ML);
42
42
bool processPostOrderLoops (MachineLoop *ML);
@@ -82,19 +82,20 @@ static MachineInstr *findWLS(MachineLoop *ML) {
82
82
}
83
83
84
84
// / Checks if loop has a backwards branching WLS, and if possible, fixes it.
85
- // / This requires checking the preheader ( or it's predecessor) for a WLS and if
86
- // / its target is before it.
87
- // / If moving the target block wouldn 't produce another backwards WLS or a new
88
- // / forwards LE branch, then move the target block after the preheader (or it's
89
- // / predecessor) .
85
+ // / This requires checking the predecessor (ie. preheader or it's predecessor)
86
+ // / for a WLS and if its loopExit/ target is before it.
87
+ // / If moving the predecessor won 't convert a WLS (to the predecessor) from
88
+ // / a forward to a backward branching WLS, then move the predecessor block
89
+ // / to before the loopExit/target .
90
90
bool ARMBlockPlacement::fixBackwardsWLS (MachineLoop *ML) {
91
91
MachineInstr *WlsInstr = findWLS (ML);
92
92
if (!WlsInstr)
93
93
return false ;
94
94
95
95
MachineBasicBlock *Predecessor = WlsInstr->getParent ();
96
96
MachineBasicBlock *LoopExit = WlsInstr->getOperand (2 ).getMBB ();
97
- // We don't want to move the function's entry block.
97
+
98
+ // We don't want to move Preheader to before the function's entry block.
98
99
if (!LoopExit->getPrevNode ())
99
100
return false ;
100
101
if (blockIsBefore (Predecessor, LoopExit))
@@ -103,77 +104,38 @@ bool ARMBlockPlacement::fixBackwardsWLS(MachineLoop *ML) {
103
104
<< Predecessor->getFullName () << " to "
104
105
<< LoopExit->getFullName () << " \n " );
105
106
106
- // Make sure that moving the target block doesn't cause any of its WLSs
107
- // that were previously not backwards to become backwards
108
- bool CanMove = true ;
109
- MachineInstr *WlsInLoopExit = findWLSInBlock (LoopExit);
110
- if (WlsInLoopExit) {
111
- // An example loop structure where the LoopExit can't be moved, since
112
- // bb1's WLS will become backwards once it's moved after bb3
113
- // bb1: - LoopExit
114
- // WLS bb2
115
- // bb2: - LoopExit2
116
- // ...
117
- // bb3: - Predecessor
118
- // WLS bb1
119
- // bb4: - Header
120
- MachineBasicBlock *LoopExit2 = WlsInLoopExit->getOperand (2 ).getMBB ();
121
- // If the WLS from LoopExit to LoopExit2 is already backwards then
122
- // moving LoopExit won't affect it, so it can be moved. If LoopExit2 is
123
- // after the Predecessor then moving will keep it as a forward branch, so it
124
- // can be moved. If LoopExit2 is between the Predecessor and LoopExit then
125
- // moving LoopExit will make it a backwards branch, so it can't be moved
126
- // since we'd fix one and introduce one backwards branch.
127
- // TODO: Analyse the blocks to make a decision if it would be worth
128
- // moving LoopExit even if LoopExit2 is between the Predecessor and
129
- // LoopExit.
130
- if (!blockIsBefore (LoopExit2, LoopExit) &&
131
- (LoopExit2 == Predecessor || blockIsBefore (LoopExit2, Predecessor))) {
132
- LLVM_DEBUG (dbgs () << DEBUG_PREFIX
133
- << " Can't move the target block as it would "
134
- " introduce a new backwards WLS branch\n " );
135
- CanMove = false ;
136
- }
137
- }
138
-
139
- if (CanMove) {
140
- // Make sure no LEs become forwards.
141
- // An example loop structure where the LoopExit can't be moved, since
142
- // bb2's LE will become forwards once bb1 is moved after bb3.
143
- // bb1: - LoopExit
144
- // bb2:
145
- // LE bb1 - Terminator
146
- // bb3: - Predecessor
147
- // WLS bb1
148
- // bb4: - Header
149
- for (auto It = LoopExit->getIterator (); It != Predecessor->getIterator ();
150
- It++) {
151
- MachineBasicBlock *MBB = &*It;
152
- for (auto &Terminator : MBB->terminators ()) {
153
- if (Terminator.getOpcode () != ARM::t2LoopEnd &&
154
- Terminator.getOpcode () != ARM::t2LoopEndDec)
155
- continue ;
156
- MachineBasicBlock *LETarget = Terminator.getOperand (2 ).getMBB ();
157
- // The LE will become forwards branching if it branches to LoopExit
158
- // which isn't allowed by the architecture, so we should avoid
159
- // introducing these.
160
- // TODO: Analyse the blocks to make a decision if it would be worth
161
- // moving LoopExit even if we'd introduce a forwards LE
162
- if (LETarget == LoopExit) {
163
- LLVM_DEBUG (dbgs () << DEBUG_PREFIX
164
- << " Can't move the target block as it would "
165
- " introduce a new forwards LE branch\n " );
166
- CanMove = false ;
167
- break ;
168
- }
107
+ // Make sure no forward branching WLSs to the Predecessor become backwards
108
+ // branching. An example loop structure where the Predecessor can't be moved,
109
+ // since bb2's WLS will become forwards once bb3 is moved before/above bb1.
110
+ //
111
+ // bb1: - LoopExit
112
+ // bb2:
113
+ // WLS bb3
114
+ // bb3: - Predecessor
115
+ // WLS bb1
116
+ // bb4: - Header
117
+ for (auto It = ++LoopExit->getIterator (); It != Predecessor->getIterator ();
118
+ ++It) {
119
+ MachineBasicBlock *MBB = &*It;
120
+ for (auto &Terminator : MBB->terminators ()) {
121
+ if (Terminator.getOpcode () != ARM::t2WhileLoopStartLR)
122
+ continue ;
123
+ MachineBasicBlock *WLSTarget = Terminator.getOperand (2 ).getMBB ();
124
+ // TODO: Analyse the blocks to make a decision if it would be worth
125
+ // moving Preheader even if we'd introduce a backwards WLS
126
+ if (WLSTarget == Predecessor) {
127
+ LLVM_DEBUG (
128
+ dbgs () << DEBUG_PREFIX
129
+ << " Can't move Predecessor"
130
+ " block as it would convert a WLS from forward to a "
131
+ " backwards branching WLS\n " );
132
+ return false ;
169
133
}
170
134
}
171
135
}
172
136
173
- if (CanMove)
174
- moveBasicBlock (LoopExit, Predecessor);
175
-
176
- return CanMove;
137
+ moveBasicBlock (Predecessor, LoopExit);
138
+ return true ;
177
139
}
178
140
179
141
// / Updates ordering (of WLS BB and their loopExits) in inner loops first
@@ -212,18 +174,20 @@ bool ARMBlockPlacement::blockIsBefore(MachineBasicBlock *BB,
212
174
return BBUtils->getOffsetOf (Other) > BBUtils->getOffsetOf (BB);
213
175
}
214
176
215
- // / Moves a given MBB to be positioned after another MBB while maintaining
216
- // / existing control flow
177
+ // Moves a BasicBlock before another, without changing the control flow
217
178
void ARMBlockPlacement::moveBasicBlock (MachineBasicBlock *BB,
218
- MachineBasicBlock *After ) {
219
- LLVM_DEBUG (dbgs () << DEBUG_PREFIX << " Moving " << BB->getName () << " after "
220
- << After ->getName () << " \n " );
179
+ MachineBasicBlock *Before ) {
180
+ LLVM_DEBUG (dbgs () << DEBUG_PREFIX << " Moving " << BB->getName () << " before "
181
+ << Before ->getName () << " \n " );
221
182
MachineBasicBlock *BBPrevious = BB->getPrevNode ();
222
183
assert (BBPrevious && " Cannot move the function entry basic block" );
223
- MachineBasicBlock *AfterNext = After->getNextNode ();
224
184
MachineBasicBlock *BBNext = BB->getNextNode ();
225
185
226
- BB->moveAfter (After);
186
+ MachineBasicBlock *BeforePrev = Before->getPrevNode ();
187
+ assert (BeforePrev &&
188
+ " Cannot move the given block to before the function entry block" );
189
+ MachineFunction *F = BB->getParent ();
190
+ BB->moveBefore (Before);
227
191
228
192
// Since only the blocks are to be moved around (but the control flow must
229
193
// not change), if there were any fall-throughs (to/from adjacent blocks),
@@ -251,12 +215,14 @@ void ARMBlockPlacement::moveBasicBlock(MachineBasicBlock *BB,
251
215
// Fix fall-through to the moved BB from the one that used to be before it.
252
216
if (BBPrevious->isSuccessor (BB))
253
217
FixFallthrough (BBPrevious, BB);
254
- // Fix fall through from the destination BB to the one that used to follow .
255
- if (AfterNext && After ->isSuccessor (AfterNext ))
256
- FixFallthrough (After, AfterNext );
218
+ // Fix fall through from the destination BB to the one that used to before it .
219
+ if (BeforePrev ->isSuccessor (Before ))
220
+ FixFallthrough (BeforePrev, Before );
257
221
// Fix fall through from the moved BB to the one that used to follow.
258
222
if (BBNext && BB->isSuccessor (BBNext))
259
223
FixFallthrough (BB, BBNext);
260
224
261
- BBUtils->adjustBBOffsetsAfter (After);
225
+ F->RenumberBlocks ();
226
+ BBUtils->computeAllBlockSizes ();
227
+ BBUtils->adjustBBOffsetsAfter (&F->front ());
262
228
}
0 commit comments