summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/BranchFolding.cpp44
-rw-r--r--test/CodeGen/X86/tail-opts.ll27
2 files changed, 61 insertions, 10 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 9add42af6f..ea6a223884 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -495,6 +495,15 @@ static bool ProfitableToMerge(MachineBasicBlock *MBB1,
return true;
}
+ // If one of the blocks can be completely merged and happens to be in
+ // a position where the other could fall through into it, merge any number
+ // of instructions, because it can be done without a branch.
+ // TODO: If the blocks are not adjacent, move one of them so that they are?
+ if (MBB1->isLayoutSuccessor(MBB2) && I2 == MBB2->begin())
+ return true;
+ if (MBB2->isLayoutSuccessor(MBB1) && I1 == MBB1->begin())
+ return true;
+
// If both blocks have an unconditional branch temporarily stripped out,
// treat that as an additional common instruction.
if (MBB1 != PredBB && MBB2 != PredBB &&
@@ -716,16 +725,31 @@ bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB,
MachineBasicBlock *EntryBB = MergePotentials.begin()->getBlock()->
getParent()->begin();
unsigned commonTailIndex = SameTails.size();
- for (unsigned i=0; i<SameTails.size(); i++) {
- MachineBasicBlock *MBB = SameTails[i].getBlock();
- if (MBB == EntryBB)
- continue;
- if (MBB == PredBB) {
- commonTailIndex = i;
- break;
+ // If there are two blocks, check to see if one can be made to fall through
+ // into the other.
+ if (SameTails.size() == 2 &&
+ SameTails[0].getBlock()->isLayoutSuccessor(SameTails[1].getBlock()) &&
+ SameTails[1].tailIsWholeBlock())
+ commonTailIndex = 1;
+ else if (SameTails.size() == 2 &&
+ SameTails[1].getBlock()->isLayoutSuccessor(
+ SameTails[0].getBlock()) &&
+ SameTails[0].tailIsWholeBlock())
+ commonTailIndex = 0;
+ else {
+ // Otherwise just pick one, favoring the fall-through predecessor if
+ // there is one.
+ for (unsigned i = 0, e = SameTails.size(); i != e; ++i) {
+ MachineBasicBlock *MBB = SameTails[i].getBlock();
+ if (MBB == EntryBB && SameTails[i].tailIsWholeBlock())
+ continue;
+ if (MBB == PredBB) {
+ commonTailIndex = i;
+ break;
+ }
+ if (SameTails[i].tailIsWholeBlock())
+ commonTailIndex = i;
}
- if (MBB->begin() == SameTails[i].getTailStartPos())
- commonTailIndex = i;
}
if (commonTailIndex == SameTails.size() ||
@@ -1049,7 +1073,7 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB,
continue;
// Don't duplicate into a fall-through predecessor unless its the
// only predecessor.
- if (&*next(MachineFunction::iterator(PredBB)) == TailBB &&
+ if (PredBB->isLayoutSuccessor(TailBB) &&
PrevFallsThrough &&
TailBB->pred_size() != 1)
continue;
diff --git a/test/CodeGen/X86/tail-opts.ll b/test/CodeGen/X86/tail-opts.ll
index 79825b7fd5..fdf96d6086 100644
--- a/test/CodeGen/X86/tail-opts.ll
+++ b/test/CodeGen/X86/tail-opts.ll
@@ -266,3 +266,30 @@ bb3: ; preds = %bb2, %bb1, %lvalue_
declare fastcc i32 @lvalue_p(%union.tree_node* nocapture) nounwind readonly
declare fastcc %union.tree_node* @default_conversion(%union.tree_node*) nounwind
+
+
+; If one tail merging candidate falls through into the other,
+; tail merging is likely profitable regardless of how few
+; instructions are involved. This function should have only
+; one ret instruction.
+
+; CHECK: foo:
+; CHECK: call func
+; CHECK-NEXT: .LBB5_2:
+; CHECK-NEXT: addq $8, %rsp
+; CHECK-NEXT: ret
+
+define void @foo(i1* %V) nounwind {
+entry:
+ %t0 = icmp eq i1* %V, null
+ br i1 %t0, label %return, label %bb
+
+bb:
+ call void @func()
+ ret void
+
+return:
+ ret void
+}
+
+declare void @func()