aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2018-11-06 19:41:35 +0000
committerTeresa Johnson <tejohnson@google.com>2018-11-06 19:41:35 +0000
commitcb397461e1b5d99072931a309cc8903faac6db26 (patch)
tree6c1666bef906e0da6128ad8169a6fc06709de100 /llvm
parentd768ecf5a7a88c5ea7dc7201447742e9c8624b3b (diff)
downloadllvm-cb397461e1b5d99072931a309cc8903faac6db26.zip
llvm-cb397461e1b5d99072931a309cc8903faac6db26.tar.gz
llvm-cb397461e1b5d99072931a309cc8903faac6db26.tar.bz2
[ThinLTO] Split NotEligibleToImport into legality and inlinability flags
Summary: The NotEligibleToImport flag on the GlobalValueSummary was set if it isn't legal to import (e.g. because it references unpromotable locals) and when it can't be inlined (in which case importing is pointless). I split out the inlinable piece into a separate flag on the FunctionSummary (doesn't make sense for aliases or global variables), because in the future we may want to import for reasons other than inlining. Reviewers: davidxl Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, arphaman, llvm-commits Differential Revision: https://reviews.llvm.org/D53345 llvm-svn: 346261
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/ModuleSummaryIndex.h13
-rw-r--r--llvm/include/llvm/Transforms/IPO/FunctionImport.h8
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp19
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp7
-rw-r--r--llvm/lib/AsmParser/LLToken.h1
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp1
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--llvm/lib/IR/AsmWriter.cpp1
-rw-r--r--llvm/lib/IR/ModuleSummaryIndex.cpp5
-rw-r--r--llvm/lib/Transforms/IPO/FunctionImport.cpp10
-rw-r--r--llvm/test/Assembler/thinlto-summary.ll4
-rw-r--r--llvm/test/Bitcode/thinlto-function-summary.ll2
-rw-r--r--llvm/test/ThinLTO/X86/dot-dumper.ll2
14 files changed, 52 insertions, 23 deletions
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index 8510afe..9a456ac 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -478,13 +478,17 @@ public:
TypeCheckedLoadConstVCalls;
};
- /// Function attribute flags. Used to track if a function accesses memory,
- /// recurses or aliases.
+ /// Flags specific to function summaries.
struct FFlags {
+ // Function attribute flags. Used to track if a function accesses memory,
+ // recurses or aliases.
unsigned ReadNone : 1;
unsigned ReadOnly : 1;
unsigned NoRecurse : 1;
unsigned ReturnDoesNotAlias : 1;
+
+ // Indicate if the global value cannot be inlined.
+ unsigned NoInline : 1;
};
/// Create an empty FunctionSummary (with specified call edges).
@@ -511,8 +515,7 @@ private:
/// during the initial compile step when the summary index is first built.
unsigned InstCount;
- /// Function attribute flags. Used to track if a function accesses memory,
- /// recurses or aliases.
+ /// Function summary specific flags.
FFlags FunFlags;
/// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
@@ -546,7 +549,7 @@ public:
return GVS->getSummaryKind() == FunctionKind;
}
- /// Get function attribute flags.
+ /// Get function summary flags.
FFlags fflags() const { return FunFlags; }
/// Get the instruction count recorded for this function.
diff --git a/llvm/include/llvm/Transforms/IPO/FunctionImport.h b/llvm/include/llvm/Transforms/IPO/FunctionImport.h
index d427cb8..5ad8805 100644
--- a/llvm/include/llvm/Transforms/IPO/FunctionImport.h
+++ b/llvm/include/llvm/Transforms/IPO/FunctionImport.h
@@ -56,10 +56,14 @@ public:
// to find at least one summary for the GUID that is global or a local
// in the referenced module for direct calls.
LocalLinkageNotInModule,
- // This corresponse to the NotEligibleToImport being set on the summary,
+ // This corresponds to the NotEligibleToImport being set on the summary,
// which can happen in a few different cases (e.g. local that can't be
// renamed or promoted because it is referenced on a llvm*.used variable).
- NotEligible
+ NotEligible,
+ // This corresponds to NoInline being set on the function summary,
+ // which will happen if it is known that the inliner will not be able
+ // to inline the function (e.g. it is marked with a NoInline attribute).
+ NoInline
};
/// Information optionally tracked for candidates the importer decided
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 3eb150b..29b96ac 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -350,20 +350,18 @@ static void computeFunctionSummary(
bool NonRenamableLocal = isNonRenamableLocal(F);
bool NotEligibleForImport =
- NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
- // Inliner doesn't handle variadic functions.
- // FIXME: refactor this to use the same code that inliner is using.
- F.isVarArg() ||
- // Don't try to import functions with noinline attribute.
- F.getAttributes().hasFnAttribute(Attribute::NoInline);
+ NonRenamableLocal || HasInlineAsmMaybeReferencingInternal;
GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
/* Live = */ false, F.isDSOLocal());
FunctionSummary::FFlags FunFlags{
F.hasFnAttribute(Attribute::ReadNone),
F.hasFnAttribute(Attribute::ReadOnly),
- F.hasFnAttribute(Attribute::NoRecurse),
- F.returnDoesNotAlias(),
- };
+ F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(),
+ // Inliner doesn't handle variadic functions.
+ // FIXME: refactor this to use the same code that inliner is using.
+ F.isVarArg() ||
+ // Don't try to import functions with noinline attribute.
+ F.getAttributes().hasFnAttribute(Attribute::NoInline)};
auto FuncSummary = llvm::make_unique<FunctionSummary>(
Flags, NumInsts, FunFlags, RefEdges.takeVector(),
CallGraphEdges.takeVector(), TypeTests.takeVector(),
@@ -478,7 +476,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
F->hasFnAttribute(Attribute::ReadNone),
F->hasFnAttribute(Attribute::ReadOnly),
F->hasFnAttribute(Attribute::NoRecurse),
- F->returnDoesNotAlias()},
+ F->returnDoesNotAlias(),
+ /* NoInline = */ false},
ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{},
ArrayRef<GlobalValue::GUID>{},
ArrayRef<FunctionSummary::VFuncId>{},
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 53787b2..af4f439 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -740,6 +740,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(readOnly);
KEYWORD(noRecurse);
KEYWORD(returnDoesNotAlias);
+ KEYWORD(noInline);
KEYWORD(calls);
KEYWORD(callee);
KEYWORD(hotness);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index e83b9f8..5fe1e12 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -7714,6 +7714,7 @@ bool LLParser::ParseFlag(unsigned &Val) {
/// := 'funcFlags' ':' '(' ['readNone' ':' Flag]?
/// [',' 'readOnly' ':' Flag]? [',' 'noRecurse' ':' Flag]?
/// [',' 'returnDoesNotAlias' ':' Flag]? ')'
+/// [',' 'noInline' ':' Flag]? ')'
bool LLParser::ParseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
assert(Lex.getKind() == lltok::kw_funcFlags);
Lex.Lex();
@@ -7749,6 +7750,12 @@ bool LLParser::ParseOptionalFFlags(FunctionSummary::FFlags &FFlags) {
return true;
FFlags.ReturnDoesNotAlias = Val;
break;
+ case lltok::kw_noInline:
+ Lex.Lex();
+ if (ParseToken(lltok::colon, "expected ':'") || ParseFlag(Val))
+ return true;
+ FFlags.NoInline = Val;
+ break;
default:
return Error(Lex.getLoc(), "expected function flag type");
}
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index a3a9930..f8f5955 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -369,6 +369,7 @@ enum Kind {
kw_readOnly,
kw_noRecurse,
kw_returnDoesNotAlias,
+ kw_noInline,
kw_calls,
kw_callee,
kw_hotness,
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index aa83955..56e05f8 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -876,6 +876,7 @@ static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) {
Flags.ReadOnly = (RawFlags >> 1) & 0x1;
Flags.NoRecurse = (RawFlags >> 2) & 0x1;
Flags.ReturnDoesNotAlias = (RawFlags >> 3) & 0x1;
+ Flags.NoInline = (RawFlags >> 4) & 0x1;
return Flags;
}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index d59da25..f4634c9 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -971,6 +971,7 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {
RawFlags |= (Flags.ReadOnly << 1);
RawFlags |= (Flags.NoRecurse << 2);
RawFlags |= (Flags.ReturnDoesNotAlias << 3);
+ RawFlags |= (Flags.NoInline << 4);
return RawFlags;
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index eb2311d..3b57573 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2871,6 +2871,7 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
Out << ", readOnly: " << FFlags.ReadOnly;
Out << ", noRecurse: " << FFlags.NoRecurse;
Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias;
+ Out << ", noInline: " << FFlags.NoInline;
Out << ")";
}
if (!FS->calls().empty()) {
diff --git a/llvm/lib/IR/ModuleSummaryIndex.cpp b/llvm/lib/IR/ModuleSummaryIndex.cpp
index e63407c..8d85f79 100644
--- a/llvm/lib/IR/ModuleSummaryIndex.cpp
+++ b/llvm/lib/IR/ModuleSummaryIndex.cpp
@@ -182,8 +182,9 @@ static std::string linkageToString(GlobalValue::LinkageTypes LT) {
static std::string fflagsToString(FunctionSummary::FFlags F) {
auto FlagValue = [](unsigned V) { return V ? '1' : '0'; };
- char FlagRep[] = {FlagValue(F.ReadNone), FlagValue(F.ReadOnly),
- FlagValue(F.NoRecurse), FlagValue(F.ReturnDoesNotAlias), 0};
+ char FlagRep[] = {FlagValue(F.ReadNone), FlagValue(F.ReadOnly),
+ FlagValue(F.NoRecurse), FlagValue(F.ReturnDoesNotAlias),
+ FlagValue(F.NoInline), 0};
return FlagRep;
}
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 16a3d11..31531be 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -237,11 +237,19 @@ selectCallee(const ModuleSummaryIndex &Index,
return false;
}
+ // Skip if it isn't legal to import (e.g. may reference unpromotable
+ // locals).
if (Summary->notEligibleToImport()) {
Reason = FunctionImporter::ImportFailureReason::NotEligible;
return false;
}
+ // Don't bother importing if we can't inline it anyway.
+ if (Summary->fflags().NoInline) {
+ Reason = FunctionImporter::ImportFailureReason::NoInline;
+ return false;
+ }
+
return true;
});
if (It == CalleeSummaryList.end())
@@ -318,6 +326,8 @@ getFailureName(FunctionImporter::ImportFailureReason Reason) {
return "LocalLinkageNotInModule";
case FunctionImporter::ImportFailureReason::NotEligible:
return "NotEligible";
+ case FunctionImporter::ImportFailureReason::NoInline:
+ return "NoInline";
}
llvm_unreachable("invalid reason");
}
diff --git a/llvm/test/Assembler/thinlto-summary.ll b/llvm/test/Assembler/thinlto-summary.ll
index 01bf3a8..64af835 100644
--- a/llvm/test/Assembler/thinlto-summary.ll
+++ b/llvm/test/Assembler/thinlto-summary.ll
@@ -81,8 +81,8 @@
; CHECK: ^13 = gv: (guid: 12, summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0))))
; CHECK: ^14 = gv: (guid: 13, summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 1))))
; CHECK: ^15 = gv: (guid: 14, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 1, live: 1, dsoLocal: 0), insts: 1)))
-; CHECK: ^16 = gv: (guid: 15, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 1, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0))))
-; CHECK: ^17 = gv: (guid: 16, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 0, readOnly: 1, noRecurse: 0, returnDoesNotAlias: 1), calls: ((callee: ^15)))))
+; CHECK: ^16 = gv: (guid: 15, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 1, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0, noInline: 0))))
+; CHECK: ^17 = gv: (guid: 16, summaries: (function: (module: ^1, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 1, funcFlags: (readNone: 0, readOnly: 1, noRecurse: 0, returnDoesNotAlias: 1, noInline: 0), calls: ((callee: ^15)))))
; CHECK: ^18 = gv: (guid: 17, summaries: (alias: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 1), aliasee: ^14)))
; CHECK: ^19 = gv: (guid: 18, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 4, typeIdInfo: (typeTests: (^24, ^26)))))
; CHECK: ^20 = gv: (guid: 19, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 8, typeIdInfo: (typeTestAssumeVCalls: (vFuncId: (^27, offset: 16))))))
diff --git a/llvm/test/Bitcode/thinlto-function-summary.ll b/llvm/test/Bitcode/thinlto-function-summary.ll
index 5922a8b..7f59eea 100644
--- a/llvm/test/Bitcode/thinlto-function-summary.ll
+++ b/llvm/test/Bitcode/thinlto-function-summary.ll
@@ -20,7 +20,7 @@
; 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=16
+; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=0 op2=1 op3=16
; BC-NEXT: <ALIAS {{.*}} op0=5 op1=0 op2=3
; BC-NEXT: </GLOBALVAL_SUMMARY_BLOCK
; BC: <STRTAB_BLOCK
diff --git a/llvm/test/ThinLTO/X86/dot-dumper.ll b/llvm/test/ThinLTO/X86/dot-dumper.ll
index 25cd0ed..72175a1 100644
--- a/llvm/test/ThinLTO/X86/dot-dumper.ll
+++ b/llvm/test/ThinLTO/X86/dot-dumper.ll
@@ -34,7 +34,7 @@
; CLUSTER1: // Module: {{.*}}2.bc
; CLUSTER1-NEXT: subgraph cluster_1 {
; CLUSTER1-DAG: M1_[[A:[0-9]+]] [{{.*}}A|extern{{.*}}]; // variable
-; CLUSTER1-DAG: M1_[[FOO:[0-9]+]] [{{.*}}foo|extern{{.*}}]; // function, not eligible to import
+; CLUSTER1-DAG: M1_[[FOO:[0-9]+]] [{{.*}}foo|extern{{.*}} ffl: 00001{{.*}}]; // function
; CLUSTER1-DAG: M1_[[B:[0-9]+]] [{{.*}}B|extern{{.*}}]; // variable
; CLUSTER1-DAG: M1_[[BAR:[0-9]+]] [{{.*}}bar|extern{{.*}}]; // function, dead
; CLUSTER1-NEXT: // Edges: