llvm.org GIT mirror llvm / a3376d2
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225236 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 4 years ago
3 changed file(s) with 66 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
768768 return std::move(ModuleToFunctionPassAdaptor(std::move(Pass)));
769769 }
770770
771 /// \brief A template utility pass to force an analysis result to be available.
772 ///
773 /// This is a no-op pass which simply forces a specific analysis pass's result
774 /// to be available when it is run.
775 template struct NoopAnalysisRequirementPass {
776 /// \brief Run this pass over some unit of IR.
777 ///
778 /// This pass can be run over any unit of IR and use any analysis manager
779 /// provided they satisfy the basic API requirements. When this pass is
780 /// created, these methods can be instantiated to satisfy whatever the
781 /// context requires.
782 template
783 PreservedAnalyses run(T &&Arg, AnalysisManagerT *AM) {
784 if (AM)
785 (void)AM->template getResult(std::forward(Arg));
786
787 return PreservedAnalyses::all();
788 }
789
790 static StringRef name() { return "No-op Analysis Requirement Pass"; }
791 };
792
771793 }
772794
773795 #endif
8585 ; CHECK-NO-VERIFY-NOT: VerifierPass
8686 ; CHECK-NO-VERIFY: Finished module pass manager
8787
88 ; RUN: opt -disable-output -debug-pass-manager -debug-cgscc-pass-manager -passes='cgscc(no-op-cgscc)' %s 2>&1 \
88 ; RUN: opt -disable-output -debug-pass-manager -passes='require' %s 2>&1 \
8989 ; RUN: | FileCheck %s --check-prefix=CHECK-LCG-ANALYSIS
9090 ; CHECK-LCG-ANALYSIS: Starting module pass manager
91 ; CHECK-LCG-ANALYSIS: Running module pass: ModuleToPostOrderCGSCCPassAdaptor
92 ; CHECK-LCG-ANALYSIS: Running module analysis: CGSCCAnalysisManagerModuleProxy
91 ; CHECK-LCG-ANALYSIS: Running module pass: No-op Analysis Requirement Pass
9392 ; CHECK-LCG-ANALYSIS: Running module analysis: Lazy CallGraph Analysis
94 ; CHECK-LCG-ANALYSIS: Starting CGSCC pass manager run.
9593
9694 ; Make sure no-op passes that preserve all analyses don't even try to do any
9795 ; analysis invalidation.
5353 #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
5454 #include "PassRegistry.def"
5555
56 // We also support building a require pass around any analysis.
57 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
58 if (Name == "require<" NAME ">") \
59 return true;
60 #include "PassRegistry.def"
61
5662 return false;
5763 }
5864
6268 #define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
6369 #include "PassRegistry.def"
6470
71 // We also support building a require pass around any analysis.
72 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
73 if (Name == "require<" NAME ">") \
74 return true;
75 #include "PassRegistry.def"
76
6577 return false;
6678 }
6779
6981 if (Name == "no-op-function") return true;
7082
7183 #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
84 #include "PassRegistry.def"
85
86 // We also support building a require pass around any analysis.
87 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
88 if (Name == "require<" NAME ">") \
89 return true;
7290 #include "PassRegistry.def"
7391
7492 return false;
87105 }
88106 #include "PassRegistry.def"
89107
108 // We also support building a require pass around any analysis.
109 #define MODULE_ANALYSIS(NAME, CREATE_PASS) \
110 if (Name == "require<" NAME ">") { \
111 MPM.addPass(NoopAnalysisRequirementPass()); \
112 return true; \
113 }
114 #include "PassRegistry.def"
115
90116 return false;
91117 }
92118
103129 }
104130 #include "PassRegistry.def"
105131
132 // We also support building a require pass around any analysis.
133 #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
134 if (Name == "require<" NAME ">") { \
135 CGPM.addPass(NoopAnalysisRequirementPass()); \
136 return true; \
137 }
138 #include "PassRegistry.def"
139
106140 return false;
107141 }
108142
115149 #define FUNCTION_PASS(NAME, CREATE_PASS) \
116150 if (Name == NAME) { \
117151 FPM.addPass(CREATE_PASS); \
152 return true; \
153 }
154 #include "PassRegistry.def"
155
156 // We also support building a require pass around any analysis.
157 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
158 if (Name == "require<" NAME ">") { \
159 FPM.addPass(NoopAnalysisRequirementPass()); \
118160 return true; \
119161 }
120162 #include "PassRegistry.def"