Index: lib/CodeGen/BranchFolding.h =================================================================== --- lib/CodeGen/BranchFolding.h +++ lib/CodeGen/BranchFolding.h @@ -33,10 +33,12 @@ MBFIWrapper &MBFI, const MachineBranchProbabilityInfo &MBPI); - bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, - const TargetRegisterInfo *tri, MachineModuleInfo *mmi, - MachineLoopInfo *mli = nullptr, - bool AfterPlacement = false); + bool OptimizeFunction( + MachineFunction &MF, const TargetInstrInfo *tii, + const TargetRegisterInfo *tri, MachineModuleInfo *mmi, + MachineLoopInfo *mli = nullptr, + SmallPtrSet *unavoidables = nullptr, + bool AfterPlacement = false); private: class MergePotentialsElt { @@ -102,6 +104,7 @@ const TargetRegisterInfo *TRI; MachineModuleInfo *MMI; MachineLoopInfo *MLI; + SmallPtrSet *UnavoidableBlocks; RegScavenger *RS; public: Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -140,6 +140,8 @@ FuncletMembership.erase(MBB); if (MLI) MLI->removeBlock(MBB); + if (UnavoidableBlocks) + UnavoidableBlocks->erase(MBB); } /// OptimizeImpDefsBlock - If a basic block is just a bunch of implicit_def @@ -198,11 +200,10 @@ /// OptimizeFunction - Perhaps branch folding, tail merging and other /// CFG optimizations on the given function. Block placement changes the layout /// and may create new tail merging opportunities. -bool BranchFolder::OptimizeFunction(MachineFunction &MF, - const TargetInstrInfo *tii, - const TargetRegisterInfo *tri, - MachineModuleInfo *mmi, - MachineLoopInfo *mli, bool AfterPlacement) { +bool BranchFolder::OptimizeFunction( + MachineFunction &MF, const TargetInstrInfo *tii, + const TargetRegisterInfo *tri, MachineModuleInfo *mmi, MachineLoopInfo *mli, + SmallPtrSet *unavoidables, bool AfterPlacement) { if (!tii) return false; TriedMerging.clear(); @@ -212,6 +213,7 @@ TRI = tri; MMI = mmi; MLI = mli; + UnavoidableBlocks = unavoidables; RS = nullptr; // Use a RegScavenger to help update liveness when required. @@ -462,6 +464,9 @@ if (MachineLoop *ML = MLI->getLoopFor(&CurMBB)) ML->addBasicBlockToLoop(NewMBB, MLI->getBase()); + if (UnavoidableBlocks && UnavoidableBlocks->count(&CurMBB)) + UnavoidableBlocks->insert(NewMBB); + // NewMBB inherits CurMBB's block frequency. MBBFreqInfo.setBlockFreq(NewMBB, MBBFreqInfo.getBlockFreq(&CurMBB)); Index: lib/CodeGen/MachineBlockPlacement.cpp =================================================================== --- lib/CodeGen/MachineBlockPlacement.cpp +++ lib/CodeGen/MachineBlockPlacement.cpp @@ -262,6 +262,9 @@ /// all terminators of the MachineFunction. SmallPtrSet UnavoidableBlocks; + /// \brief A flag to show if UnavoidableBlocks is calculated. + bool HasUnavoidableBlocks; + /// \brief Allocator and owner of BlockChain structures. /// /// We build BlockChains lazily while processing the loop structure of @@ -1389,7 +1392,7 @@ /// When OutlineOpitonalBranches is on, this method colects BBs that /// dominates all terminator blocks of the function \p F. void MachineBlockPlacement::collectMustExecuteBBs() { - if (OutlineOptionalBranches) { + if (OutlineOptionalBranches && !HasUnavoidableBlocks) { // Find the nearest common dominator of all of F's terminators. MachineBasicBlock *Terminator = nullptr; for (MachineBasicBlock &MBB : *F) { @@ -1408,6 +1411,7 @@ UnavoidableBlocks.insert(&MBB); } } + HasUnavoidableBlocks = true; } } @@ -1657,6 +1661,7 @@ TII = MF.getSubtarget().getInstrInfo(); TLI = MF.getSubtarget().getTargetLowering(); MDT = &getAnalysis(); + HasUnavoidableBlocks = false; assert(BlockToChain.empty()); buildCFGChains(); @@ -1673,9 +1678,11 @@ BranchFolder BF(/*EnableTailMerge=*/true, /*CommonHoist=*/false, *MBFI, *MBPI); - if (BF.OptimizeFunction(MF, TII, MF.getSubtarget().getRegisterInfo(), - getAnalysisIfAvailable(), MLI, - /*AfterBlockPlacement=*/true)) { + if (BF.OptimizeFunction( + MF, TII, MF.getSubtarget().getRegisterInfo(), + getAnalysisIfAvailable(), MLI, + (OutlineOptionalBranches ? &UnavoidableBlocks : nullptr), + /*AfterBlockPlacement=*/true)) { // Redo the layout if tail merging creates/removes/moves blocks. BlockToChain.clear(); ChainAllocator.DestroyAll(); Index: test/CodeGen/AArch64/tailmerging_in_mbp.ll =================================================================== --- test/CodeGen/AArch64/tailmerging_in_mbp.ll +++ test/CodeGen/AArch64/tailmerging_in_mbp.ll @@ -1,4 +1,5 @@ -; RUN: llc <%s -march=aarch64 | FileCheck %s +; RUN: llc < %s -march=aarch64 | FileCheck %s +; RUN: llc < %s -march=aarch64 -outline-optional-branches | FileCheck %s --check-prefix=OUTLINE ; CHECK-LABEL: test: ; CHECK: LBB0_7: @@ -61,3 +62,14 @@ %j.4 = add i64 %j.3, 10 ret i64 %j.4 } +; OUTLINE-LABEL: test: +; OUTLINE: entry +; OUTLINE: for.end +; OUTLINE: for.body.preheader +; OUTLINE: cond.false.i +; OUTLINE: cond.false6.i +; OUTLINE: cond.false11.i +; OUTLINE: cond.false12.i +; OUTLINE: if.end +; OUTLINE: LBB0_9: +