<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 5, 2015 at 6:10 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Mon Jan  5 20:10:51 2015<br>
New Revision: 225236<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=225236&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=225236&view=rev</a><br>
Log:<br>
[PM] Add a utility to the new pass manager for generating a pass which<br>
is a no-op other than requiring some analysis results be available.<br>
<br>
This can be used in real pass pipelines to force the usually lazy<br>
analysis running to eagerly compute something at a specific point, </blockquote><div><br>Any particular reason this would be useful/necessary?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">and<br>
it can be used to test the pass manager infrastructure (my primary use<br>
at the moment).<br>
<br>
I've also added bit of pipeline parsing magic to support generating<br>
these directly from the opt command so that you can directly use these<br>
when debugging your analysis. The syntax is:<br>
<br>
  require<analysis-name><br>
<br>
This can be used at any level of the pass manager. For example:<br>
<br>
  cgscc(function(require<my-analysis>,no-op-function))<br>
<br>
This would produce a no-op function pass requiring my-analysis, followed<br>
by a fully no-op function pass, both of these in a function pass manager<br>
which is nested inside of a bottom-up CGSCC pass manager which is in the<br>
top-level (implicit) module pass manager.<br>
<br>
I have zero attachment to the particular syntax I'm using here. Consider<br>
it a straw man for use while I'm testing and fleshing things out.<br>
Suggestions for better syntax welcome, and I'll update everything based<br>
on any consensus that develops.<br>
<br>
I've used this new functionality to more directly test the analysis<br>
printing rather than relying on the cgscc pass manager running an<br>
analysis for me. This is still minimally tested because I need to have<br>
analyses to run first! ;] That patch is next, but wanted to keep this<br>
one separate for easier review and discussion.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/PassManager.h<br>
    llvm/trunk/test/Other/new-pass-manager.ll<br>
    llvm/trunk/tools/opt/Passes.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/PassManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=225236&r1=225235&r2=225236&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=225236&r1=225235&r2=225236&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/PassManager.h (original)<br>
+++ llvm/trunk/include/llvm/IR/PassManager.h Mon Jan  5 20:10:51 2015<br>
@@ -769,6 +769,28 @@ createModuleToFunctionPassAdaptor(Functi<br>
   return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));<br>
 }<br>
<br>
+/// \brief A template utility pass to force an analysis result to be available.<br>
+///<br>
+/// This is a no-op pass which simply forces a specific analysis pass's result<br>
+/// to be available when it is run.<br>
+template <typename AnalysisT> struct NoopAnalysisRequirementPass {<br>
+  /// \brief Run this pass over some unit of IR.<br>
+  ///<br>
+  /// This pass can be run over any unit of IR and use any analysis manager<br>
+  /// provided they satisfy the basic API requirements. When this pass is<br>
+  /// created, these methods can be instantiated to satisfy whatever the<br>
+  /// context requires.<br>
+  template <typename T, typename AnalysisManagerT><br>
+  PreservedAnalyses run(T &&Arg, AnalysisManagerT *AM) {<br>
+    if (AM)<br>
+      (void)AM->template getResult<AnalysisT>(std::forward<T>(Arg));<br>
+<br>
+    return PreservedAnalyses::all();<br>
+  }<br>
+<br>
+  static StringRef name() { return "No-op Analysis Requirement Pass"; }<br>
+};<br>
+<br>
 }<br>
<br>
 #endif<br>
<br>
Modified: llvm/trunk/test/Other/new-pass-manager.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=225236&r1=225235&r2=225236&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=225236&r1=225235&r2=225236&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Other/new-pass-manager.ll (original)<br>
+++ llvm/trunk/test/Other/new-pass-manager.ll Mon Jan  5 20:10:51 2015<br>
@@ -86,13 +86,11 @@<br>
 ; CHECK-NO-VERIFY-NOT: VerifierPass<br>
 ; CHECK-NO-VERIFY: Finished module pass manager<br>
<br>
-; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager -passes='cgscc(no-op-cgscc)' %s 2>&1 \<br>
+; RUN: opt -disable-output -debug-pass-manager -passes='require<lcg>' %s 2>&1 \<br>
 ; RUN:     | FileCheck %s --check-prefix=CHECK-LCG-ANALYSIS<br>
 ; CHECK-LCG-ANALYSIS: Starting module pass manager<br>
-; CHECK-LCG-ANALYSIS: Running module pass: ModuleToPostOrderCGSCCPassAdaptor<br>
-; CHECK-LCG-ANALYSIS: Running module analysis: CGSCCAnalysisManagerModuleProxy<br>
+; CHECK-LCG-ANALYSIS: Running module pass: No-op Analysis Requirement Pass<br>
 ; CHECK-LCG-ANALYSIS: Running module analysis: Lazy CallGraph Analysis<br>
-; CHECK-LCG-ANALYSIS: Starting CGSCC pass manager run.<br>
<br>
 ; Make sure no-op passes that preserve all analyses don't even try to do any<br>
 ; analysis invalidation.<br>
<br>
Modified: llvm/trunk/tools/opt/Passes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=225236&r1=225235&r2=225236&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=225236&r1=225235&r2=225236&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/opt/Passes.cpp (original)<br>
+++ llvm/trunk/tools/opt/Passes.cpp Mon Jan  5 20:10:51 2015<br>
@@ -54,6 +54,12 @@ static bool isModulePassName(StringRef N<br>
 #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;<br>
 #include "PassRegistry.def"<br>
<br>
+  // We also support building a require pass around any analysis.<br>
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \<br>
+  if (Name == "require<" NAME ">")                                             \<br>
+    return true;<br>
+#include "PassRegistry.def"<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -63,6 +69,12 @@ static bool isCGSCCPassName(StringRef Na<br>
 #define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;<br>
 #include "PassRegistry.def"<br>
<br>
+  // We also support building a require pass around any analysis.<br>
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \<br>
+  if (Name == "require<" NAME ">")                                             \<br>
+    return true;<br>
+#include "PassRegistry.def"<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -72,6 +84,12 @@ static bool isFunctionPassName(StringRef<br>
 #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;<br>
 #include "PassRegistry.def"<br>
<br>
+  // We also support building a require pass around any analysis.<br>
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \<br>
+  if (Name == "require<" NAME ">")                                             \<br>
+    return true;<br>
+#include "PassRegistry.def"<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -88,6 +106,14 @@ static bool parseModulePassName(ModulePa<br>
   }<br>
 #include "PassRegistry.def"<br>
<br>
+  // We also support building a require pass around any analysis.<br>
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \<br>
+  if (Name == "require<" NAME ">") {                                           \<br>
+    MPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \<br>
+    return true;                                                               \<br>
+  }<br>
+#include "PassRegistry.def"<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -104,6 +130,14 @@ static bool parseCGSCCPassName(CGSCCPass<br>
   }<br>
 #include "PassRegistry.def"<br>
<br>
+  // We also support building a require pass around any analysis.<br>
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \<br>
+  if (Name == "require<" NAME ">") {                                           \<br>
+    CGPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());        \<br>
+    return true;                                                               \<br>
+  }<br>
+#include "PassRegistry.def"<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -119,6 +153,14 @@ static bool parseFunctionPassName(Functi<br>
     return true;                                                               \<br>
   }<br>
 #include "PassRegistry.def"<br>
+<br>
+  // We also support building a require pass around any analysis.<br>
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \<br>
+  if (Name == "require<" NAME ">") {                                           \<br>
+    FPM.addPass(NoopAnalysisRequirementPass<decltype(CREATE_PASS)>());         \<br>
+    return true;                                                               \<br>
+  }<br>
+#include "PassRegistry.def"<br>
<br>
   return false;<br>
 }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>