Index: include/llvm/CodeGen/Passes.h =================================================================== --- include/llvm/CodeGen/Passes.h +++ include/llvm/CodeGen/Passes.h @@ -423,7 +423,7 @@ /// This pass performs outlining on machine instructions directly before /// printing assembly. - ModulePass *createMachineOutlinerPass(); + ModulePass *createMachineOutlinerPass(bool RunOnAllFunctions = true); /// This pass expands the experimental reduction intrinsics into sequences of /// shuffles. Index: include/llvm/CodeGen/TargetInstrInfo.h =================================================================== --- include/llvm/CodeGen/TargetInstrInfo.h +++ include/llvm/CodeGen/TargetInstrInfo.h @@ -1652,6 +1652,11 @@ "TargetInstrInfo::isFunctionSafeToOutlineFrom!"); } + /// Return true if the function should be outlined from by default. + virtual bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const { + return false; + } + private: unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode; unsigned CatchRetOpcode; Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -205,6 +205,9 @@ void setMachineOutliner(bool Enable) { Options.EnableMachineOutliner = Enable; } + void setSupportsDefaultOutlining(bool Enable) { + Options.SupportsDefaultOutlining = Enable; + } bool shouldPrintMachineCode() const { return Options.PrintMachineCode; } Index: include/llvm/Target/TargetOptions.h =================================================================== --- include/llvm/Target/TargetOptions.h +++ include/llvm/Target/TargetOptions.h @@ -111,7 +111,7 @@ NoTrapAfterNoreturn(false), EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false), EmitStackSizeSection(false), - EnableMachineOutliner(false) {} + EnableMachineOutliner(false), SupportsDefaultOutlining(false) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs /// option is specified on the command line, and should enable debugging @@ -235,6 +235,9 @@ /// Enables the MachineOutliner pass. unsigned EnableMachineOutliner : 1; + /// Set if the target supports default outlining behaviour. + unsigned SupportsDefaultOutlining : 1; + /// FloatABIType - This setting is set by -float-abi=xxx option is specfied /// on the command line. This setting may either be Default, Soft, or Hard. /// Default selects the target's default behavior. Soft selects the ABI for Index: lib/CodeGen/MachineOutliner.cpp =================================================================== --- lib/CodeGen/MachineOutliner.cpp +++ lib/CodeGen/MachineOutliner.cpp @@ -688,6 +688,12 @@ /// linkonceodr linkage. bool OutlineFromLinkOnceODRs = false; + /// Set to true if the outliner should run on all functions in the module + /// considered safe for outlining. + /// Set to true by default for compatibility with llc's -run-pass option. + /// Set when the pass is constructed in TargetPassConfig. + bool RunOnAllFunctions = true; + // Collection of IR functions created by the outliner. std::vector CreatedIRFunctions; @@ -806,8 +812,10 @@ char MachineOutliner::ID = 0; namespace llvm { -ModulePass *createMachineOutlinerPass() { - return new MachineOutliner(); +ModulePass *createMachineOutlinerPass(bool RunOnAllFunctions) { + MachineOutliner *OL = new MachineOutliner(); + OL->RunOnAllFunctions = RunOnAllFunctions; + return OL; } } // namespace llvm @@ -1331,6 +1339,20 @@ const TargetRegisterInfo *TRI = STI.getRegisterInfo(); const TargetInstrInfo *TII = STI.getInstrInfo(); + // If the user passed -enable-machine-outliner=always or + // -enable-machine-outliner, the pass will run on all functions in the module. + // Otherwise, if the target supports default outlining, it will run on all + // functions deemed by the target to be worth outlining from by default. Tell + // the user how the outliner is running. + LLVM_DEBUG( + dbgs() << "Machine Outliner: Running on "; + if (RunOnAllFunctions) + dbgs() << "all functions"; + else + dbgs() << "target-default functions"; + dbgs() << "\n" + ); + // If the user specifies that they want to outline from linkonceodrs, set // it here. OutlineFromLinkOnceODRs = EnableLinkOnceODROutlining; @@ -1355,6 +1377,9 @@ if (!MF) continue; + if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault(*MF)) + continue; + // We have a MachineFunction. Ask the target if it's suitable for outlining. // If it isn't, then move on to the next Function in the module. if (!TII->isFunctionSafeToOutlineFrom(*MF, OutlineFromLinkOnceODRs)) Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -111,11 +111,11 @@ cl::desc("Verify generated machine code"), cl::init(false), cl::ZeroOrMore); -enum RunOutliner { AlwaysOutline, NeverOutline }; +enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault }; // Enable or disable the MachineOutliner. static cl::opt EnableMachineOutliner( "enable-machine-outliner", cl::desc("Enable the machine outliner"), - cl::Hidden, cl::ValueOptional, cl::init(NeverOutline), + cl::Hidden, cl::ValueOptional, cl::init(TargetDefault), cl::values(clEnumValN(AlwaysOutline, "always", "Run on all functions guaranteed to be beneficial"), clEnumValN(NeverOutline, "never", "Disable all outlining"), @@ -914,8 +914,13 @@ addPass(&PatchableFunctionID, false); if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None && - EnableMachineOutliner == AlwaysOutline) - addPass(createMachineOutlinerPass()); + EnableMachineOutliner != NeverOutline) { + bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline); + bool AddOutliner = RunOnAllFunctions || + TM->Options.SupportsDefaultOutlining; + if (AddOutliner) + addPass(createMachineOutlinerPass(RunOnAllFunctions)); + } // Add passes that directly emit MI after all other MI passes. addPreEmitPass2(); Index: test/CodeGen/AArch64/machine-outliner-flags.ll =================================================================== --- test/CodeGen/AArch64/machine-outliner-flags.ll +++ test/CodeGen/AArch64/machine-outliner-flags.ll @@ -1,9 +1,12 @@ +; REQUIRES: asserts ; RUN: llc %s -debug-pass=Structure -verify-machineinstrs \ -; RUN: -enable-machine-outliner=always -mtriple arm64---- -o /dev/null 2>&1 \ +; RUN: --debug-only=machine-outliner -enable-machine-outliner=always \ +; RUN: -mtriple arm64---- -o /dev/null 2>&1 \ ; RUN: | FileCheck %s -check-prefix=ALWAYS ; RUN: llc %s -debug-pass=Structure -verify-machineinstrs \ -; RUN: -enable-machine-outliner -mtriple arm64---- -o /dev/null 2>&1 \ +; RUN: --debug-only=machine-outliner -enable-machine-outliner \ +; RUN: -mtriple arm64---- -o /dev/null 2>&1 \ ; RUN: | FileCheck %s -check-prefix=ENABLE ; RUN: llc %s -debug-pass=Structure -verify-machineinstrs \ @@ -31,7 +34,9 @@ ; * -enable-machine-outliner=never is passed ; ALWAYS: Machine Outliner +; ALWAYS: Machine Outliner: Running on all functions ; ENABLE: Machine Outliner +; ENABLE: Machine Outliner: Running on all functions ; NEVER-NOT: Machine Outliner ; NOT-ADDED-NOT: Machine Outliner ; OPTNONE-NOT: Machine Outliner