aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/BranchFolding.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-01 01:16:12 +0000
committerChris Lattner <sabre@nondot.org>2006-11-01 01:16:12 +0000
commit1d08d83230338ca5969ff6ae6737a978336538bf (patch)
tree79f0222795d7af2aa8d1f861bacdf41e7975ed09 /lib/CodeGen/BranchFolding.cpp
parentd8ccff0c3e5028019a02dd44bf7d906efc9effd8 (diff)
downloadexternal_llvm-1d08d83230338ca5969ff6ae6737a978336538bf.zip
external_llvm-1d08d83230338ca5969ff6ae6737a978336538bf.tar.gz
external_llvm-1d08d83230338ca5969ff6ae6737a978336538bf.tar.bz2
make tail merging more aggressive. If two blocks share a common tail, but the
tail is not an entire block for either of them, pick one, split it, then merge the common part. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31336 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/BranchFolding.cpp')
-rw-r--r--lib/CodeGen/BranchFolding.cpp69
1 files changed, 53 insertions, 16 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 1138146..ac243f3 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -44,7 +44,9 @@ namespace {
bool TailMergeBlocks(MachineFunction &MF);
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
MachineBasicBlock *NewDest);
-
+ MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB,
+ MachineBasicBlock::iterator BBI1);
+
// Branch optzn.
bool OptimizeBranches(MachineFunction &MF);
void OptimizeBlock(MachineBasicBlock *MBB);
@@ -256,6 +258,31 @@ void BranchFolder::ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
++NumTailMerge;
}
+/// SplitMBBAt - Given a machine basic block and an iterator into it, split the
+/// MBB so that the part before the iterator falls into the part starting at the
+/// iterator. This returns the new MBB.
+MachineBasicBlock *BranchFolder::SplitMBBAt(MachineBasicBlock &CurMBB,
+ MachineBasicBlock::iterator BBI1) {
+ // Create the fall-through block.
+ MachineFunction::iterator MBBI = &CurMBB;
+ MachineBasicBlock *NewMBB = new MachineBasicBlock(CurMBB.getBasicBlock());
+ CurMBB.getParent()->getBasicBlockList().insert(++MBBI, NewMBB);
+
+ // Move all the successors of this block to the specified block.
+ while (!CurMBB.succ_empty()) {
+ MachineBasicBlock *S = *(CurMBB.succ_end()-1);
+ NewMBB->addSuccessor(S);
+ CurMBB.removeSuccessor(S);
+ }
+
+ // Add an edge from CurMBB to NewMBB for the fall-through.
+ CurMBB.addSuccessor(NewMBB);
+
+ // Splice the code over.
+ NewMBB->splice(NewMBB->end(), &CurMBB, BBI1, CurMBB.end());
+ return NewMBB;
+}
+
bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
MadeChange = false;
@@ -318,27 +345,37 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
// Otherwise, move the matching block to the right position.
std::swap(MergePotentials[FoundMatch], *(MergePotentials.end()-2));
}
-
- // If either block is the entire common tail, make the longer one branch to
- // the shorter one.
+
MachineBasicBlock *MBB2 = (MergePotentials.end()-2)->second;
- if (CurMBB->begin() == BBI1) {
- // Hack the end off MBB2, making it jump to CurMBB instead.
- ReplaceTailWithBranchTo(BBI2, CurMBB);
- // This modifies MBB2, so remove it from the worklist.
- MergePotentials.erase(MergePotentials.end()-2);
- MadeChange = true;
- continue;
- } else if (MBB2->begin() == BBI2) {
+
+ // If neither block is the entire common tail, split the tail of one block
+ // to make it redundant with the other tail.
+ if (CurMBB->begin() != BBI1 && MBB2->begin() != BBI2) {
+ if (0) { // Enable this to disable partial tail merges.
+ MergePotentials.pop_back();
+ continue;
+ }
+ // TODO: if we had some notion of which block was hotter, we could split
+ // the hot block, so it is the fall-through. For now, just split the
+ // second block.
+ MBB2 = SplitMBBAt(*MBB2, BBI2);
+ BBI2 = MBB2->begin();
+ (MergePotentials.end()-2)->second = MBB2;
+ }
+
+ if (MBB2->begin() == BBI2) {
// Hack the end off CurMBB, making it jump to MBBI@ instead.
ReplaceTailWithBranchTo(BBI1, MBB2);
// This modifies CurMBB, so remove it from the worklist.
MergePotentials.pop_back();
- MadeChange = true;
- continue;
+ } else {
+ assert(CurMBB->begin() == BBI1 && "Didn't split block correctly?");
+ // Hack the end off MBB2, making it jump to CurMBB instead.
+ ReplaceTailWithBranchTo(BBI2, CurMBB);
+ // This modifies MBB2, so remove it from the worklist.
+ MergePotentials.erase(MergePotentials.end()-2);
}
-
- MergePotentials.pop_back();
+ MadeChange = true;
}
return MadeChange;