diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index 9add42af6fe..ea6a2238843 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; iisLayoutSuccessor(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 79825b7fd59..fdf96d60866 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()