Skip to content

Commit

Permalink
Don't import variadic functions
Browse files Browse the repository at this point in the history
Summary:
This patch adds IsVariadicFunction bit to summary in order
to not import variadic functions. Inliner doesn't inline
variadic functions because it is hard to reason about it.

This one small fix improves Importer by about 16%
(going from 86% to 100% of imported functions that are
inlined anywhere)
on some spec benchmarks like 'int' and others.

Reviewers: eraman, mehdi_amini, tejohnson

Subscribers: mehdi_amini, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278432 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
prazek committed Aug 11, 2016
1 parent 5747888 commit fb2a7f9
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 10 deletions.
20 changes: 17 additions & 3 deletions include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,23 @@ class GlobalValueSummary {
/// 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<Function>(&GV))
// Inliner doesn't handle variadic functions.
// FIXME: refactor this to use the same code that inliner is using.
IsNotViableToInline = F->isVarArg();
}
};

private:
Expand Down Expand Up @@ -175,6 +187,8 @@ class GlobalValueSummary {
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()); }
Expand Down
7 changes: 4 additions & 3 deletions lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,16 +720,17 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
}
}

// 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
// like getDecodedLinkage() above. Any future change to the linkage enum and
// 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) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
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.
Expand Down
4 changes: 4 additions & 0 deletions lib/Transforms/IPO/FunctionImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ static bool eligibleForImport(const ModuleSummaryIndex &Index,
// 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.
Expand Down
14 changes: 11 additions & 3 deletions test/Bitcode/thinlto-function-summary.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
; BC-NEXT: <PERMODULE {{.*}} op0=1 op1=0
; BC-NEXT: <PERMODULE {{.*}} op0=2 op1=0
; BC-NEXT: <PERMODULE {{.*}} op0=3 op1=7
; BC-NEXT: <ALIAS {{.*}} op0=4 op1=0 op2=3
; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=32
; BC-NEXT: <ALIAS {{.*}} op0=5 op1=0 op2=3
; BC-NEXT: </GLOBALVAL_SUMMARY_BLOCK
; BC-NEXT: <VALUE_SYMTAB
; BC-NEXT: <FNENTRY {{.*}} op0=3 {{.*}}> record string = 'anon.
; BC-NEXT: <FNENTRY {{.*}} op0=4 {{.*}}> record string = 'variadic'
; BC-NEXT: <FNENTRY {{.*}} op0=1 {{.*}}> record string = 'foo'
; BC-NEXT: <FNENTRY {{.*}} op0=2 {{.*}}> record string = 'bar'
; BC-NEXT: <FNENTRY {{.*}} op0=4 {{.*}}> record string = 'f'
; BC-NEXT: <FNENTRY {{.*}} op0=5 {{.*}}> record string = 'f'
; BC-NEXT: <ENTRY {{.*}} record string = 'h'
; BC-NEXT: <FNENTRY {{.*}} op0=3 {{.*}}> record string = 'anon.


; RUN: opt -name-anon-functions -module-summary < %s | llvm-dis | FileCheck %s
; Check that this round-trips correctly.
Expand Down Expand Up @@ -56,3 +60,7 @@ entry:
return: ; preds = %entry
ret void
}

define i32 @variadic(...) {
ret i32 42
}
5 changes: 5 additions & 0 deletions test/Transforms/FunctionImport/Inputs/funcimport.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
define void @globalfunc1() #0 {
entry:
call void @funcwithpersonality()
call void (...) @variadic()
ret void
}

Expand Down Expand Up @@ -146,4 +147,8 @@ entry:
ret void
}

; Variadic function should not be imported because inliner doesn't handle it.
define void @variadic(...) {
ret void
}

4 changes: 4 additions & 0 deletions test/Transforms/FunctionImport/funcimport.ll
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ entry:
call void (...) @weakfunc()
call void (...) @linkoncefunc2()
call void (...) @referencelargelinkonce()
call void (...) @variadic()
ret i32 0
}

Expand Down Expand Up @@ -105,6 +106,9 @@ 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(...)

; INSTLIMDEF-DAG: Import globalfunc2
; INSTLIMDEF-DAG: 13 function-import - Number of functions imported
; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}
Expand Down

0 comments on commit fb2a7f9

Please sign in to comment.