Index: include/llvm/IR/PassManager.h =================================================================== --- include/llvm/IR/PassManager.h +++ include/llvm/IR/PassManager.h @@ -211,6 +211,31 @@ static void *ID() { return (void *)&DerivedT::PassID; } }; +/// A class template to provide analysis sets for IR units. +/// +/// Analyses operate on units of IR. It is useful to be able to talk about +/// preservation of all analyses for a given unit of IR as a set. This class +/// template can be used with the \c PreservedAnalyses API for that purpose and +/// the \c AnalysisManager will automatically check and use this set to skip +/// invalidation events. +/// +/// Note that you must provide an explicit instantiation declaration and +/// definition for this template in order to get the correct behavior on +/// Windows. Otherwise, the address of SetID will not be stable. +template +class AllAnalysesOn { +public: + static void *ID() { return (void *)&SetID; } + +private: + static char SetID; +}; + +template char AllAnalysesOn::SetID; + +extern template class AllAnalysesOn; +extern template class AllAnalysesOn; + /// \brief Manages a sequence of passes over units of IR. /// /// A pass manager contains a sequence of passes to run over units of IR. It is @@ -271,6 +296,13 @@ //IR.getContext().yield(); } + // Because we invalidate the analysis manager as this runs, we also + // preserve all function analyses by definition. Either they apply to + // functions other than the one this pass is running over (in which case we + // cannot have invalidated them), or we've already handled any necessary + // invalidation above. + PA.preserve>(); + if (DebugLogging) dbgs() << "Finished " << getTypeName() << " pass manager run.\n"; @@ -571,8 +603,8 @@ /// \brief Invalidate the results for a function.. PreservedAnalyses invalidateImpl(IRUnitT &IR, PreservedAnalyses PA) { - // Short circuit for a common case of all analyses being preserved. - if (PA.areAllPreserved()) + // Short circuit for common cases of all analyses being preserved. + if (PA.areAllPreserved() || PA.preserved>()) return PA; if (DebugLogging) Index: lib/IR/PassManager.cpp =================================================================== --- lib/IR/PassManager.cpp +++ lib/IR/PassManager.cpp @@ -15,6 +15,8 @@ // Explicit template instantiations for core template typedefs. namespace llvm { +template class AllAnalysesOn; +template class AllAnalysesOn; template class PassManager; template class PassManager; template class AnalysisManager; Index: test/Other/new-pass-manager.ll =================================================================== --- test/Other/new-pass-manager.ll +++ test/Other/new-pass-manager.ll @@ -213,19 +213,14 @@ ; CHECK-INVALIDATE-ALL: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL: Running analysis: NoOpFunctionAnalysis ; CHECK-INVALIDATE-ALL: Running pass: InvalidateAllAnalysesPass -; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL: Invalidating analysis: NoOpFunctionAnalysis ; CHECK-INVALIDATE-ALL: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL: Running analysis: NoOpFunctionAnalysis ; CHECK-INVALIDATE-ALL: Finished llvm::Function pass manager run -; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses -; CHECK-INVALIDATE-ALL-NOT: Running analysis: NoOpFunctionAnalysis -; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL: Invalidating analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL: Running analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL: Finished llvm::Module pass manager run -; CHECK-INVALIDATE-ALL: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-NOT: Invalidating analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL-NOT: Running analysis: NoOpModuleAnalysis @@ -247,26 +242,20 @@ ; CHECK-INVALIDATE-ALL-CG: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpFunctionAnalysis ; CHECK-INVALIDATE-ALL-CG: Running pass: InvalidateAllAnalysesPass -; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-CG: Invalidating analysis: NoOpFunctionAnalysis ; CHECK-INVALIDATE-ALL-CG: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpFunctionAnalysis ; CHECK-INVALIDATE-ALL-CG: Finished llvm::Function pass manager run -; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-CG-NOT: Running analysis: NoOpFunctionAnalysis -; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-CG: Invalidating analysis: NoOpCGSCCAnalysis ; CHECK-INVALIDATE-ALL-CG: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpCGSCCAnalysis ; CHECK-INVALIDATE-ALL-CG: Finished llvm::LazyCallGraph::SCC pass manager run -; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-CG-NOT: Invalidating analysis: NoOpCGSCCAnalysis -; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-CG: Invalidating analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL-CG: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL-CG: Running analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL-CG: Finished llvm::Module pass manager run -; CHECK-INVALIDATE-ALL-CG: Invalidating all non-preserved analyses ; CHECK-INVALIDATE-ALL-CG-NOT: Invalidating analysis: NoOpModuleAnalysis ; CHECK-INVALIDATE-ALL-CG: Running pass: RequireAnalysisPass ; CHECK-INVALIDATE-ALL-CG-NOT: Running analysis: NoOpModuleAnalysis