diff options
Diffstat (limited to 'lib/CodeGen/TargetPassConfig.cpp')
| -rw-r--r-- | lib/CodeGen/TargetPassConfig.cpp | 147 |
1 files changed, 101 insertions, 46 deletions
diff --git a/lib/CodeGen/TargetPassConfig.cpp b/lib/CodeGen/TargetPassConfig.cpp index 2db03288f2ac..28126fcf766d 100644 --- a/lib/CodeGen/TargetPassConfig.cpp +++ b/lib/CodeGen/TargetPassConfig.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Threading.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" @@ -107,10 +108,10 @@ static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden, cl::desc("Print LLVM IR input to isel pass")); static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, cl::desc("Dump garbage collector data")); -static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, - cl::desc("Verify generated machine code"), - cl::init(false), - cl::ZeroOrMore); +static cl::opt<cl::boolOrDefault> + VerifyMachineCode("verify-machineinstrs", cl::Hidden, + cl::desc("Verify generated machine code"), + cl::ZeroOrMore); enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault }; // Enable or disable the MachineOutliner. static cl::opt<RunOutliner> EnableMachineOutliner( @@ -136,13 +137,15 @@ static cl::opt<std::string> PrintMachineInstrs( "print-machineinstrs", cl::ValueOptional, cl::desc("Print machine instrs"), cl::value_desc("pass-name"), cl::init("option-unspecified"), cl::Hidden); -static cl::opt<int> EnableGlobalISelAbort( +static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort( "global-isel-abort", cl::Hidden, cl::desc("Enable abort calls when \"global\" instruction selection " - "fails to lower/select an instruction: 0 disable the abort, " - "1 enable the abort, and " - "2 disable the abort but emit a diagnostic on failure"), - cl::init(1)); + "fails to lower/select an instruction"), + cl::values( + clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"), + clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"), + clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2", + "Disable the abort but emit a diagnostic on failure"))); // Temporary option to allow experimenting with MachineScheduler as a post-RA // scheduler. Targets can "properly" enable this with @@ -342,11 +345,39 @@ static AnalysisID getPassIDFromName(StringRef PassName) { return PI ? PI->getTypeInfo() : nullptr; } +static std::pair<StringRef, unsigned> +getPassNameAndInstanceNum(StringRef PassName) { + StringRef Name, InstanceNumStr; + std::tie(Name, InstanceNumStr) = PassName.split(','); + + unsigned InstanceNum = 0; + if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum)) + report_fatal_error("invalid pass instance specifier " + PassName); + + return std::make_pair(Name, InstanceNum); +} + void TargetPassConfig::setStartStopPasses() { - StartBefore = getPassIDFromName(StartBeforeOpt); - StartAfter = getPassIDFromName(StartAfterOpt); - StopBefore = getPassIDFromName(StopBeforeOpt); - StopAfter = getPassIDFromName(StopAfterOpt); + StringRef StartBeforeName; + std::tie(StartBeforeName, StartBeforeInstanceNum) = + getPassNameAndInstanceNum(StartBeforeOpt); + + StringRef StartAfterName; + std::tie(StartAfterName, StartAfterInstanceNum) = + getPassNameAndInstanceNum(StartAfterOpt); + + StringRef StopBeforeName; + std::tie(StopBeforeName, StopBeforeInstanceNum) + = getPassNameAndInstanceNum(StopBeforeOpt); + + StringRef StopAfterName; + std::tie(StopAfterName, StopAfterInstanceNum) + = getPassNameAndInstanceNum(StopAfterOpt); + + StartBefore = getPassIDFromName(StartBeforeName); + StartAfter = getPassIDFromName(StartAfterName); + StopBefore = getPassIDFromName(StopBeforeName); + StopAfter = getPassIDFromName(StopAfterName); if (StartBefore && StartAfter) report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") + Twine(StartAfterOptName) + Twine(" specified!")); @@ -383,6 +414,9 @@ TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm) if (TM.Options.EnableIPRA) setRequiresCodeGenSCCOrder(); + if (EnableGlobalISelAbort.getNumOccurrences()) + TM.Options.GlobalISelAbort = EnableGlobalISelAbort; + setStartStopPasses(); } @@ -418,8 +452,13 @@ TargetPassConfig::TargetPassConfig() "triple set?"); } -bool TargetPassConfig::hasLimitedCodeGenPipeline() const { - return StartBefore || StartAfter || StopBefore || StopAfter; +bool TargetPassConfig::willCompleteCodeGenPipeline() { + return StopBeforeOpt.empty() && StopAfterOpt.empty(); +} + +bool TargetPassConfig::hasLimitedCodeGenPipeline() { + return !StartBeforeOpt.empty() || !StartAfterOpt.empty() || + !willCompleteCodeGenPipeline(); } std::string @@ -482,9 +521,9 @@ void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) { // and shouldn't reference it. AnalysisID PassID = P->getPassID(); - if (StartBefore == PassID) + if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum) Started = true; - if (StopBefore == PassID) + if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum) Stopped = true; if (Started && !Stopped) { std::string Banner; @@ -507,9 +546,11 @@ void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) { } else { delete P; } - if (StopAfter == PassID) + + if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum) Stopped = true; - if (StartAfter == PassID) + + if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum) Started = true; if (Stopped && !Started) report_fatal_error("Cannot stop compilation after pass that is not run"); @@ -552,7 +593,7 @@ void TargetPassConfig::addPrintPass(const std::string &Banner) { } void TargetPassConfig::addVerifyPass(const std::string &Banner) { - bool Verify = VerifyMachineCode; + bool Verify = VerifyMachineCode == cl::BOU_TRUE; #ifdef EXPENSIVE_CHECKS if (VerifyMachineCode == cl::BOU_UNSET) Verify = TM->isMachineVerifierClean(); @@ -714,18 +755,34 @@ void TargetPassConfig::addISelPrepare() { bool TargetPassConfig::addCoreISelPasses() { // Enable FastISel with -fast-isel, but allow that to be overridden. TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE); - if (EnableFastISelOption == cl::BOU_TRUE || - (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel())) - TM->setFastISel(true); - // Ask the target for an instruction selector. - // Explicitly enabling fast-isel should override implicitly enabled - // global-isel. - if (EnableGlobalISelOption == cl::BOU_TRUE || - (EnableGlobalISelOption == cl::BOU_UNSET && - TM->Options.EnableGlobalISel && EnableFastISelOption != cl::BOU_TRUE)) { + // Determine an instruction selector. + enum class SelectorType { SelectionDAG, FastISel, GlobalISel }; + SelectorType Selector; + + if (EnableFastISelOption == cl::BOU_TRUE) + Selector = SelectorType::FastISel; + else if (EnableGlobalISelOption == cl::BOU_TRUE || + (TM->Options.EnableGlobalISel && + EnableGlobalISelOption != cl::BOU_FALSE)) + Selector = SelectorType::GlobalISel; + else if (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel()) + Selector = SelectorType::FastISel; + else + Selector = SelectorType::SelectionDAG; + + // Set consistently TM->Options.EnableFastISel and EnableGlobalISel. + if (Selector == SelectorType::FastISel) { + TM->setFastISel(true); + TM->setGlobalISel(false); + } else if (Selector == SelectorType::GlobalISel) { TM->setFastISel(false); + TM->setGlobalISel(true); + } + // Add instruction selector passes. + if (Selector == SelectorType::GlobalISel) { + SaveAndRestore<bool> SavedAddingMachinePasses(AddingMachinePasses, true); if (addIRTranslator()) return true; @@ -804,15 +861,17 @@ void TargetPassConfig::addMachinePasses() { AddingMachinePasses = true; // Insert a machine instr printer pass after the specified pass. - if (!StringRef(PrintMachineInstrs.getValue()).equals("") && - !StringRef(PrintMachineInstrs.getValue()).equals("option-unspecified")) { - const PassRegistry *PR = PassRegistry::getPassRegistry(); - const PassInfo *TPI = PR->getPassInfo(PrintMachineInstrs.getValue()); - const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer")); - assert (TPI && IPI && "Pass ID not registered!"); - const char *TID = (const char *)(TPI->getTypeInfo()); - const char *IID = (const char *)(IPI->getTypeInfo()); - insertPass(TID, IID); + StringRef PrintMachineInstrsPassName = PrintMachineInstrs.getValue(); + if (!PrintMachineInstrsPassName.equals("") && + !PrintMachineInstrsPassName.equals("option-unspecified")) { + if (const PassInfo *TPI = getPassInfo(PrintMachineInstrsPassName)) { + const PassRegistry *PR = PassRegistry::getPassRegistry(); + const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer")); + assert(IPI && "failed to get \"machineinstr-printer\" PassInfo!"); + const char *TID = (const char *)(TPI->getTypeInfo()); + const char *IID = (const char *)(IPI->getTypeInfo()); + insertPass(TID, IID); + } } // Print the instruction selected machine code... @@ -981,7 +1040,8 @@ bool TargetPassConfig::getOptimizeRegAlloc() const { } /// RegisterRegAlloc's global Registry tracks allocator registration. -MachinePassRegistry RegisterRegAlloc::Registry; +MachinePassRegistry<RegisterRegAlloc::FunctionPassCtor> + RegisterRegAlloc::Registry; /// A dummy default pass factory indicates whether the register allocator is /// overridden on the command line. @@ -1155,14 +1215,9 @@ void TargetPassConfig::addBlockPlacement() { /// GlobalISel Configuration //===---------------------------------------------------------------------===// bool TargetPassConfig::isGlobalISelAbortEnabled() const { - if (EnableGlobalISelAbort.getNumOccurrences() > 0) - return EnableGlobalISelAbort == 1; - - // When no abort behaviour is specified, we don't abort if the target says - // that GISel is enabled. - return !TM->Options.EnableGlobalISel; + return TM->Options.GlobalISelAbort == GlobalISelAbortMode::Enable; } bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const { - return EnableGlobalISelAbort == 2; + return TM->Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag; } |
