forked from OSchip/llvm-project
[ThinLTO] Update handling of vararg functions to match inliner
Summary: Previously we marked all vararg functions as non-inlinable in the function summary, which prevented their importing. However, the corresponding inliner restriction was loosened in r321940/r342675 to only apply to functions calling va_start. Adjust the summary flag computation to match. Reviewers: davidxl Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D54270 llvm-svn: 346883
This commit is contained in:
parent
d84cf13690
commit
32dc5b9bf1
|
@ -246,10 +246,15 @@ static void computeFunctionSummary(
|
|||
findRefEdges(Index, &F, RefEdges, Visited);
|
||||
|
||||
bool HasInlineAsmMaybeReferencingInternal = false;
|
||||
bool InitsVarArgs = false;
|
||||
for (const BasicBlock &BB : F)
|
||||
for (const Instruction &I : BB) {
|
||||
if (isa<DbgInfoIntrinsic>(I))
|
||||
continue;
|
||||
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I)) {
|
||||
if (II->getIntrinsicID() == Intrinsic::vastart)
|
||||
InitsVarArgs = true;
|
||||
}
|
||||
++NumInsts;
|
||||
findRefEdges(Index, &I, RefEdges, Visited);
|
||||
auto CS = ImmutableCallSite(&I);
|
||||
|
@ -357,9 +362,9 @@ static void computeFunctionSummary(
|
|||
F.hasFnAttribute(Attribute::ReadNone),
|
||||
F.hasFnAttribute(Attribute::ReadOnly),
|
||||
F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(),
|
||||
// Inliner doesn't handle variadic functions.
|
||||
// Inliner doesn't handle variadic functions with va_start calls.
|
||||
// FIXME: refactor this to use the same code that inliner is using.
|
||||
F.isVarArg() ||
|
||||
InitsVarArgs ||
|
||||
// Don't try to import functions with noinline attribute.
|
||||
F.getAttributes().hasFnAttribute(Attribute::NoInline)};
|
||||
auto FuncSummary = llvm::make_unique<FunctionSummary>(
|
||||
|
|
|
@ -13,18 +13,23 @@
|
|||
; BC-NEXT: <FUNCTION op0=7 op1=39
|
||||
; "variadic"
|
||||
; BC-NEXT: <FUNCTION op0=46 op1=8
|
||||
; "llvm.va_start"
|
||||
; BC-NEXT: <FUNCTION op0=54 op1=13
|
||||
; "f"
|
||||
; BC-NEXT: <ALIAS op0=54 op1=1
|
||||
; BC-NEXT: <ALIAS op0=67 op1=1
|
||||
; BC: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; BC-NEXT: <VERSION
|
||||
; BC-NEXT: <PERMODULE {{.*}} op0=1 op1=0
|
||||
; BC-NEXT: <PERMODULE {{.*}} op0=2 op1=0
|
||||
; BC-NEXT: <PERMODULE {{.*}} op0=3 op1=7
|
||||
; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=0 op2=1 op3=16
|
||||
; BC-NEXT: <ALIAS {{.*}} op0=5 op1=0 op2=3
|
||||
; Summary for @variadic has flags (op3) = 16 since non-inlinable owing to
|
||||
; va_start call.
|
||||
; flag is set due to va_start call.
|
||||
; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=0 op2=4 op3=16
|
||||
; BC-NEXT: <ALIAS {{.*}} op0=6 op1=0 op2=3
|
||||
; BC-NEXT: </GLOBALVAL_SUMMARY_BLOCK
|
||||
; BC: <STRTAB_BLOCK
|
||||
; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicf{{.*}}'
|
||||
; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicllvm.va_startf{{.*}}'
|
||||
|
||||
|
||||
; RUN: opt -name-anon-globals -module-summary < %s | llvm-dis | FileCheck %s
|
||||
|
@ -68,5 +73,10 @@ return: ; preds = %entry
|
|||
}
|
||||
|
||||
define i32 @variadic(...) {
|
||||
%ap = alloca i8*, align 8
|
||||
%ap.0 = bitcast i8** %ap to i8*
|
||||
call void @llvm.va_start(i8* %ap.0)
|
||||
ret i32 42
|
||||
}
|
||||
|
||||
declare void @llvm.va_start(i8*) nounwind
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
define void @globalfunc1() #0 {
|
||||
entry:
|
||||
call void @funcwithpersonality()
|
||||
call void (...) @variadic()
|
||||
call void (...) @variadic_va_start()
|
||||
ret void
|
||||
}
|
||||
|
||||
|
@ -147,8 +147,19 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
; Variadic function should not be imported because inliner doesn't handle it.
|
||||
define void @variadic(...) {
|
||||
; Variadic function without va_start can be imported because inliner
|
||||
; can handle it.
|
||||
define void @variadic_no_va_start(...) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; Variadic function with va_start should not be imported because inliner
|
||||
; doesn't handle it.
|
||||
define void @variadic_va_start(...) {
|
||||
%ap = alloca i8*, align 8
|
||||
%ap.0 = bitcast i8** %ap to i8*
|
||||
call void @llvm.va_start(i8* %ap.0)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.va_start(i8*) nounwind
|
||||
|
|
|
@ -29,7 +29,8 @@ entry:
|
|||
call void (...) @weakfunc()
|
||||
call void (...) @linkoncefunc2()
|
||||
call void (...) @referencelargelinkonce()
|
||||
call void (...) @variadic()
|
||||
call void (...) @variadic_no_va_start()
|
||||
call void (...) @variadic_va_start()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
|
@ -103,11 +104,19 @@ declare void @linkoncefunc2(...) #1
|
|||
; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !thinlto_src_module !0 {
|
||||
; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.{{.*}}()
|
||||
|
||||
; CHECK-DAG: declare void @variadic(...)
|
||||
declare void @variadic(...)
|
||||
; We can import variadic functions without a va_start, since the inliner
|
||||
; can handle them.
|
||||
; INSTLIMDEF-DAG: Import variadic_no_va_start
|
||||
; CHECK-DAG: define available_externally void @variadic_no_va_start(...) !thinlto_src_module !0 {
|
||||
declare void @variadic_no_va_start(...)
|
||||
|
||||
; We shouldn't import variadic functions without a va_start, since the inliner
|
||||
; cannot handle them.
|
||||
; CHECK-DAG: declare void @variadic_va_start(...)
|
||||
declare void @variadic_va_start(...)
|
||||
|
||||
; INSTLIMDEF-DAG: Import globalfunc2
|
||||
; INSTLIMDEF-DAG: 13 function-import - Number of functions imported
|
||||
; INSTLIMDEF-DAG: 14 function-import - Number of functions imported
|
||||
; INSTLIMDEF-DAG: 4 function-import - Number of global variables imported
|
||||
|
||||
; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}
|
||||
|
@ -147,7 +156,7 @@ declare void @variadic(...)
|
|||
; GUID-DAG: GUID {{.*}} is linkoncefunc
|
||||
|
||||
; DUMP: Module [[M1:.*]] imports from 1 module
|
||||
; DUMP-NEXT: 13 functions imported from [[M2:.*]]
|
||||
; DUMP-NEXT: 14 functions imported from [[M2:.*]]
|
||||
; DUMP-NEXT: 4 vars imported from [[M2]]
|
||||
; DUMP: Imported 13 functions for Module [[M1]]
|
||||
; DUMP: Imported 14 functions for Module [[M1]]
|
||||
; DUMP-NEXT: Imported 4 global variables for Module [[M1]]
|
||||
|
|
Loading…
Reference in New Issue