aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorMingming Liu <mingmingl@google.com>2024-06-20 10:50:31 -0700
committerGitHub <noreply@github.com>2024-06-20 10:50:31 -0700
commit8d9db947b725fefbb02905c5d6be05e09a306f6b (patch)
treea2c0874a18e3391bb1b319029860cb99b2a2d986 /llvm/lib/LTO/LTO.cpp
parent836703087d761f9cbf81b6f9593bc5313660f559 (diff)
downloadllvm-8d9db947b725fefbb02905c5d6be05e09a306f6b.zip
llvm-8d9db947b725fefbb02905c5d6be05e09a306f6b.tar.gz
llvm-8d9db947b725fefbb02905c5d6be05e09a306f6b.tar.bz2
Reland "[ThinLTO] Populate declaration import status except for distributed ThinLTO under a default-off new option" (#95482)
Make `FunctionsToImportTy` an `unordered_map` rather than `DenseMap`. Credit goes to jvoung@ for the 'DenseMap -> unordered_map' change. This is a reland of https://github.com/llvm/llvm-project/pull/92718 * `DenseMap` allocates space for a large number of key/value pairs and wastes space when the number of elements are small. * While init bucket size is zero [1], it quickly allocates buckets for 64 elements [2] when the number of elements is small (for example, 3 or 4 elements). The programmer manual [3] also mentions it could waste space. * Experiments show `FunctionsToImportTy.size()` is smaller than 4 for multiple binaries with high indexing ram usage. `unordered_map` grows factor is at most 2 in llvm libc [4] for insert operations. With this change, `ComputeCrossModuleImport` ram increase is smaller than 0.5G on a couple of binaries with high indexing ram usage. A wider range of (pre-release) tests pass. [1] https://github.com/llvm/llvm-project/blob/ad79a14c9e5ec4a369eed4adf567c22cc029863f/llvm/include/llvm/ADT/DenseMap.h#L431-L432 [2] https://github.com/llvm/llvm-project/blob/ad79a14c9e5ec4a369eed4adf567c22cc029863f/llvm/include/llvm/ADT/DenseMap.h#L849 [3] https://llvm.org/docs/ProgrammersManual.html#llvm-adt-densemap-h [4] https://github.com/llvm/llvm-project/blob/ad79a14c9e5ec4a369eed4adf567c22cc029863f/libcxx/include/__hash_table#L1525-L1526 **Original commit message** The goal is to populate `declaration` import status if a new flag `-import-declaration` is on. * For in-process ThinLTO, the `declaration` status is visible to backend `function-import` pass, so `FunctionImporter::importFunctions` should read the import status and be no-op for declaration summaries. Basically, the postlink pipeline is updated to keep its current behavior (import definitions), but not updated to handle `declaration` summaries. Two use cases ([better call-graph sort](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) or [cross-module auto-init](https://github.com/llvm/llvm-project/pull/87597#discussion_r1556067195)) would use this bit differently. * For distributed ThinLTO, the `declaration` status is not serialized to bitcode. As discussed, https://github.com/llvm/llvm-project/pull/87600 will do this.
Diffstat (limited to 'llvm/lib/LTO/LTO.cpp')
-rw-r--r--llvm/lib/LTO/LTO.cpp32
1 files changed, 20 insertions, 12 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 2ba7f58..6bbec53 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -123,6 +123,9 @@ void llvm::computeLTOCacheKey(
support::endian::write64le(Data, I);
Hasher.update(Data);
};
+ auto AddUint8 = [&](const uint8_t I) {
+ Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&I, 1));
+ };
AddString(Conf.CPU);
// FIXME: Hash more of Options. For now all clients initialize Options from
// command-line flags (which is unsupported in production), but may set
@@ -158,18 +161,18 @@ void llvm::computeLTOCacheKey(
auto ModHash = Index.getModuleHash(ModuleID);
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
- std::vector<uint64_t> ExportsGUID;
+ std::vector<std::pair<uint64_t, uint8_t>> ExportsGUID;
ExportsGUID.reserve(ExportList.size());
- for (const auto &VI : ExportList) {
- auto GUID = VI.getGUID();
- ExportsGUID.push_back(GUID);
- }
+ for (const auto &[VI, ExportType] : ExportList)
+ ExportsGUID.push_back(
+ std::make_pair(VI.getGUID(), static_cast<uint8_t>(ExportType)));
// Sort the export list elements GUIDs.
llvm::sort(ExportsGUID);
- for (uint64_t GUID : ExportsGUID) {
+ for (auto [GUID, ExportType] : ExportsGUID) {
// The export list can impact the internalization, be conservative here
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
@@ -201,7 +204,7 @@ void llvm::computeLTOCacheKey(
[](const ImportModule &Lhs, const ImportModule &Rhs) -> bool {
return Lhs.getHash() < Rhs.getHash();
});
- std::vector<uint64_t> ImportedGUIDs;
+ std::vector<std::pair<uint64_t, uint8_t>> ImportedGUIDs;
for (const ImportModule &Entry : ImportModulesVector) {
auto ModHash = Entry.getHash();
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
@@ -209,11 +212,13 @@ void llvm::computeLTOCacheKey(
AddUint64(Entry.getFunctions().size());
ImportedGUIDs.clear();
- for (auto &Fn : Entry.getFunctions())
- ImportedGUIDs.push_back(Fn);
+ for (auto &[Fn, ImportType] : Entry.getFunctions())
+ ImportedGUIDs.push_back(std::make_pair(Fn, ImportType));
llvm::sort(ImportedGUIDs);
- for (auto &GUID : ImportedGUIDs)
+ for (auto &[GUID, Type] : ImportedGUIDs) {
AddUint64(GUID);
+ AddUint8(Type);
+ }
}
// Include the hash for the resolved ODR.
@@ -283,9 +288,9 @@ void llvm::computeLTOCacheKey(
// Imported functions may introduce new uses of type identifier resolutions,
// so we need to collect their used resolutions as well.
for (const ImportModule &ImpM : ImportModulesVector)
- for (auto &ImpF : ImpM.getFunctions()) {
+ for (auto &[GUID, UnusedImportType] : ImpM.getFunctions()) {
GlobalValueSummary *S =
- Index.findSummaryInModule(ImpF, ImpM.getIdentifier());
+ Index.findSummaryInModule(GUID, ImpM.getIdentifier());
AddUsedThings(S);
// If this is an alias, we also care about any types/etc. that the aliasee
// may reference.
@@ -1397,6 +1402,7 @@ public:
llvm::StringRef ModulePath,
const std::string &NewModulePath) {
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
+
std::error_code EC;
gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
ImportList, ModuleToSummariesForIndex);
@@ -1405,6 +1411,8 @@ public:
sys::fs::OpenFlags::OF_None);
if (EC)
return errorCodeToError(EC);
+
+ // TODO: Serialize declaration bits to bitcode.
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex);
if (ShouldEmitImportsFiles) {