[llvm] [LTO] Introduce a new class ImportIDTable (PR #106503)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 29 09:10:01 PDT 2024
================
@@ -96,6 +97,76 @@ class FunctionImporter {
std::tuple<unsigned, const GlobalValueSummary *,
std::unique_ptr<ImportFailureInfo>>>;
+ // Issues import IDs. Each ID uniquely corresponds to a tuple of
+ // (FromModule, GUID, Definition/Declaration).
+ //
+ // The import IDs make the import list space efficient by referring to each
+ // import with a 32-bit integer ID while maintaining a central table that maps
+ // those integer IDs to tuples of (FromModule, GUID, Def/Decl).
+ //
+ // In one large application, a pair of (FromModule, GUID) is mentioned in
+ // import lists more than 50 times on average across all destination modules.
+ // Mentioning the 32-byte tuple:
+ //
+ // std::tuple<StringRef, GlobalValue::GUID, GlobalValueSummary::ImportKind>
+ //
+ // 50 times by value in various import lists would be costly. We can reduce
+ // the memory footprint of import lists by placing one copy in a central table
+ // and referring to it with 32-bit integer IDs.
+ //
+ // To save space within the central table, we only store pairs of
+ // (FromModule, GUID) in the central table. In the actual 32-bit integer ID,
+ // the top 31 bits index into the central table while the bottom 1 bit
+ // indicates whether an ID is for GlobalValueSummary::Declaration or
+ // GlobalValueSummary::Definition.
+ class ImportIDTable {
+ public:
+ using ImportIDTy = uint32_t;
+
+ // Create a pair of import IDs [Def, Decl] for a given pair of FromModule
----------------
kazutakahirata wrote:
Yes, we need both. `addDefinition` will look like:
```
auto [Def, Decl] = ImportIDs.createImportIDs(FromModule, GUID);
if (ImportSet.insert(Def).second)
// Remove Decl in case it's there. Note that a definition takes
// precedence over a declaration for a given GUID.
return ImportSet.erase(Decl) ? AddDefinitionStatus::ChangedToDefinition
: AddDefinitionStatus::Inserted;
return AddDefinitionStatus::NoChange;
```
`maybeAddDeclaration` will look like:
```
auto [Def, Decl] = ImportIDs.createImportIDs(FromModule, GUID);
// Insert Decl only if Def is not present.
if (!ImportSet.contains(Def))
ImportSet.insert(Decl);
```
We could avoid the double interactions with `ImportSet` (`insert` followed by `erase` or `contains` followed by `insert`) by computing a hash on the top 31 bits and upgrade an existing declaration to definition in place without the second lookup, but that would be more work.
https://github.com/llvm/llvm-project/pull/106503
More information about the llvm-commits
mailing list