aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetPassConfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetPassConfig.cpp')
-rw-r--r--lib/CodeGen/TargetPassConfig.cpp147
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;
}