[llvm-commits] CVS: llvm/lib/CodeGen/BranchFolding.cpp
Chris Lattner
sabre at nondot.org
Sun Oct 29 13:05:55 PST 2006
Changes in directory llvm/lib/CodeGen:
BranchFolding.cpp updated: 1.26 -> 1.27
---
Log message:
Make CanFallThrough more intelligent (so it can handle blocks with (e.g.) no
successors), and make island block movement more general.
This compiles CodeGen/X86/2006-04-27-ISelFoldingBug.ll to:
_loadAndRLEsource_no_exit_2E_1_label_2E_0:
subl $8, %esp
movl %esi, 4(%esp)
movl %ebx, (%esp)
movl 16(%esp), %eax
movl 12(%esp), %ecx
LBB1_3: #label.0
movl _last, %edx
movl %edx, %esi
incl %esi
movl %esi, _last
movl %ecx, %ebx
# TRUNCATE movb %bl, %bl
movl _block, %esi
movb %bl, 1(%esi,%edx)
cmpl %eax, _last
jge LBB1_2 #codeRepl5.exitStub
LBB1_4: #label.0
cmpl $257, %ecx
je LBB1_2 #codeRepl5.exitStub
LBB1_1: #label.0.no_exit.1_crit_edge.exitStub
movl $1, %eax
movl (%esp), %ebx
movl 4(%esp), %esi
addl $8, %esp
ret
LBB1_2: #codeRepl5.exitStub
xorl %eax, %eax
movl (%esp), %ebx
movl 4(%esp), %esi
addl $8, %esp
ret
instead of:
_loadAndRLEsource_no_exit_2E_1_label_2E_0:
subl $8, %esp
movl %esi, 4(%esp)
movl %ebx, (%esp)
movl 16(%esp), %eax
movl 12(%esp), %ecx
jmp LBB1_3 #label.0
LBB1_1: #label.0.no_exit.1_crit_edge.exitStub
movl $1, %eax
movl (%esp), %ebx
movl 4(%esp), %esi
addl $8, %esp
ret
LBB1_2: #codeRepl5.exitStub
xorl %eax, %eax
movl (%esp), %ebx
movl 4(%esp), %esi
addl $8, %esp
ret
LBB1_3: #label.0
movl _last, %edx
movl %edx, %esi
incl %esi
movl %esi, _last
movl %ecx, %ebx
# TRUNCATE movb %bl, %bl
movl _block, %esi
movb %bl, 1(%esi,%edx)
cmpl %eax, _last
jge LBB1_2 #codeRepl5.exitStub
LBB1_4: #label.0
cmpl $257, %ecx
jne LBB1_1 #label.0.no_exit.1_crit_edge.exitStub
jmp LBB1_2 #codeRepl5.exitStub
... which is much better layout :)
---
Diffs of the changes: (+94 -62)
BranchFolding.cpp | 156 ++++++++++++++++++++++++++++++++----------------------
1 files changed, 94 insertions(+), 62 deletions(-)
Index: llvm/lib/CodeGen/BranchFolding.cpp
diff -u llvm/lib/CodeGen/BranchFolding.cpp:1.26 llvm/lib/CodeGen/BranchFolding.cpp:1.27
--- llvm/lib/CodeGen/BranchFolding.cpp:1.26 Sat Oct 28 13:34:47 2006
+++ llvm/lib/CodeGen/BranchFolding.cpp Sun Oct 29 15:05:41 2006
@@ -48,6 +48,11 @@
bool OptimizeBranches(MachineFunction &MF);
void OptimizeBlock(MachineBasicBlock *MBB);
void RemoveDeadBlock(MachineBasicBlock *MBB);
+
+ bool CanFallThrough(MachineBasicBlock *CurBB);
+ bool CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable,
+ MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ const std::vector<MachineOperand> &Cond);
};
}
@@ -443,19 +448,37 @@
}
}
-/// CanFallThrough - Return true of the specified branch condition can transfer
-/// control to FallthroughBlock, the block immediately after the branch.
-static bool CanFallThrough(MachineBasicBlock *TBB,
- MachineBasicBlock *FBB,
- const std::vector<MachineOperand> &Cond,
- MachineFunction::iterator FallthroughBlock) {
+/// CanFallThrough - Return true if the specified block (with the specified
+/// branch condition) can implicitly transfer control to the block after it by
+/// falling off the end of it. This should return false if it can reach the
+/// block after it, but it uses an explicit branch to do so (e.g. a table jump).
+///
+/// True is a conservative answer.
+///
+bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB,
+ bool BranchUnAnalyzable,
+ MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ const std::vector<MachineOperand> &Cond) {
+ MachineFunction::iterator Fallthrough = CurBB;
+ ++Fallthrough;
+ // If FallthroughBlock is off the end of the function, it can't fall through.
+ if (Fallthrough == CurBB->getParent()->end())
+ return false;
+
+ // If FallthroughBlock isn't a successor of CurBB, no fallthrough is possible.
+ if (!CurBB->isSuccessor(Fallthrough))
+ return false;
+
+ // If we couldn't analyze the branch, assume it could fall through.
+ if (BranchUnAnalyzable) return true;
+
// If there is no branch, control always falls through.
if (TBB == 0) return true;
// If there is some explicit branch to the fallthrough block, it can obviously
// reach, even though the branch should get folded to fall through implicitly.
- if (MachineFunction::iterator(TBB) == FallthroughBlock ||
- MachineFunction::iterator(FBB) == FallthroughBlock)
+ if (MachineFunction::iterator(TBB) == Fallthrough ||
+ MachineFunction::iterator(FBB) == Fallthrough)
return true;
// If it's an unconditional branch to some block not the fall through, it
@@ -467,6 +490,20 @@
return FBB == 0;
}
+/// CanFallThrough - Return true if the specified can implicitly transfer
+/// control to the block after it by falling off the end of it. This should
+/// return false if it can reach the block after it, but it uses an explicit
+/// branch to do so (e.g. a table jump).
+///
+/// True is a conservative answer.
+///
+bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB) {
+ MachineBasicBlock *TBB = 0, *FBB = 0;
+ std::vector<MachineOperand> Cond;
+ bool CurUnAnalyzable = TII->AnalyzeBranch(*CurBB, TBB, FBB, Cond);
+ return CanFallThrough(CurBB, CurUnAnalyzable, TBB, FBB, Cond);
+}
+
/// OptimizeBlock - Analyze and optimize control flow related to the specified
/// block. This is never called on the entry block.
void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
@@ -504,8 +541,8 @@
MachineBasicBlock *PriorTBB = 0, *PriorFBB = 0;
std::vector<MachineOperand> PriorCond;
- bool PriorUnAnalyzable = false;
- PriorUnAnalyzable = TII->AnalyzeBranch(PrevBB, PriorTBB, PriorFBB, PriorCond);
+ bool PriorUnAnalyzable =
+ TII->AnalyzeBranch(PrevBB, PriorTBB, PriorFBB, PriorCond);
if (!PriorUnAnalyzable) {
// If the CFG for the prior block has extra edges, remove them.
MadeChange |= CorrectExtraCFGEdges(PrevBB, PriorTBB, PriorFBB,
@@ -561,7 +598,8 @@
// Analyze the branch in the current block.
MachineBasicBlock *CurTBB = 0, *CurFBB = 0;
std::vector<MachineOperand> CurCond;
- if (!TII->AnalyzeBranch(*MBB, CurTBB, CurFBB, CurCond)) {
+ bool CurUnAnalyzable = TII->AnalyzeBranch(*MBB, CurTBB, CurFBB, CurCond);
+ if (!CurUnAnalyzable) {
// If the CFG for the prior block has extra edges, remove them.
MadeChange |= CorrectExtraCFGEdges(*MBB, CurTBB, CurFBB,
!CurCond.empty(),
@@ -630,62 +668,56 @@
// Add the branch back if the block is more than just an uncond branch.
TII->InsertBranch(*MBB, CurTBB, 0, CurCond);
}
-
- // If the prior block doesn't fall through into this block, and if this
- // block doesn't fall through into some other block, see if we can find a
- // place to move this block where a fall-through will happen.
- if (!PriorUnAnalyzable && !CanFallThrough(PriorTBB, PriorFBB,
- PriorCond, MBB)) {
- // Now we know that there was no fall-through into this block, check to
- // see if it has fall-throughs.
- if (!CanFallThrough(CurTBB, CurFBB, CurCond, FallThrough)) {
-
- // Check all the predecessors of this block. If one of them has no fall
- // throughs, move this block right after it.
- for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
- E = MBB->pred_end(); PI != E; ++PI) {
- // Analyze the branch at the end of the pred.
- MachineBasicBlock *PredBB = *PI;
- MachineFunction::iterator PredFallthrough = PredBB; ++PredFallthrough;
- MachineBasicBlock *PredTBB = 0, *PredFBB = 0;
- std::vector<MachineOperand> PredCond;
- if (PredBB != MBB &&
- !TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond) &&
- !CanFallThrough(PredTBB, PredFBB, PredCond, PredFallthrough)) {
- MBB->moveAfter(PredBB);
- MadeChange = true;
- return OptimizeBlock(MBB);
- }
- }
-
- // Check all successors to see if we can move this block before it.
- for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
- E = MBB->succ_end(); SI != E; ++SI) {
- // Analyze the branch at the end of the block before the succ.
- MachineBasicBlock *SuccBB = *SI;
- MachineFunction::iterator SuccPrev = SuccBB; --SuccPrev;
- MachineBasicBlock *SuccPrevTBB = 0, *SuccPrevFBB = 0;
- std::vector<MachineOperand> SuccPrevCond;
- if (SuccBB != MBB &&
- !TII->AnalyzeBranch(*SuccPrev, SuccPrevTBB, SuccPrevFBB,
- SuccPrevCond) &&
- !CanFallThrough(SuccPrevTBB, SuccPrevFBB, SuccPrevCond, SuccBB)) {
- MBB->moveBefore(SuccBB);
- MadeChange = true;
- return OptimizeBlock(MBB);
- }
+ }
+
+ // If the prior block doesn't fall through into this block, and if this
+ // block doesn't fall through into some other block, see if we can find a
+ // place to move this block where a fall-through will happen.
+ if (!CanFallThrough(&PrevBB, PriorUnAnalyzable,
+ PriorTBB, PriorFBB, PriorCond)) {
+ // Now we know that there was no fall-through into this block, check to
+ // see if it has a fall-through into its successor.
+ if (!CanFallThrough(MBB, CurUnAnalyzable, CurTBB, CurFBB, CurCond)) {
+ // Check all the predecessors of this block. If one of them has no fall
+ // throughs, move this block right after it.
+ for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+ E = MBB->pred_end(); PI != E; ++PI) {
+ // Analyze the branch at the end of the pred.
+ MachineBasicBlock *PredBB = *PI;
+ MachineFunction::iterator PredFallthrough = PredBB; ++PredFallthrough;
+ MachineBasicBlock *PredTBB = 0, *PredFBB = 0;
+ std::vector<MachineOperand> PredCond;
+ if (PredBB != MBB && !CanFallThrough(PredBB)) {
+ MBB->moveAfter(PredBB);
+ MadeChange = true;
+ return OptimizeBlock(MBB);
}
+ }
- // Okay, there is no really great place to put this block. If, however,
- // the block before this one would be a fall-through if this block were
- // removed, move this block to the end of the function.
- if (FallThrough != MBB->getParent()->end() &&
- CanFallThrough(PriorTBB, PriorFBB, PriorCond, FallThrough)) {
- MBB->moveAfter(--MBB->getParent()->end());
+ // Check all successors to see if we can move this block before it.
+ for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
+ E = MBB->succ_end(); SI != E; ++SI) {
+ // Analyze the branch at the end of the block before the succ.
+ MachineBasicBlock *SuccBB = *SI;
+ MachineFunction::iterator SuccPrev = SuccBB; --SuccPrev;
+ MachineBasicBlock *SuccPrevTBB = 0, *SuccPrevFBB = 0;
+ std::vector<MachineOperand> SuccPrevCond;
+ if (SuccBB != MBB && !CanFallThrough(SuccPrev)) {
+ MBB->moveBefore(SuccBB);
MadeChange = true;
- return;
+ return OptimizeBlock(MBB);
}
}
+
+ // Okay, there is no really great place to put this block. If, however,
+ // the block before this one would be a fall-through if this block were
+ // removed, move this block to the end of the function.
+ if (FallThrough != MBB->getParent()->end() &&
+ PrevBB.isSuccessor(FallThrough)) {
+ MBB->moveAfter(--MBB->getParent()->end());
+ MadeChange = true;
+ return;
+ }
}
}
}
More information about the llvm-commits
mailing list