Skip to content

Commit 3082a38

Browse files
[LTO] Introduce helper functions to add GUIDs to ImportList (NFC) (#105555)
The new helper functions make the intent clearer while hiding implementation details, including how we handle previously added entries. Note that: - If we are adding a GUID as a GlobalValueSummary::Definition, then we override a previously added GlobalValueSummary::Declaration entry for the same GUID. - If we are adding a GUID as a GlobalValueSummary::Declaration, then a previously added GlobalValueSummary::Definition entry for the same GUID takes precedence, and no change is made.
1 parent e738c81 commit 3082a38

File tree

4 files changed

+64
-42
lines changed

4 files changed

+64
-42
lines changed

llvm/include/llvm/Transforms/IPO/FunctionImport.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,33 @@ class FunctionImporter {
122122
/// Import functions in Module \p M based on the supplied import list.
123123
Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList);
124124

125+
enum class AddDefinitionStatus {
126+
NoChange,
127+
Inserted,
128+
ChangedToDefinition,
129+
};
130+
131+
// Add the given GUID to ImportList as a definition. If the same GUID has
132+
// been added as a declaration previously, that entry is overridden.
133+
static AddDefinitionStatus addDefinition(ImportMapTy &ImportList,
134+
StringRef FromModule,
135+
GlobalValue::GUID GUID);
136+
137+
// Add the given GUID to ImportList as a declaration. If the same GUID has
138+
// been added as a definition previously, that entry takes precedence, and no
139+
// change is made.
140+
static void maybeAddDeclaration(ImportMapTy &ImportList, StringRef FromModule,
141+
GlobalValue::GUID GUID);
142+
143+
static void addGUID(ImportMapTy &ImportList, StringRef FromModule,
144+
GlobalValue::GUID GUID,
145+
GlobalValueSummary::ImportKind ImportKind) {
146+
if (ImportKind == GlobalValueSummary::Definition)
147+
addDefinition(ImportList, FromModule, GUID);
148+
else
149+
maybeAddDeclaration(ImportList, FromModule, GUID);
150+
}
151+
125152
private:
126153
/// The summaries index used to trigger importing.
127154
const ModuleSummaryIndex &Index;

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -726,14 +726,8 @@ bool lto::initImportList(const Module &M,
726726
if (Summary->modulePath() == M.getModuleIdentifier())
727727
continue;
728728
// Add an entry to provoke importing by thinBackend.
729-
// Try emplace the entry first. If an entry with the same key already
730-
// exists, set the value to 'std::min(existing-value, new-value)' to make
731-
// sure a definition takes precedence over a declaration.
732-
auto [Iter, Inserted] = ImportList[Summary->modulePath()].try_emplace(
733-
GUID, Summary->importType());
734-
735-
if (!Inserted)
736-
Iter->second = std::min(Iter->second, Summary->importType());
729+
FunctionImporter::addGUID(ImportList, Summary->modulePath(), GUID,
730+
Summary->importType());
737731
}
738732
}
739733
return true;

llvm/lib/Transforms/IPO/FunctionImport.cpp

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,25 @@ using EdgeInfo = std::tuple<const FunctionSummary *, unsigned /* Threshold */>;
334334

335335
} // anonymous namespace
336336

337+
FunctionImporter::AddDefinitionStatus
338+
FunctionImporter::addDefinition(ImportMapTy &ImportList, StringRef FromModule,
339+
GlobalValue::GUID GUID) {
340+
auto [It, Inserted] =
341+
ImportList[FromModule].try_emplace(GUID, GlobalValueSummary::Definition);
342+
if (Inserted)
343+
return AddDefinitionStatus::Inserted;
344+
if (It->second == GlobalValueSummary::Definition)
345+
return AddDefinitionStatus::NoChange;
346+
It->second = GlobalValueSummary::Definition;
347+
return AddDefinitionStatus::ChangedToDefinition;
348+
}
349+
350+
void FunctionImporter::maybeAddDeclaration(ImportMapTy &ImportList,
351+
StringRef FromModule,
352+
GlobalValue::GUID GUID) {
353+
ImportList[FromModule].try_emplace(GUID, GlobalValueSummary::Declaration);
354+
}
355+
337356
/// Import globals referenced by a function or other globals that are being
338357
/// imported, if importing such global is possible.
339358
class GlobalsImporter final {
@@ -392,17 +411,13 @@ class GlobalsImporter final {
392411

393412
// If there isn't an entry for GUID, insert <GUID, Definition> pair.
394413
// Otherwise, definition should take precedence over declaration.
395-
auto [Iter, Inserted] =
396-
ImportList[RefSummary->modulePath()].try_emplace(
397-
VI.getGUID(), GlobalValueSummary::Definition);
414+
if (FunctionImporter::addDefinition(
415+
ImportList, RefSummary->modulePath(), VI.getGUID()) !=
416+
FunctionImporter::AddDefinitionStatus::Inserted)
417+
break;
418+
398419
// Only update stat and exports if we haven't already imported this
399420
// variable.
400-
if (!Inserted) {
401-
// Set the value to 'std::min(existing-value, new-value)' to make
402-
// sure a definition takes precedence over a declaration.
403-
Iter->second = std::min(GlobalValueSummary::Definition, Iter->second);
404-
break;
405-
}
406421
NumImportedGlobalVarsThinLink++;
407422
// Any references made by this variable will be marked exported
408423
// later, in ComputeCrossModuleImport, after import decisions are
@@ -882,13 +897,10 @@ static void computeImportForFunction(
882897
if (ImportDeclaration && SummaryForDeclImport) {
883898
StringRef DeclSourceModule = SummaryForDeclImport->modulePath();
884899

885-
// Since definition takes precedence over declaration for the same VI,
886-
// try emplace <VI, declaration> pair without checking insert result.
887-
// If insert doesn't happen, there must be an existing entry keyed by
888-
// VI. Note `ExportLists` only keeps track of exports due to imported
900+
// Note `ExportLists` only keeps track of exports due to imported
889901
// definitions.
890-
ImportList[DeclSourceModule].try_emplace(
891-
VI.getGUID(), GlobalValueSummary::Declaration);
902+
FunctionImporter::maybeAddDeclaration(ImportList, DeclSourceModule,
903+
VI.getGUID());
892904
}
893905
// Update with new larger threshold if this was a retry (otherwise
894906
// we would have already inserted with NewThreshold above). Also
@@ -937,22 +949,16 @@ static void computeImportForFunction(
937949

938950
// Try emplace the definition entry, and update stats based on insertion
939951
// status.
940-
auto [Iter, Inserted] = ImportList[ExportModulePath].try_emplace(
941-
VI.getGUID(), GlobalValueSummary::Definition);
942-
943-
// We previously decided to import this GUID definition if it was already
944-
// inserted in the set of imports from the exporting module.
945-
if (Inserted || Iter->second == GlobalValueSummary::Declaration) {
952+
if (FunctionImporter::addDefinition(ImportList, ExportModulePath,
953+
VI.getGUID()) !=
954+
FunctionImporter::AddDefinitionStatus::NoChange) {
946955
NumImportedFunctionsThinLink++;
947956
if (IsHotCallsite)
948957
NumImportedHotFunctionsThinLink++;
949958
if (IsCriticalCallsite)
950959
NumImportedCriticalFunctionsThinLink++;
951960
}
952961

953-
if (Iter->second == GlobalValueSummary::Declaration)
954-
Iter->second = GlobalValueSummary::Definition;
955-
956962
// Any calls/references made by this function will be marked exported
957963
// later, in ComputeCrossModuleImport, after import decisions are
958964
// complete, which is more efficient than adding them here.
@@ -1300,13 +1306,8 @@ static void ComputeCrossModuleImportForModuleFromIndexForTest(
13001306
if (Summary->modulePath() == ModulePath)
13011307
continue;
13021308
// Add an entry to provoke importing by thinBackend.
1303-
auto [Iter, Inserted] = ImportList[Summary->modulePath()].try_emplace(
1304-
GUID, Summary->importType());
1305-
if (!Inserted) {
1306-
// Use 'std::min' to make sure definition (with enum value 0) takes
1307-
// precedence over declaration (with enum value 1).
1308-
Iter->second = std::min(Iter->second, Summary->importType());
1309-
}
1309+
FunctionImporter::addGUID(ImportList, Summary->modulePath(), GUID,
1310+
Summary->importType());
13101311
}
13111312
#ifndef NDEBUG
13121313
dumpImportListForModule(Index, ModulePath, ImportList);

llvm/tools/llvm-link/llvm-link.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,9 @@ static bool importFunctions(const char *argv0, Module &DestModule) {
381381
// definition, so make the import type definition directly.
382382
// FIXME: A follow-up patch should add test coverage for import declaration
383383
// in `llvm-link` CLI (e.g., by introducing a new command line option).
384-
auto &Entry =
385-
ImportList[FileNameStringCache.insert(FileName).first->getKey()];
386-
Entry[F->getGUID()] = GlobalValueSummary::Definition;
384+
FunctionImporter::addDefinition(
385+
ImportList, FileNameStringCache.insert(FileName).first->getKey(),
386+
F->getGUID());
387387
}
388388
auto CachedModuleLoader = [&](StringRef Identifier) {
389389
return ModuleLoaderCache.takeModule(std::string(Identifier));

0 commit comments

Comments
 (0)