Skip to content

Commit 599d2a3

Browse files
malJajmemfrob
authored andcommitted
[ARM] Simplification to ARMBlockPlacement Pass.
It simplifies the logic by moving the predecessor (preHeader or it's predecessor) above the target (or loopExit), instead of moving the target to after the predecessor. Since the loopExit is no longer being moved, directions of any branches within/to it are unaffected. While the predecessor is being moved, the backwards movement simplifies some considerations, and the only consideration now required is that a forward WLS to the predecessor should not become backwards. Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D100094
1 parent d6a261a commit 599d2a3

File tree

4 files changed

+359
-365
lines changed

4 files changed

+359
-365
lines changed

llvm/lib/Target/ARM/ARMBlockPlacement.cpp

Lines changed: 51 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class ARMBlockPlacement : public MachineFunctionPass {
3636
ARMBlockPlacement() : MachineFunctionPass(ID) {}
3737

3838
bool runOnMachineFunction(MachineFunction &MF) override;
39-
void moveBasicBlock(MachineBasicBlock *BB, MachineBasicBlock *After);
39+
void moveBasicBlock(MachineBasicBlock *BB, MachineBasicBlock *Before);
4040
bool blockIsBefore(MachineBasicBlock *BB, MachineBasicBlock *Other);
4141
bool fixBackwardsWLS(MachineLoop *ML);
4242
bool processPostOrderLoops(MachineLoop *ML);
@@ -82,19 +82,20 @@ static MachineInstr *findWLS(MachineLoop *ML) {
8282
}
8383

8484
/// 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.
9090
bool ARMBlockPlacement::fixBackwardsWLS(MachineLoop *ML) {
9191
MachineInstr *WlsInstr = findWLS(ML);
9292
if (!WlsInstr)
9393
return false;
9494

9595
MachineBasicBlock *Predecessor = WlsInstr->getParent();
9696
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.
9899
if (!LoopExit->getPrevNode())
99100
return false;
100101
if (blockIsBefore(Predecessor, LoopExit))
@@ -103,77 +104,38 @@ bool ARMBlockPlacement::fixBackwardsWLS(MachineLoop *ML) {
103104
<< Predecessor->getFullName() << " to "
104105
<< LoopExit->getFullName() << "\n");
105106

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;
169133
}
170134
}
171135
}
172136

173-
if (CanMove)
174-
moveBasicBlock(LoopExit, Predecessor);
175-
176-
return CanMove;
137+
moveBasicBlock(Predecessor, LoopExit);
138+
return true;
177139
}
178140

179141
/// Updates ordering (of WLS BB and their loopExits) in inner loops first
@@ -212,18 +174,20 @@ bool ARMBlockPlacement::blockIsBefore(MachineBasicBlock *BB,
212174
return BBUtils->getOffsetOf(Other) > BBUtils->getOffsetOf(BB);
213175
}
214176

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
217178
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");
221182
MachineBasicBlock *BBPrevious = BB->getPrevNode();
222183
assert(BBPrevious && "Cannot move the function entry basic block");
223-
MachineBasicBlock *AfterNext = After->getNextNode();
224184
MachineBasicBlock *BBNext = BB->getNextNode();
225185

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);
227191

228192
// Since only the blocks are to be moved around (but the control flow must
229193
// not change), if there were any fall-throughs (to/from adjacent blocks),
@@ -251,12 +215,14 @@ void ARMBlockPlacement::moveBasicBlock(MachineBasicBlock *BB,
251215
// Fix fall-through to the moved BB from the one that used to be before it.
252216
if (BBPrevious->isSuccessor(BB))
253217
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);
257221
// Fix fall through from the moved BB to the one that used to follow.
258222
if (BBNext && BB->isSuccessor(BBNext))
259223
FixFallthrough(BB, BBNext);
260224

261-
BBUtils->adjustBBOffsetsAfter(After);
225+
F->RenumberBlocks();
226+
BBUtils->computeAllBlockSizes();
227+
BBUtils->adjustBBOffsetsAfter(&F->front());
262228
}

0 commit comments

Comments
 (0)