[llvm] r225162 - [PM] Add names and debug logging for analysis passes to the new pass

Chandler Carruth chandlerc at gmail.com
Mon Jan 5 04:21:46 PST 2015


Author: chandlerc
Date: Mon Jan  5 06:21:44 2015
New Revision: 225162

URL: http://llvm.org/viewvc/llvm-project?rev=225162&view=rev
Log:
[PM] Add names and debug logging for analysis passes to the new pass
manager.

This starts to allow us to test analyses more easily, but it's really
only the beginning. Some of the code here is still untestable without
manual changes to create analysis passes, but I wanted to factor it into
a small of chunks as possible.

Next up in order to be able to test things are, in no particular order:
- No-op analyses passes so we don't have to use real ones to exercise
  the pass maneger itself.
- Automatic way of generating dummy passes that require an analysis be
  run, including a variant that calls a 'print' method on a pass to make
  it even easier to print out the results of an analysis.
- Dummy passes that invalidate all analyses for their IR unit so we can
  test invalidation and re-runs.
- Automatic way to print each analysis pass as it is re-run.
- Automatic but optional verification of analysis passes everywhere
  possible.

I'm not claiming I'll get to all of these immediately, but that's what
is in the pipeline at some stage. I'm fleshing out exactly what I need
and what to prioritize by working on converting analyses and then trying
to test the conversion. =]

Modified:
    llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h
    llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
    llvm/trunk/include/llvm/IR/PassManager.h
    llvm/trunk/include/llvm/IR/PassManagerInternal.h
    llvm/trunk/lib/Analysis/CGSCCPassManager.cpp
    llvm/trunk/lib/IR/PassManager.cpp
    llvm/trunk/test/Other/new-pass-manager.ll
    llvm/trunk/unittests/IR/PassManagerTest.cpp

Modified: llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h (original)
+++ llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h Mon Jan  5 06:21:44 2015
@@ -195,6 +195,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "CGSCCAnalysisManagerModuleProxy"; }
+
   explicit CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManager &CGAM)
       : CGAM(&CGAM) {}
   // We have to explicitly define all the special member functions because MSVC
@@ -265,6 +267,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "ModuleAnalysisManagerCGSCCProxy"; }
+
   ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManager &MAM)
       : MAM(&MAM) {}
   // We have to explicitly define all the special member functions because MSVC
@@ -417,6 +421,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "FunctionAnalysisManagerCGSCCProxy"; }
+
   explicit FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManager &FAM)
       : FAM(&FAM) {}
   // We have to explicitly define all the special member functions because MSVC
@@ -487,6 +493,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "CGSCCAnalysisManagerFunctionProxy"; }
+
   CGSCCAnalysisManagerFunctionProxy(const CGSCCAnalysisManager &CGAM)
       : CGAM(&CGAM) {}
   // We have to explicitly define all the special member functions because MSVC

Modified: llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyCallGraph.h?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LazyCallGraph.h (original)
+++ llvm/trunk/include/llvm/Analysis/LazyCallGraph.h Mon Jan  5 06:21:44 2015
@@ -252,6 +252,12 @@ public:
     /// \brief Test if this SCC is a descendant of \a C.
     bool isDescendantOf(const SCC &C) const;
 
+    /// \brief Short name useful for debugging or logging.
+    ///
+    /// We use the name of the first function in the SCC to name the SCC for
+    /// the purposes of debugging and logging.
+    StringRef getName() const { return (*begin())->getFunction().getName(); }
+
     ///@{
     /// \name Mutation API
     ///
@@ -537,6 +543,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "Lazy CallGraph Analysis"; }
+
   /// \brief Compute the \c LazyCallGraph for the module \c M.
   ///
   /// This just builds the set of entry points to the call graph. The rest is

Modified: llvm/trunk/include/llvm/IR/PassManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PassManager.h (original)
+++ llvm/trunk/include/llvm/IR/PassManager.h Mon Jan  5 06:21:44 2015
@@ -557,6 +557,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "FunctionAnalysisManagerModuleProxy"; }
+
   explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
       : FAM(&FAM) {}
   // We have to explicitly define all the special member functions because MSVC
@@ -663,6 +665,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "ModuleAnalysisManagerFunctionProxy"; }
+
   ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
       : MAM(&MAM) {}
   // We have to explicitly define all the special member functions because MSVC

Modified: llvm/trunk/include/llvm/IR/PassManagerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManagerInternal.h?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PassManagerInternal.h (original)
+++ llvm/trunk/include/llvm/IR/PassManagerInternal.h Mon Jan  5 06:21:44 2015
@@ -256,6 +256,9 @@ struct AnalysisPassConcept {
   /// users.
   virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
   run(IRUnitT IR, AnalysisManagerT *AM) = 0;
+
+  /// \brief Polymorphic method to access the name of a pass.
+  virtual StringRef name() = 0;
 };
 
 /// \brief Wrapper to model the analysis pass concept.
@@ -299,6 +302,11 @@ struct AnalysisPassModel<IRUnitT, Analys
     return make_unique<ResultModelT>(Pass.run(IR, AM));
   }
 
+  /// \brief The model delegates to a static \c PassT::name method.
+  ///
+  /// The returned string ref must point to constant immutable data!
+  StringRef name() override { return PassT::name(); }
+
   PassT Pass;
 };
 
@@ -333,6 +341,11 @@ struct AnalysisPassModel<IRUnitT, Analys
     return make_unique<ResultModelT>(Pass.run(IR));
   }
 
+  /// \brief The model delegates to a static \c PassT::name method.
+  ///
+  /// The returned string ref must point to constant immutable data!
+  StringRef name() override { return PassT::name(); }
+
   PassT Pass;
 };
 

Modified: llvm/trunk/lib/Analysis/CGSCCPassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CGSCCPassManager.cpp?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CGSCCPassManager.cpp (original)
+++ llvm/trunk/lib/Analysis/CGSCCPassManager.cpp Mon Jan  5 06:21:44 2015
@@ -84,11 +84,18 @@ void CGSCCAnalysisManager::invalidateImp
   if (RI == CGSCCAnalysisResults.end())
     return;
 
+  if (DebugPM)
+    dbgs() << "Invalidating CGSCC analysis: " << lookupPass(PassID).name()
+           << "\n";
   CGSCCAnalysisResultLists[&C].erase(RI->second);
 }
 
 void CGSCCAnalysisManager::invalidateImpl(LazyCallGraph::SCC &C,
                                           const PreservedAnalyses &PA) {
+  if (DebugPM)
+    dbgs() << "Invalidating all non-preserved analyses for SCC: " << C.getName()
+           << "\n";
+
   // Clear all the invalidated results associated specifically with this
   // function.
   SmallVector<void *, 8> InvalidatedPassIDs;
@@ -97,6 +104,10 @@ void CGSCCAnalysisManager::invalidateImp
                                           E = ResultsList.end();
        I != E;)
     if (I->second->invalidate(C, PA)) {
+      if (DebugPM)
+        dbgs() << "Invalidating CGSCC analysis: " << lookupPass(I->first).name()
+               << "\n";
+
       InvalidatedPassIDs.push_back(I->first);
       I = ResultsList.erase(I);
     } else {

Modified: llvm/trunk/lib/IR/PassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassManager.cpp?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/lib/IR/PassManager.cpp (original)
+++ llvm/trunk/lib/IR/PassManager.cpp Mon Jan  5 06:21:44 2015
@@ -52,8 +52,12 @@ ModuleAnalysisManager::getResultImpl(voi
 
   // If we don't have a cached result for this module, look up the pass and run
   // it to produce a result, which we then add to the cache.
-  if (Inserted)
-    RI->second = lookupPass(PassID).run(M, this);
+  if (Inserted) {
+    auto &P = lookupPass(PassID);
+    if (DebugPM)
+      dbgs() << "Running module analysis: " << P.name() << "\n";
+    RI->second = P.run(M, this);
+  }
 
   return *RI->second;
 }
@@ -66,18 +70,30 @@ ModuleAnalysisManager::getCachedResultIm
 }
 
 void ModuleAnalysisManager::invalidateImpl(void *PassID, Module &M) {
+  if (DebugPM)
+    dbgs() << "Invalidating module analysis: " << lookupPass(PassID).name()
+           << "\n";
   ModuleAnalysisResults.erase(PassID);
 }
 
 void ModuleAnalysisManager::invalidateImpl(Module &M,
                                            const PreservedAnalyses &PA) {
+  if (DebugPM)
+    dbgs() << "Invalidating all non-preserved analyses for module: "
+           << M.getModuleIdentifier() << "\n";
+
   // FIXME: This is a total hack based on the fact that erasure doesn't
   // invalidate iteration for DenseMap.
   for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(),
                                           E = ModuleAnalysisResults.end();
        I != E; ++I)
-    if (I->second->invalidate(M, PA))
+    if (I->second->invalidate(M, PA)) {
+      if (DebugPM)
+        dbgs() << "Invalidating module analysis: "
+               << lookupPass(I->first).name() << "\n";
+
       ModuleAnalysisResults.erase(I);
+    }
 }
 
 PreservedAnalyses FunctionPassManager::run(Function &F,
@@ -128,8 +144,11 @@ FunctionAnalysisManager::getResultImpl(v
   // If we don't have a cached result for this function, look up the pass and
   // run it to produce a result, which we then add to the cache.
   if (Inserted) {
+    auto &P = lookupPass(PassID);
+    if (DebugPM)
+      dbgs() << "Running function analysis: " << P.name() << "\n";
     FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[&F];
-    ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this));
+    ResultList.emplace_back(PassID, P.run(F, this));
     RI->second = std::prev(ResultList.end());
   }
 
@@ -149,11 +168,18 @@ void FunctionAnalysisManager::invalidate
   if (RI == FunctionAnalysisResults.end())
     return;
 
+  if (DebugPM)
+    dbgs() << "Invalidating function analysis: " << lookupPass(PassID).name()
+           << "\n";
   FunctionAnalysisResultLists[&F].erase(RI->second);
 }
 
 void FunctionAnalysisManager::invalidateImpl(Function &F,
                                              const PreservedAnalyses &PA) {
+  if (DebugPM)
+    dbgs() << "Invalidating all non-preserved analyses for function: "
+           << F.getName() << "\n";
+
   // Clear all the invalidated results associated specifically with this
   // function.
   SmallVector<void *, 8> InvalidatedPassIDs;
@@ -162,6 +188,10 @@ void FunctionAnalysisManager::invalidate
                                              E = ResultsList.end();
        I != E;)
     if (I->second->invalidate(F, PA)) {
+      if (DebugPM)
+        dbgs() << "Invalidating function analysis: "
+               << lookupPass(I->first).name() << "\n";
+
       InvalidatedPassIDs.push_back(I->first);
       I = ResultsList.erase(I);
     } else {

Modified: llvm/trunk/test/Other/new-pass-manager.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pass-manager.ll (original)
+++ llvm/trunk/test/Other/new-pass-manager.ll Mon Jan  5 06:21:44 2015
@@ -28,6 +28,8 @@
 ; RUN:     | FileCheck %s --check-prefix=CHECK-FUNCTION-PRINT
 ; CHECK-FUNCTION-PRINT: Starting module pass manager
 ; CHECK-FUNCTION-PRINT: Running module pass: VerifierPass
+; CHECK-FUNCTION-PRINT: Running module pass: ModuleToFunctionPassAdaptor
+; CHECK-FUNCTION-PRINT: Running module analysis: FunctionAnalysisManagerModuleProxy
 ; CHECK-FUNCTION-PRINT: Starting function pass manager
 ; CHECK-FUNCTION-PRINT: Running function pass: PrintFunctionPass
 ; CHECK-FUNCTION-PRINT-NOT: ModuleID
@@ -84,6 +86,14 @@
 ; CHECK-NO-VERIFY-NOT: VerifierPass
 ; CHECK-NO-VERIFY: Finished module pass manager
 
+; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager -passes='cgscc(no-op-cgscc)' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-LCG-ANALYSIS
+; CHECK-LCG-ANALYSIS: Starting module pass manager
+; CHECK-LCG-ANALYSIS: Running module pass: ModuleToPostOrderCGSCCPassAdaptor
+; CHECK-LCG-ANALYSIS: Running module analysis: CGSCCAnalysisManagerModuleProxy
+; CHECK-LCG-ANALYSIS: Running module analysis: Lazy CallGraph Analysis
+; CHECK-LCG-ANALYSIS: Starting CGSCC pass manager run.
+
 define void @foo() {
   ret void
 }

Modified: llvm/trunk/unittests/IR/PassManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassManagerTest.cpp?rev=225162&r1=225161&r2=225162&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PassManagerTest.cpp (original)
+++ llvm/trunk/unittests/IR/PassManagerTest.cpp Mon Jan  5 06:21:44 2015
@@ -29,6 +29,9 @@ public:
   /// \brief Returns an opaque, unique ID for this pass type.
   static void *ID() { return (void *)&PassID; }
 
+  /// \brief Returns the name of the analysis.
+  static StringRef name() { return "TestFunctionAnalysis"; }
+
   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
 
   /// \brief Run the analysis pass over the function and return a result.
@@ -60,6 +63,8 @@ public:
 
   static void *ID() { return (void *)&PassID; }
 
+  static StringRef name() { return "TestModuleAnalysis"; }
+
   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
 
   Result run(Module &M, ModuleAnalysisManager *AM) {





More information about the llvm-commits mailing list