diff options
author | Quentin Colombet <qcolombet@apple.com> | 2017-07-31 18:24:07 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2017-07-31 18:24:07 +0000 |
commit | 15f6ffbf7c26bb468d6a5f525560538c0f1a103e (patch) | |
tree | 96cbb79ccfc4f637c3a485b7e137b038aff9e516 /llvm/lib/CodeGen | |
parent | e2a247ccb0e08de8fcd5999e453bac5feb66b2a7 (diff) | |
download | bcm5719-llvm-15f6ffbf7c26bb468d6a5f525560538c0f1a103e.tar.gz bcm5719-llvm-15f6ffbf7c26bb468d6a5f525560538c0f1a103e.zip |
[TargetPassConfig] Feature generic options to setup start/stop-after/before
This patch refactors the code used in llc such that all the users of the
addPassesToEmitFile API have access to a homogeneous way of handling
start/stop-after/before options right out of the box.
In particular, just invoking addPassesToEmitFile will set the proper
pipeline without additional effort (modulo parsing a .mir file if the
start-before/after options are used.
NFC.
Differential Revision: https://reviews.llvm.org/D30913
llvm-svn: 309599
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/LLVMTargetMachine.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetPassConfig.cpp | 85 |
2 files changed, 107 insertions, 21 deletions
diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp index f2defb4fd62..ad105429bfe 100644 --- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp +++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp @@ -92,24 +92,25 @@ TargetIRAnalysis LLVMTargetMachine::getTargetIRAnalysis() { /// addPassesToX helper drives creation and initialization of TargetPassConfig. static MCContext * addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, - bool DisableVerify, AnalysisID StartBefore, - AnalysisID StartAfter, AnalysisID StopBefore, - AnalysisID StopAfter) { + bool DisableVerify, bool &WillCompleteCodeGenPipeline, + raw_pwrite_stream &Out, MachineModuleInfo *MMI) { // Targets may override createPassConfig to provide a target-specific // subclass. TargetPassConfig *PassConfig = TM->createPassConfig(PM); - PassConfig->setStartStopPasses(StartBefore, StartAfter, StopBefore, - StopAfter); // Set PassConfig options provided by TargetMachine. PassConfig->setDisableVerify(DisableVerify); + WillCompleteCodeGenPipeline = PassConfig->willCompleteCodeGenPipeline(); PM.add(PassConfig); - MachineModuleInfo *MMI = new MachineModuleInfo(TM); + if (!MMI) + MMI = new MachineModuleInfo(TM); PM.add(MMI); if (PassConfig->addISelPasses()) return nullptr; PassConfig->addMachinePasses(); PassConfig->setInitialized(); + if (!WillCompleteCodeGenPipeline) + PM.add(createPrintMIRPass(Out)); return &MMI->getContext(); } @@ -185,23 +186,20 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, return false; } -bool LLVMTargetMachine::addPassesToEmitFile( - PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, - bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter, - AnalysisID StopBefore, AnalysisID StopAfter) { +bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, + raw_pwrite_stream &Out, + CodeGenFileType FileType, + bool DisableVerify, + MachineModuleInfo *MMI) { // Add common CodeGen passes. - MCContext *Context = - addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter, - StopBefore, StopAfter); + bool WillCompleteCodeGenPipeline = true; + MCContext *Context = addPassesToGenerateCode( + this, PM, DisableVerify, WillCompleteCodeGenPipeline, Out, MMI); if (!Context) return true; - if (StopBefore || StopAfter) { - PM.add(createPrintMIRPass(Out)); - } else { - if (addAsmPrinter(PM, Out, FileType, *Context)) - return true; - } + if (WillCompleteCodeGenPipeline && addAsmPrinter(PM, Out, FileType, *Context)) + return true; PM.add(createFreeMachineFunctionPass()); return false; @@ -216,10 +214,13 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, raw_pwrite_stream &Out, bool DisableVerify) { // Add common CodeGen passes. - Ctx = addPassesToGenerateCode(this, PM, DisableVerify, nullptr, nullptr, - nullptr, nullptr); + bool WillCompleteCodeGenPipeline = true; + Ctx = addPassesToGenerateCode(this, PM, DisableVerify, + WillCompleteCodeGenPipeline, Out, + /*MachineModuleInfo*/ nullptr); if (!Ctx) return true; + assert(WillCompleteCodeGenPipeline && "CodeGen pipeline has been altered"); if (Options.MCOptions.MCSaveTempLabels) Ctx->setAllowTemporaryLabels(false); diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index 817e58ce59e..de0d2264de2 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -153,6 +153,34 @@ static cl::opt<CFLAAType> UseCFLAA( clEnumValN(CFLAAType::Both, "both", "Enable both variants of CFL-AA"))); +/// Option names for limiting the codegen pipeline. +/// Those are used in error reporting and we didn't want +/// to duplicate their names all over the place. +const char *StartAfterOptName = "start-after"; +const char *StartBeforeOptName = "start-before"; +const char *StopAfterOptName = "stop-after"; +const char *StopBeforeOptName = "stop-before"; + +static cl::opt<std::string> + StartAfterOpt(StringRef(StartAfterOptName), + cl::desc("Resume compilation after a specific pass"), + cl::value_desc("pass-name"), cl::init("")); + +static cl::opt<std::string> + StartBeforeOpt(StringRef(StartBeforeOptName), + cl::desc("Resume compilation before a specific pass"), + cl::value_desc("pass-name"), cl::init("")); + +static cl::opt<std::string> + StopAfterOpt(StringRef(StopAfterOptName), + cl::desc("Stop compilation after a specific pass"), + cl::value_desc("pass-name"), cl::init("")); + +static cl::opt<std::string> + StopBeforeOpt(StringRef(StopBeforeOptName), + cl::desc("Stop compilation before a specific pass"), + cl::value_desc("pass-name"), cl::init("")); + /// Allow standard passes to be disabled by command line options. This supports /// simple binary flags that either suppress the pass or do nothing. /// i.e. -disable-mypass=false has no effect. @@ -282,6 +310,37 @@ TargetPassConfig::~TargetPassConfig() { delete Impl; } +static const PassInfo *getPassInfo(StringRef PassName) { + if (PassName.empty()) + return nullptr; + + const PassRegistry &PR = *PassRegistry::getPassRegistry(); + const PassInfo *PI = PR.getPassInfo(PassName); + if (!PI) + report_fatal_error(Twine('\"') + Twine(PassName) + + Twine("\" pass is not registered.")); + return PI; +} + +static AnalysisID getPassIDFromName(StringRef PassName) { + const PassInfo *PI = getPassInfo(PassName); + return PI ? PI->getTypeInfo() : nullptr; +} + +void TargetPassConfig::setStartStopPasses() { + StartBefore = getPassIDFromName(StartBeforeOpt); + StartAfter = getPassIDFromName(StartAfterOpt); + StopBefore = getPassIDFromName(StopBeforeOpt); + StopAfter = getPassIDFromName(StopAfterOpt); + if (StartBefore && StartAfter) + report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") + + Twine(StartAfterOptName) + Twine(" specified!")); + if (StopBefore && StopAfter) + report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") + + Twine(StopAfterOptName) + Twine(" specified!")); + Started = (StartAfter == nullptr) && (StartBefore == nullptr); +} + // Out of line constructor provides default values for pass options and // registers all common codegen passes. TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm) @@ -305,6 +364,8 @@ TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm) if (TM.Options.EnableIPRA) setRequiresCodeGenSCCOrder(); + + setStartStopPasses(); } CodeGenOpt::Level TargetPassConfig::getOptLevel() const { @@ -339,6 +400,30 @@ TargetPassConfig::TargetPassConfig() "triple set?"); } +bool TargetPassConfig::hasLimitedCodeGenPipeline() const { + return StartBefore || StartAfter || StopBefore || StopAfter; +} + +std::string +TargetPassConfig::getLimitedCodeGenPipelineReason(const char *Separator) const { + if (!hasLimitedCodeGenPipeline()) + return std::string(); + std::string Res; + static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt, + &StopAfterOpt, &StopBeforeOpt}; + static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName, + StopAfterOptName, StopBeforeOptName}; + bool IsFirst = true; + for (int Idx = 0; Idx < 4; ++Idx) + if (!PassNames[Idx]->empty()) { + if (!IsFirst) + Res += Separator; + IsFirst = false; + Res += OptNames[Idx]; + } + return Res; +} + // Helper to verify the analysis is really immutable. void TargetPassConfig::setOpt(bool &Opt, bool Val) { assert(!Initialized && "PassConfig is immutable"); |