diff --git a/llvm/include/llvm/IR/LegacyPassManagers.h b/llvm/include/llvm/IR/LegacyPassManagers.h --- a/llvm/include/llvm/IR/LegacyPassManagers.h +++ b/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() { diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h --- a/llvm/include/llvm/Pass.h +++ b/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); }; //===----------------------------------------------------------------------===// diff --git a/llvm/include/llvm/PassAnalysisSupport.h b/llvm/include/llvm/PassAnalysisSupport.h --- a/llvm/include/llvm/PassAnalysisSupport.h +++ b/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 (e.g. because the analysis requires +/// BreakCriticalEdges), 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); + Pass *ResultPass; + bool LocalChanged; + std::tie(ResultPass, LocalChanged) = Resolver->findImplPass(this, PI, F); + assert(ResultPass && "Unable to find requested analysis info"); + if (Changed) + *Changed |= LocalChanged; // Because the AnalysisType may not be a subclass of pass (for // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/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