summaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetPassConfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetPassConfig.cpp')
-rw-r--r--lib/CodeGen/TargetPassConfig.cpp145
1 files changed, 127 insertions, 18 deletions
diff --git a/lib/CodeGen/TargetPassConfig.cpp b/lib/CodeGen/TargetPassConfig.cpp
index 817e58ce59e1..121bed5a79cb 100644
--- a/lib/CodeGen/TargetPassConfig.cpp
+++ b/lib/CodeGen/TargetPassConfig.cpp
@@ -47,6 +47,9 @@
using namespace llvm;
+cl::opt<bool> EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
+ cl::desc("Enable interprocedural register allocation "
+ "to reduce load/store at procedure calls."));
static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
cl::desc("Disable Post Regalloc Scheduler"));
static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
@@ -90,7 +93,11 @@ static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inli
static cl::opt<bool> EnableImplicitNullChecks(
"enable-implicit-null-checks",
cl::desc("Fold null checks into faulting memory operations"),
- cl::init(false));
+ cl::init(false), cl::Hidden);
+static cl::opt<bool>
+ EnableMergeICmps("enable-mergeicmps",
+ cl::desc("Merge ICmp chains into a single memcmp"),
+ cl::init(false), cl::Hidden);
static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
@@ -104,6 +111,11 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
static cl::opt<bool> EnableMachineOutliner("enable-machine-outliner",
cl::Hidden,
cl::desc("Enable machine outliner"));
+static cl::opt<bool> EnableLinkOnceODROutlining(
+ "enable-linkonceodr-outlining",
+ cl::Hidden,
+ cl::desc("Enable the machine outliner on linkonceodr functions"),
+ cl::init(false));
// Enable or disable FastISel. Both options are needed, because
// FastISel is enabled by default with -fast, and we wish to be
// able to enable or disable fast-isel independently from -O0.
@@ -115,10 +127,9 @@ static cl::opt<cl::boolOrDefault>
EnableGlobalISel("global-isel", cl::Hidden,
cl::desc("Enable the \"global\" instruction selector"));
-static cl::opt<std::string>
-PrintMachineInstrs("print-machineinstrs", cl::ValueOptional,
- cl::desc("Print machine instrs"),
- cl::value_desc("pass-name"), cl::init("option-unspecified"));
+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(
"global-isel-abort", cl::Hidden,
@@ -153,6 +164,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(""), cl::Hidden);
+
+static cl::opt<std::string>
+ StartBeforeOpt(StringRef(StartBeforeOptName),
+ cl::desc("Resume compilation before a specific pass"),
+ cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
+
+static cl::opt<std::string>
+ StopAfterOpt(StringRef(StopAfterOptName),
+ cl::desc("Stop compilation after a specific pass"),
+ cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
+
+static cl::opt<std::string>
+ StopBeforeOpt(StringRef(StopBeforeOptName),
+ cl::desc("Stop compilation before a specific pass"),
+ cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
+
/// 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 +321,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)
@@ -303,8 +373,17 @@ TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
if (StringRef(PrintMachineInstrs.getValue()).equals(""))
TM.Options.PrintMachineCode = true;
+ if (EnableIPRA.getNumOccurrences())
+ TM.Options.EnableIPRA = EnableIPRA;
+ else {
+ // If not explicitly specified, use target default.
+ TM.Options.EnableIPRA = TM.useIPRA();
+ }
+
if (TM.Options.EnableIPRA)
setRequiresCodeGenSCCOrder();
+
+ setStartStopPasses();
}
CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
@@ -339,6 +418,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");
@@ -496,6 +599,16 @@ void TargetPassConfig::addIRPasses() {
addPass(createPrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
}
+ if (getOptLevel() != CodeGenOpt::None) {
+ // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
+ // loads and compares. ExpandMemCmpPass then tries to expand those calls
+ // into optimally-sized loads and compares. The transforms are enabled by a
+ // target lowering hook.
+ if (EnableMergeICmps)
+ addPass(createMergeICmpsPass());
+ addPass(createExpandMemCmpPass());
+ }
+
// Run GC lowering passes for builtin collectors
// TODO: add a pass insertion point here
addPass(createGCLoweringPass());
@@ -511,8 +624,8 @@ void TargetPassConfig::addIRPasses() {
if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
addPass(createPartiallyInlineLibCallsPass());
- // Insert calls to mcount-like functions.
- addPass(createCountingFunctionInserterPass());
+ // Instrument function entry and exit, e.g. with calls to mcount().
+ addPass(createPostInlineEntryExitInstrumenterPass());
// Add scalarization of target's unsupported masked memory intrinsics pass.
// the unsupported intrinsic will be replaced with a chain of basic blocks,
@@ -653,10 +766,9 @@ bool TargetPassConfig::addISelPasses() {
/// -regalloc=... command line option.
static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
- RegisterPassParser<RegisterRegAlloc> >
-RegAlloc("regalloc",
- cl::init(&useDefaultRegisterAllocator),
- cl::desc("Register allocator to use"));
+ RegisterPassParser<RegisterRegAlloc>>
+ RegAlloc("regalloc", cl::Hidden, cl::init(&useDefaultRegisterAllocator),
+ cl::desc("Register allocator to use"));
/// Add the complete set of target-independent postISel code generator passes.
///
@@ -694,9 +806,6 @@ void TargetPassConfig::addMachinePasses() {
// Print the instruction selected machine code...
printAndVerify("After Instruction Selection");
- if (TM->Options.EnableIPRA)
- addPass(createRegUsageInfoPropPass());
-
// Expand pseudo-instructions emitted by ISel.
addPass(&ExpandISelPseudosID);
@@ -709,6 +818,9 @@ void TargetPassConfig::addMachinePasses() {
addPass(&LocalStackSlotAllocationID, false);
}
+ if (TM->Options.EnableIPRA)
+ addPass(createRegUsageInfoPropPass());
+
// Run pre-ra passes.
addPreRegAlloc();
@@ -788,7 +900,7 @@ void TargetPassConfig::addMachinePasses() {
addPass(&PatchableFunctionID, false);
if (EnableMachineOutliner)
- PM->add(createMachineOutlinerPass());
+ PM->add(createMachineOutlinerPass(EnableLinkOnceODROutlining));
AddingMachinePasses = false;
}
@@ -824,9 +936,6 @@ void TargetPassConfig::addMachineSSAOptimization() {
addPass(&MachineLICMID, false);
addPass(&MachineCSEID, false);
- // Coalesce basic blocks with the same branch condition
- addPass(&BranchCoalescingID);
-
addPass(&MachineSinkingID);
addPass(&PeepholeOptimizerID);