Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -371,11 +371,9 @@ addExtensionsToPM(EP_LateLoopOptimizations, MPM); MPM.add(createLoopDeletionPass()); // Delete dead loops - if (EnableLoopInterchange) { - // FIXME: These are function passes and break the loop pass pipeline. + if (EnableLoopInterchange) MPM.add(createLoopInterchangePass()); // Interchange loops - MPM.add(createCFGSimplificationPass()); - } + if (!DisableUnrollLoops) MPM.add(createSimpleLoopUnrollPass(OptLevel)); // Unroll small loops addExtensionsToPM(EP_LoopOptimizerEnd, MPM); Index: lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- lib/Transforms/Scalar/LoopInterchange.cpp +++ lib/Transforms/Scalar/LoopInterchange.cpp @@ -20,6 +20,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/DependenceAnalysis.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" @@ -271,7 +272,7 @@ return true; } -static void populateWorklist(Loop &L, SmallVector &V) { +static LoopVector populateWorklist(Loop &L) { LLVM_DEBUG(dbgs() << "Calling populateWorklist on Func: " << L.getHeader()->getParent()->getName() << " Loop: %" << L.getHeader()->getName() << '\n'); @@ -282,16 +283,15 @@ // The current loop has multiple subloops in it hence it is not tightly // nested. // Discard all loops above it added into Worklist. - if (Vec->size() != 1) { - LoopList.clear(); - return; - } + if (Vec->size() != 1) + return {}; + LoopList.push_back(CurrentLoop); CurrentLoop = Vec->front(); Vec = &CurrentLoop->getSubLoops(); } LoopList.push_back(CurrentLoop); - V.push_back(std::move(LoopList)); + return LoopList; } static PHINode *getInductionVariable(Loop *L, ScalarEvolution *SE) { @@ -327,10 +327,9 @@ class LoopInterchangeLegality { public: LoopInterchangeLegality(Loop *Outer, Loop *Inner, ScalarEvolution *SE, - LoopInfo *LI, DominatorTree *DT, bool PreserveLCSSA, + LoopInfo *LI, DominatorTree *DT, OptimizationRemarkEmitter *ORE) - : OuterLoop(Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT), - PreserveLCSSA(PreserveLCSSA), ORE(ORE) {} + : OuterLoop(Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT), ORE(ORE) {} /// Check if the loops can be interchanged. bool canInterchangeLoops(unsigned InnerLoopId, unsigned OuterLoopId, @@ -359,7 +358,6 @@ ScalarEvolution *SE; LoopInfo *LI; DominatorTree *DT; - bool PreserveLCSSA; /// Interface to emit optimization remarks. OptimizationRemarkEmitter *ORE; @@ -432,37 +430,33 @@ }; // Main LoopInterchange Pass. -struct LoopInterchange : public FunctionPass { +struct LoopInterchange : public LoopPass { + LPPassManager *LPM; static char ID; ScalarEvolution *SE = nullptr; LoopInfo *LI = nullptr; DependenceInfo *DI = nullptr; DominatorTree *DT = nullptr; - bool PreserveLCSSA; /// Interface to emit optimization remarks. OptimizationRemarkEmitter *ORE; - LoopInterchange() : FunctionPass(ID) { + LoopInterchange() : LoopPass(ID) { initializeLoopInterchangePass(*PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addRequired(); AU.addRequired(); - AU.addRequired(); AU.addRequired(); - AU.addRequiredID(LoopSimplifyID); - AU.addRequiredID(LCSSAID); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); + getLoopAnalysisUsage(AU); } - bool runOnFunction(Function &F) override { - if (skipFunction(F)) + bool runOnLoop(Loop *L, LPPassManager &LPM) override { + if (skipLoop(L) || L->getParentLoop()) return false; SE = &getAnalysis().getSE(); @@ -470,21 +464,8 @@ DI = &getAnalysis().getDI(); DT = &getAnalysis().getDomTree(); ORE = &getAnalysis().getORE(); - PreserveLCSSA = mustPreserveAnalysisID(LCSSAID); - // Build up a worklist of loop pairs to analyze. - SmallVector Worklist; - - for (Loop *L : *LI) - populateWorklist(*L, Worklist); - - LLVM_DEBUG(dbgs() << "Worklist size = " << Worklist.size() << "\n"); - bool Changed = true; - while (!Worklist.empty()) { - LoopVector LoopList = Worklist.pop_back_val(); - Changed = processLoopList(LoopList, F); - } - return Changed; + return processLoopList(populateWorklist(*L)); } bool isComputableLoopNest(LoopVector LoopList) { @@ -512,7 +493,7 @@ return LoopList.size() - 1; } - bool processLoopList(LoopVector LoopList, Function &F) { + bool processLoopList(LoopVector LoopList) { bool Changed = false; unsigned LoopNestDepth = LoopList.size(); if (LoopNestDepth < 2) { @@ -580,8 +561,7 @@ Loop *InnerLoop = LoopList[InnerLoopId]; Loop *OuterLoop = LoopList[OuterLoopId]; - LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, LI, DT, - PreserveLCSSA, ORE); + LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, LI, DT, ORE); if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) { LLVM_DEBUG(dbgs() << "Not interchanging loops. Cannot prove legality.\n"); return false; @@ -1506,13 +1486,11 @@ INITIALIZE_PASS_BEGIN(LoopInterchange, "loop-interchange", "Interchanges loops for cache reuse", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(DependenceAnalysisWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopSimplify) -INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_END(LoopInterchange, "loop-interchange",