From: Alex Lorenz Date: Mon, 6 Jul 2015 17:44:26 +0000 (+0000) Subject: llc: Add a 'run-pass' option. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=edfa571cbd115bf534d8aa92c8d9da1253f6ac76;p=oota-llvm.git llc: Add a 'run-pass' option. This commit adds a 'run-pass' option to llc, which instructs the compiler to run one specific code generation pass only. Llc already has the 'start-after' and the 'stop-after' options, and this new option complements the other two by making it easier to write tests that want to invoke a single pass only. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D10776 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241476 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h index 554511d6f4a..4b2e0b06584 100644 --- a/include/llvm/CodeGen/CommandFlags.h +++ b/include/llvm/CodeGen/CommandFlags.h @@ -206,6 +206,10 @@ cl::opt StartAfter("start-after", cl::value_desc("pass-name"), cl::init("")); +cl::opt + RunPass("run-pass", cl::desc("Run compiler only for one specific pass"), + cl::value_desc("pass-name"), cl::init("")); + cl::opt DataSections("data-sections", cl::desc("Emit data into separate sections"), cl::init(false)); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 538c995a7b4..ecf679f0ca0 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -101,7 +101,7 @@ public: private: PassManagerBase *PM; - AnalysisID StartAfter; + AnalysisID StartBefore, StartAfter; AnalysisID StopAfter; bool Started; bool Stopped; @@ -142,16 +142,24 @@ public: CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } - /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow - /// running only a portion of the normal code-gen pass sequence. If the - /// Start pass ID is zero, then compilation will begin at the normal point; - /// otherwise, clear the Started flag to indicate that passes should not be - /// added until the starting pass is seen. If the Stop pass ID is zero, - /// then compilation will continue to the end. - void setStartStopPasses(AnalysisID Start, AnalysisID Stop) { - StartAfter = Start; - StopAfter = Stop; - Started = (StartAfter == nullptr); + /// Set the StartAfter, StartBefore and StopAfter passes to allow running only + /// a portion of the normal code-gen pass sequence. + /// + /// If the StartAfter and StartBefore pass ID is zero, then compilation will + /// begin at the normal point; otherwise, clear the Started flag to indicate + /// that passes should not be added until the starting pass is seen. If the + /// Stop pass ID is zero, then compilation will continue to the end. + /// + /// This function expects that at least one of the StartAfter or the + /// StartBefore pass IDs is null. + void setStartStopPasses(AnalysisID StartBefore, AnalysisID StartAfter, + AnalysisID StopAfter) { + if (StartAfter) + assert(!StartBefore && "Start after and start before passes are given"); + this->StartBefore = StartBefore; + this->StartAfter = StartAfter; + this->StopAfter = StopAfter; + Started = (StartAfter == nullptr) && (StartBefore == nullptr); } void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); } diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 64a923b80ed..06a2b13836e 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -212,8 +212,8 @@ public: /// supported, or false on success. virtual bool addPassesToEmitFile( PassManagerBase &, raw_pwrite_stream &, CodeGenFileType, - bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr, - AnalysisID /*StopAfter*/ = nullptr, + bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr, + AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopAfter*/ = nullptr, MachineFunctionInitializer * /*MFInitializer*/ = nullptr) { return true; } @@ -260,8 +260,8 @@ public: /// emitted. Typically this will involve several steps of code generation. bool addPassesToEmitFile( PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, - bool DisableVerify = true, AnalysisID StartAfter = nullptr, - AnalysisID StopAfter = nullptr, + bool DisableVerify = true, AnalysisID StartBefore = nullptr, + AnalysisID StartAfter = nullptr, AnalysisID StopAfter = nullptr, MachineFunctionInitializer *MFInitializer = nullptr) override; /// Add passes to the specified pass manager to get machine code emitted with diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index b486bdc9145..37299eb664c 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -90,8 +90,8 @@ TargetIRAnalysis LLVMTargetMachine::getTargetIRAnalysis() { /// addPassesToX helper drives creation and initialization of TargetPassConfig. static MCContext * addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, - bool DisableVerify, AnalysisID StartAfter, - AnalysisID StopAfter, + bool DisableVerify, AnalysisID StartBefore, + AnalysisID StartAfter, AnalysisID StopAfter, MachineFunctionInitializer *MFInitializer = nullptr) { // Add internal analysis passes from the target machine. @@ -100,7 +100,7 @@ addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, // Targets may override createPassConfig to provide a target-specific // subclass. TargetPassConfig *PassConfig = TM->createPassConfig(PM); - PassConfig->setStartStopPasses(StartAfter, StopAfter); + PassConfig->setStartStopPasses(StartBefore, StartAfter, StopAfter); // Set PassConfig options provided by TargetMachine. PassConfig->setDisableVerify(DisableVerify); @@ -143,11 +143,12 @@ addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, bool LLVMTargetMachine::addPassesToEmitFile( PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, - bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter, - MachineFunctionInitializer *MFInitializer) { + bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter, + AnalysisID StopAfter, MachineFunctionInitializer *MFInitializer) { // Add common CodeGen passes. - MCContext *Context = addPassesToGenerateCode( - this, PM, DisableVerify, StartAfter, StopAfter, MFInitializer); + MCContext *Context = + addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter, + StopAfter, MFInitializer); if (!Context) return true; @@ -231,7 +232,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, raw_pwrite_stream &Out, bool DisableVerify) { // Add common CodeGen passes. - Ctx = addPassesToGenerateCode(this, PM, DisableVerify, nullptr, nullptr); + Ctx = addPassesToGenerateCode(this, PM, DisableVerify, nullptr, nullptr, + nullptr); if (!Ctx) return true; diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 210a7a1649c..0821e6ad158 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -214,10 +214,10 @@ TargetPassConfig::~TargetPassConfig() { // Out of line constructor provides default values for pass options and // registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) - : ImmutablePass(ID), PM(&pm), StartAfter(nullptr), StopAfter(nullptr), - Started(true), Stopped(false), AddingMachinePasses(false), TM(tm), - Impl(nullptr), Initialized(false), DisableVerify(false), - EnableTailMerge(true), EnableShrinkWrap(false) { + : ImmutablePass(ID), PM(&pm), StartBefore(nullptr), StartAfter(nullptr), + StopAfter(nullptr), Started(true), Stopped(false), + AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false), + DisableVerify(false), EnableTailMerge(true), EnableShrinkWrap(false) { Impl = new PassConfigImpl(); @@ -288,6 +288,8 @@ void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) { // and shouldn't reference it. AnalysisID PassID = P->getPassID(); + if (StartBefore == PassID) + Started = true; if (Started && !Stopped) { std::string Banner; // Construct banner message before PM->add() as that may delete the pass. diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index bc5d7f65b2f..272688edb8a 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -2148,8 +2148,8 @@ char CppWriter::ID = 0; bool CPPTargetMachine::addPassesToEmitFile( PassManagerBase &PM, raw_pwrite_stream &o, CodeGenFileType FileType, - bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter, - MachineFunctionInitializer *MFInitializer) { + bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter, + AnalysisID StopAfter, MachineFunctionInitializer *MFInitializer) { if (FileType != TargetMachine::CGFT_AssemblyFile) return true; auto FOut = llvm::make_unique(o); diff --git a/lib/Target/CppBackend/CPPTargetMachine.h b/lib/Target/CppBackend/CPPTargetMachine.h index ebf0635b12e..00e402feffb 100644 --- a/lib/Target/CppBackend/CPPTargetMachine.h +++ b/lib/Target/CppBackend/CPPTargetMachine.h @@ -31,7 +31,8 @@ struct CPPTargetMachine : public TargetMachine { public: bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, bool DisableVerify, - AnalysisID StartAfter, AnalysisID StopAfter, + AnalysisID StartBefore, AnalysisID StartAfter, + AnalysisID StopAfter, MachineFunctionInitializer *MFInitializer) override; }; diff --git a/test/CodeGen/Generic/run-pass.ll b/test/CodeGen/Generic/run-pass.ll new file mode 100644 index 00000000000..55d62ec1864 --- /dev/null +++ b/test/CodeGen/Generic/run-pass.ll @@ -0,0 +1,7 @@ +; RUN: llc < %s -debug-pass=Structure -run-pass=gc-lowering -o /dev/null 2>&1 | FileCheck %s + +; CHECK: -gc-lowering +; CHECK: FunctionPass Manager +; CHECK-NEXT: Lower Garbage Collection Instructions +; CHECK-NEXT: Machine Function Analysis +; CHECK-NEXT: MIR Printing Pass diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 88e73716099..e33cd795d3a 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -333,29 +333,44 @@ static int compileModule(char **argv, LLVMContext &Context) { OS = BOS.get(); } + AnalysisID StartBeforeID = nullptr; AnalysisID StartAfterID = nullptr; AnalysisID StopAfterID = nullptr; const PassRegistry *PR = PassRegistry::getPassRegistry(); - if (!StartAfter.empty()) { - const PassInfo *PI = PR->getPassInfo(StartAfter); - if (!PI) { - errs() << argv[0] << ": start-after pass is not registered.\n"; + if (!RunPass.empty()) { + if (!StartAfter.empty() || !StopAfter.empty()) { + errs() << argv[0] << ": start-after and/or stop-after passes are " + "redundant when run-pass is specified.\n"; return 1; } - StartAfterID = PI->getTypeInfo(); - } - if (!StopAfter.empty()) { - const PassInfo *PI = PR->getPassInfo(StopAfter); + const PassInfo *PI = PR->getPassInfo(RunPass); if (!PI) { - errs() << argv[0] << ": stop-after pass is not registered.\n"; + errs() << argv[0] << ": run-pass pass is not registered.\n"; return 1; } - StopAfterID = PI->getTypeInfo(); + StopAfterID = StartBeforeID = PI->getTypeInfo(); + } else { + if (!StartAfter.empty()) { + const PassInfo *PI = PR->getPassInfo(StartAfter); + if (!PI) { + errs() << argv[0] << ": start-after pass is not registered.\n"; + return 1; + } + StartAfterID = PI->getTypeInfo(); + } + if (!StopAfter.empty()) { + const PassInfo *PI = PR->getPassInfo(StopAfter); + if (!PI) { + errs() << argv[0] << ": stop-after pass is not registered.\n"; + return 1; + } + StopAfterID = PI->getTypeInfo(); + } } // Ask the target to add backend passes as necessary. - if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartAfterID, - StopAfterID, MIR.get())) { + if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartBeforeID, + StartAfterID, StopAfterID, MIR.get())) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1;