Index: include/llvm/Analysis/PostDominators.h =================================================================== --- include/llvm/Analysis/PostDominators.h +++ include/llvm/Analysis/PostDominators.h @@ -29,6 +29,8 @@ class PostDominatorTree : public PostDomTreeBase { public: using Base = PostDomTreeBase; + PostDominatorTree() = default; + explicit PostDominatorTree(Function &F) { recalculate(F); } /// Handle invalidation explicitly. bool invalidate(Function &F, const PreservedAnalyses &PA, Index: include/llvm/Transforms/Utils/BasicBlockUtils.h =================================================================== --- include/llvm/Transforms/Utils/BasicBlockUtils.h +++ include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -34,6 +34,7 @@ class LoopInfo; class MDNode; class MemoryDependenceResults; +class PostDominatorTree; class ReturnInst; class TargetLibraryInfo; class Value; @@ -82,14 +83,16 @@ /// during critical edge splitting. struct CriticalEdgeSplittingOptions { DominatorTree *DT; + PostDominatorTree *PDT; LoopInfo *LI; bool MergeIdenticalEdges = false; bool DontDeleteUselessPHIs = false; bool PreserveLCSSA = false; CriticalEdgeSplittingOptions(DominatorTree *DT = nullptr, - LoopInfo *LI = nullptr) - : DT(DT), LI(LI) {} + LoopInfo *LI = nullptr, + PostDominatorTree *PDT = nullptr) + : DT(DT), PDT(PDT), LI(LI) {} CriticalEdgeSplittingOptions &setMergeIdenticalEdges() { MergeIdenticalEdges = true; Index: lib/Transforms/Scalar/LinearizeCFG.cpp =================================================================== --- lib/Transforms/Scalar/LinearizeCFG.cpp +++ lib/Transforms/Scalar/LinearizeCFG.cpp @@ -2605,7 +2605,7 @@ SmallVector OrderedUnstructuredBlocks; // FIXME: PDT update - CriticalEdgeSplittingOptions CESO(DT); + CriticalEdgeSplittingOptions CESO(DT, nullptr, PDT); SplitAllCriticalEdges(*Func, CESO); //DenseSet UnstructuredBlocks; Index: lib/Transforms/Utils/BreakCriticalEdges.cpp =================================================================== --- lib/Transforms/Utils/BreakCriticalEdges.cpp +++ lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -23,6 +23,7 @@ #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/CFG.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" @@ -48,10 +49,14 @@ bool runOnFunction(Function &F) override { auto *DTWP = getAnalysisIfAvailable(); auto *DT = DTWP ? &DTWP->getDomTree() : nullptr; + + auto *PDTWP = getAnalysisIfAvailable(); + auto *PDT = PDTWP ? &PDTWP->getPostDomTree() : nullptr; + auto *LIWP = getAnalysisIfAvailable(); auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr; unsigned N = - SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI)); + SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI, PDT)); NumBroken += N; return N > 0; } @@ -197,11 +202,12 @@ // If we have nothing to update, just return. auto *DT = Options.DT; + auto *PDT = Options.PDT; auto *LI = Options.LI; - if (!DT && !LI) + if (!DT && !PDT && !LI) return NewBB; - if (DT) { + if (DT || PDT) { // Update the DominatorTree. // ---> NewBB -----\ // / V @@ -217,7 +223,10 @@ if (llvm::find(successors(TIBB), DestBB) == succ_end(TIBB)) Updates.push_back({DominatorTree::Delete, TIBB, DestBB}); - DT->applyUpdates(Updates); + if (DT) + DT->applyUpdates(Updates); + if (PDT) + PDT->applyUpdates(Updates); } // Update LoopInfo if it is around. Index: unittests/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- unittests/Transforms/Utils/BasicBlockUtils.cpp +++ unittests/Transforms/Utils/BasicBlockUtils.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" @@ -50,3 +51,31 @@ SplitBlockPredecessors(&F->getEntryBlock(), {}, "split.entry", &DT); EXPECT_TRUE(DT.verify()); } + +TEST(BasicBlockUtils, SplitCriticalEdge) { + LLVMContext C; + + std::unique_ptr M = parseIR( + C, + "define void @crit_edge(i1 %cond0, i1 %cond1) {\n" + "entry:\n" + " br i1 %cond0, label %bb0, label %bb1\n" + "bb0:\n" + " br label %bb1\n" + "bb1:\n" + " br label %bb2\n" + "bb2:\n" + " ret void\n" + "}\n" + "\n" + ); + + auto *F = M->getFunction("crit_edge"); + DominatorTree DT(*F); + PostDominatorTree PDT(*F); + + CriticalEdgeSplittingOptions CESO(&DT, nullptr, &PDT); + EXPECT_EQ(1u, SplitAllCriticalEdges(*F, CESO)); + EXPECT_TRUE(DT.verify()); + EXPECT_TRUE(PDT.verify()); +}