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
; 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.
#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;
}
#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;
}
#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;
}
}
#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;
}
}
#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;
}
}
#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;
}