Index: include/llvm/CodeGen/TargetInstrInfo.h =================================================================== --- include/llvm/CodeGen/TargetInstrInfo.h +++ include/llvm/CodeGen/TargetInstrInfo.h @@ -1686,6 +1686,11 @@ "Target didn't implement TargetInstrInfo::insertOutlinerPrologue!"); } + /// Return true if the function should be outlined from by default. + virtual bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const { + return false; + } + /// Return true if the function can safely be outlined from. /// A function \p MF is considered safe for outlining if an outlined function /// produced from instructions in F will produce a program which produces the Index: lib/CodeGen/MachineOutliner.cpp =================================================================== --- lib/CodeGen/MachineOutliner.cpp +++ lib/CodeGen/MachineOutliner.cpp @@ -88,6 +88,18 @@ STATISTIC(NumOutlined, "Number of candidates outlined"); STATISTIC(FunctionsCreated, "Number of functions created"); +// If passed in, enable the MachineOutliner on all functions except for +// linkonceodrs by default. +// FIXME: This should be changed to something that describes *what* you want to +// outline from. By default, the target decides if there's anything it wants +// to outline from. The user should be able to override this if they wish. E.g, +// -outline-from=all, -outline-from=size, -outline-from=minsize... +static cl::opt EnableMachineOutliner( + "enable-machine-outliner", + cl::Hidden, + cl::desc("Enable the machine outliner on all functions"), + cl::init(false)); + // Set to true if the user wants the outliner to run on linkonceodr linkage // functions. This is false by default because the linker can dedupe linkonceodr // functions. Since the outliner is confined to a single module (modulo LTO), @@ -1439,7 +1451,6 @@ // If the user specifies that they want to outline from linkonceodrs, set // it here. OutlineFromLinkOnceODRs = EnableLinkOnceODROutlining; - InstructionMapper Mapper; // Build instruction mappings for each function in the module. Start by @@ -1460,6 +1471,13 @@ if (!MF) continue; + // If the user hasn't specified that they want to enable the outliner, then + // check if the target wants this function to be outlined from. + if (!EnableMachineOutliner && + !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,9 +111,9 @@ cl::desc("Verify generated machine code"), cl::init(false), cl::ZeroOrMore); -static cl::opt EnableMachineOutliner("enable-machine-outliner", +static cl::opt DisableMachineOutliner("disable-machine-outliner", cl::Hidden, - cl::desc("Enable machine outliner")); + cl::desc("Disable machine outliner")); // 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. @@ -901,7 +901,7 @@ addPass(&XRayInstrumentationID, false); addPass(&PatchableFunctionID, false); - if (EnableMachineOutliner) + if (!DisableMachineOutliner) addPass(createMachineOutlinerPass()); // Add passes that directly emit MI after all other MI passes. Index: lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.h +++ lib/Target/AArch64/AArch64InstrInfo.h @@ -238,7 +238,7 @@ /// AArch64 supports the MachineOutliner. bool useMachineOutliner() const override { return true; } - + bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; bool canOutlineWithoutLRSave(MachineBasicBlock::iterator &CallInsertionPt) const; bool isFunctionSafeToOutlineFrom(MachineFunction &MF, Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5004,6 +5004,11 @@ FrameID); } +bool AArch64InstrInfo::shouldOutlineFromFunctionByDefault( + MachineFunction &MF) const { + return MF.getFunction().optForMinSize(); +} + bool AArch64InstrInfo::isFunctionSafeToOutlineFrom( MachineFunction &MF, bool OutlineFromLinkOnceODRs) const { const Function &F = MF.getFunction(); Index: test/CodeGen/AArch64/machine-outliner-calls.mir =================================================================== --- test/CodeGen/AArch64/machine-outliner-calls.mir +++ test/CodeGen/AArch64/machine-outliner-calls.mir @@ -8,7 +8,7 @@ ret void } - attributes #0 = { noredzone } + attributes #0 = { noredzone minsize } ... --- Index: test/CodeGen/AArch64/machine-outliner-flags.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/machine-outliner-flags.ll @@ -0,0 +1,9 @@ +; RUN: llc %s -debug-pass=Structure -mtriple arm64---- -o - 2>&1 | FileCheck %s -check-prefix=DEFAULT +; RUN: llc %s -debug-pass=Structure -disable-machine-outliner -mtriple arm64---- -o - 2>&1 | FileCheck %s -check-prefix=DISABLED + +; Ensure that the MachineOutliner is added by default in arm64 +; DEFAULT: Machine Outliner +; DISABLED-NOT: Machine Outliner + +define void @foo(float %x) #0 { ret void } +attributes #0 = { noredzone minsize } Index: test/CodeGen/AArch64/machine-outliner.mir =================================================================== --- test/CodeGen/AArch64/machine-outliner.mir +++ test/CodeGen/AArch64/machine-outliner.mir @@ -15,7 +15,7 @@ ret void } - attributes #0 = { noinline noredzone "no-frame-pointer-elim"="true" } + attributes #0 = { minsize noinline noredzone "no-frame-pointer-elim"="true" } ... --- # This test ensures that we