diff options
Diffstat (limited to 'tools/opt')
-rw-r--r-- | tools/opt/NewPMDriver.cpp | 20 | ||||
-rw-r--r-- | tools/opt/PassRegistry.def | 51 | ||||
-rw-r--r-- | tools/opt/Passes.cpp | 145 | ||||
-rw-r--r-- | tools/opt/PrintSCC.cpp | 6 | ||||
-rw-r--r-- | tools/opt/opt.cpp | 30 |
5 files changed, 225 insertions, 27 deletions
diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp index fc4a1bf..8076ff4 100644 --- a/tools/opt/NewPMDriver.cpp +++ b/tools/opt/NewPMDriver.cpp @@ -16,6 +16,7 @@ #include "NewPMDriver.h" #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/IRPrintingPasses.h" @@ -34,14 +35,27 @@ 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; - // FIXME: Lift this registration of analysis passes into a .def file adjacent - // to the one used to associate names with passes. - MAM.registerPass(LazyCallGraphAnalysis()); +#define MODULE_ANALYSIS(NAME, CREATE_PASS) \ + MAM.registerPass(CREATE_PASS); +#include "PassRegistry.def" + +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ + CGAM.registerPass(CREATE_PASS); +#include "PassRegistry.def" + +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ + FAM.registerPass(CREATE_PASS); +#include "PassRegistry.def" // Cross register the analysis managers through their proxies. MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM)); + MAM.registerPass(CGSCCAnalysisManagerModuleProxy(CGAM)); + CGAM.registerPass(FunctionAnalysisManagerCGSCCProxy(FAM)); + CGAM.registerPass(ModuleAnalysisManagerCGSCCProxy(MAM)); + FAM.registerPass(CGSCCAnalysisManagerFunctionProxy(CGAM)); FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM)); ModulePassManager MPM; diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def new file mode 100644 index 0000000..e1e4900 --- /dev/null +++ b/tools/opt/PassRegistry.def @@ -0,0 +1,51 @@ +//===- PassRegistry.def - Registry of passes --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is used as the registry of passes that are part of the core LLVM +// libraries. This file describes both transformation passes and analyses +// Analyses are registered while transformation passes have names registered +// that can be used when providing a textual pass pipeline. +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +#ifndef MODULE_ANALYSIS +#define MODULE_ANALYSIS(NAME, CREATE_PASS) +#endif +MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis()) +#undef MODULE_ANALYSIS + +#ifndef MODULE_PASS +#define MODULE_PASS(NAME, CREATE_PASS) +#endif +MODULE_PASS("print", PrintModulePass(dbgs())) +MODULE_PASS("print-cg", LazyCallGraphPrinterPass(dbgs())) +#undef MODULE_PASS + +#ifndef CGSCC_ANALYSIS +#define CGSCC_ANALYSIS(NAME, CREATE_PASS) +#endif +#undef CGSCC_ANALYSIS + +#ifndef CGSCC_PASS +#define CGSCC_PASS(NAME, CREATE_PASS) +#endif +#undef CGSCC_PASS + +#ifndef FUNCTION_ANALYSIS +#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) +#endif +#undef FUNCTION_ANALYSIS + +#ifndef FUNCTION_PASS +#define FUNCTION_PASS(NAME, CREATE_PASS) +#endif +FUNCTION_PASS("print", PrintFunctionPass(dbgs())) +#undef FUNCTION_PASS diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index ffdf9bf..a171f42 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "Passes.h" +#include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h" @@ -31,6 +32,14 @@ struct NoOpModulePass { static StringRef name() { return "NoOpModulePass"; } }; +/// \brief No-op CGSCC pass which does nothing. +struct NoOpCGSCCPass { + PreservedAnalyses run(LazyCallGraph::SCC *C) { + return PreservedAnalyses::all(); + } + static StringRef name() { return "NoOpCGSCCPass"; } +}; + /// \brief No-op function pass which does nothing. struct NoOpFunctionPass { PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); } @@ -39,19 +48,29 @@ struct NoOpFunctionPass { } // End anonymous namespace. -// FIXME: Factor all of the parsing logic into a .def file that we include -// under different macros. static bool isModulePassName(StringRef Name) { if (Name == "no-op-module") return true; - if (Name == "print") return true; - if (Name == "print-cg") return true; + +#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#include "PassRegistry.def" + + return false; +} + +static bool isCGSCCPassName(StringRef Name) { + if (Name == "no-op-cgscc") return true; + +#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#include "PassRegistry.def" return false; } static bool isFunctionPassName(StringRef Name) { if (Name == "no-op-function") return true; - if (Name == "print") return true; + +#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#include "PassRegistry.def" return false; } @@ -61,14 +80,30 @@ static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { MPM.addPass(NoOpModulePass()); return true; } - if (Name == "print") { - MPM.addPass(PrintModulePass(dbgs())); - return true; + +#define MODULE_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + MPM.addPass(CREATE_PASS); \ + return true; \ } - if (Name == "print-cg") { - MPM.addPass(LazyCallGraphPrinterPass(dbgs())); +#include "PassRegistry.def" + + return false; +} + +static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { + if (Name == "no-op-cgscc") { + CGPM.addPass(NoOpCGSCCPass()); return true; } + +#define CGSCC_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + CGPM.addPass(CREATE_PASS); \ + return true; \ + } +#include "PassRegistry.def" + return false; } @@ -77,10 +112,14 @@ static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { FPM.addPass(NoOpFunctionPass()); return true; } - if (Name == "print") { - FPM.addPass(PrintFunctionPass(dbgs())); - return true; + +#define FUNCTION_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + FPM.addPass(CREATE_PASS); \ + return true; \ } +#include "PassRegistry.def" + return false; } @@ -121,6 +160,55 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM, } } +static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, + StringRef &PipelineText, + bool VerifyEachPass) { + for (;;) { + // Parse nested pass managers by recursing. + if (PipelineText.startswith("cgscc(")) { + CGSCCPassManager NestedCGPM; + + // Parse the inner pipeline into the nested manager. + PipelineText = PipelineText.substr(strlen("cgscc(")); + if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + CGPM.addPass(std::move(NestedCGPM)); + } else if (PipelineText.startswith("function(")) { + FunctionPassManager NestedFPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("function(")); + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM))); + } else { + // Otherwise try to parse a pass name. + size_t End = PipelineText.find_first_of(",)"); + if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End))) + return false; + // FIXME: No verifier support for CGSCC passes! + + PipelineText = PipelineText.substr(End); + } + + if (PipelineText.empty() || PipelineText[0] == ')') + return true; + + assert(PipelineText[0] == ','); + PipelineText = PipelineText.substr(1); + } +} + static bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText, bool VerifyEachPass) { @@ -139,6 +227,20 @@ 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; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("cgscc(")); + if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + MPM.addPass( + createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM))); } else if (PipelineText.startswith("function(")) { FunctionPassManager NestedFPM; @@ -180,6 +282,14 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, 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) || @@ -196,6 +306,15 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && PipelineText.empty(); + if (isCGSCCPassName(FirstName)) { + CGSCCPassManager CGPM; + if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) + return false; + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + return true; + } + if (isFunctionPassName(FirstName)) { FunctionPassManager FPM; if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp index cbc0a55..78ede2b 100644 --- a/tools/opt/PrintSCC.cpp +++ b/tools/opt/PrintSCC.cpp @@ -39,7 +39,7 @@ namespace { CFGSCC() : FunctionPass(ID) {} bool runOnFunction(Function& func) override; - void print(raw_ostream &O, const Module* = 0) const override { } + void print(raw_ostream &O, const Module* = nullptr) const override { } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); @@ -53,7 +53,7 @@ namespace { // run - Print out SCCs in the call graph for the specified module. bool runOnModule(Module &M) override; - void print(raw_ostream &O, const Module* = 0) const override { } + void print(raw_ostream &O, const Module* = nullptr) const override { } // getAnalysisUsage - This pass requires the CallGraph. void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -75,7 +75,7 @@ bool CFGSCC::runOnFunction(Function &F) { unsigned sccNum = 0; errs() << "SCCs for Function " << F.getName() << " in PostOrder:"; for (scc_iterator<Function*> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) { - std::vector<BasicBlock*> &nextSCC = *SCCI; + const std::vector<BasicBlock *> &nextSCC = *SCCI; errs() << "\nSCC #" << ++sccNum << " : "; for (std::vector<BasicBlock*>::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 5a19881..6f0fbf6 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -35,6 +35,7 @@ #include "llvm/MC/SubtargetFeature.h" #include "llvm/PassManager.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" @@ -191,7 +192,10 @@ static inline void addPass(PassManagerBase &PM, Pass *P) { PM.add(P); // If we are verifying all of the intermediate steps, add the verifier... - if (VerifyEach) PM.add(createVerifierPass()); + if (VerifyEach) { + PM.add(createVerifierPass()); + PM.add(createDebugInfoVerifierPass()); + } } /// AddOptimizationPasses - This routine adds optimization passes @@ -201,7 +205,8 @@ static inline void addPass(PassManagerBase &PM, Pass *P) { /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, unsigned OptLevel, unsigned SizeLevel) { - FPM.add(createVerifierPass()); // Verify that input is correct + FPM.add(createVerifierPass()); // Verify that input is correct + MPM.add(createDebugInfoVerifierPass()); // Verify that debug info is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; @@ -240,6 +245,9 @@ static void AddStandardCompilePasses(PassManagerBase &PM) { if (StripDebug) addPass(PM, createStripSymbolsPass(true)); + // Verify debug info only after it's (possibly) stripped. + PM.add(createDebugInfoVerifierPass()); + if (DisableOptimizations) return; // -std-compile-opts adds the same module passes as -O3. @@ -257,6 +265,9 @@ static void AddStandardLinkPasses(PassManagerBase &PM) { if (StripDebug) addPass(PM, createStripSymbolsPass(true)); + // Verify debug info only after it's (possibly) stripped. + PM.add(createDebugInfoVerifierPass()); + if (DisableOptimizations) return; PassManagerBuilder Builder; @@ -285,7 +296,7 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) { Error); // Some modules don't specify a triple, and this is okay. if (!TheTarget) { - return 0; + return nullptr; } // Package up features to be passed to target/subtarget @@ -341,8 +352,9 @@ int main(int argc, char **argv) { initializeInstrumentation(Registry); initializeTarget(Registry); // For codegen passes, only passes that do IR to IR transformation are - // supported. For now, just add CodeGenPrepare. + // supported. initializeCodeGenPreparePass(Registry); + initializeAtomicExpandLoadLinkedPass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); @@ -362,7 +374,7 @@ int main(int argc, char **argv) { std::unique_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); - if (M.get() == 0) { + if (!M.get()) { Err.print(argv[0], errs()); return 1; } @@ -442,7 +454,7 @@ int main(int argc, char **argv) { Passes.add(new DataLayoutPass(M.get())); Triple ModuleTriple(M->getTargetTriple()); - TargetMachine *Machine = 0; + TargetMachine *Machine = nullptr; if (ModuleTriple.getArch()) Machine = GetTargetMachine(Triple(ModuleTriple)); std::unique_ptr<TargetMachine> TM(Machine); @@ -526,7 +538,7 @@ int main(int argc, char **argv) { } const PassInfo *PassInf = PassList[i]; - Pass *P = 0; + Pass *P = nullptr; if (PassInf->getTargetMachineCtor()) P = PassInf->getTargetMachineCtor()(TM.get()); else if (PassInf->getNormalCtor()) @@ -600,8 +612,10 @@ int main(int argc, char **argv) { } // Check that the module is well formed on completion of optimization - if (!NoVerify && !VerifyEach) + if (!NoVerify && !VerifyEach) { Passes.add(createVerifierPass()); + Passes.add(createDebugInfoVerifierPass()); + } // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { |