Index: llvm/include/llvm/IR/LegacyPassManagers.h =================================================================== --- llvm/include/llvm/IR/LegacyPassManagers.h +++ llvm/include/llvm/IR/LegacyPassManagers.h @@ -330,7 +330,8 @@ /// through getAnalysis interface. virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); - virtual Pass *getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F); + virtual std::tuple getOnTheFlyPass(Pass *P, AnalysisID PI, + Function &F); /// Initialize available analysis information. void initializeAnalysisInfo() { Index: llvm/include/llvm/Pass.h =================================================================== --- llvm/include/llvm/Pass.h +++ llvm/include/llvm/Pass.h @@ -203,14 +203,17 @@ template AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h - template - AnalysisType &getAnalysis(Function &F); // Defined in PassAnalysisSupport.h + template + AnalysisType & + getAnalysis(Function &F, + bool *Changed = nullptr); // Defined in PassAnalysisSupport.h template AnalysisType &getAnalysisID(AnalysisID PI) const; - template - AnalysisType &getAnalysisID(AnalysisID PI, Function &F); + template + AnalysisType &getAnalysisID(AnalysisID PI, Function &F, + bool *Changed = nullptr); }; //===----------------------------------------------------------------------===// Index: llvm/include/llvm/PassAnalysisSupport.h =================================================================== --- llvm/include/llvm/PassAnalysisSupport.h +++ llvm/include/llvm/PassAnalysisSupport.h @@ -167,7 +167,7 @@ } /// Find pass that is implementing PI. Initialize pass for Function F. - Pass *findImplPass(Pass *P, AnalysisID PI, Function &F); + std::tuple findImplPass(Pass *P, AnalysisID PI, Function &F); void addAnalysisImplsPair(AnalysisID PI, Pass *P) { if (findImplPass(PI) == P) @@ -246,23 +246,30 @@ /// getAnalysis() - This function is used by subclasses to get /// to the analysis information that they claim to use by overriding the -/// getAnalysisUsage function. -template -AnalysisType &Pass::getAnalysis(Function &F) { +/// getAnalysisUsage function. If as part of the dependencies, an IR +/// transformation is triggered, and Changed is non null, *Changed is updated. +template +AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) { assert(Resolver &&"Pass has not been inserted into a PassManager object!"); - return getAnalysisID(&AnalysisType::ID, F); + return getAnalysisID(&AnalysisType::ID, F, Changed); } -template -AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) { +template +AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) { assert(PI && "getAnalysis for unregistered pass!"); assert(Resolver && "Pass has not been inserted into a PassManager object!"); // PI *must* appear in AnalysisImpls. Because the number of passes used // should be a small number, we just do a linear search over a (dense) // vector. - Pass *ResultPass = Resolver->findImplPass(this, PI, F); + auto PassStatus = Resolver->findImplPass(this, PI, F); + + Pass *ResultPass = std::get(PassStatus); assert(ResultPass && "Unable to find requested analysis info"); + if (Changed) + *Changed |= std::get(PassStatus); + assert((Changed || !std::get(PassStatus)) && + "A pass trigged a code update but the update status is lost"); // Because the AnalysisType may not be a subclass of pass (for // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially Index: llvm/lib/IR/LegacyPassManager.cpp =================================================================== --- llvm/lib/IR/LegacyPassManager.cpp +++ llvm/lib/IR/LegacyPassManager.cpp @@ -437,7 +437,8 @@ /// Return function pass corresponding to PassInfo PI, that is /// required by module pass MP. Instantiate analysis pass, by using /// its runOnFunction() for function F. - Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F) override; + std::tuple getOnTheFlyPass(Pass *MP, AnalysisID PI, + Function &F) override; StringRef getPassName() const override { return "Module Pass Manager"; } @@ -1290,7 +1291,8 @@ llvm_unreachable("Unable to schedule pass"); } -Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { +std::tuple PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, + Function &F) { llvm_unreachable("Unable to find on the fly pass"); } @@ -1307,8 +1309,8 @@ return PM.findAnalysisPass(ID, dir); } -Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, - Function &F) { +std::tuple +AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, Function &F) { return PM.getOnTheFlyPass(P, AnalysisPI, F); } @@ -1665,16 +1667,17 @@ /// Return function pass corresponding to PassInfo PI, that is /// required by module pass MP. Instantiate analysis pass, by using /// its runOnFunction() for function F. -Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){ +std::tuple MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, + Function &F) { FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP]; assert(FPP && "Unable to find on the fly pass"); FPP->releaseMemoryOnTheFly(); - FPP->run(F); - return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI); + bool Changed = FPP->run(F); + return std::make_tuple(((PMTopLevelManager *)FPP)->findAnalysisPass(PI), + Changed); } - //===----------------------------------------------------------------------===// // PassManagerImpl implementation Index: llvm/lib/Transforms/IPO/LoopExtractor.cpp =================================================================== --- llvm/lib/Transforms/IPO/LoopExtractor.cpp +++ llvm/lib/Transforms/IPO/LoopExtractor.cpp @@ -131,18 +131,19 @@ if (F.empty()) return false; - LoopInfo &LI = getAnalysis(F).getLoopInfo(); + bool Changed = false; + LoopInfo &LI = getAnalysis(F, &Changed).getLoopInfo(); // If there are no loops in the function. if (LI.empty()) - return false; + return Changed; DominatorTree &DT = getAnalysis(F).getDomTree(); // If there is more than one top-level loop in this function, extract all of // the loops. if (std::next(LI.begin()) != LI.end()) - return extractLoops(LI.begin(), LI.end(), LI, DT); + return Changed | extractLoops(LI.begin(), LI.end(), LI, DT); // Otherwise there is exactly one top-level loop. Loop *TLL = *LI.begin(); @@ -171,14 +172,14 @@ } if (ShouldExtractLoop) - return extractLoop(TLL, LI, DT); + return Changed | extractLoop(TLL, LI, DT); } // Okay, this function is a minimal container around the specified loop. // If we extract the loop, we will continue to just keep extracting it // infinitely... so don't extract it. However, if the loop contains any // sub-loops, extract them. - return extractLoops(TLL->begin(), TLL->end(), LI, DT); + return Changed | extractLoops(TLL->begin(), TLL->end(), LI, DT); } bool LoopExtractor::extractLoops(Loop::iterator From, Loop::iterator To,