diff options
Diffstat (limited to 'lib/CodeGen/TargetPassConfig.cpp')
-rw-r--r-- | lib/CodeGen/TargetPassConfig.cpp | 145 |
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); |