]> granicus.if.org Git - llvm/commitdiff
Do not early-inline recursive calls in sample profile loader.
authorDehao Chen <dehao@google.com>
Thu, 8 Jun 2017 20:11:57 +0000 (20:11 +0000)
committerDehao Chen <dehao@google.com>
Thu, 8 Jun 2017 20:11:57 +0000 (20:11 +0000)
Summary: Early-inlining of recursive call makes the code size bloat exponentially. We should not disable it.

Reviewers: davidxl, dnovillo, iteratee

Reviewed By: iteratee

Subscribers: iteratee, llvm-commits, sanjoy

Differential Revision: https://reviews.llvm.org/D34017

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

lib/Transforms/IPO/SampleProfile.cpp
test/Transforms/SampleProfile/Inputs/indirect-call.prof
test/Transforms/SampleProfile/indirect-call.ll

index e755e2bd8f260765e0de3a3c87e9f5b9e9b05572..67bc8f5f6b7adb7a348ec4a5b16bec7a4b1c4494 100644 (file)
@@ -695,6 +695,13 @@ bool SampleProfileLoader::inlineHotFunctions(
           CallSite(I).isIndirectCall())
         for (const auto *FS : findIndirectCallFunctionSamples(*I)) {
           auto CalleeFunctionName = FS->getName();
+          // If it is a recursive call, we do not inline it as it could bloat
+          // the code exponentially. There is way to better handle this, e.g.
+          // clone the caller first, and inline the cloned caller if it is
+          // recursive. As llvm does not inline recursive calls, we will simply
+          // ignore it instead of handling it explicitly.
+          if (CalleeFunctionName == F.getName())
+            continue;
           const char *Reason = "Callee function not available";
           auto R = SymbolMap.find(CalleeFunctionName);
           if (R == SymbolMap.end())
index ff7be5df977a646a9738c84caf9141b725862130..ff1368142a0dc29ec637547b41ae8e3e052a870f 100644 (file)
@@ -17,3 +17,6 @@ test_inline_strip:3000:0
 test_inline_strip_conflict:3000:0
  1: foo_inline_strip_conflict:3000
   1: 3000
+test_norecursive_inline:3000:0
+ 1: test_norecursive_inline:3000
+  20: 3000
index 4101f6f492e531dced792ce921ede6c50e72b336..bee98f1066d2fb3a4afefc06e51795384a8c3a5d 100644 (file)
@@ -69,7 +69,18 @@ define void @test_noinline(void ()*) !dbg !12 {
   ret void
 }
 
+; CHECK-LABEL: @test_norecursive_inline
+; If the indirect call target is the caller, we should not promote it.
+define void @test_norecursive_inline() !dbg !24 {
+; CHECK-NOT: icmp
+; CHECK: call
+  %1 = load void ()*, void ()** @y, align 8
+  call void %1(), !dbg !25
+  ret void
+}
+
 @x = global i32 0, align 4
+@y = global void ()* null, align 8
 
 define i32* @foo_inline1(i32* %x) !dbg !14 {
   ret i32* %x
@@ -142,3 +153,5 @@ define void @test_direct() !dbg !22 {
 !21 = distinct !DISubprogram(name: "foo_direct", scope: !1, file: !1, line: 21, unit: !0)
 !22 = distinct !DISubprogram(name: "test_direct", scope: !1, file: !1, line: 22, unit: !0)
 !23 = !DILocation(line: 23, scope: !22)
+!24 = distinct !DISubprogram(name: "test_norecursive_inline", scope: !1, file: !1, line: 12, unit: !0)
+!25 = !DILocation(line: 13, scope: !24)