diff options
-rw-r--r-- | llvm/include/llvm/IR/ModuleSummaryIndex.h | 13 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/IPO/FunctionImport.h | 8 | ||||
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/ModuleSummaryIndex.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionImport.cpp | 10 | ||||
-rw-r--r-- | llvm/test/Assembler/thinlto-summary.ll | 4 | ||||
-rw-r--r-- | llvm/test/Bitcode/thinlto-function-summary.ll | 2 | ||||
-rw-r--r-- | llvm/test/ThinLTO/X86/dot-dumper.ll | 2 |
14 files changed, 52 insertions, 23 deletions
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h index 8510afe60a1..9a456acf966 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 d427cb809bf..5ad880574ef 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 3eb150becfa..29b96ac746b 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 53787b25d0b..af4f43986ef 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 e83b9f80592..5fe1e125d48 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 a3a9930f9e3..f8f5955a16c 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 aa83955e646..56e05f8f085 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 d59da255be4..f4634c9d3f4 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 eb2311da63b..3b575739263 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 e63407c3e75..8d85f7901b0 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 16a3d112b29..31531beea5e 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 01bf3a8c810..64af835ae2b 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 5922a8b3c4d..7f59eeabd9c 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 25cd0ed617f..72175a1ea4d 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: |