Skip to content

[LTO] Don't make unnecessary copies of ImportIDTable #106998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

kazutakahirata
Copy link
Contributor

Without this patch, {ImportMapTy,SortedImportList}::{begin,end} make
unnecessary copies of ImportIDTable via:

map_iterator(Imports.begin(), IDs);

The second parameter, IDs, is passed by value, so we make a copy of
MapVector inside ImportIDTable every time we call begin and end.
These begin and end show up as time-consuming functions in the
performance profile.

This patch fixes the problem by passing IDs by reference with
std::cref.

While we are at it, this patch deletes the copy constructor and
assignment operator. I cannot think of any legitimate need reason to
make a copy of the deduplication table.

Without this patch, {ImportMapTy,SortedImportList}::{begin,end} make
unnecessary copies of ImportIDTable via:

  map_iterator(Imports.begin(), IDs);

The second parameter, IDs, is passed by value, so we make a copy of
MapVector inside ImportIDTable every time we call begin and end.
These begin and end show up as time-consuming functions in the
performance profile.

This patch fixes the problem by passing IDs by reference with
std::cref.

While we are at it, this patch deletes the copy constructor and
assignment operator.  I cannot think of any legitimate need reason to
make a copy of the deduplication table.
@llvmbot
Copy link
Member

llvmbot commented Sep 2, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Kazu Hirata (kazutakahirata)

Changes

Without this patch, {ImportMapTy,SortedImportList}::{begin,end} make
unnecessary copies of ImportIDTable via:

map_iterator(Imports.begin(), IDs);

The second parameter, IDs, is passed by value, so we make a copy of
MapVector inside ImportIDTable every time we call begin and end.
These begin and end show up as time-consuming functions in the
performance profile.

This patch fixes the problem by passing IDs by reference with
std::cref.

While we are at it, this patch deletes the copy constructor and
assignment operator. I cannot think of any legitimate need reason to
make a copy of the deduplication table.


Full diff: https://github.com/llvm/llvm-project/pull/106998.diff

1 Files Affected:

  • (modified) llvm/include/llvm/Transforms/IPO/FunctionImport.h (+15-6)
diff --git a/llvm/include/llvm/Transforms/IPO/FunctionImport.h b/llvm/include/llvm/Transforms/IPO/FunctionImport.h
index b5b328d96b2737..000bd9273d9116 100644
--- a/llvm/include/llvm/Transforms/IPO/FunctionImport.h
+++ b/llvm/include/llvm/Transforms/IPO/FunctionImport.h
@@ -113,6 +113,13 @@ class FunctionImporter {
   public:
     using ImportIDTy = uint32_t;
 
+    ImportIDTable() = default;
+
+    // Three is something wrong with the application logic if we need to make a
+    // copy of this and potentially make a fork.
+    ImportIDTable(const ImportIDTable &) = delete;
+    ImportIDTable &operator=(const ImportIDTable &) = delete;
+
     // Create a pair of import IDs [Def, Decl] for a given pair of FromModule
     // and GUID.
     std::pair<ImportIDTy, ImportIDTy> createImportIDs(StringRef FromModule,
@@ -218,9 +225,10 @@ class FunctionImporter {
     getImportType(StringRef FromModule, GlobalValue::GUID GUID) const;
 
     // Iterate over the import list.  The caller gets tuples of FromModule,
-    // GUID, and ImportKind instead of import IDs.
-    auto begin() const { return map_iterator(Imports.begin(), IDs); }
-    auto end() const { return map_iterator(Imports.end(), IDs); }
+    // GUID, and ImportKind instead of import IDs.  std::cref below prevents
+    // map_iterator from deep-copying IDs.
+    auto begin() const { return map_iterator(Imports.begin(), std::cref(IDs)); }
+    auto end() const { return map_iterator(Imports.end(), std::cref(IDs)); }
 
     friend class SortedImportList;
 
@@ -251,9 +259,10 @@ class FunctionImporter {
     }
 
     // Iterate over the import list.  The caller gets tuples of FromModule,
-    // GUID, and ImportKind instead of import IDs.
-    auto begin() const { return map_iterator(Imports.begin(), IDs); }
-    auto end() const { return map_iterator(Imports.end(), IDs); }
+    // GUID, and ImportKind instead of import IDs.  std::cref below prevents
+    // map_iterator from deep-copying IDs.
+    auto begin() const { return map_iterator(Imports.begin(), std::cref(IDs)); }
+    auto end() const { return map_iterator(Imports.end(), std::cref(IDs)); }
 
   private:
     const ImportIDTable &IDs;

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable.

@kazutakahirata kazutakahirata merged commit 9a1d14a into llvm:main Sep 3, 2024
8 checks passed
@kazutakahirata kazutakahirata deleted the cleanup_thinlto_ImportIDTable_ref branch September 3, 2024 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants