Skip to content

Commit

Permalink
[ThinLTO] Track definitions only in export-set
Browse files Browse the repository at this point in the history
  • Loading branch information
minglotus-6 committed Jul 1, 2024
1 parent 9b94056 commit 7a276ba
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 37 deletions.
10 changes: 3 additions & 7 deletions llvm/include/llvm/Transforms/IPO/FunctionImport.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,9 @@ class FunctionImporter {
/// index's module path string table).
using ImportMapTy = DenseMap<StringRef, FunctionsToImportTy>;

/// The map contains an entry for every global value the module exports.
/// The key is ValueInfo, and the value indicates whether the definition
/// or declaration is visible to another module. If a function's definition is
/// visible to other modules, the global values this function referenced are
/// visible and shouldn't be internalized.
/// TODO: Rename to `ExportMapTy`.
using ExportSetTy = DenseMap<ValueInfo, GlobalValueSummary::ImportKind>;
/// The set contains an entry for every global value the module exports as
// a definition.
using ExportSetTy = DenseSet<ValueInfo>;

/// A function of this type is used to load modules referenced by the index.
using ModuleLoaderTy =
Expand Down
12 changes: 4 additions & 8 deletions llvm/lib/LTO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,15 @@ void llvm::computeLTOCacheKey(
auto ModHash = Index.getModuleHash(ModuleID);
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));

std::vector<std::pair<uint64_t, uint8_t>> ExportsGUID;
std::vector<uint64_t> ExportsGUID;
ExportsGUID.reserve(ExportList.size());
for (const auto &[VI, ExportType] : ExportList)
ExportsGUID.push_back(
std::make_pair(VI.getGUID(), static_cast<uint8_t>(ExportType)));
for (const auto &VI : ExportList)
ExportsGUID.push_back(VI.getGUID());

// Sort the export list elements GUIDs.
llvm::sort(ExportsGUID);
for (auto [GUID, ExportType] : ExportsGUID) {
// The export list can impact the internalization, be conservative here
for (auto GUID : ExportsGUID)
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&GUID, sizeof(GUID)));
AddUint8(ExportType);
}

// Include the hash for every module we import functions from. The set of
// imported symbols for each module may affect code generation and is
Expand Down
53 changes: 31 additions & 22 deletions llvm/lib/Transforms/IPO/FunctionImport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,7 @@ class GlobalsImporter final {
// later, in ComputeCrossModuleImport, after import decisions are
// complete, which is more efficient than adding them here.
if (ExportLists)
(*ExportLists)[RefSummary->modulePath()][VI] =
GlobalValueSummary::Definition;
(*ExportLists)[RefSummary->modulePath()].insert(VI);

// If variable is not writeonly we attempt to recursively analyze
// its references in order to import referenced constants.
Expand Down Expand Up @@ -582,7 +581,7 @@ class WorkloadImportsManager : public ModuleImportsManager {
GlobalValueSummary::Definition;
GVI.onImportingSummary(*GVS);
if (ExportLists)
(*ExportLists)[ExportingModule][VI] = GlobalValueSummary::Definition;
(*ExportLists)[ExportingModule].insert(VI);
}
LLVM_DEBUG(dbgs() << "[Workload] Done\n");
}
Expand Down Expand Up @@ -819,9 +818,6 @@ static void computeImportForFunction(
// try emplace <VI, declaration> pair without checking insert result.
// If insert doesn't happen, there must be an existing entry keyed by
// VI.
if (ExportLists)
(*ExportLists)[DeclSourceModule].try_emplace(
VI, GlobalValueSummary::Declaration);
ImportList[DeclSourceModule].try_emplace(
VI.getGUID(), GlobalValueSummary::Declaration);
}
Expand Down Expand Up @@ -892,7 +888,7 @@ static void computeImportForFunction(
// later, in ComputeCrossModuleImport, after import decisions are
// complete, which is more efficient than adding them here.
if (ExportLists)
(*ExportLists)[ExportModulePath][VI] = GlobalValueSummary::Definition;
(*ExportLists)[ExportModulePath].insert(VI);
}

auto GetAdjustedThreshold = [](unsigned Threshold, bool IsHotCallsite) {
Expand Down Expand Up @@ -998,10 +994,27 @@ static bool isGlobalVarSummary(const ModuleSummaryIndex &Index,
return false;
}

template <class T>
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont,
unsigned &DefinedGVS,
unsigned &DefinedFS) {
static unsigned
numGlobalVarSummariesInSet(const ModuleSummaryIndex &Index,
FunctionImporter::ExportSetTy &ExportSet,
unsigned &DefinedGVS, unsigned &DefinedFS) {
unsigned NumGVS = 0;
DefinedGVS = 0;
DefinedFS = 0;
for (auto &VI : ExportSet) {
if (isGlobalVarSummary(Index, VI.getGUID())) {
++DefinedGVS;
++NumGVS;
} else
++DefinedFS;
}
return NumGVS;
}

static unsigned
numGlobalVarSummaries(const ModuleSummaryIndex &Index,
FunctionImporter::FunctionsToImportTy &Cont,
unsigned &DefinedGVS, unsigned &DefinedFS) {
unsigned NumGVS = 0;
DefinedGVS = 0;
DefinedFS = 0;
Expand Down Expand Up @@ -1046,7 +1059,7 @@ static bool checkVariableImport(
};

for (auto &ExportPerModule : ExportLists)
for (auto &[VI, Unused] : ExportPerModule.second)
for (auto &VI : ExportPerModule.second)
if (!FlattenedImports.count(VI.getGUID()) &&
IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
return false;
Expand Down Expand Up @@ -1082,11 +1095,7 @@ void llvm::ComputeCrossModuleImport(
FunctionImporter::ExportSetTy NewExports;
const auto &DefinedGVSummaries =
ModuleToDefinedGVSummaries.lookup(ELI.first);
for (auto &[EI, Type] : ELI.second) {
// If a variable is exported as a declaration, its 'refs' and 'calls' are
// not further exported.
if (Type == GlobalValueSummary::Declaration)
continue;
for (auto &EI : ELI.second) {
// Find the copy defined in the exporting module so that we can mark the
// values it references in that specific definition as exported.
// Below we will add all references and called values, without regard to
Expand All @@ -1108,19 +1117,19 @@ void llvm::ComputeCrossModuleImport(
for (const auto &VI : GVS->refs()) {
// Try to emplace the declaration entry. If a definition entry
// already exists for key `VI`, this is a no-op.
NewExports.try_emplace(VI, GlobalValueSummary::Declaration);
NewExports.insert(VI);
}
} else {
auto *FS = cast<FunctionSummary>(S);
for (const auto &Edge : FS->calls()) {
// Try to emplace the declaration entry. If a definition entry
// already exists for key `VI`, this is a no-op.
NewExports.try_emplace(Edge.first, GlobalValueSummary::Declaration);
NewExports.insert(Edge.first);
}
for (const auto &Ref : FS->refs()) {
// Try to emplace the declaration entry. If a definition entry
// already exists for key `VI`, this is a no-op.
NewExports.try_emplace(Ref, GlobalValueSummary::Declaration);
NewExports.insert(Ref);
}
}
}
Expand All @@ -1129,7 +1138,7 @@ void llvm::ComputeCrossModuleImport(
// the same ref/call target multiple times in above loop, and it is more
// efficient to avoid a set lookup each time.
for (auto EI = NewExports.begin(); EI != NewExports.end();) {
if (!DefinedGVSummaries.count(EI->first.getGUID()))
if (!DefinedGVSummaries.count(EI->getGUID()))
NewExports.erase(EI++);
else
++EI;
Expand All @@ -1146,7 +1155,7 @@ void llvm::ComputeCrossModuleImport(
auto &Exports = ExportLists[ModName];
unsigned DefinedGVS = 0, DefinedFS = 0;
unsigned NumGVS =
numGlobalVarSummaries(Index, Exports, DefinedGVS, DefinedFS);
numGlobalVarSummariesInSet(Index, Exports, DefinedGVS, DefinedFS);
LLVM_DEBUG(dbgs() << "* Module " << ModName << " exports " << DefinedFS
<< " function as definitions, "
<< Exports.size() - NumGVS - DefinedFS
Expand Down

0 comments on commit 7a276ba

Please sign in to comment.