Skip to content

Commit 55fe7b7

Browse files
author
serge-sans-paille
committed
Improve LegacyPassManager API to correctly report modified status
When calling on-the-fly passes from the legacy pass manager, the modification status is not reported, which is a problem in case we depend on an acutal transformation pass, and not only analyse. Update the Legacy PM API to optionally report the changed status, assert if a change is detected but this change is lost. Related to https://reviews.llvm.org/D80916 Differential Revision: https://reviews.llvm.org/D81236
1 parent f0bab78 commit 55fe7b7

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

llvm/include/llvm/IR/LegacyPassManagers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ class PMDataManager {
330330
/// through getAnalysis interface.
331331
virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
332332

333-
virtual Pass *getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F);
333+
virtual std::tuple<Pass *, bool> getOnTheFlyPass(Pass *P, AnalysisID PI,
334+
Function &F);
334335

335336
/// Initialize available analysis information.
336337
void initializeAnalysisInfo() {

llvm/include/llvm/Pass.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,17 @@ class Pass {
203203
template<typename AnalysisType>
204204
AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
205205

206-
template<typename AnalysisType>
207-
AnalysisType &getAnalysis(Function &F); // Defined in PassAnalysisSupport.h
206+
template <typename AnalysisType>
207+
AnalysisType &
208+
getAnalysis(Function &F,
209+
bool *Changed = nullptr); // Defined in PassAnalysisSupport.h
208210

209211
template<typename AnalysisType>
210212
AnalysisType &getAnalysisID(AnalysisID PI) const;
211213

212-
template<typename AnalysisType>
213-
AnalysisType &getAnalysisID(AnalysisID PI, Function &F);
214+
template <typename AnalysisType>
215+
AnalysisType &getAnalysisID(AnalysisID PI, Function &F,
216+
bool *Changed = nullptr);
214217
};
215218

216219
//===----------------------------------------------------------------------===//

llvm/include/llvm/PassAnalysisSupport.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class AnalysisResolver {
167167
}
168168

169169
/// Find pass that is implementing PI. Initialize pass for Function F.
170-
Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
170+
std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F);
171171

172172
void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
173173
if (findImplPass(PI) == P)
@@ -246,23 +246,30 @@ AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
246246

247247
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
248248
/// to the analysis information that they claim to use by overriding the
249-
/// getAnalysisUsage function.
250-
template<typename AnalysisType>
251-
AnalysisType &Pass::getAnalysis(Function &F) {
249+
/// getAnalysisUsage function. If as part of the dependencies, an IR
250+
/// transformation is triggered (e.g. because the analysis requires
251+
/// BreakCriticalEdges), and Changed is non null, *Changed is updated.
252+
template <typename AnalysisType>
253+
AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) {
252254
assert(Resolver &&"Pass has not been inserted into a PassManager object!");
253255

254-
return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
256+
return getAnalysisID<AnalysisType>(&AnalysisType::ID, F, Changed);
255257
}
256258

257-
template<typename AnalysisType>
258-
AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) {
259+
template <typename AnalysisType>
260+
AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) {
259261
assert(PI && "getAnalysis for unregistered pass!");
260262
assert(Resolver && "Pass has not been inserted into a PassManager object!");
261263
// PI *must* appear in AnalysisImpls. Because the number of passes used
262264
// should be a small number, we just do a linear search over a (dense)
263265
// vector.
264-
Pass *ResultPass = Resolver->findImplPass(this, PI, F);
266+
Pass *ResultPass;
267+
bool LocalChanged;
268+
std::tie(ResultPass, LocalChanged) = Resolver->findImplPass(this, PI, F);
269+
265270
assert(ResultPass && "Unable to find requested analysis info");
271+
if (Changed)
272+
*Changed |= LocalChanged;
266273

267274
// Because the AnalysisType may not be a subclass of pass (for
268275
// AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially

llvm/lib/IR/LegacyPassManager.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@ class MPPassManager : public Pass, public PMDataManager {
437437
/// Return function pass corresponding to PassInfo PI, that is
438438
/// required by module pass MP. Instantiate analysis pass, by using
439439
/// its runOnFunction() for function F.
440-
Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F) override;
440+
std::tuple<Pass *, bool> getOnTheFlyPass(Pass *MP, AnalysisID PI,
441+
Function &F) override;
441442

442443
StringRef getPassName() const override { return "Module Pass Manager"; }
443444

@@ -1290,7 +1291,8 @@ void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
12901291
llvm_unreachable("Unable to schedule pass");
12911292
}
12921293

1293-
Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) {
1294+
std::tuple<Pass *, bool> PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI,
1295+
Function &F) {
12941296
llvm_unreachable("Unable to find on the fly pass");
12951297
}
12961298

@@ -1307,8 +1309,8 @@ Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
13071309
return PM.findAnalysisPass(ID, dir);
13081310
}
13091311

1310-
Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI,
1311-
Function &F) {
1312+
std::tuple<Pass *, bool>
1313+
AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, Function &F) {
13121314
return PM.getOnTheFlyPass(P, AnalysisPI, F);
13131315
}
13141316

@@ -1665,16 +1667,17 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
16651667
/// Return function pass corresponding to PassInfo PI, that is
16661668
/// required by module pass MP. Instantiate analysis pass, by using
16671669
/// its runOnFunction() for function F.
1668-
Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
1670+
std::tuple<Pass *, bool> MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI,
1671+
Function &F) {
16691672
FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
16701673
assert(FPP && "Unable to find on the fly pass");
16711674

16721675
FPP->releaseMemoryOnTheFly();
1673-
FPP->run(F);
1674-
return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
1676+
bool Changed = FPP->run(F);
1677+
return std::make_tuple(((PMTopLevelManager *)FPP)->findAnalysisPass(PI),
1678+
Changed);
16751679
}
16761680

1677-
16781681
//===----------------------------------------------------------------------===//
16791682
// PassManagerImpl implementation
16801683

0 commit comments

Comments
 (0)