diff options
author | Stephen Hines <srhines@google.com> | 2015-04-01 18:49:24 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-01 18:49:26 +0000 |
commit | 3fa16bd6062e23bcdb82ed4dd965674792e6b761 (patch) | |
tree | 9348fc507292f7e8715d22d64ce5a32131b4f875 /tools/opt | |
parent | beed47390a60f6f0c77532b3d3f76bb47ef49423 (diff) | |
parent | ebe69fe11e48d322045d5949c83283927a0d790b (diff) | |
download | external_llvm-3fa16bd6062e23bcdb82ed4dd965674792e6b761.zip external_llvm-3fa16bd6062e23bcdb82ed4dd965674792e6b761.tar.gz external_llvm-3fa16bd6062e23bcdb82ed4dd965674792e6b761.tar.bz2 |
Merge "Update aosp/master LLVM for rebase to r230699."
Diffstat (limited to 'tools/opt')
-rw-r--r-- | tools/opt/NewPMDriver.cpp | 40 | ||||
-rw-r--r-- | tools/opt/NewPMDriver.h | 6 | ||||
-rw-r--r-- | tools/opt/PassRegistry.def | 26 | ||||
-rw-r--r-- | tools/opt/Passes.cpp | 236 | ||||
-rw-r--r-- | tools/opt/Passes.h | 114 | ||||
-rw-r--r-- | tools/opt/opt.cpp | 67 |
6 files changed, 324 insertions, 165 deletions
diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp index 8076ff4..a73750d 100644 --- a/tools/opt/NewPMDriver.cpp +++ b/tools/opt/NewPMDriver.cpp @@ -17,8 +17,8 @@ #include "Passes.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/CGSCCPassManager.h" -#include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -27,28 +27,29 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; using namespace opt_tool; -bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, - tool_output_file *Out, StringRef PassPipeline, - OutputKind OK, VerifierKind VK) { - FunctionAnalysisManager FAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; +static cl::opt<bool> + DebugPM("debug-pass-manager", cl::Hidden, + cl::desc("Print pass management debugging information")); -#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ - MAM.registerPass(CREATE_PASS); -#include "PassRegistry.def" +bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, + TargetMachine *TM, tool_output_file *Out, + StringRef PassPipeline, OutputKind OK, + VerifierKind VK) { + Passes P(TM); -#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ - CGAM.registerPass(CREATE_PASS); -#include "PassRegistry.def" + FunctionAnalysisManager FAM(DebugPM); + CGSCCAnalysisManager CGAM(DebugPM); + ModuleAnalysisManager MAM(DebugPM); -#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ - FAM.registerPass(CREATE_PASS); -#include "PassRegistry.def" + // Register all the basic analyses with the managers. + P.registerModuleAnalyses(MAM); + P.registerCGSCCAnalyses(CGAM); + P.registerFunctionAnalyses(FAM); // Cross register the analysis managers through their proxies. MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM)); @@ -58,11 +59,12 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, FAM.registerPass(CGSCCAnalysisManagerFunctionProxy(CGAM)); FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM)); - ModulePassManager MPM; + ModulePassManager MPM(DebugPM); if (VK > VK_NoVerifier) MPM.addPass(VerifierPass()); - if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) { + if (!P.parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass, + DebugPM)) { errs() << Arg0 << ": unable to parse pass pipeline description.\n"; return false; } @@ -86,7 +88,7 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. - MPM.run(&M, &MAM); + MPM.run(M, &MAM); // Declare success. if (OK != OK_NoOutput) diff --git a/tools/opt/NewPMDriver.h b/tools/opt/NewPMDriver.h index f977bac..5384fe2 100644 --- a/tools/opt/NewPMDriver.h +++ b/tools/opt/NewPMDriver.h @@ -26,6 +26,7 @@ namespace llvm { class LLVMContext; class Module; +class TargetMachine; class tool_output_file; namespace opt_tool { @@ -48,8 +49,9 @@ enum VerifierKind { /// file. It's interface is consequentially somewhat ad-hoc, but will go away /// when the transition finishes. bool runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, - tool_output_file *Out, StringRef PassPipeline, - opt_tool::OutputKind OK, opt_tool::VerifierKind VK); + TargetMachine *TM, tool_output_file *Out, + StringRef PassPipeline, opt_tool::OutputKind OK, + opt_tool::VerifierKind VK); } #endif diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def index e1e4900..d768a3a 100644 --- a/tools/opt/PassRegistry.def +++ b/tools/opt/PassRegistry.def @@ -20,32 +20,58 @@ #define MODULE_ANALYSIS(NAME, CREATE_PASS) #endif MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis()) +MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis()) +MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) #undef MODULE_ANALYSIS #ifndef MODULE_PASS #define MODULE_PASS(NAME, CREATE_PASS) #endif +MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +MODULE_PASS("no-op-module", NoOpModulePass()) MODULE_PASS("print", PrintModulePass(dbgs())) MODULE_PASS("print-cg", LazyCallGraphPrinterPass(dbgs())) +MODULE_PASS("verify", VerifierPass()) #undef MODULE_PASS #ifndef CGSCC_ANALYSIS #define CGSCC_ANALYSIS(NAME, CREATE_PASS) #endif +CGSCC_ANALYSIS("no-op-cgscc", NoOpCGSCCAnalysis()) #undef CGSCC_ANALYSIS #ifndef CGSCC_PASS #define CGSCC_PASS(NAME, CREATE_PASS) #endif +CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass()) #undef CGSCC_PASS #ifndef FUNCTION_ANALYSIS #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) #endif +FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis()) +FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis()) +FUNCTION_ANALYSIS("loops", LoopAnalysis()) +FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis()) +FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) +FUNCTION_ANALYSIS("targetir", + TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis()) #undef FUNCTION_ANALYSIS #ifndef FUNCTION_PASS #define FUNCTION_PASS(NAME, CREATE_PASS) #endif +FUNCTION_PASS("early-cse", EarlyCSEPass()) +FUNCTION_PASS("instcombine", InstCombinePass()) +FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass()) +FUNCTION_PASS("no-op-function", NoOpFunctionPass()) +FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass()) FUNCTION_PASS("print", PrintFunctionPass(dbgs())) +FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs())) +FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs())) +FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs())) +FUNCTION_PASS("simplify-cfg", SimplifyCFGPass()) +FUNCTION_PASS("verify", VerifierPass()) +FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass()) #undef FUNCTION_PASS diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index a171f42..e5ad5c0 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -15,12 +15,22 @@ //===----------------------------------------------------------------------===// #include "Passes.h" +#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/Support/Debug.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/Scalar/EarlyCSE.h" +#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" +#include "llvm/Transforms/Scalar/SimplifyCFG.h" using namespace llvm; @@ -28,112 +38,184 @@ namespace { /// \brief No-op module pass which does nothing. struct NoOpModulePass { - PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); } + PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); } static StringRef name() { return "NoOpModulePass"; } }; +/// \brief No-op module analysis. +struct NoOpModuleAnalysis { + struct Result {}; + Result run(Module &) { return Result(); } + static StringRef name() { return "NoOpModuleAnalysis"; } + static void *ID() { return (void *)&PassID; } +private: + static char PassID; +}; + +char NoOpModuleAnalysis::PassID; + /// \brief No-op CGSCC pass which does nothing. struct NoOpCGSCCPass { - PreservedAnalyses run(LazyCallGraph::SCC *C) { + PreservedAnalyses run(LazyCallGraph::SCC &C) { return PreservedAnalyses::all(); } static StringRef name() { return "NoOpCGSCCPass"; } }; +/// \brief No-op CGSCC analysis. +struct NoOpCGSCCAnalysis { + struct Result {}; + Result run(LazyCallGraph::SCC &) { return Result(); } + static StringRef name() { return "NoOpCGSCCAnalysis"; } + static void *ID() { return (void *)&PassID; } +private: + static char PassID; +}; + +char NoOpCGSCCAnalysis::PassID; + /// \brief No-op function pass which does nothing. struct NoOpFunctionPass { - PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); } + PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); } static StringRef name() { return "NoOpFunctionPass"; } }; +/// \brief No-op function analysis. +struct NoOpFunctionAnalysis { + struct Result {}; + Result run(Function &) { return Result(); } + static StringRef name() { return "NoOpFunctionAnalysis"; } + static void *ID() { return (void *)&PassID; } +private: + static char PassID; +}; + +char NoOpFunctionAnalysis::PassID; + } // End anonymous namespace. -static bool isModulePassName(StringRef Name) { - if (Name == "no-op-module") return true; +void Passes::registerModuleAnalyses(ModuleAnalysisManager &MAM) { +#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ + MAM.registerPass(CREATE_PASS); +#include "PassRegistry.def" +} + +void Passes::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) { +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ + CGAM.registerPass(CREATE_PASS); +#include "PassRegistry.def" +} + +void Passes::registerFunctionAnalyses(FunctionAnalysisManager &FAM) { +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + FAM.registerPass(CREATE_PASS); +#include "PassRegistry.def" +} +#ifndef NDEBUG +static bool isModulePassName(StringRef Name) { #define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ + return true; #include "PassRegistry.def" return false; } +#endif static bool isCGSCCPassName(StringRef Name) { - if (Name == "no-op-cgscc") return true; - #define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ + return true; #include "PassRegistry.def" return false; } static bool isFunctionPassName(StringRef Name) { - if (Name == "no-op-function") return true; - #define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \ + return true; #include "PassRegistry.def" return false; } -static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { - if (Name == "no-op-module") { - MPM.addPass(NoOpModulePass()); - return true; - } - +bool Passes::parseModulePassName(ModulePassManager &MPM, StringRef Name) { #define MODULE_PASS(NAME, CREATE_PASS) \ if (Name == NAME) { \ MPM.addPass(CREATE_PASS); \ return true; \ } +#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">") { \ + MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \ + return true; \ + } \ + if (Name == "invalidate<" NAME ">") { \ + MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \ + return true; \ + } #include "PassRegistry.def" return false; } -static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { - if (Name == "no-op-cgscc") { - CGPM.addPass(NoOpCGSCCPass()); - return true; - } - +bool Passes::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { #define CGSCC_PASS(NAME, CREATE_PASS) \ if (Name == NAME) { \ CGPM.addPass(CREATE_PASS); \ return true; \ } +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">") { \ + CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \ + return true; \ + } \ + if (Name == "invalidate<" NAME ">") { \ + CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \ + return true; \ + } #include "PassRegistry.def" return false; } -static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { - if (Name == "no-op-function") { - FPM.addPass(NoOpFunctionPass()); - return true; - } - +bool Passes::parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { #define FUNCTION_PASS(NAME, CREATE_PASS) \ if (Name == NAME) { \ FPM.addPass(CREATE_PASS); \ return true; \ } +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + if (Name == "require<" NAME ">") { \ + FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>()); \ + return true; \ + } \ + if (Name == "invalidate<" NAME ">") { \ + FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>()); \ + return true; \ + } #include "PassRegistry.def" return false; } -static bool parseFunctionPassPipeline(FunctionPassManager &FPM, - StringRef &PipelineText, - bool VerifyEachPass) { +bool Passes::parseFunctionPassPipeline(FunctionPassManager &FPM, + StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("function(")) { - FunctionPassManager NestedFPM; + FunctionPassManager NestedFPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("function(")); - if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, + DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); @@ -160,17 +242,18 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM, } } -static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, - StringRef &PipelineText, - bool VerifyEachPass) { +bool Passes::parseCGSCCPassPipeline(CGSCCPassManager &CGPM, + StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("cgscc(")) { - CGSCCPassManager NestedCGPM; + CGSCCPassManager NestedCGPM(DebugLogging); // Parse the inner pipeline into the nested manager. PipelineText = PipelineText.substr(strlen("cgscc(")); - if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || + if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass, + DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); @@ -179,11 +262,12 @@ static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, // Add the nested pass manager with the appropriate adaptor. CGPM.addPass(std::move(NestedCGPM)); } else if (PipelineText.startswith("function(")) { - FunctionPassManager NestedFPM; + FunctionPassManager NestedFPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("function(")); - if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, + DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); @@ -209,17 +293,18 @@ static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, } } -static bool parseModulePassPipeline(ModulePassManager &MPM, - StringRef &PipelineText, - bool VerifyEachPass) { +bool Passes::parseModulePassPipeline(ModulePassManager &MPM, + StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("module(")) { - ModulePassManager NestedMPM; + ModulePassManager NestedMPM(DebugLogging); // Parse the inner pipeline into the nested manager. PipelineText = PipelineText.substr(strlen("module(")); - if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) || + if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass, + DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); @@ -228,11 +313,12 @@ static bool parseModulePassPipeline(ModulePassManager &MPM, // Now add the nested manager as a module pass. MPM.addPass(std::move(NestedMPM)); } else if (PipelineText.startswith("cgscc(")) { - CGSCCPassManager NestedCGPM; + CGSCCPassManager NestedCGPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("cgscc(")); - if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || + if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass, + DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); @@ -242,11 +328,12 @@ static bool parseModulePassPipeline(ModulePassManager &MPM, MPM.addPass( createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM))); } else if (PipelineText.startswith("function(")) { - FunctionPassManager NestedFPM; + FunctionPassManager NestedFPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("function(")); - if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, + DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); @@ -276,48 +363,39 @@ static bool parseModulePassPipeline(ModulePassManager &MPM, // Primary pass pipeline description parsing routine. // FIXME: Should this routine accept a TargetMachine or require the caller to // pre-populate the analysis managers with target-specific stuff? -bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, - bool VerifyEachPass) { - // Look at the first entry to figure out which layer to start parsing at. - if (PipelineText.startswith("module(")) - return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && - PipelineText.empty(); - if (PipelineText.startswith("cgscc(")) { - CGSCCPassManager CGPM; - if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || - !PipelineText.empty()) - return false; - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); - return true; - } - if (PipelineText.startswith("function(")) { - FunctionPassManager FPM; - if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || - !PipelineText.empty()) - return false; - MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); - return true; - } - - // This isn't a direct pass manager name, look for the end of a pass name. +bool Passes::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, + bool VerifyEachPass, bool DebugLogging) { + // By default, try to parse the pipeline as-if it were within an implicit + // 'module(...)' pass pipeline. If this will parse at all, it needs to + // consume the entire string. + if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging)) + return PipelineText.empty(); + + // This isn't parsable as a module pipeline, look for the end of a pass name + // and directly drop down to that layer. StringRef FirstName = PipelineText.substr(0, PipelineText.find_first_of(",)")); - if (isModulePassName(FirstName)) - return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && - PipelineText.empty(); + assert(!isModulePassName(FirstName) && + "Already handled all module pipeline options."); + // If this looks like a CGSCC pass, parse the whole thing as a CGSCC + // pipeline. if (isCGSCCPassName(FirstName)) { - CGSCCPassManager CGPM; - if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || + CGSCCPassManager CGPM(DebugLogging); + if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass, + DebugLogging) || !PipelineText.empty()) return false; MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); return true; } + // Similarly, if this looks like a Function pass, parse the whole thing as + // a Function pipelien. if (isFunctionPassName(FirstName)) { - FunctionPassManager FPM; - if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || + FunctionPassManager FPM(DebugLogging); + if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass, + DebugLogging) || !PipelineText.empty()) return false; MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); diff --git a/tools/opt/Passes.h b/tools/opt/Passes.h index 3bd6752..d3cb628 100644 --- a/tools/opt/Passes.h +++ b/tools/opt/Passes.h @@ -1,4 +1,4 @@ -//===- Passes.h - Parsing, selection, and running of passes -----*- C++ -*-===// +//===- Passes.h - Utilities for manipulating all passes ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// /// \file /// -/// Interfaces for producing common pass manager configurations and parsing -/// textual pass specifications. +/// Interfaces for registering passes, producing common pass manager +/// configurations, and parsing of pass pipelines. /// //===----------------------------------------------------------------------===// @@ -17,40 +17,88 @@ #define LLVM_TOOLS_OPT_PASSES_H #include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/IR/PassManager.h" namespace llvm { -class ModulePassManager; +class TargetMachine; -/// \brief Parse a textual pass pipeline description into a \c ModulePassManager. +/// \brief This class provides access to all of LLVM's passes. /// -/// The format of the textual pass pipeline description looks something like: -/// -/// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...) -/// -/// Pass managers have ()s describing the nest structure of passes. All passes -/// are comma separated. As a special shortcut, if the very first pass is not -/// a module pass (as a module pass manager is), this will automatically form -/// the shortest stack of pass managers that allow inserting that first pass. -/// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes -/// 'lpassN', all of these are valid: -/// -/// fpass1,fpass2,fpass3 -/// cgpass1,cgpass2,cgpass3 -/// lpass1,lpass2,lpass3 -/// -/// And they are equivalent to the following (resp.): -/// -/// module(function(fpass1,fpass2,fpass3)) -/// module(cgscc(cgpass1,cgpass2,cgpass3)) -/// module(function(loop(lpass1,lpass2,lpass3))) -/// -/// This shortcut is especially useful for debugging and testing small pass -/// combinations. Note that these shortcuts don't introduce any other magic. If -/// the sequence of passes aren't all the exact same kind of pass, it will be -/// an error. You cannot mix different levels implicitly, you must explicitly -/// form a pass manager in which to nest passes. -bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, - bool VerifyEachPass = true); +/// It's members provide the baseline state available to passes during their +/// construction. The \c PassRegistry.def file specifies how to construct all +/// of the built-in passes, and those may reference these members during +/// construction. +class Passes { + TargetMachine *TM; + +public: + explicit Passes(TargetMachine *TM = nullptr) : TM(TM) {} + + /// \brief Registers all available module analysis passes. + /// + /// This is an interface that can be used to populate a \c + /// ModuleAnalysisManager with all registered module analyses. Callers can + /// still manually register any additional analyses. + void registerModuleAnalyses(ModuleAnalysisManager &MAM); + + /// \brief Registers all available CGSCC analysis passes. + /// + /// This is an interface that can be used to populate a \c CGSCCAnalysisManager + /// with all registered CGSCC analyses. Callers can still manually register any + /// additional analyses. + void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM); + + /// \brief Registers all available function analysis passes. + /// + /// This is an interface that can be used to populate a \c + /// FunctionAnalysisManager with all registered function analyses. Callers can + /// still manually register any additional analyses. + void registerFunctionAnalyses(FunctionAnalysisManager &FAM); + + /// \brief Parse a textual pass pipeline description into a \c ModulePassManager. + /// + /// The format of the textual pass pipeline description looks something like: + /// + /// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...) + /// + /// Pass managers have ()s describing the nest structure of passes. All passes + /// are comma separated. As a special shortcut, if the very first pass is not + /// a module pass (as a module pass manager is), this will automatically form + /// the shortest stack of pass managers that allow inserting that first pass. + /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes + /// 'lpassN', all of these are valid: + /// + /// fpass1,fpass2,fpass3 + /// cgpass1,cgpass2,cgpass3 + /// lpass1,lpass2,lpass3 + /// + /// And they are equivalent to the following (resp.): + /// + /// module(function(fpass1,fpass2,fpass3)) + /// module(cgscc(cgpass1,cgpass2,cgpass3)) + /// module(function(loop(lpass1,lpass2,lpass3))) + /// + /// This shortcut is especially useful for debugging and testing small pass + /// combinations. Note that these shortcuts don't introduce any other magic. If + /// the sequence of passes aren't all the exact same kind of pass, it will be + /// an error. You cannot mix different levels implicitly, you must explicitly + /// form a pass manager in which to nest passes. + bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, + bool VerifyEachPass = true, bool DebugLogging = false); + +private: + bool parseModulePassName(ModulePassManager &MPM, StringRef Name); + bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name); + bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name); + bool parseFunctionPassPipeline(FunctionPassManager &FPM, + StringRef &PipelineText, bool VerifyEachPass, + bool DebugLogging); + bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging); + bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText, + bool VerifyEachPass, bool DebugLogging); +}; } diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index cdd22e4..d952525 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -20,6 +20,8 @@ #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/RegionPass.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/IR/DataLayout.h" @@ -33,7 +35,7 @@ #include "llvm/LinkAllIR.h" #include "llvm/LinkAllPasses.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/PassManager.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" @@ -45,7 +47,6 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" -#include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include <algorithm> @@ -179,7 +180,7 @@ DefaultDataLayout("default-data-layout", -static inline void addPass(PassManagerBase &PM, Pass *P) { +static inline void addPass(legacy::PassManagerBase &PM, Pass *P) { // Add the pass to the pass manager... PM.add(P); @@ -194,7 +195,8 @@ static inline void addPass(PassManagerBase &PM, Pass *P) { /// OptLevel. /// /// OptLevel - Optimization Level -static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, +static void AddOptimizationPasses(legacy::PassManagerBase &MPM, + legacy::FunctionPassManager &FPM, unsigned OptLevel, unsigned SizeLevel) { FPM.add(createVerifierPass()); // Verify that input is correct MPM.add(createDebugInfoVerifierPass()); // Verify that debug info is correct @@ -229,7 +231,7 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.populateModulePassManager(MPM); } -static void AddStandardLinkPasses(PassManagerBase &PM) { +static void AddStandardLinkPasses(legacy::PassManagerBase &PM) { PassManagerBuilder Builder; Builder.VerifyInput = true; Builder.StripDebug = StripDebug; @@ -307,7 +309,6 @@ int main(int argc, char **argv) { // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); - initializeDebugIRPass(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); @@ -323,6 +324,8 @@ int main(int argc, char **argv) { initializeCodeGenPreparePass(Registry); initializeAtomicExpandPass(Registry); initializeRewriteSymbolsPass(Registry); + initializeWinEHPreparePass(Registry); + initializeDwarfEHPreparePass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); @@ -341,7 +344,7 @@ int main(int argc, char **argv) { // Load the input module... std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context); - if (!M.get()) { + if (!M) { Err.print(argv[0], errs()); return 1; } @@ -369,6 +372,12 @@ int main(int argc, char **argv) { } } + Triple ModuleTriple(M->getTargetTriple()); + TargetMachine *Machine = nullptr; + if (ModuleTriple.getArch()) + Machine = GetTargetMachine(ModuleTriple); + std::unique_ptr<TargetMachine> TM(Machine); + // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. @@ -390,8 +399,8 @@ int main(int argc, char **argv) { // The user has asked to use the new pass manager and provided a pipeline // string. Hand off the rest of the functionality to the new code for that // layer. - return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline, - OK, VK) + return runPassPipeline(argv[0], Context, *M, TM.get(), Out.get(), + PassPipeline, OK, VK) ? 0 : 1; } @@ -399,44 +408,37 @@ int main(int argc, char **argv) { // Create a PassManager to hold and optimize the collection of passes we are // about to build. // - PassManager Passes; + legacy::PassManager Passes; // Add an appropriate TargetLibraryInfo pass for the module's triple. - TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple())); + TargetLibraryInfoImpl TLII(ModuleTriple); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) - TLI->disableAllFunctions(); - Passes.add(TLI); + TLII.disableAllFunctions(); + Passes.add(new TargetLibraryInfoWrapperPass(TLII)); // Add an appropriate DataLayout instance for this module. - const DataLayout *DL = M.get()->getDataLayout(); + const DataLayout *DL = M->getDataLayout(); if (!DL && !DefaultDataLayout.empty()) { M->setDataLayout(DefaultDataLayout); - DL = M.get()->getDataLayout(); + DL = M->getDataLayout(); } if (DL) Passes.add(new DataLayoutPass()); - Triple ModuleTriple(M->getTargetTriple()); - TargetMachine *Machine = nullptr; - if (ModuleTriple.getArch()) - Machine = GetTargetMachine(Triple(ModuleTriple)); - std::unique_ptr<TargetMachine> TM(Machine); - // Add internal analysis passes from the target machine. - if (TM.get()) - TM->addAnalysisPasses(Passes); + Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis() + : TargetIRAnalysis())); - std::unique_ptr<FunctionPassManager> FPasses; + std::unique_ptr<legacy::FunctionPassManager> FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { - FPasses.reset(new FunctionPassManager(M.get())); + FPasses.reset(new legacy::FunctionPassManager(M.get())); if (DL) FPasses->add(new DataLayoutPass()); - if (TM.get()) - TM->addAnalysisPasses(*FPasses); - + FPasses->add(createTargetTransformInfoWrapperPass( + TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())); } if (PrintBreakpoints) { @@ -446,7 +448,8 @@ int main(int argc, char **argv) { OutputFilename = "-"; std::error_code EC; - Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None)); + Out = llvm::make_unique<tool_output_file>(OutputFilename, EC, + sys::fs::F_None); if (EC) { errs() << EC.message() << '\n'; return 1; @@ -556,8 +559,8 @@ int main(int argc, char **argv) { if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization(); - for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) - FPasses->run(*F); + for (Function &F : *M) + FPasses->run(F); FPasses->doFinalization(); } @@ -579,7 +582,7 @@ int main(int argc, char **argv) { cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. - Passes.run(*M.get()); + Passes.run(*M); // Declare success. if (!NoOutput || PrintBreakpoints) |