diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -116,6 +116,11 @@ cl::desc( "Number of times to rerun the outliner after the initial outline")); +static cl::opt OutlinerBenefitThreshold( + "outliner-benefit-threshold", cl::init(1), cl::Hidden, + cl::desc( + "The minimum size in bytes before an outlining candidate is accepted")); + namespace { /// Maps \p MachineInstrs to unsigned integers and stores the mappings. @@ -664,7 +669,7 @@ continue; // Is it better to outline this candidate than not? - if (OF->getBenefit() < 1) { + if (OF.getBenefit() < OutlinerBenefitThreshold) { emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq, *OF); continue; } @@ -840,7 +845,7 @@ }); // If we made it unbeneficial to outline this function, skip it. - if (OF.getBenefit() < 1) + if (OF.getBenefit() < OutlinerBenefitThreshold) continue; // It's beneficial. Create the function and outline its sequence's diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-threshold.ll b/llvm/test/CodeGen/AArch64/machine-outliner-threshold.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-threshold.ll @@ -0,0 +1,96 @@ +; RUN: llc -verify-machineinstrs -enable-machine-outliner -aarch64-load-store-renaming=true -mtriple=aarch64-apple-darwin -outliner-benefit-threshold=60 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -enable-machine-outliner -aarch64-load-store-renaming=true -mtriple=aarch64-apple-darwin < %s | FileCheck %s -check-prefix=ALL + +define void @cat() { + ; CHECK-LABEL: _cat: + ; CHECK: sub sp, sp, #32 + ; CHECK-NOT: OUTLINED_FUNCTION + ; ALL: [[OUTLINED:OUTLINED_FUNCTION_[0-9]+]] + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, ptr %1, align 4 + store i32 2, ptr %2, align 4 + store i32 3, ptr %3, align 4 + store i32 4, ptr %4, align 4 + store i32 5, ptr %5, align 4 + store i32 6, ptr %6, align 4 + ret void +} + +define void @dog() { + ; CHECK-LABEL: _dog: + ; CHECK: sub sp, sp, #32 + ; CHECK-NOT: OUTLINED_FUNCTION + ; ALL: [[OUTLINED]] + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, ptr %1, align 4 + store i32 2, ptr %2, align 4 + store i32 3, ptr %3, align 4 + store i32 4, ptr %4, align 4 + store i32 5, ptr %5, align 4 + store i32 6, ptr %6, align 4 + ret void +} + +define void @other_cat() { + ; CHECK-LABEL: _other_cat: + ; CHECK: [[OUTLINED:OUTLINED_FUNCTION_[0-9]+]] + ; ALL: [[OUTLINED2:OUTLINED_FUNCTION_[0-9]+]] + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, ptr %1, align 4 + store i32 2, ptr %2, align 4 + store i32 3, ptr %3, align 4 + store i32 4, ptr %4, align 4 + store i32 5, ptr %5, align 4 + store i32 6, ptr %6, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + store i32 7, ptr %7, align 4 + store i32 8, ptr %8, align 4 + store i32 9, ptr %9, align 4 + ret void +} + +define void @other_dog() { + ; CHECK-LABEL: _other_dog: + ; CHECK: [[OUTLINED]] + ; ALL: [[OUTLINED2]] + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + store i32 1, ptr %1, align 4 + store i32 2, ptr %2, align 4 + store i32 3, ptr %3, align 4 + store i32 4, ptr %4, align 4 + store i32 5, ptr %5, align 4 + store i32 6, ptr %6, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + store i32 7, ptr %7, align 4 + store i32 8, ptr %8, align 4 + store i32 9, ptr %9, align 4 + ret void +} + +; CHECK: [[OUTLINED]]: +; ALL-DAG: [[OUTLINED]]: +; ALL-DAG: [[OUTLINED2]]: diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-threshold.mir b/llvm/test/CodeGen/AArch64/machine-outliner-threshold.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-threshold.mir @@ -0,0 +1,106 @@ +# RUN: llc -mtriple=aarch64--- -run-pass=prologepilog -run-pass=machine-outliner -verify-machineinstrs -frame-pointer=non-leaf %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64--- -run-pass=prologepilog -outliner-benefit-threshold=10 -run-pass=machine-outliner -verify-machineinstrs -frame-pointer=non-leaf %s -o - | FileCheck %s -check-prefix=THRESHOLD +--- | + + @x = common global i32 0, align 4 + + define void @baz() #0 { + ret void + } + + define void @bar(i32 %a) #0 { + ret void + } + + attributes #0 = { noinline noredzone } +... +--- +# Check that two we outline two differnet sequences, one from bb1 and one from +# bb2 when the threshold is 1. +# CHECK-LABEL: bb.1: +# CHECK: BL @OUTLINED_FUNCTION_[[F0:[0-9]+]], implicit-def $lr, implicit $sp +# CHECK-NEXT: $w11 = ORRWri $wzr, 2 +# CHECK-NEXT: BL @OUTLINED_FUNCTION_[[F0]], implicit-def $lr, implicit $sp +# CHECK-NEXT: $w8 = ORRWri $wzr, 0 +# CHECK-NOT: $w11 = KILL renamable $w11, implicit killed $w11 + +# CHECK-LABEL: bb.2: +# CHECK: BL @OUTLINED_FUNCTION_[[F1:[0-9]+]], implicit-def $lr, implicit $sp +# CHECK-NEXT: $w9 = ORRWri $wzr, 0 +# CHECK-NEXT: BL @OUTLINED_FUNCTION_[[F1]], implicit-def $lr, implicit $sp +# CHECK-NEXT: $w8 = ORRWri $wzr, 0 +# CHECK-NOT: $w11 = KILL renamable $w11, implicit killed $w11 + +# Check that the sequences in bb.2 don't get outlined with a threshold of 10 but +# the sequences in bb.1 do. +# THRESHOLD-LABEL: bb.1: +# THRESHOLD: BL @OUTLINED_FUNCTION_[[F0:[0-9]+]], implicit-def $lr, implicit $sp +# THRESHOLD-NEXT: $w11 = ORRWri $wzr, 2 +# THRESHOLD-NEXT: BL @OUTLINED_FUNCTION_[[F0]], implicit-def $lr, implicit $sp +# THRESHOLD-NEXT: $w8 = ORRWri $wzr, 0 +# THRESHOLD-NOT: $w11 = KILL renamable $w11, implicit killed $w11 + +# THRESHOLD-LABEL: bb.2: +# THRESHOLD-NOT: BL @OUTLINED_FUNCTION +name: bar +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $lr, $w8 + $sp = frame-setup SUBXri $sp, 32, 0 + $fp = frame-setup ADDXri $sp, 16, 0 + + bb.1: + BL @baz, implicit-def dead $lr, implicit $sp + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + $w11 = KILL renamable $w11, implicit killed $w11 + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + BL @baz, implicit-def dead $lr, implicit $sp + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 2 + BL @baz, implicit-def dead $lr, implicit $sp + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + BL @baz, implicit-def dead $lr, implicit $sp + $w11 = ORRWri $wzr, 1 + $w11 = ORRWri $wzr, 1 + $w8 = ORRWri $wzr, 0 + + bb.2: + $w15 = ORRWri $wzr, 1 + $w15 = ORRWri $wzr, 1 + $w15 = ORRWri $wzr, 1 + $w15 = ORRWri $wzr, 1 + $x15 = ADDXri $sp, 48, 0; + $w9 = ORRWri $wzr, 0 + $w15 = ORRWri $wzr, 1 + $w15 = ORRWri $wzr, 1 + $w15 = ORRWri $wzr, 1 + $w15 = ORRWri $wzr, 1 + $x15 = ADDXri $sp, 48, 0; + $w8 = ORRWri $wzr, 0 + + bb.3: + $fp, $lr = LDPXi $sp, 2 + $sp = ADDXri $sp, 32, 0 + RET undef $lr + +... +--- +name: baz +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0, $lr, $w8 + RET undef $lr + +# CHECK-LABEL: name: OUTLINED_FUNCTION_{{[0-9]}} +# CHECK-LABEL: name: OUTLINED_FUNCTION_{{[1-9]}} + +# THRESHOLD-LABEL: name: OUTLINED_FUNCTION_{{[0-9]}} +# THRESHOLD-NOT: name: OUTLINED_FUNCTION_{{[1-9]}}