From a7dcfa746e8eab05e0750adc2c6dd1fabae5636d Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 10 Mar 2018 14:53:44 +0000 Subject: [PATCH] [PartialInlining] Use isInlineViable to detect constructs preventing inlining. Use isInlineViable to prevent inlining of functions with non-inlinable constructs, in case cost analysis is skipped. Reviewers: efriedma, sfertile, davide, davidxl Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D42846 llvm-svn: 327207 --- llvm/lib/Transforms/IPO/PartialInlining.cpp | 6 +- .../CodeExtractor/PartialInlineNotViable.ll | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/CodeExtractor/PartialInlineNotViable.ll diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp index fc1f2874f853..a16269be632c 100644 --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -769,13 +769,13 @@ bool PartialInlinerImpl::shouldPartialInline( BlockFrequency WeightedOutliningRcost) { using namespace ore; - if (SkipCostAnalysis) - return true; - Instruction *Call = CS.getInstruction(); Function *Callee = CS.getCalledFunction(); assert(Callee == Cloner.ClonedFunc); + if (SkipCostAnalysis) + return isInlineViable(*Callee); + Function *Caller = CS.getCaller(); auto &CalleeTTI = (*GetTTI)(*Callee); auto &ORE = (*GetORE)(*Caller); diff --git a/llvm/test/Transforms/CodeExtractor/PartialInlineNotViable.ll b/llvm/test/Transforms/CodeExtractor/PartialInlineNotViable.ll new file mode 100644 index 000000000000..010d677e5dc8 --- /dev/null +++ b/llvm/test/Transforms/CodeExtractor/PartialInlineNotViable.ll @@ -0,0 +1,63 @@ +; RUN: opt < %s -partial-inliner -skip-partial-inlining-cost-analysis -S | FileCheck %s +; + +define i32 @callee_indr_branch(i32 %v) { +entry: + %cmp = icmp sgt i32 %v, 2000 + %addr = select i1 %cmp, i8* blockaddress(@callee_indr_branch, %if.then), i8* blockaddress(@callee_indr_branch, %if.end) + indirectbr i8* %addr, [ label %if.then, label %if.end] + +if.then: ; preds = %entry + %mul = mul nsw i32 %v, 10 + br label %if.then2 + +if.then2: + %sub = sub i32 %v, 10 + br label %if.end + +if.end: ; preds = %if.then, %entry + %v2 = phi i32 [ %v, %entry ], [ %mul, %if.then2 ] + %add = add nsw i32 %v2, 200 + ret i32 %add +} + +declare void @use_fp(i8 *) +declare void @llvm.localescape(...) +declare i8* @llvm.frameaddress(i32) +declare i8* @llvm.localrecover(i8*, i8*, i32) + + + +define i32 @callee_frameescape(i32 %v) { +entry: + %a = alloca i32 + call void (...) @llvm.localescape(i32* %a) + %cmp = icmp sgt i32 %v, 2000 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %mul = mul nsw i32 %v, 10 + br label %if.then2 + +if.then2: + %sub = sub i32 %v, 10 + br label %if.end + +if.end: ; preds = %if.then, %entry + %v2 = phi i32 [ %v, %entry ], [ %mul, %if.then2 ] + %add = add nsw i32 %v2, 200 + ret i32 %add +} + + +; CHECK-LABEL: @caller +; CHECK: %r1 = call i32 @callee_indr_branch(i32 %v) +; CHECK-NEXT: %r2 = call i32 @callee_frameescape(i32 %v) +define i32 @caller(i32 %v) { +entry: + %r1 = call i32 @callee_indr_branch(i32 %v) + %r2 = call i32 @callee_frameescape(i32 %v) + %res = add i32 %r1, %r2 + ret i32 %res +} +