Index: llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h +++ llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h @@ -104,11 +104,23 @@ /// Indicate if the global value is located in a specific section. unsigned HasSection : 1; + /// Indicate if the function is not viable to inline. + unsigned IsNotViableToInline : 1; + /// Convenience Constructors - explicit GVFlags(GlobalValue::LinkageTypes Linkage, bool HasSection) - : Linkage(Linkage), HasSection(HasSection) {} + explicit GVFlags(GlobalValue::LinkageTypes Linkage, bool HasSection, + bool IsNotViableToInline) + : Linkage(Linkage), HasSection(HasSection), + IsNotViableToInline(IsNotViableToInline) {} + GVFlags(const GlobalValue &GV) - : Linkage(GV.getLinkage()), HasSection(GV.hasSection()) {} + : Linkage(GV.getLinkage()), HasSection(GV.hasSection()) { + IsNotViableToInline = false; + if (const auto *F = dyn_cast(&GV)) + // Inliner doesn't handle variadic functions. + // FIXME: refactor this to use the same code that inliner is using. + IsNotViableToInline = F->isVarArg(); + } }; private: @@ -175,6 +187,8 @@ Flags.Linkage = Linkage; } + bool isNotViableToInline() const { return Flags.IsNotViableToInline; } + /// Return true if this summary is for a GlobalValue that needs promotion /// to be referenced from another module. bool needsRenaming() const { return GlobalValue::isLocalLinkage(linkage()); } Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -720,7 +720,7 @@ } } -// Decode the flags for GlobalValue in the summary +/// Decode the flags for GlobalValue in the summary. static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, uint64_t Version) { // Summary were not emitted before LLVM 3.9, we don't need to upgrade Linkage @@ -728,8 +728,9 @@ // to getDecodedLinkage() will need to be taken into account here as above. auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits RawFlags = RawFlags >> 4; - auto HasSection = RawFlags & 0x1; // bool - return GlobalValueSummary::GVFlags(Linkage, HasSection); + bool HasSection = RawFlags & 0x1; + bool IsNotViableToInline = RawFlags & 0x2; + return GlobalValueSummary::GVFlags(Linkage, HasSection, IsNotViableToInline); } static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { Index: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -991,7 +991,7 @@ uint64_t RawFlags = 0; RawFlags |= Flags.HasSection; // bool - + RawFlags |= (Flags.IsNotViableToInline << 1); // Linkage don't need to be remapped at that time for the summary. Any future // change to the getEncodedLinkage() function will need to be taken into // account here as well. Index: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp @@ -130,6 +130,10 @@ // FIXME: we may be able to import it by copying it without promotion. return false; + // Don't import functions that are not viable to inline. + if (Summary.isNotViableToInline()) + return false; + // Check references (and potential calls) in the same module. If the current // value references a global that can't be externally referenced it is not // eligible for import. Index: llvm/trunk/test/Bitcode/thinlto-function-summary.ll =================================================================== --- llvm/trunk/test/Bitcode/thinlto-function-summary.ll +++ llvm/trunk/test/Bitcode/thinlto-function-summary.ll @@ -9,13 +9,17 @@ ; BC-NEXT: record string = 'anon. +; BC-NEXT: record string = 'variadic' ; BC-NEXT: record string = 'foo' ; BC-NEXT: record string = 'bar' -; BC-NEXT: record string = 'f' +; BC-NEXT: record string = 'f' +; BC-NEXT: record string = 'anon. + ; RUN: opt -name-anon-functions -module-summary < %s | llvm-dis | FileCheck %s ; Check that this round-trips correctly. @@ -56,3 +60,7 @@ return: ; preds = %entry ret void } + +define i32 @variadic(...) { + ret i32 42 +} Index: llvm/trunk/test/Transforms/FunctionImport/Inputs/funcimport.ll =================================================================== --- llvm/trunk/test/Transforms/FunctionImport/Inputs/funcimport.ll +++ llvm/trunk/test/Transforms/FunctionImport/Inputs/funcimport.ll @@ -11,6 +11,7 @@ define void @globalfunc1() #0 { entry: call void @funcwithpersonality() + call void (...) @variadic() ret void } @@ -146,4 +147,8 @@ ret void } +; Variadic function should not be imported because inliner doesn't handle it. +define void @variadic(...) { + ret void +} Index: llvm/trunk/test/Transforms/FunctionImport/funcimport.ll =================================================================== --- llvm/trunk/test/Transforms/FunctionImport/funcimport.ll +++ llvm/trunk/test/Transforms/FunctionImport/funcimport.ll @@ -32,6 +32,7 @@ call void (...) @weakfunc() call void (...) @linkoncefunc2() call void (...) @referencelargelinkonce() + call void (...) @variadic() ret i32 0 } @@ -105,6 +106,9 @@ ; 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(...) + ; INSTLIMDEF-DAG: Import globalfunc2 ; INSTLIMDEF-DAG: 13 function-import - Number of functions imported ; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}