[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