]> granicus.if.org Git - llvm/commitdiff
[InlineCost] Remove skew when calculating call costs
authorJames Molloy <james.molloy@arm.com>
Mon, 14 Nov 2016 11:14:41 +0000 (11:14 +0000)
committerJames Molloy <james.molloy@arm.com>
Mon, 14 Nov 2016 11:14:41 +0000 (11:14 +0000)
When calculating the cost of a call instruction we were applying a heuristic penalty as well as the cost of the instruction itself.

However, when calculating the benefit from inlining we weren't discounting the equivalent penalty for the call instruction that would be removed! This caused skew in the calculation and meant we wouldn't inline in the following, trivial case:

  int g() {
    h();
  }
  int f() {
    g();
  }

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286814 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/InlineCost.cpp
test/Transforms/Inline/alloca-bonus.ll
test/Transforms/Inline/inline-cold-callee.ll
test/Transforms/Inline/inline-cold.ll
test/Transforms/Inline/inline-hot-callee.ll
test/Transforms/Inline/inline-hot-callsite.ll
test/Transforms/Inline/inline-optsize.ll
test/Transforms/Inline/inline_unreachable-2.ll
test/Transforms/Inline/optimization-remarks-passed-yaml.ll
test/Transforms/Inline/ptr-diff.ll

index d820069e6ce31e127f7eb0a53dea890ca9dfc70e..6c3525fad4e1945b9cef8e54f85192b63c84e72d 100644 (file)
@@ -1255,7 +1255,9 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
       Cost -= InlineConstants::InstrCost;
     }
   }
-
+  // The call instruction also disappears after inlining.
+  Cost -= InlineConstants::InstrCost + InlineConstants::CallPenalty;
+  
   // If there is only one call of the function, and it has internal linkage,
   // the cost of inlining it drops dramatically.
   bool OnlyOneCallAndLocalLinkage =
index 649fac909fba6e76c1ce3d0b82dd0c347d7e1105..76a59ff6915ccabd54deab326e61f90d72b80729 100644 (file)
@@ -22,6 +22,7 @@ define void @inner1(i32 *%ptr) {
   %E = bitcast i32* %ptr to i8*
   %F = select i1 false, i32* %ptr, i32* @glbl
   call void @llvm.lifetime.start(i64 0, i8* %E)
+  call void @extern()
   ret void
 }
 
@@ -42,6 +43,7 @@ define void @inner2(i32 *%ptr) {
   %E = bitcast i32* %ptr to i8*
   %F = select i1 false, i32* %ptr, i32* @glbl
   call void @llvm.lifetime.start(i64 0, i8* %E)
+  call void @extern()
   ret void
 }
 
@@ -56,6 +58,7 @@ define void @outer3() {
 define void @inner3(i32 *%ptr, i1 %x) {
   %A = icmp eq i32* %ptr, null
   %B = and i1 %x, %A
+  call void @extern()
   br i1 %A, label %bb.true, label %bb.false
 bb.true:
   ; This block musn't be counted in the inline cost.
@@ -97,6 +100,7 @@ define void @outer4(i32 %A) {
 define void @inner4(i32 *%ptr, i32 %A) {
   %B = getelementptr inbounds i32, i32* %ptr, i32 %A
   %C = icmp eq i32* %ptr, null
+  call void @extern()
   br i1 %C, label %bb.true, label %bb.false
 bb.true:
   ; This block musn't be counted in the inline cost.
@@ -139,6 +143,7 @@ define void @outer5() {
 define void @inner5(i1 %flag, i32 *%ptr) {
   %A = load i32, i32* %ptr
   store i32 0, i32* %ptr
+  call void @extern()
   %C = getelementptr inbounds i32, i32* %ptr, i32 0
   br i1 %flag, label %if.then, label %exit
 
@@ -153,3 +158,4 @@ exit:
   ret void
 }
 
+declare void @extern()
index 8e202e91ffab52fbfe880a6589cff3546e071ca8..cfd56c281730858e3b7c608759e215d539e559a9 100644 (file)
@@ -9,7 +9,7 @@ define i32 @callee1(i32 %x) !prof !21 {
   %x1 = add i32 %x, 1
   %x2 = add i32 %x1, 1
   %x3 = add i32 %x2, 1
-
+  call void @extern()
   ret i32 %x3
 }
 
@@ -18,7 +18,7 @@ define i32 @callee2(i32 %x) !prof !22 {
   %x1 = add i32 %x, 1
   %x2 = add i32 %x1, 1
   %x3 = add i32 %x2, 1
-
+  call void @extern()
   ret i32 %x3
 }
 
@@ -32,6 +32,8 @@ define i32 @caller2(i32 %y1) !prof !22 {
   ret i32 %y3
 }
 
+declare void @extern()
+
 !llvm.module.flags = !{!1}
 !21 = !{!"function_entry_count", i64 100}
 !22 = !{!"function_entry_count", i64 1}
index b3c134538a45cb766a2b83fd46f9d8f920dd58a0..93d2569d87adc30a2bfd2189a533fca6355961ce 100644 (file)
@@ -17,6 +17,7 @@
 ; Function Attrs: nounwind readnone uwtable
 define i32 @simpleFunction(i32 %a) #0 {
 entry:
+  call void @extern()
   %a1 = load volatile i32, i32* @a
   %x1 = add i32 %a1,  %a1
   %a2 = load volatile i32, i32* @a
@@ -54,6 +55,7 @@ define i32 @ColdFunction(i32 %a) #1 {
 ; DEFAULT-LABEL: @ColdFunction
 ; DEFAULT: ret
 entry:
+  call void @extern()
   %a1 = load volatile i32, i32* @a
   %x1 = add i32 %a1,  %a1
   %a2 = load volatile i32, i32* @a
@@ -91,6 +93,7 @@ define i32 @ColdFunction2(i32 %a) #1 {
 ; DEFAULT-LABEL: @ColdFunction2
 ; DEFAULT: ret
 entry:
+  call void @extern()
   %a1 = load volatile i32, i32* @a
   %x1 = add i32 %a1,  %a1
   %a2 = load volatile i32, i32* @a
@@ -196,5 +199,6 @@ entry:
   ret i32 %add
 }
 
+declare void @extern()
 attributes #0 = { nounwind readnone uwtable }
 attributes #1 = { nounwind cold readnone uwtable }
index 7a04b517bf60f757c7bcb3bd4e4b96ee0b37317a..59d44bbb501f3b592a34509f131e2fb7d835f0ee 100644 (file)
@@ -9,7 +9,7 @@ define i32 @callee1(i32 %x) !prof !21 {
   %x1 = add i32 %x, 1
   %x2 = add i32 %x1, 1
   %x3 = add i32 %x2, 1
-
+  call void @extern()
   ret i32 %x3
 }
 
@@ -18,7 +18,7 @@ define i32 @callee2(i32 %x) !prof !22 {
   %x1 = add i32 %x, 1
   %x2 = add i32 %x1, 1
   %x3 = add i32 %x2, 1
-
+  call void @extern()
   ret i32 %x3
 }
 
@@ -32,6 +32,8 @@ define i32 @caller2(i32 %y1) !prof !22 {
   ret i32 %y3
 }
 
+declare void @extern()
+
 !llvm.module.flags = !{!1}
 !21 = !{!"function_entry_count", i64 300}
 !22 = !{!"function_entry_count", i64 1}
index 46993f49cc64520d93d9ee1333baa68e7026f08b..cc18fe6099cf0484ea0f4b43e0b643eed5bb69a2 100644 (file)
@@ -9,7 +9,7 @@ define i32 @callee1(i32 %x) {
   %x1 = add i32 %x, 1
   %x2 = add i32 %x1, 1
   %x3 = add i32 %x2, 1
-
+  call void @extern()
   ret i32 %x3
 }
 
@@ -18,7 +18,7 @@ define i32 @callee2(i32 %x) {
   %x1 = add i32 %x, 1
   %x2 = add i32 %x1, 1
   %x3 = add i32 %x2, 1
-
+  call void @extern()
   ret i32 %x3
 }
 
@@ -32,6 +32,8 @@ define i32 @caller2(i32 %y1) {
   ret i32 %y3
 }
 
+declare void @extern()
+
 !llvm.module.flags = !{!1}
 !21 = !{!"branch_weights", i64 300}
 !22 = !{!"branch_weights", i64 1}
index 7e62245fd3f021d6ac314a7f235ce7983d56ba48..c7cd9b3189d1922f44058f62b58b42a6f25c15df 100644 (file)
@@ -12,6 +12,7 @@
 ; This function should be larger than the inline threshold for -Oz (25), but
 ; smaller than the inline threshold for optsize (75).
 define i32 @inner() {
+  call void @extern()
   %a1 = load volatile i32, i32* @a
   %x1 = add i32 %a1,  %a1
   %a2 = load volatile i32, i32* @a
@@ -42,3 +43,5 @@ define i32 @outer2() minsize {
    %r = call i32 @inner()
    ret i32 %r
 }
+
+declare void @extern()
\ No newline at end of file
index 57f090effc5b10d4ba664dde506fc3ce1df66cc3..cc038c9b72087476225d621086450de4b1ae131d 100644 (file)
@@ -8,6 +8,7 @@ define void @caller(i32 %a, i1 %b) #0 {
 }
 
 define void @callee(i32 %a, i1 %b) {
+  call void @extern()
   call void asm sideeffect "", ""()
   br i1 %b, label %bb1, label %bb2
 bb1:
@@ -17,3 +18,5 @@ bb2:
   call void asm sideeffect "", ""()
   ret void
 }
+
+declare void @extern()
\ No newline at end of file
index 1e173342d8beec0df0e4192df385d4e49b86a13b..f532a16485767dd1274b90fdefa8ed459c29d324 100644 (file)
@@ -12,7 +12,7 @@
 ;  4       return foo();
 ;  5     }
 
-; CHECK:      remark: /tmp/s.c:4:10: foo can be inlined into bar with cost={{[0-9]+}} (threshold={{[0-9]+}}) (hotness: 30)
+; CHECK:      remark: /tmp/s.c:4:10: foo can be inlined into bar with cost={{[0-9\-]+}} (threshold={{[0-9]+}}) (hotness: 30)
 ; CHECK-NEXT: remark: /tmp/s.c:4:10: foo inlined into bar (hotness: 30)
 
 ; YAML:      --- !Analysis
@@ -28,7 +28,7 @@
 ; YAML-NEXT:   - Caller: bar
 ; YAML-NEXT:     DebugLoc:        { File: /tmp/s.c, Line: 3, Column: 0 }
 ; YAML-NEXT:   - String: ' with cost='
-; YAML-NEXT:   - Cost: '{{[0-9]+}}'
+; YAML-NEXT:   - Cost: '{{[0-9\-]+}}'
 ; YAML-NEXT:   - String: ' (threshold='
 ; YAML-NEXT:   - Threshold: '{{[0-9]+}}'
 ; YAML-NEXT:   - String: ')'
index 728f3793ee2d2ce39d88d8b278cfad83ea7e46de..d4647b7891b103b7b9c78b5e2ddce828ff5c428e 100644 (file)
@@ -4,7 +4,7 @@ target datalayout = "p:32:32-p1:64:64-p2:16:16-n16:32:64"
 
 define i32 @outer1() {
 ; CHECK-LABEL: @outer1(
-; CHECK-NOT: call
+; CHECK-NOT: call i32
 ; CHECK: ret i32
 
   %ptr = alloca i32
@@ -15,6 +15,7 @@ define i32 @outer1() {
 }
 
 define i32 @inner1(i32* %begin, i32* %end) {
+  call void @extern()
   %begin.i = ptrtoint i32* %begin to i32
   %end.i = ptrtoint i32* %end to i32
   %distance = sub i32 %end.i, %begin.i
@@ -43,6 +44,7 @@ define i32 @outer2(i32* %ptr) {
 }
 
 define i32 @inner2(i32* %begin, i32* %end) {
+  call void @extern()
   %begin.i = ptrtoint i32* %begin to i32
   %end.i = ptrtoint i32* %end to i32
   %distance = sub i32 %end.i, %begin.i
@@ -60,6 +62,7 @@ else:
 ; The inttoptrs are free since it is a smaller integer to a larger
 ; pointer size
 define i32 @inttoptr_free_cost(i32 %a, i32 %b, i32 %c) {
+  call void @extern()
   %p1 = inttoptr i32 %a to i32 addrspace(1)*
   %p2 = inttoptr i32 %b to i32 addrspace(1)*
   %p3 = inttoptr i32 %c to i32 addrspace(1)*
@@ -73,7 +76,7 @@ define i32 @inttoptr_free_cost(i32 %a, i32 %b, i32 %c) {
 
 define i32 @inttoptr_free_cost_user(i32 %begin, i32 %end) {
 ; CHECK-LABEL: @inttoptr_free_cost_user(
-; CHECK-NOT: call
+; CHECK-NOT: call i32
   %x = call i32 @inttoptr_free_cost(i32 %begin, i32 %end, i32 9)
   ret i32 %x
 }
@@ -81,6 +84,7 @@ define i32 @inttoptr_free_cost_user(i32 %begin, i32 %end) {
 ; The inttoptrs have a cost since it is a larger integer to a smaller
 ; pointer size
 define i32 @inttoptr_cost_smaller_ptr(i32 %a, i32 %b, i32 %c) {
+  call void @extern()
   %p1 = inttoptr i32 %a to i32 addrspace(2)*
   %p2 = inttoptr i32 %b to i32 addrspace(2)*
   %p3 = inttoptr i32 %c to i32 addrspace(2)*
@@ -94,8 +98,9 @@ define i32 @inttoptr_cost_smaller_ptr(i32 %a, i32 %b, i32 %c) {
 
 define i32 @inttoptr_cost_smaller_ptr_user(i32 %begin, i32 %end) {
 ; CHECK-LABEL: @inttoptr_cost_smaller_ptr_user(
-; CHECK: call
+; CHECK: call i32
   %x = call i32 @inttoptr_cost_smaller_ptr(i32 %begin, i32 %end, i32 9)
   ret i32 %x
 }
 
+declare void @extern()
\ No newline at end of file