diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp index ab1edf47d8db..f92e921949a0 100644 --- a/llvm/lib/Transforms/Utils/LCSSA.cpp +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp @@ -71,24 +71,26 @@ static bool isExitBlock(BasicBlock *BB, return is_contained(ExitBlocks, BB); } +// Cache the Loop ExitBlocks computed during the analysis. We expect to get a +// lot of instructions within the same loops, computing the exit blocks is +// expensive, and we're not mutating the loop structure. +using LoopExitBlocksTy = SmallDenseMap>; + /// For every instruction from the worklist, check to see if it has any uses /// that are outside the current loop. If so, insert LCSSA PHI nodes and /// rewrite the uses. -bool llvm::formLCSSAForInstructions(SmallVectorImpl &Worklist, - const DominatorTree &DT, const LoopInfo &LI, - ScalarEvolution *SE, - SmallVectorImpl *PHIsToRemove, - SmallVectorImpl *InsertedPHIs) { +static bool +formLCSSAForInstructionsImpl(SmallVectorImpl &Worklist, + const DominatorTree &DT, const LoopInfo &LI, + ScalarEvolution *SE, + SmallVectorImpl *PHIsToRemove, + SmallVectorImpl *InsertedPHIs, + LoopExitBlocksTy &LoopExitBlocks) { SmallVector UsesToRewrite; SmallSetVector LocalPHIsToRemove; PredIteratorCache PredCache; bool Changed = false; - // Cache the Loop ExitBlocks across this loop. We expect to get a lot of - // instructions within the same loops, computing the exit blocks is - // expensive, and we're not mutating the loop structure. - SmallDenseMap> LoopExitBlocks; - while (!Worklist.empty()) { UsesToRewrite.clear(); @@ -317,13 +319,28 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl &Worklist, return Changed; } +/// For every instruction from the worklist, check to see if it has any uses +/// that are outside the current loop. If so, insert LCSSA PHI nodes and +/// rewrite the uses. +bool llvm::formLCSSAForInstructions(SmallVectorImpl &Worklist, + const DominatorTree &DT, const LoopInfo &LI, + ScalarEvolution *SE, + SmallVectorImpl *PHIsToRemove, + SmallVectorImpl *InsertedPHIs) { + LoopExitBlocksTy LoopExitBlocks; + + return formLCSSAForInstructionsImpl(Worklist, DT, LI, SE, PHIsToRemove, + InsertedPHIs, LoopExitBlocks); +} + // Compute the set of BasicBlocks in the loop `L` dominating at least one exit. static void computeBlocksDominatingExits( - Loop &L, const DominatorTree &DT, SmallVector &ExitBlocks, + Loop &L, const DominatorTree &DT, + const SmallVectorImpl &ExitBlocks, SmallSetVector &BlocksDominatingExits) { // We start from the exit blocks, as every block trivially dominates itself // (not strictly). - SmallVector BBWorklist(ExitBlocks); + SmallVector BBWorklist(ExitBlocks.begin(), ExitBlocks.end()); while (!BBWorklist.empty()) { BasicBlock *BB = BBWorklist.pop_back_val(); @@ -360,8 +377,9 @@ static void computeBlocksDominatingExits( } } -bool llvm::formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI, - ScalarEvolution *SE) { +static bool formLCSSAImpl(Loop &L, const DominatorTree &DT, const LoopInfo *LI, + ScalarEvolution *SE, + LoopExitBlocksTy &LoopExitBlocks) { bool Changed = false; #ifdef EXPENSIVE_CHECKS @@ -372,8 +390,9 @@ bool llvm::formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI, } #endif - SmallVector ExitBlocks; - L.getExitBlocks(ExitBlocks); + if (!LoopExitBlocks.count(&L)) + L.getExitBlocks(LoopExitBlocks[&L]); + const SmallVectorImpl &ExitBlocks = LoopExitBlocks[&L]; if (ExitBlocks.empty()) return false; @@ -414,26 +433,43 @@ bool llvm::formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI, } } - Changed = formLCSSAForInstructions(Worklist, DT, *LI, SE); + Changed = formLCSSAForInstructionsImpl(Worklist, DT, *LI, SE, nullptr, + nullptr, LoopExitBlocks); assert(L.isLCSSAForm(DT)); return Changed; } +bool llvm::formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI, + ScalarEvolution *SE) { + LoopExitBlocksTy LoopExitBlocks; + + return formLCSSAImpl(L, DT, LI, SE, LoopExitBlocks); +} + /// Process a loop nest depth first. -bool llvm::formLCSSARecursively(Loop &L, const DominatorTree &DT, - const LoopInfo *LI, ScalarEvolution *SE) { +static bool formLCSSARecursivelyImpl(Loop &L, const DominatorTree &DT, + const LoopInfo *LI, ScalarEvolution *SE, + LoopExitBlocksTy &LoopExitBlocks) { bool Changed = false; // Recurse depth-first through inner loops. for (Loop *SubLoop : L.getSubLoops()) - Changed |= formLCSSARecursively(*SubLoop, DT, LI, SE); + Changed |= formLCSSARecursivelyImpl(*SubLoop, DT, LI, SE, LoopExitBlocks); - Changed |= formLCSSA(L, DT, LI, SE); + Changed |= formLCSSAImpl(L, DT, LI, SE, LoopExitBlocks); return Changed; } +/// Process a loop nest depth first. +bool llvm::formLCSSARecursively(Loop &L, const DominatorTree &DT, + const LoopInfo *LI, ScalarEvolution *SE) { + LoopExitBlocksTy LoopExitBlocks; + + return formLCSSARecursivelyImpl(L, DT, LI, SE, LoopExitBlocks); +} + /// Process all loops in the function, inner-most out. static bool formLCSSAOnAllLoops(const LoopInfo *LI, const DominatorTree &DT, ScalarEvolution *SE) {