Index: include/llvm/Transforms/Utils/LoopUtils.h =================================================================== --- include/llvm/Transforms/Utils/LoopUtils.h +++ include/llvm/Transforms/Utils/LoopUtils.h @@ -323,6 +323,25 @@ BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, bool PreserveLCSSA); +/// \brief Ensures LCSSA form for instruction Inst in the scope of loop L. +/// +/// For the given instruction in the loop which have uses outside of the loop, +/// an LCSSA PHI node is inserted and the uses outside the loop are rewritten to +/// use this node. +/// +/// LoopInfo and DominatorTree are required and preserved. +/// ExitBlocks is a vector containing exit blocks of the loop L. +/// PredCache should be a valid PredIteratorCache object. +/// +/// ExitBlocks and PredCache are used to avoid redundant recomputations for +/// every call of this routine. +/// +/// Returns true if any modifications are made. +bool formLCSSAForInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, + LoopInfo &LI, + const SmallVectorImpl &ExitBlocks, + PredIteratorCache &PredCache); + /// \brief Put loop into LCSSA form. /// /// Looks at all instructions in the loop which have uses outside of the Index: lib/Transforms/Utils/LCSSA.cpp =================================================================== --- lib/Transforms/Utils/LCSSA.cpp +++ lib/Transforms/Utils/LCSSA.cpp @@ -60,9 +60,10 @@ /// Given an instruction in the loop, check to see if it has any uses that are /// outside the current loop. If so, insert LCSSA PHI nodes and rewrite the /// uses. -static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, - const SmallVectorImpl &ExitBlocks, - PredIteratorCache &PredCache, LoopInfo *LI) { +bool llvm::formLCSSAForInstruction( + Loop &L, Instruction &Inst, DominatorTree &DT, LoopInfo &LI, + const SmallVectorImpl &ExitBlocks, + PredIteratorCache &PredCache) { SmallVector UsesToRewrite; // Tokens cannot be used in PHI nodes, so we skip over them. @@ -145,7 +146,7 @@ // have uses outside of L2. Remember all PHIs in such situation as to // revisit than later on. FIXME: Remove this if indirectbr support into // LoopSimplify gets improved. - if (auto *OtherLoop = LI->getLoopFor(ExitBB)) + if (auto *OtherLoop = LI.getLoopFor(ExitBB)) if (!L.contains(OtherLoop)) PostProcessPHIs.push_back(PN); } @@ -181,7 +182,7 @@ continue; BasicBlock *PHIBB = I->getParent(); - Loop *OtherLoop = LI->getLoopFor(PHIBB); + Loop *OtherLoop = LI.getLoopFor(PHIBB); SmallVector EBs; OtherLoop->getExitBlocks(EBs); if (EBs.empty()) @@ -190,7 +191,7 @@ // Recurse and re-process each PHI instruction. FIXME: we should really // convert this entire thing to a worklist approach where we process a // vector of instructions... - processInstruction(*OtherLoop, *I, DT, EBs, PredCache, LI); + formLCSSAForInstruction(*OtherLoop, *I, DT, LI, EBs, PredCache); } // Remove PHI nodes that did not have any uses rewritten. @@ -243,7 +244,7 @@ !isa(I.user_back()))) continue; - Changed |= processInstruction(L, I, DT, ExitBlocks, PredCache, LI); + Changed |= formLCSSAForInstruction(L, I, DT, *LI, ExitBlocks, PredCache); } }