aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorMingming Liu <mingmingl@google.com>2024-04-10 19:46:01 -0700
committerGitHub <noreply@github.com>2024-04-10 19:46:01 -0700
commitdda73336ad22bd0b5ecda17040c50fb10fcbe5fb (patch)
treec5655d75797516814f2508c98dc21408e7e67e8f /llvm/lib
parent999b9e6ddb4324600a46c8f7006acec81fe3af0f (diff)
downloadllvm-dda73336ad22bd0b5ecda17040c50fb10fcbe5fb.zip
llvm-dda73336ad22bd0b5ecda17040c50fb10fcbe5fb.tar.gz
llvm-dda73336ad22bd0b5ecda17040c50fb10fcbe5fb.tar.bz2
[ThinLTO]Record import type in GlobalValueSummary::GVFlags (#87597)
The motivating use case is to support import the function declaration across modules to construct call graph edges for indirect calls [1] when importing the function definition costs too much compile time (e.g., the function is too large has no `noinline` attribute). 1. Currently, when the compiled IR module doesn't have a function definition but its postlink combined summary contains the function summary or a global alias summary with this function as aliasee, the function definition will be imported from source module by IRMover. The implementation is in FunctionImporter::importFunctions [2] 2. In order for FunctionImporter to import a declaration of a function, both function summary and alias summary need to carry the def / decl state. Specifically, all existing summary fields doesn't differ across import modules, but the def / decl state of is decided by `<ImportModule, Function>`. This change encodes the def/decl state in `GlobalValueSummary::GVFlags`. In the subsequent changes 1. The indexing step `computeImportForModule` [3] will compute the set of definitions and the set of declarations for each module, and passing on the information to bitcode writer. 2. Bitcode writer will look up the def/decl state and sets the state when it writes out the flag value. This is demonstrated in https://github.com/llvm/llvm-project/pull/87600 3. Function importer will read the def/decl state when reading the combined summary to figure out two sets of global values, and IRMover will be updated to import the declaration (aka linkGlobalValuePrototype [4]) into the destination module. - The next change is https://github.com/llvm/llvm-project/pull/87600 [1] mentioned in rfc https://discourse.llvm.org/t/rfc-for-better-call-graph-sort-build-a-more-complete-call-graph-by-adding-more-indirect-call-edges/74029#support-cross-module-function-declaration-import-5 [2] https://github.com/llvm/llvm-project/blob/3b337242ee165554f0017b00671381ec5b1ba855/llvm/lib/Transforms/IPO/FunctionImport.cpp#L1608-L1764 [3] https://github.com/llvm/llvm-project/blob/3b337242ee165554f0017b00671381ec5b1ba855/llvm/lib/Transforms/IPO/FunctionImport.cpp#L856 [4] https://github.com/llvm/llvm-project/blob/3b337242ee165554f0017b00671381ec5b1ba855/llvm/lib/Linker/IRMover.cpp#L605
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp12
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp3
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp33
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp3
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp2
-rw-r--r--llvm/lib/IR/AsmWriter.cpp12
-rw-r--r--llvm/lib/IR/ModuleSummaryIndex.cpp4
7 files changed, 61 insertions, 8 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index 3ad0bab..deda1ee 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -635,7 +635,8 @@ static void computeFunctionSummary(
HasIndirBranchToBlockAddress || HasIFuncCall;
GlobalValueSummary::GVFlags Flags(
F.getLinkage(), F.getVisibility(), NotEligibleForImport,
- /* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable());
+ /* Live = */ false, F.isDSOLocal(), F.canBeOmittedFromSymbolTable(),
+ GlobalValueSummary::ImportKind::Definition);
FunctionSummary::FFlags FunFlags{
F.doesNotAccessMemory(), F.onlyReadsMemory() && !F.doesNotAccessMemory(),
F.hasFnAttribute(Attribute::NoRecurse), F.returnDoesNotAlias(),
@@ -761,7 +762,8 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
bool NonRenamableLocal = isNonRenamableLocal(V);
GlobalValueSummary::GVFlags Flags(
V.getLinkage(), V.getVisibility(), NonRenamableLocal,
- /* Live = */ false, V.isDSOLocal(), V.canBeOmittedFromSymbolTable());
+ /* Live = */ false, V.isDSOLocal(), V.canBeOmittedFromSymbolTable(),
+ GlobalValueSummary::Definition);
VTableFuncList VTableFuncs;
// If splitting is not enabled, then we compute the summary information
@@ -807,7 +809,8 @@ static void computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
bool NonRenamableLocal = isNonRenamableLocal(A);
GlobalValueSummary::GVFlags Flags(
A.getLinkage(), A.getVisibility(), NonRenamableLocal,
- /* Live = */ false, A.isDSOLocal(), A.canBeOmittedFromSymbolTable());
+ /* Live = */ false, A.isDSOLocal(), A.canBeOmittedFromSymbolTable(),
+ GlobalValueSummary::Definition);
auto AS = std::make_unique<AliasSummary>(Flags);
auto AliaseeVI = Index.getValueInfo(Aliasee->getGUID());
assert(AliaseeVI && "Alias expects aliasee summary to be available");
@@ -887,7 +890,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
GlobalValue::InternalLinkage, GlobalValue::DefaultVisibility,
/* NotEligibleToImport = */ true,
/* Live = */ true,
- /* Local */ GV->isDSOLocal(), GV->canBeOmittedFromSymbolTable());
+ /* Local */ GV->isDSOLocal(), GV->canBeOmittedFromSymbolTable(),
+ GlobalValueSummary::Definition);
CantBePromoted.insert(GV->getGUID());
// Create the appropriate summary type.
if (Function *F = dyn_cast<Function>(GV)) {
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 2301a27..8ded07f 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -737,6 +737,9 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(live);
KEYWORD(dsoLocal);
KEYWORD(canAutoHide);
+ KEYWORD(importType);
+ KEYWORD(definition);
+ KEYWORD(declaration);
KEYWORD(function);
KEYWORD(insts);
KEYWORD(funcFlags);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index f546e05..6310412 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2083,6 +2083,20 @@ void LLParser::parseOptionalVisibility(unsigned &Res) {
Lex.Lex();
}
+bool LLParser::parseOptionalImportType(lltok::Kind Kind,
+ GlobalValueSummary::ImportKind &Res) {
+ switch (Kind) {
+ default:
+ return tokError("unknown import kind. Expect definition or declaration.");
+ case lltok::kw_definition:
+ Res = GlobalValueSummary::Definition;
+ return false;
+ case lltok::kw_declaration:
+ Res = GlobalValueSummary::Declaration;
+ return false;
+ }
+}
+
/// parseOptionalDLLStorageClass
/// ::= /*empty*/
/// ::= 'dllimport'
@@ -9230,7 +9244,8 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
/*NotEligibleToImport=*/false,
- /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
+ /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false,
+ GlobalValueSummary::Definition);
unsigned InstCount;
std::vector<FunctionSummary::EdgeTy> Calls;
FunctionSummary::TypeIdInfo TypeIdInfo;
@@ -9317,7 +9332,8 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
/*NotEligibleToImport=*/false,
- /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
+ /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false,
+ GlobalValueSummary::Definition);
GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
/* WriteOnly */ false,
/* Constant */ false,
@@ -9375,7 +9391,8 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
/*NotEligibleToImport=*/false,
- /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
+ /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false,
+ GlobalValueSummary::Definition);
if (parseToken(lltok::colon, "expected ':' here") ||
parseToken(lltok::lparen, "expected '(' here") ||
parseModuleReference(ModulePath) ||
@@ -10161,6 +10178,16 @@ bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
return true;
GVFlags.CanAutoHide = Flag;
break;
+ case lltok::kw_importType:
+ Lex.Lex();
+ if (parseToken(lltok::colon, "expected ':'"))
+ return true;
+ GlobalValueSummary::ImportKind IK;
+ if (parseOptionalImportType(Lex.getKind(), IK))
+ return true;
+ GVFlags.ImportType = static_cast<unsigned>(IK);
+ Lex.Lex();
+ break;
default:
return error(Lex.getLoc(), "expected gv flag type");
}
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 92c3495..fe4f0d6 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1141,6 +1141,7 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
// to getDecodedLinkage() will need to be taken into account here as above.
auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits
auto Visibility = GlobalValue::VisibilityTypes((RawFlags >> 8) & 3); // 2 bits
+ auto IK = GlobalValueSummary::ImportKind((RawFlags >> 10) & 1); // 1 bit
RawFlags = RawFlags >> 4;
bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3;
// The Live flag wasn't introduced until version 3. For dead stripping
@@ -1151,7 +1152,7 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
bool AutoHide = (RawFlags & 0x8);
return GlobalValueSummary::GVFlags(Linkage, Visibility, NotEligibleToImport,
- Live, Local, AutoHide);
+ Live, Local, AutoHide, IK);
}
// Decode the flags for GlobalVariable in the summary
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index dd554e4..6d01e3b 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1217,6 +1217,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
RawFlags |= (Flags.Visibility << 8); // 2 bits
+ RawFlags |= (Flags.ImportType << 10); // 1 bit
+
return RawFlags;
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index b778a14..609de92 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -3306,6 +3306,16 @@ static const char *getVisibilityName(GlobalValue::VisibilityTypes Vis) {
llvm_unreachable("invalid visibility");
}
+static const char *getImportTypeName(GlobalValueSummary::ImportKind IK) {
+ switch (IK) {
+ case GlobalValueSummary::Definition:
+ return "definition";
+ case GlobalValueSummary::Declaration:
+ return "declaration";
+ }
+ assert(false && "invalid import kind");
+}
+
void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
Out << ", insts: " << FS->instCount();
if (FS->fflags().anyFlagSet())
@@ -3545,6 +3555,8 @@ void AssemblyWriter::printSummary(const GlobalValueSummary &Summary) {
Out << ", live: " << GVFlags.Live;
Out << ", dsoLocal: " << GVFlags.DSOLocal;
Out << ", canAutoHide: " << GVFlags.CanAutoHide;
+ Out << ", importType: "
+ << getImportTypeName(GlobalValueSummary::ImportKind(GVFlags.ImportType));
Out << ")";
if (Summary.getSummaryKind() == GlobalValueSummary::AliasKind)
diff --git a/llvm/lib/IR/ModuleSummaryIndex.cpp b/llvm/lib/IR/ModuleSummaryIndex.cpp
index 198c730..6713d32 100644
--- a/llvm/lib/IR/ModuleSummaryIndex.cpp
+++ b/llvm/lib/IR/ModuleSummaryIndex.cpp
@@ -644,6 +644,10 @@ void ModuleSummaryIndex::exportToDot(
A.addComment("dsoLocal");
if (Flags.CanAutoHide)
A.addComment("canAutoHide");
+ if (Flags.ImportType == GlobalValueSummary::ImportKind::Definition)
+ A.addComment("definition");
+ else if (Flags.ImportType == GlobalValueSummary::ImportKind::Declaration)
+ A.addComment("declaration");
if (GUIDPreservedSymbols.count(SummaryIt.first))
A.addComment("preserved");