Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp =================================================================== --- llvm/lib/Transforms/IPO/LoopExtractor.cpp +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp @@ -15,10 +15,11 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AssumptionCache.h" -#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" +#include "llvm/IR/OptBisect.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/IPO.h" @@ -35,16 +36,17 @@ STATISTIC(NumExtracted, "Number of loops extracted"); namespace { - struct LoopExtractor : public LoopPass { + struct LoopExtractor : public ModulePass { static char ID; // Pass identification, replacement for typeid unsigned NumLoops; explicit LoopExtractor(unsigned numLoops = ~0) - : LoopPass(ID), NumLoops(numLoops) { + : ModulePass(ID), NumLoops(numLoops) { initializeLoopExtractorPass(*PassRegistry::getPassRegistry()); } - bool runOnLoop(Loop *L, LPPassManager &) override; + bool runOnModule(Module &M) override; + bool visitLoop(Loop *L, DominatorTree &DT, LoopInfo &LI); void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequiredID(BreakCriticalEdgesID); @@ -62,6 +64,7 @@ INITIALIZE_PASS_DEPENDENCY(BreakCriticalEdges) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_END(LoopExtractor, "loop-extract", "Extract loops into new functions", false, false) @@ -82,20 +85,47 @@ // Pass *llvm::createLoopExtractorPass() { return new LoopExtractor(); } -bool LoopExtractor::runOnLoop(Loop *L, LPPassManager &LPM) { - if (skipLoop(L)) +bool LoopExtractor::runOnModule(Module &M) { + if (skipModule(M)) return false; - // Only visit top-level loops. - if (L->getParentLoop()) + if (M.empty()) return false; + bool Changed = false; + SmallVector TopLevelLoops; + + // The end of the function list may change (new functions will be added at the + // end), so we run from the first to the current last. + auto I = M.begin(), E = --M.end(); + while (true) { + Function &F = *I; + + if (!F.empty()) { + DominatorTree &DT = getAnalysis(F).getDomTree(); + LoopInfo &LI = getAnalysis(F).getLoopInfo(); + + // Only visit top-level loops. + // Save the list, as it may change. + TopLevelLoops.assign(LI.begin(), LI.end()); + for (Loop *L : TopLevelLoops) + Changed |= visitLoop(L, DT, LI); + } + + // If this is the last function. + if (I == E) + break; + + ++I; + } + return Changed; +} + +bool LoopExtractor::visitLoop(Loop *L, DominatorTree &DT, LoopInfo &LI) { // If LoopSimplify form is not available, stay out of trouble. if (!L->isLoopSimplifyForm()) return false; - DominatorTree &DT = getAnalysis().getDomTree(); - LoopInfo &LI = getAnalysis().getLoopInfo(); bool Changed = false; // If there is more than one top-level loop in this function, extract all of @@ -148,9 +178,6 @@ CodeExtractor Extractor(DT, *L, false, nullptr, nullptr, AC); if (Extractor.extractCodeRegion(CEAC) != nullptr) { Changed = true; - // After extraction, the loop is replaced by a function call, so - // we shouldn't try to run any more loop passes on it. - LPM.markLoopAsDeleted(*L); LI.erase(L); } ++NumExtracted;