From: Dehao Chen Date: Thu, 8 Jun 2017 20:11:57 +0000 (+0000) Subject: Do not early-inline recursive calls in sample profile loader. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d3e685c4b06aeea9fa9769e75922b914cb58647;p=llvm Do not early-inline recursive calls in sample profile loader. 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 --- diff --git a/lib/Transforms/IPO/SampleProfile.cpp b/lib/Transforms/IPO/SampleProfile.cpp index e755e2bd8f2..67bc8f5f6b7 100644 --- a/lib/Transforms/IPO/SampleProfile.cpp +++ b/lib/Transforms/IPO/SampleProfile.cpp @@ -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()) diff --git a/test/Transforms/SampleProfile/Inputs/indirect-call.prof b/test/Transforms/SampleProfile/Inputs/indirect-call.prof index ff7be5df977..ff1368142a0 100644 --- a/test/Transforms/SampleProfile/Inputs/indirect-call.prof +++ b/test/Transforms/SampleProfile/Inputs/indirect-call.prof @@ -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 diff --git a/test/Transforms/SampleProfile/indirect-call.ll b/test/Transforms/SampleProfile/indirect-call.ll index 4101f6f492e..bee98f1066d 100644 --- a/test/Transforms/SampleProfile/indirect-call.ll +++ b/test/Transforms/SampleProfile/indirect-call.ll @@ -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)