[llvm] r225236 - [PM] Add a utility to the new pass manager for generating a pass which

Chandler Carruth chandlerc at gmail.com
Mon Jan 5 18:10:52 PST 2015


Author: chandlerc
Date: Mon Jan  5 20:10:51 2015
New Revision: 225236

URL: http://llvm.org/viewvc/llvm-project?rev=225236&view=rev
Log:
[PM] Add a utility to the new pass manager for generating a pass which
is a no-op other than requiring some analysis results be available.

This can be used in real pass pipelines to force the usually lazy
analysis running to eagerly compute something at a specific point, and
it can be used to test the pass manager infrastructure (my primary use
at the moment).

I've also added bit of pipeline parsing magic to support generating
these directly from the opt command so that you can directly use these
when debugging your analysis. The syntax is:

  require<analysis-name>

This can be used at any level of the pass manager. For example:

  cgscc(function(require<my-analysis>,no-op-function))

This would produce a no-op function pass requiring my-analysis, followed
by a fully no-op function pass, both of these in a function pass manager
which is nested inside of a bottom-up CGSCC pass manager which is in the
top-level (implicit) module pass manager.

I have zero attachment to the particular syntax I'm using here. Consider
it a straw man for use while I'm testing and fleshing things out.
Suggestions for better syntax welcome, and I'll update everything based
on any consensus that develops.

I've used this new functionality to more directly test the analysis
printing rather than relying on the cgscc pass manager running an
analysis for me. This is still minimally tested because I need to have
analyses to run first! ;] That patch is next, but wanted to keep this
one separate for easier review and discussion.

Modified:
    llvm/trunk/include/llvm/IR/PassManager.h
    llvm/trunk/test/Other/new-pass-manager.ll
    llvm/trunk/tools/opt/Passes.cpp

Modified: llvm/trunk/include/llvm/IR/PassManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=225236&r1=225235&r2=225236&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PassManager.h (original)
+++ llvm/trunk/include/llvm/IR/PassManager.h Mon Jan  5 20:10:51 2015
@@ -769,6 +769,28 @@ createModuleToFunctionPassAdaptor(Functi
   return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
 }
 
+/// \brief A template utility pass to force an analysis result to be available.
+///
+/// This is a no-op pass which simply forces a specific analysis pass's result
+/// to be available when it is run.
+template <typename AnalysisT> struct NoopAnalysisRequirementPass {
+  /// \brief Run this pass over some unit of IR.
+  ///
+  /// This pass can be run over any unit of IR and use any analysis manager
+  /// provided they satisfy the basic API requirements. When this pass is
+  /// created, these methods can be instantiated to satisfy whatever the
+  /// context requires.
+  template <typename T, typename AnalysisManagerT>
+  PreservedAnalyses run(T &&Arg, AnalysisManagerT *AM) {
+    if (AM)
+      (void)AM->template getResult<AnalysisT>(std::forward<T>(Arg));
+
+    return PreservedAnalyses::all();
+  }
+
+  static StringRef name() { return "No-op Analysis Requirement Pass"; }
+};
+
 }
 
 #endif

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=225236&r1=225235&r2=225236&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pass-manager.ll (original)
+++ llvm/trunk/test/Other/new-pass-manager.ll Mon Jan  5 20:10:51 2015
@@ -86,13 +86,11 @@
 ; 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: opt -disable-output -debug-pass-manager -passes='require<lcg>' %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 pass: No-op Analysis Requirement Pass
 ; CHECK-LCG-ANALYSIS: Running module analysis: Lazy CallGraph Analysis
-; CHECK-LCG-ANALYSIS: Starting CGSCC pass manager run.
 
 ; Make sure no-op passes that preserve all analyses don't even try to do any
 ; analysis invalidation.

Modified: llvm/trunk/tools/opt/Passes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=225236&r1=225235&r2=225236&view=diff
==============================================================================
--- llvm/trunk/tools/opt/Passes.cpp (original)
+++ llvm/trunk/tools/opt/Passes.cpp Mon Jan  5 20:10:51 2015
@@ -54,6 +54,12 @@ static bool isModulePassName(StringRef N
 #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
 #include "PassRegistry.def"
 
+  // We also support building a require pass around any analysis.
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
+  if (Name == "require<" NAME ">")                                             \
+    return true;
+#include "PassRegistry.def"
+
   return false;
 }
 
@@ -63,6 +69,12 @@ static bool isCGSCCPassName(StringRef Na
 #define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
 #include "PassRegistry.def"
 
+  // We also support building a require pass around any analysis.
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
+  if (Name == "require<" NAME ">")                                             \
+    return true;
+#include "PassRegistry.def"
+
   return false;
 }
 
@@ -72,6 +84,12 @@ static bool isFunctionPassName(StringRef
 #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
 #include "PassRegistry.def"
 
+  // We also support building a require pass around any analysis.
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
+  if (Name == "require<" NAME ">")                                             \
+    return true;
+#include "PassRegistry.def"
+
   return false;
 }
 
@@ -88,6 +106,14 @@ static bool parseModulePassName(ModulePa
   }
 #include "PassRegistry.def"
 
+  // We also support building a require pass around any analysis.
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
+  if (Name == "require<" NAME ">") {                                           \
+    MPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \
+    return true;                                                               \
+  }
+#include "PassRegistry.def"
+
   return false;
 }
 
@@ -104,6 +130,14 @@ static bool parseCGSCCPassName(CGSCCPass
   }
 #include "PassRegistry.def"
 
+  // We also support building a require pass around any analysis.
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
+  if (Name == "require<" NAME ">") {                                           \
+    CGPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());        \
+    return true;                                                               \
+  }
+#include "PassRegistry.def"
+
   return false;
 }
 
@@ -119,6 +153,14 @@ static bool parseFunctionPassName(Functi
     return true;                                                               \
   }
 #include "PassRegistry.def"
+
+  // We also support building a require pass around any analysis.
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
+  if (Name == "require<" NAME ">") {                                           \
+    FPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \
+    return true;                                                               \
+  }
+#include "PassRegistry.def"
 
   return false;
 }





More information about the llvm-commits mailing list