[llvm] 2556f58 - [FuncSpec] Don't specialize function which are easy to inline
Chuanqi Xu via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 23 04:22:12 PDT 2021
Author: Chuanqi Xu
Date: 2021-08-23T19:20:21+08:00
New Revision: 2556f58148836f0af3ad2c73fe54bbdf49f0295a
URL: https://github.com/llvm/llvm-project/commit/2556f58148836f0af3ad2c73fe54bbdf49f0295a
DIFF: https://github.com/llvm/llvm-project/commit/2556f58148836f0af3ad2c73fe54bbdf49f0295a.diff
LOG: [FuncSpec] Don't specialize function which are easy to inline
It would waste time to specialize a function which would inline finally.
This patch did two things:
- Don't specialize functions which are always-inline.
- Don't spescialize functions whose lines of code are less than threshold
(100 by default).
For spec2017int, this patch could reduce the number of specialized
functions by 33%. Then the compile time didn't increase for every
benchmark.
Reviewed By: SjoerdMeijer, xbolva00, snehasish
Differential Revision: https://reviews.llvm.org/D107897
Added:
llvm/test/Transforms/FunctionSpecialization/function-specialization-always-inline.ll
Modified:
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers.ll
llvm/test/Transforms/FunctionSpecialization/function-specialization-loop.ll
llvm/test/Transforms/FunctionSpecialization/function-specialization-stats.ll
llvm/test/Transforms/FunctionSpecialization/function-specialization2.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 7cb1ecc656f3f..757efe2e8dd81 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -66,6 +66,12 @@ static cl::opt<unsigned> MaxConstantsThreshold(
"specialization"),
cl::init(3));
+static cl::opt<unsigned> SmallFunctionThreshold(
+ "func-specialization-size-threshold", cl::Hidden,
+ cl::desc("For functions whose IR instruction count below this threshold, "
+ " they wouldn't be specialized to avoid useless sepcializations."),
+ cl::init(100));
+
static cl::opt<unsigned>
AvgLoopIterationCount("func-specialization-avg-iters-cost", cl::Hidden,
cl::desc("Average loop iteration count cost"),
@@ -340,6 +346,10 @@ class FunctionSpecializer {
if (!Solver.isBlockExecutable(&F->getEntryBlock()))
return false;
+ // It wastes time to specialize a function which would get inlined finally.
+ if (F->hasFnAttribute(Attribute::AlwaysInline))
+ return false;
+
LLVM_DEBUG(dbgs() << "FnSpecialization: Try function: " << F->getName()
<< "\n");
@@ -430,7 +440,11 @@ class FunctionSpecializer {
// If the code metrics reveal that we shouldn't duplicate the function, we
// shouldn't specialize it. Set the specialization cost to Invalid.
- if (Metrics.notDuplicatable) {
+ // Or if the lines of codes implies that this function is easy to get
+ // inlined so that we shouldn't specialize it.
+ if (Metrics.notDuplicatable ||
+ (!ForceFunctionSpecialization &&
+ Metrics.NumInsts < SmallFunctionThreshold)) {
InstructionCost C{};
C.setInvalid();
return C;
diff --git a/llvm/test/Transforms/FunctionSpecialization/function-specialization-always-inline.ll b/llvm/test/Transforms/FunctionSpecialization/function-specialization-always-inline.ll
new file mode 100644
index 0000000000000..ff5816c3e1008
--- /dev/null
+++ b/llvm/test/Transforms/FunctionSpecialization/function-specialization-always-inline.ll
@@ -0,0 +1,61 @@
+; RUN: opt -function-specialization -func-specialization-avg-iters-cost=3 -func-specialization-size-threshold=10 -S < %s | FileCheck %s
+
+; CHECK-NOT: foo.{{[0-9]+}}
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+
+ at A = external dso_local constant i32, align 4
+ at B = external dso_local constant i32, align 4
+ at C = external dso_local constant i32, align 4
+ at D = external dso_local constant i32, align 4
+
+declare i1 @cond_begin()
+declare i1 @cond_end()
+declare i1 @getCond()
+
+define internal i32 @foo(i32 %x, i32* %b, i32* %c) alwaysinline {
+entry:
+ br label %loop.entry
+
+loop.entry:
+ br label %loop2.entry
+
+loop2.entry:
+ br label %loop2.body
+
+loop2.body:
+ %0 = load i32, i32* %b, align 4
+ %1 = load i32, i32* %c, align 4
+ %add.0 = add nsw i32 %0, %1
+ %add = add nsw i32 %add.0, %x
+ br label %loop2.end
+
+loop2.end:
+ %cond.end = call i1 @cond_end()
+ br i1 %cond.end, label %loop2.entry, label %loop.end
+
+loop.end:
+ %cond2.end = call i1 @getCond()
+ br i1 %cond2.end, label %loop.entry, label %return
+
+return:
+ ret i32 %add
+}
+
+define dso_local i32 @bar(i32 %x, i32 %y) {
+entry:
+ %tobool = icmp ne i32 %x, 0
+ br i1 %tobool, label %if.then, label %if.else
+
+if.then:
+ %call = call i32 @foo(i32 %x, i32* @A, i32* @C)
+ br label %return
+
+if.else:
+ %call1 = call i32 @foo(i32 %y, i32* @B, i32* @D)
+ br label %return
+
+return:
+ %retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
+ ret i32 %retval.0
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers.ll b/llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers.ll
index 598f73691ba74..542c166c0726c 100644
--- a/llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers.ll
+++ b/llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-integers.ll
@@ -1,4 +1,4 @@
-; RUN: opt -function-specialization -function-specialization-for-literal-constant=true -S < %s | FileCheck %s
+; RUN: opt -function-specialization -function-specialization-for-literal-constant=true -func-specialization-size-threshold=10 -S < %s | FileCheck %s
; Check that the literal constant parameter could be specialized.
; CHECK: @foo.1(
diff --git a/llvm/test/Transforms/FunctionSpecialization/function-specialization-loop.ll b/llvm/test/Transforms/FunctionSpecialization/function-specialization-loop.ll
index 4ebe09c8ac919..c997b05daff6a 100644
--- a/llvm/test/Transforms/FunctionSpecialization/function-specialization-loop.ll
+++ b/llvm/test/Transforms/FunctionSpecialization/function-specialization-loop.ll
@@ -1,4 +1,4 @@
-; RUN: opt -function-specialization -func-specialization-avg-iters-cost=3 -S < %s | FileCheck %s
+; RUN: opt -function-specialization -func-specialization-avg-iters-cost=3 -func-specialization-size-threshold=10 -S < %s | FileCheck %s
; Check that the loop depth results in a larger specialization bonus.
; CHECK: @foo.1(
diff --git a/llvm/test/Transforms/FunctionSpecialization/function-specialization-stats.ll b/llvm/test/Transforms/FunctionSpecialization/function-specialization-stats.ll
index 62131775e33ad..a3959561dc151 100644
--- a/llvm/test/Transforms/FunctionSpecialization/function-specialization-stats.ll
+++ b/llvm/test/Transforms/FunctionSpecialization/function-specialization-stats.ll
@@ -1,5 +1,5 @@
; REQUIRES: asserts
-; RUN: opt -stats -function-specialization -S < %s 2>&1 | FileCheck %s
+; RUN: opt -stats -function-specialization -S -force-function-specialization < %s 2>&1 | FileCheck %s
; CHECK: 2 function-specialization - Number of functions specialized
diff --git a/llvm/test/Transforms/FunctionSpecialization/function-specialization2.ll b/llvm/test/Transforms/FunctionSpecialization/function-specialization2.ll
index 591f8762fe834..c7bceed3bd91c 100644
--- a/llvm/test/Transforms/FunctionSpecialization/function-specialization2.ll
+++ b/llvm/test/Transforms/FunctionSpecialization/function-specialization2.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -function-specialization -deadargelim -S < %s | FileCheck %s
-; RUN: opt -function-specialization -func-specialization-max-iters=1 -deadargelim -S < %s | FileCheck %s
-; RUN: opt -function-specialization -func-specialization-max-iters=0 -deadargelim -S < %s | FileCheck %s --check-prefix=DISABLED
-; RUN: opt -function-specialization -func-specialization-avg-iters-cost=1 -deadargelim -S < %s | FileCheck %s
+; RUN: opt -function-specialization -deadargelim -force-function-specialization -S < %s | FileCheck %s
+; RUN: opt -function-specialization -func-specialization-max-iters=1 -deadargelim -force-function-specialization -S < %s | FileCheck %s
+; RUN: opt -function-specialization -func-specialization-max-iters=0 -deadargelim -force-function-specialization -S < %s | FileCheck %s --check-prefix=DISABLED
+; RUN: opt -function-specialization -func-specialization-avg-iters-cost=1 -deadargelim -force-function-specialization -S < %s | FileCheck %s
; DISABLED-NOT: @func.1(
; DISABLED-NOT: @func.2(
More information about the llvm-commits
mailing list