diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 59855b5fc91..c1025434cc7 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -769,6 +769,28 @@ createModuleToFunctionPassAdaptor(FunctionPassT Pass) { return std::move(ModuleToFunctionPassAdaptor(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 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 + PreservedAnalyses run(T &&Arg, AnalysisManagerT *AM) { + if (AM) + (void)AM->template getResult(std::forward(Arg)); + + return PreservedAnalyses::all(); + } + + static StringRef name() { return "No-op Analysis Requirement Pass"; } +}; + } #endif diff --git a/test/Other/new-pass-manager.ll b/test/Other/new-pass-manager.ll index bb338d42253..9c1f46929ff 100644 --- a/test/Other/new-pass-manager.ll +++ b/test/Other/new-pass-manager.ll @@ -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' %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. diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index 6ac044a0d05..d20becbe5ea 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -54,6 +54,12 @@ static bool isModulePassName(StringRef Name) { #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 Name) { #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 Name) { #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(ModulePassManager &MPM, StringRef Name) { } #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()); \ + return true; \ + } +#include "PassRegistry.def" + return false; } @@ -104,6 +130,14 @@ static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { } #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()); \ + return true; \ + } +#include "PassRegistry.def" + return false; } @@ -120,6 +154,14 @@ static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { } #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()); \ + return true; \ + } +#include "PassRegistry.def" + return false; }