diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/CGSCCPassManager.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopPassManager.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/PassManager.cpp | 50 |
3 files changed, 92 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp index 2fa258bffea..1d3b184c621 100644 --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -76,7 +76,7 @@ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, // SCC. Therefore, the remaining analysis results in the AnalysisManager are // preserved. We mark this with a set so that we don't need to inspect each // one individually. - PA.preserve<AllAnalysesOn<LazyCallGraph::SCC>>(); + PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>(); if (DebugLogging) dbgs() << "Finished CGSCC pass manager run.\n"; @@ -87,6 +87,10 @@ PassManager<LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, bool CGSCCAnalysisManagerModuleProxy::Result::invalidate( Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &Inv) { + // If literally everything is preserved, we're done. + if (PA.areAllPreserved()) + return false; // This is still a valid proxy. + // If this proxy or the call graph is going to be invalidated, we also need // to clear all the keys coming from that analysis. // @@ -94,8 +98,9 @@ bool CGSCCAnalysisManagerModuleProxy::Result::invalidate( // that proxy isn't preserved we can't preserve this proxy either. We rely on // it to handle module -> function analysis invalidation in the face of // structural changes and so if it's unavailable we conservatively clear the - // entire SCC layer as well rather than trying to do invaliadtion ourselves. - if (!PA.preserved<CGSCCAnalysisManagerModuleProxy>() || + // entire SCC layer as well rather than trying to do invalidation ourselves. + auto PAC = PA.getChecker<CGSCCAnalysisManagerModuleProxy>(); + if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>()) || Inv.invalidate<LazyCallGraphAnalysis>(M, PA) || Inv.invalidate<FunctionAnalysisManagerModuleProxy>(M, PA)) { InnerAM->clear(); @@ -106,10 +111,45 @@ bool CGSCCAnalysisManagerModuleProxy::Result::invalidate( return true; } + // Directly check if the relevant set is preserved so we can short circuit + // invalidating SCCs below. + bool AreSCCAnalysesPreserved = + PA.allAnalysesInSetPreserved<AllAnalysesOn<LazyCallGraph::SCC>>(); + // Ok, we have a graph, so we can propagate the invalidation down into it. for (auto &RC : G->postorder_ref_sccs()) - for (auto &C : RC) - InnerAM->invalidate(C, PA); + for (auto &C : RC) { + Optional<PreservedAnalyses> InnerPA; + + // Check to see whether the preserved set needs to be adjusted based on + // module-level analysis invalidation triggering deferred invalidation + // for this SCC. + if (auto *OuterProxy = + InnerAM->getCachedResult<ModuleAnalysisManagerCGSCCProxy>(C)) + for (const auto &OuterInvalidationPair : + OuterProxy->getOuterInvalidations()) { + AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first; + const auto &InnerAnalysisIDs = OuterInvalidationPair.second; + if (Inv.invalidate(OuterAnalysisID, M, PA)) { + if (!InnerPA) + InnerPA = PA; + for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs) + InnerPA->abandon(InnerAnalysisID); + } + } + + // Check if we needed a custom PA set. If so we'll need to run the inner + // invalidation. + if (InnerPA) { + InnerAM->invalidate(C, *InnerPA); + continue; + } + + // Otherwise we only need to do invalidation if the original PA set didn't + // preserve all SCC analyses. + if (!AreSCCAnalysesPreserved) + InnerAM->invalidate(C, PA); + } // Return false to indicate that this result is still a valid proxy. return false; diff --git a/llvm/lib/Analysis/LoopPassManager.cpp b/llvm/lib/Analysis/LoopPassManager.cpp index deb68e75ded..044e5d55daf 100644 --- a/llvm/lib/Analysis/LoopPassManager.cpp +++ b/llvm/lib/Analysis/LoopPassManager.cpp @@ -33,7 +33,8 @@ bool LoopAnalysisManagerFunctionProxy::Result::invalidate( // the module may have changed. We therefore can't call // InnerAM->invalidate(), because any pointers to Functions it has may be // stale. - if (!PA.preserved(LoopAnalysisManagerFunctionProxy::ID())) + auto PAC = PA.getChecker<LoopAnalysisManagerFunctionProxy>(); + if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Loop>>()) InnerAM->clear(); // FIXME: Proper suppor for invalidation isn't yet implemented for the LPM. diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp index 7c478ea1cf6..8f68bb1daec 100644 --- a/llvm/lib/IR/PassManager.cpp +++ b/llvm/lib/IR/PassManager.cpp @@ -29,6 +29,10 @@ template <> bool FunctionAnalysisManagerModuleProxy::Result::invalidate( Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &Inv) { + // If literally everything is preserved, we're done. + if (PA.areAllPreserved()) + return false; // This is still a valid proxy. + // If this proxy isn't marked as preserved, then even if the result remains // valid, the key itself may no longer be valid, so we clear everything. // @@ -37,18 +41,54 @@ bool FunctionAnalysisManagerModuleProxy::Result::invalidate( // Specifically, any FAM-cached results for those functions need to have been // forcibly cleared. When preserved, this proxy will only invalidate results // cached on functions *still in the module* at the end of the module pass. - if (!PA.preserved(FunctionAnalysisManagerModuleProxy::ID())) { + auto PAC = PA.getChecker<FunctionAnalysisManagerModuleProxy>(); + if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) { InnerAM->clear(); return true; } - // Otherwise propagate the invalidation event to all the remaining IR units. - for (Function &F : M) - InnerAM->invalidate(F, PA); + // Directly check if the relevant set is preserved. + bool AreFunctionAnalysesPreserved = + PA.allAnalysesInSetPreserved<AllAnalysesOn<Function>>(); + + // Now walk all the functions to see if any inner analysis invalidation is + // necessary. + for (Function &F : M) { + Optional<PreservedAnalyses> FunctionPA; + + // Check to see whether the preserved set needs to be pruned based on + // module-level analysis invalidation that triggers deferred invalidation + // registered with the outer analysis manager proxy for this function. + if (auto *OuterProxy = + InnerAM->getCachedResult<ModuleAnalysisManagerFunctionProxy>(F)) + for (const auto &OuterInvalidationPair : + OuterProxy->getOuterInvalidations()) { + AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first; + const auto &InnerAnalysisIDs = OuterInvalidationPair.second; + if (Inv.invalidate(OuterAnalysisID, M, PA)) { + if (!FunctionPA) + FunctionPA = PA; + for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs) + FunctionPA->abandon(InnerAnalysisID); + } + } + + // Check if we needed a custom PA set, and if so we'll need to run the + // inner invalidation. + if (FunctionPA) { + InnerAM->invalidate(F, *FunctionPA); + continue; + } + + // Otherwise we only need to do invalidation if the original PA set didn't + // preserve all function analyses. + if (!AreFunctionAnalysesPreserved) + InnerAM->invalidate(F, PA); + } // Return false to indicate that this result is still a valid proxy. return false; } } -AnalysisKey PreservedAnalyses::AllAnalysesKey; +AnalysisSetKey PreservedAnalyses::AllAnalysesKey; |