Index: include/llvm/CodeGen/TargetInstrInfo.h =================================================================== --- include/llvm/CodeGen/TargetInstrInfo.h +++ include/llvm/CodeGen/TargetInstrInfo.h @@ -1682,6 +1682,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,19 @@ STATISTIC(NumOutlined, "Number of candidates outlined"); STATISTIC(FunctionsCreated, "Number of functions created"); +enum RunOutliner { TargetDefault, AlwaysOutline, NeverOutline }; + +// True, default, always +static cl::opt EnableMachineOutliner( + "enable-machine-outliner", cl::desc("Enable the machine outliner"), + cl::Hidden, + cl::values(clEnumValN(TargetDefault, "default", "Target default outlining"), + clEnumValN(AlwaysOutline, "always", + "Run on all functions guaranteed to be beneficial " + "(pass -enable-linkonce-odr-outlining for more)"), + clEnumValN(NeverOutline, "never", "Disable all outlining")), + cl::init(TargetDefault)); + // 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), @@ -1447,6 +1460,10 @@ } bool MachineOutliner::runOnModule(Module &M) { + // If the user never wants to outline, then stop here. + if (EnableMachineOutliner == NeverOutline) + return false; + // Check if there's anything in the module. If it's empty, then there's // nothing to outline. if (M.empty()) @@ -1490,6 +1507,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 == TargetDefault && + !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,6 @@ cl::desc("Verify generated machine code"), cl::init(false), cl::ZeroOrMore); -static cl::opt EnableMachineOutliner("enable-machine-outliner", - cl::Hidden, - cl::desc("Enable 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 +898,7 @@ addPass(&XRayInstrumentationID, false); addPass(&PatchableFunctionID, false); - if (EnableMachineOutliner) + if (getOptLevel() != CodeGenOpt::None) 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/O3-pipeline.ll =================================================================== --- test/CodeGen/AArch64/O3-pipeline.ll +++ test/CodeGen/AArch64/O3-pipeline.ll @@ -154,6 +154,8 @@ ; CHECK-NEXT: Insert fentry calls ; CHECK-NEXT: Insert XRay ops ; CHECK-NEXT: Implement the 'patchable-function' attribute +; CHECK-NEXT: Machine Outliner +; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine Optimization Remark Emitter ; CHECK-NEXT: AArch64 Assembly Printer Index: test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll =================================================================== --- test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll +++ test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll @@ -26,8 +26,9 @@ ; requested. (This hard-codes the previous pass to the Assembly Printer, ; please adjust accordingly.) -; HOTNESS: Executing Pass 'Implement the 'patchable-function' attribute' -; HOTNESS-NEXT: Freeing Pass 'Implement the 'patchable-function' attribute' +; HOTNESS: Executing Pass 'Machine Outliner' on Module ''... +; HOTNESS-NEXT: Freeing Pass 'Machine Outliner' on Module ''... +; HOTNESS-NEXT: Executing Pass 'Function Pass Manager' on Module ''... ; HOTNESS-NEXT: Executing Pass 'Lazy Machine Block Frequency Analysis' ; HOTNESS-NEXT: Executing Pass 'Machine Optimization Remark Emitter' ; HOTNESS-NEXT: Building MachineBlockFrequencyInfo on the fly @@ -41,8 +42,9 @@ ; HOTNESS: arm64-summary-remarks.ll:5:0: 1 instructions in function (hotness: 33) -; NO_HOTNESS: Executing Pass 'Implement the 'patchable-function' attribute' -; NO_HOTNESS-NEXT: Freeing Pass 'Implement the 'patchable-function' attribute' +; NO_HOTNESS: Executing Pass 'Machine Outliner' on Module ''... +; NO_HOTNESS-NEXT: Freeing Pass 'Machine Outliner' on Module ''... +; NO_HOTNESS-NEXT: Executing Pass 'Function Pass Manager' on Module ''... ; NO_HOTNESS-NEXT: Executing Pass 'Lazy Machine Block Frequency Analysis' ; NO_HOTNESS-NEXT: Executing Pass 'Machine Optimization Remark Emitter' ; NO_HOTNESS-NEXT: Executing Pass 'AArch64 Assembly Printer' Index: test/CodeGen/AArch64/cond-sel.ll =================================================================== --- test/CodeGen/AArch64/cond-sel.ll +++ test/CodeGen/AArch64/cond-sel.ll @@ -1,5 +1,5 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mcpu=cyclone | FileCheck %s -; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mcpu=cyclone -enable-machine-outliner=never | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 -enable-machine-outliner=never | FileCheck --check-prefix=CHECK-NOFP %s @var32 = global i32 0 @var64 = global i64 0 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,32 @@ +; RUN: llc %s -mtriple arm64---- -o - 2>&1 | FileCheck %s -check-prefix=DEFAULT +; RUN: llc %s -enable-machine-outliner=never -mtriple arm64---- -o - 2>&1 | FileCheck %s -check-prefix=DISABLED + +; Ensure that the MachineOutliner runs on minsize functions by default in arm64. + +; DISABLED-NOT: OUTLINED_FUNCTION + +define float @smol1(float %x) #0 { + ; DEFAULT-LABEL: smol1: + %i = fptosi float %x to i32 + %r = sitofp i32 %i to float + ; DEFAULT: b [[FN:OUTLINED_FUNCTION_[0-9]]] + ret float %r +} + +define float @smol2(float %x) #0 { + ; DEFAULT-LABEL: smol2: + %i = fptosi float %x to i32 + %r = sitofp i32 %i to float + ; DEFAULT: b [[FN]] + ret float %r +} + +define float @smol3(float %x) #0 { + ; DEFAULT-LABEL: smol3: + %i = fptosi float %x to i32 + %r = sitofp i32 %i to float + ; DEFAULT: b [[FN]] + ret float %r +} + +attributes #0 = { noredzone minsize } Index: test/CodeGen/AArch64/machine-outliner-noredzone.ll =================================================================== --- test/CodeGen/AArch64/machine-outliner-noredzone.ll +++ test/CodeGen/AArch64/machine-outliner-noredzone.ll @@ -1,5 +1,5 @@ -; RUN: llc -verify-machineinstrs -enable-machine-outliner %s -o - | FileCheck %s -; RUN: llc -verify-machineinstrs -enable-machine-outliner -aarch64-redzone %s -o - | FileCheck %s -check-prefix=REDZONE +; RUN: llc -verify-machineinstrs -enable-machine-outliner=always %s -o - | FileCheck %s +; RUN: llc -verify-machineinstrs -enable-machine-outliner=always -aarch64-redzone %s -o - | FileCheck %s -check-prefix=REDZONE ; Ensure that the MachineOutliner does not fire on functions which use a ; redzone. We don't care about what's actually outlined here. We just want to Index: test/CodeGen/AArch64/machine-outliner-remarks.ll =================================================================== --- test/CodeGen/AArch64/machine-outliner-remarks.ll +++ test/CodeGen/AArch64/machine-outliner-remarks.ll @@ -1,4 +1,4 @@ -; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -pass-remarks=machine-outliner -pass-remarks-missed=machine-outliner -o /dev/null 2>&1 | FileCheck %s +; RUN: llc %s -enable-machine-outliner=always -mtriple=aarch64-unknown-unknown -pass-remarks=machine-outliner -pass-remarks-missed=machine-outliner -o /dev/null 2>&1 | FileCheck %s ; CHECK: machine-outliner-remarks.ll:5:9: ; CHECK-SAME: Did not outline 2 instructions from 2 locations. ; CHECK-SAME: Instructions from outlining all occurrences (9) >= @@ -7,7 +7,7 @@ ; CHECK: remark: :0:0: Saved 5 instructions by outlining 7 instructions ; CHECK-SAME: from 2 locations. (Found at: machine-outliner-remarks.ll:27:9, ; CHECK-SAME: machine-outliner-remarks.ll:36:1) -; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -o /dev/null -pass-remarks-missed=machine-outliner -pass-remarks-output=%t.yaml +; RUN: llc %s -enable-machine-outliner=always -mtriple=aarch64-unknown-unknown -o /dev/null -pass-remarks-missed=machine-outliner -pass-remarks-output=%t.yaml ; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML ; YAML: --- !Missed ; YAML-NEXT: Pass: machine-outliner Index: test/CodeGen/AArch64/machine-outliner.ll =================================================================== --- test/CodeGen/AArch64/machine-outliner.ll +++ test/CodeGen/AArch64/machine-outliner.ll @@ -1,5 +1,5 @@ -; RUN: llc -verify-machineinstrs -enable-machine-outliner -mtriple=aarch64-apple-darwin < %s | FileCheck %s -; RUN: llc -verify-machineinstrs -enable-machine-outliner -enable-linkonceodr-outlining -mtriple=aarch64-apple-darwin < %s | FileCheck %s -check-prefix=ODR +; RUN: llc -verify-machineinstrs -enable-machine-outliner=always -mtriple=aarch64-apple-darwin < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -enable-machine-outliner=always -enable-linkonceodr-outlining -mtriple=aarch64-apple-darwin < %s | FileCheck %s -check-prefix=ODR define linkonce_odr void @fish() #0 { ; CHECK-LABEL: _fish: 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 Index: test/CodeGen/AArch64/max-jump-table.ll =================================================================== --- test/CodeGen/AArch64/max-jump-table.ll +++ test/CodeGen/AArch64/max-jump-table.ll @@ -1,8 +1,8 @@ -; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK0 < %t -; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=4 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK4 < %t -; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=8 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK8 < %t -; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM1 < %t -; RUN: llc %s -O2 -print-machineinstrs -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m3 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM3 < %t +; RUN: llc %s -O2 -print-machineinstrs -enable-machine-outliner=never -mtriple=aarch64-linux-gnu -jump-table-density=40 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK0 < %t +; RUN: llc %s -O2 -print-machineinstrs -enable-machine-outliner=never -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=4 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK4 < %t +; RUN: llc %s -O2 -print-machineinstrs -enable-machine-outliner=never -mtriple=aarch64-linux-gnu -jump-table-density=40 -max-jump-table-size=8 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECK8 < %t +; RUN: llc %s -O2 -print-machineinstrs -enable-machine-outliner=never -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m1 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM1 < %t +; RUN: llc %s -O2 -print-machineinstrs -enable-machine-outliner=never -mtriple=aarch64-linux-gnu -jump-table-density=40 -mcpu=exynos-m3 -o /dev/null 2> %t; FileCheck %s --check-prefixes=CHECK,CHECKM3 < %t declare void @ext(i32) @@ -44,6 +44,7 @@ ; CHECKM1-NOT: %jump-table.2: ; CHECKM3-NEXT: %jump-table.0: ; CHECKM3-NOT: %jump-table.1: +; CHECK-NEXT: Function Live Ins: $w0 bb1: tail call void @ext(i32 0) br label %return bb2: tail call void @ext(i32 2) br label %return @@ -89,6 +90,7 @@ ; CHECKM1-NOT: %jump-table.1 ; CHECKM3-NEXT: %jump-table.0: %bb.1 %bb.2 %bb.3 %bb.4 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.7 %bb.5 %bb.6{{$}} ; CHECKM3-NOT: %jump-table.1 +; CHECK-NEXT: Function Live Ins: $w0 bb1: tail call void @ext(i32 1) br label %return bb2: tail call void @ext(i32 2) br label %return Index: test/CodeGen/X86/O3-pipeline.ll =================================================================== --- test/CodeGen/X86/O3-pipeline.ll +++ test/CodeGen/X86/O3-pipeline.ll @@ -159,6 +159,8 @@ ; CHECK-NEXT: Insert fentry calls ; CHECK-NEXT: Insert XRay ops ; CHECK-NEXT: Implement the 'patchable-function' attribute +; CHECK-NEXT: Machine Outliner +; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: X86 Retpoline Thunks ; CHECK-NEXT: Check CFA info and insert CFI instructions if needed ; CHECK-NEXT: Lazy Machine Block Frequency Analysis Index: test/CodeGen/X86/cfi-inserter-check-order.ll =================================================================== --- test/CodeGen/X86/cfi-inserter-check-order.ll +++ test/CodeGen/X86/cfi-inserter-check-order.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=x86_64-- -O2 -enable-machine-outliner -debug-pass=Structure < %s -o /dev/null 2>&1 | FileCheck %s +; RUN: llc -mtriple=x86_64-- -O2 -enable-machine-outliner=always -debug-pass=Structure < %s -o /dev/null 2>&1 | FileCheck %s ; REQUIRES: asserts Index: test/CodeGen/X86/machine-outliner-debuginfo.ll =================================================================== --- test/CodeGen/X86/machine-outliner-debuginfo.ll +++ test/CodeGen/X86/machine-outliner-debuginfo.ll @@ -1,4 +1,4 @@ -; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s +; RUN: llc -enable-machine-outliner=always -mtriple=x86_64-apple-darwin < %s | FileCheck %s @x = global i32 0, align 4, !dbg !0 Index: test/CodeGen/X86/machine-outliner-disubprogram.ll =================================================================== --- test/CodeGen/X86/machine-outliner-disubprogram.ll +++ test/CodeGen/X86/machine-outliner-disubprogram.ll @@ -2,7 +2,7 @@ ; that we correctly emit DISubprograms for those functions. ; Also make sure that the DISubprograms reference the generated unit. ; make sure that if there are two outlined functions in the program, -; RUN: llc %s -enable-machine-outliner -mtriple=x86_64-apple-darwin -o /dev/null -print-after=machine-outliner +; RUN: llc %s -enable-machine-outliner=always -mtriple=x86_64-apple-darwin -o /dev/null -print-after=machine-outliner define void @f6() #0 !dbg !8 { entry: %dog = alloca i32, align 4 Index: test/CodeGen/X86/machine-outliner-noredzone.ll =================================================================== --- test/CodeGen/X86/machine-outliner-noredzone.ll +++ test/CodeGen/X86/machine-outliner-noredzone.ll @@ -1,4 +1,4 @@ -; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s +; RUN: llc -enable-machine-outliner=always -mtriple=x86_64-apple-darwin < %s | FileCheck %s ; Ensure that the outliner doesn't outline from any functions that use a redzone. declare i8* @llvm.stacksave() #1 Index: test/CodeGen/X86/machine-outliner-tailcalls.ll =================================================================== --- test/CodeGen/X86/machine-outliner-tailcalls.ll +++ test/CodeGen/X86/machine-outliner-tailcalls.ll @@ -1,4 +1,4 @@ -; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s +; RUN: llc -enable-machine-outliner=always -mtriple=x86_64-apple-darwin < %s | FileCheck %s @x = common local_unnamed_addr global i32 0, align 4 Index: test/CodeGen/X86/machine-outliner.ll =================================================================== --- test/CodeGen/X86/machine-outliner.ll +++ test/CodeGen/X86/machine-outliner.ll @@ -1,4 +1,4 @@ -; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s +; RUN: llc -enable-machine-outliner=always -mtriple=x86_64-apple-darwin < %s | FileCheck %s @x = global i32 0, align 4