1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[inline Cost] Don't mark functions accessing varargs as non-inlinable

Summary:
rL323619 marks functions that are calling va_end as not viable for
inlining. This patch reverses that since this va_end doesn't need
access to the vriadic arguments list that are saved on the stack, only
va_start does.

Reviewers: efriedma, fhahn

Reviewed By: fhahn

Subscribers: eraman, haicheng, llvm-commits

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

llvm-svn: 342675
This commit is contained in:
Sameer AbuAsal 2018-09-20 18:39:34 +00:00
parent 31ce2bb730
commit 6c1297ecd0
2 changed files with 34 additions and 7 deletions

View File

@ -137,7 +137,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
bool HasReturn; bool HasReturn;
bool HasIndirectBr; bool HasIndirectBr;
bool HasUninlineableIntrinsic; bool HasUninlineableIntrinsic;
bool UsesVarArgs; bool InitsVargArgs;
/// Number of bytes allocated statically by the callee. /// Number of bytes allocated statically by the callee.
uint64_t AllocatedSize; uint64_t AllocatedSize;
@ -283,7 +283,7 @@ public:
IsCallerRecursive(false), IsRecursiveCall(false), IsCallerRecursive(false), IsRecursiveCall(false),
ExposesReturnsTwice(false), HasDynamicAlloca(false), ExposesReturnsTwice(false), HasDynamicAlloca(false),
ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false), ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
HasUninlineableIntrinsic(false), UsesVarArgs(false), AllocatedSize(0), HasUninlineableIntrinsic(false), InitsVargArgs(false), AllocatedSize(0),
NumInstructions(0), NumVectorInstructions(0), VectorBonus(0), NumInstructions(0), NumVectorInstructions(0), VectorBonus(0),
SingleBBBonus(0), EnableLoadElimination(true), LoadEliminationCost(0), SingleBBBonus(0), EnableLoadElimination(true), LoadEliminationCost(0),
NumConstantArgs(0), NumConstantOffsetPtrArgs(0), NumAllocaArgs(0), NumConstantArgs(0), NumConstantOffsetPtrArgs(0), NumAllocaArgs(0),
@ -1239,8 +1239,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
HasUninlineableIntrinsic = true; HasUninlineableIntrinsic = true;
return false; return false;
case Intrinsic::vastart: case Intrinsic::vastart:
case Intrinsic::vaend: InitsVargArgs = true;
UsesVarArgs = true;
return false; return false;
} }
} }
@ -1587,7 +1586,7 @@ CallAnalyzer::analyzeBlock(BasicBlock *BB,
IR = "indirect branch"; IR = "indirect branch";
else if (HasUninlineableIntrinsic) else if (HasUninlineableIntrinsic)
IR = "uninlinable intrinsic"; IR = "uninlinable intrinsic";
else if (UsesVarArgs) else if (InitsVargArgs)
IR = "varargs"; IR = "varargs";
if (!IR) { if (!IR) {
if (ORE) if (ORE)
@ -2079,9 +2078,8 @@ bool llvm::isInlineViable(Function &F) {
// Disallow inlining functions that call @llvm.localescape. Doing this // Disallow inlining functions that call @llvm.localescape. Doing this
// correctly would require major changes to the inliner. // correctly would require major changes to the inliner.
case llvm::Intrinsic::localescape: case llvm::Intrinsic::localescape:
// Disallow inlining of functions that access VarArgs. // Disallow inlining of functions that initialize VarArgs with va_start.
case llvm::Intrinsic::vastart: case llvm::Intrinsic::vastart:
case llvm::Intrinsic::vaend:
return false; return false;
} }
} }

View File

@ -84,6 +84,35 @@ define i32 @call_vargs() {
; CHECK: %res1 = call i32 (...) @varg_accessed(i32 10) ; CHECK: %res1 = call i32 (...) @varg_accessed(i32 10)
; CHECK-NEXT: %res2 = call i32 (...) @varg_accessed_alwaysinline(i32 15) ; CHECK-NEXT: %res2 = call i32 (...) @varg_accessed_alwaysinline(i32 15)
define void @caller_with_vastart(i8* noalias nocapture readnone %args, ...) {
entry:
%ap = alloca i8*, align 4
%ap.ptr = bitcast i8** %ap to i8*
%ap2 = alloca i8*, align 4
%ap2.ptr = bitcast i8** %ap to i8*
call void @llvm.va_start(i8* nonnull %ap.ptr)
call fastcc void @callee_with_vaend(i8* nonnull %ap.ptr)
call void @llvm.va_start(i8* nonnull %ap2.ptr)
call fastcc void @callee_with_vaend_alwaysinline(i8* nonnull %ap2.ptr)
ret void
}
define internal fastcc void @callee_with_vaend_alwaysinline(i8* %a) alwaysinline {
entry:
tail call void @llvm.va_end(i8* %a)
ret void
}
define internal fastcc void @callee_with_vaend(i8* %a) {
entry:
tail call void @llvm.va_end(i8* %a)
ret void
}
; CHECK-LABEL: @caller_with_vastart
; CHECK-NOT: @callee_with_vaend
; CHECK-NOT: @callee_with_vaend_alwaysinline
declare void @llvm.va_start(i8*) declare void @llvm.va_start(i8*)
declare void @llvm.va_end(i8*) declare void @llvm.va_end(i8*)