[PM] Introduce an abstraction for all the analyses over a particular IR
authorChandler Carruth <chandlerc@gmail.com>
Sat, 20 Aug 2016 04:57:28 +0000 (04:57 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 20 Aug 2016 04:57:28 +0000 (04:57 +0000)
unit for use in the PreservedAnalyses set.

This doesn't have any important functional change yet but it cleans
things up and makes the analysis substantially more efficient by
avoiding querying through the type erasure for every analysis.

I also think it makes it much easier to reason about how analyses are
preserved when walking across pass managers and across IR unit
abstractions.

Thanks to Sean and Mehdi both for the comments and suggestions.

Differential Revision: https://reviews.llvm.org/D23691

llvm-svn: 279360

llvm/include/llvm/IR/PassManager.h
llvm/lib/IR/PassManager.cpp
llvm/test/Other/new-pass-manager.ll

index aac03f0..e24e716 100644 (file)
@@ -211,6 +211,31 @@ struct AnalysisInfoMixin : PassInfoMixin<DerivedT> {
   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 <typename IRUnitT>
+class AllAnalysesOn {
+public:
+  static void *ID() { return (void *)&SetID; }
+
+private:
+  static char SetID;
+};
+
+template <typename IRUnitT> char AllAnalysesOn<IRUnitT>::SetID;
+
+extern template class AllAnalysesOn<Module>;
+extern template class AllAnalysesOn<Function>;
+
 /// \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
@@ -275,6 +300,12 @@ public:
       //IR.getContext().yield();
     }
 
+    // Invaliadtion was handled after each pass in the above loop for the
+    // current unit of IR. 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<IRUnitT>>();
+
     if (DebugLogging)
       dbgs() << "Finished " << getTypeName<IRUnitT>() << " pass manager run.\n";
 
@@ -443,8 +474,8 @@ public:
   /// analyis pass which has been successfully invalidated and thus can be
   /// preserved going forward. The updated set is returned.
   PreservedAnalyses invalidate(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<AllAnalysesOn<IRUnitT>>())
       return PA;
 
     if (DebugLogging)
index 8563a40..8fafea4 100644 (file)
@@ -15,6 +15,8 @@ using namespace llvm;
 
 // Explicit template instantiations for core template typedefs.
 namespace llvm {
+template class AllAnalysesOn<Module>;
+template class AllAnalysesOn<Function>;
 template class PassManager<Module>;
 template class PassManager<Function>;
 template class AnalysisManager<Module>;
index a848093..db239e9 100644 (file)
 ; 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
 ; 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