Skip to content

[LTO] Sort DefinedGlobals in LTO cache key#210025

Merged
nikic merged 3 commits into
llvm:mainfrom
nikic:lto-cache-key-order
Jul 17, 2026
Merged

[LTO] Sort DefinedGlobals in LTO cache key#210025
nikic merged 3 commits into
llvm:mainfrom
nikic:lto-cache-key-order

Conversation

@nikic

@nikic nikic commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Sort the DefindeGlobals by GUID when computing the LTO cache key, to avoid making the cache key dependent on the insertion order. This fixes large compile-time regressions in rust incremental builds.

Alternatively one could make collectDefinedGVSummariesPerModule() work on the sortedRange(), but as that is also used in other places, it probably makes sense to sort locally.

The issue was introduced in 760bb06.

Sort the DefindeGlobals by GUID when computing the LTO cache key,
to avoid making the cache key dependent on the insertion order.
This fixes large compile-time regressions in rust incremental builds.

Alternatively one could make collectDefinedGVSummariesPerModule()
work on the sortedRange(), but as that is also used in other places,
it probably makes sense to sort locally.

The issue was introduced in 760bb06.
@llvmorg-github-actions llvmorg-github-actions Bot added the LTO Link time optimization (regular/full LTO or ThinLTO) label Jul 16, 2026
@nikic nikic mentioned this pull request Jul 16, 2026
9 tasks
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-lto

Author: Nikita Popov (nikic)

Changes

Sort the DefindeGlobals by GUID when computing the LTO cache key, to avoid making the cache key dependent on the insertion order. This fixes large compile-time regressions in rust incremental builds.

Alternatively one could make collectDefinedGVSummariesPerModule() work on the sortedRange(), but as that is also used in other places, it probably makes sense to sort locally.

The issue was introduced in 760bb06.


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

1 Files Affected:

  • (modified) llvm/lib/LTO/LTO.cpp (+4-1)
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index b0fd1d77a2d66..4863ab2973948 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -306,7 +306,10 @@ std::string llvm::computeLTOCacheKey(
 
   // Include the hash for the linkage type to reflect internalization and weak
   // resolution, and collect any used type identifier resolutions.
-  for (auto &GS : DefinedGlobals) {
+  SmallVector<std::pair<GlobalValue::GUID, GlobalValueSummary *>>
+      SortedDefinedGlobals(DefinedGlobals.begin(), DefinedGlobals.end());
+  llvm::sort(SortedDefinedGlobals, llvm::less_first());
+  for (auto &GS : SortedDefinedGlobals) {
     GlobalValue::LinkageTypes Linkage = GS.second->linkage();
     Hasher.update(
         ArrayRef<uint8_t>((const uint8_t *)&Linkage, sizeof(Linkage)));

@nocchijiang nocchijiang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we add a regression test for this? Otherwise LGTM. The failed Linux check looks unrelated.

@nikic

nikic commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

I added a test that fails before the change and passes after. It's not quite representative of what happens in Rust (which does not use linkonce_odr), but demonstrates the general issue at least.

Comment thread llvm/lib/LTO/LTO.cpp
// Include the hash for the linkage type to reflect internalization and weak
// resolution, and collect any used type identifier resolutions.
for (auto &GS : DefinedGlobals) {
SmallVector<std::pair<GlobalValue::GUID, GlobalValueSummary *>>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add a comment above this about why it is needed.

@nikic
nikic enabled auto-merge (squash) July 17, 2026 07:16
@nikic
nikic merged commit 90e31c4 into llvm:main Jul 17, 2026
10 of 11 checks passed
@nikic
nikic deleted the lto-cache-key-order branch July 17, 2026 07:51
@nikic nikic added this to the LLVM 23.x Release milestone Jul 17, 2026
@nikic

nikic commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

/cherry-pick 90e31c4

@llvmbot

llvmbot commented Jul 17, 2026

Copy link
Copy Markdown
Member

/pull-request #210274

dyung pushed a commit to llvmbot/llvm-project that referenced this pull request Jul 17, 2026
Sort the DefindeGlobals by GUID when computing the LTO cache key, to
avoid making the cache key dependent on the insertion order. This fixes
large compile-time regressions in rust incremental builds.

Alternatively one could make collectDefinedGVSummariesPerModule() work
on the sortedRange(), but as that is also used in other places, it
probably makes sense to sort locally.

The issue was introduced in 760bb06.

(cherry picked from commit 90e31c4)
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jul 24, 2026
Update to LLVM 23



Changes in this PR (apart from the LLVM update):
 * Updated cov-map tests due to minor ordering changes introduced in llvm/llvm-project@5931034. The affected tests are limited to LLVM >= 23 now.
 * Set `LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN=OFF`, which restores the previous unversioned naming of the LLVM dylib on Darwin. I expect we'll want to change this for consistency with Linux, but given the amount of trouble Darwin dylibs have caused in the past, I'm not trying to do it in this PR.
 * Distribute the llvm-project/libc subproject, which is now a build dependency of LLVM.
 * Pull in f128 Windows ABI changes from #158778. These need to land in sync with the LLVM update (as ABI of libcalls is controlled by LLVM, not our ABI lowering).
 * Disable RISCV backend on dist-i686-mingw, because the build OOMs on a large generated file. This is a temporary measure until host tools are removed by rust-lang/compiler-team#1020.
 * The llvm-project fork includes a new downstream patch for mingw: rust-lang/llvm-project@b89cd8e It works around mingw having broken TLS prior to GCC 16. (We're currently on GCC 14.)

Issues:
* [x] llvm/llvm-project#209512
* [x] llvm/llvm-project#209714
* [x] llvm/llvm-project#209718
* [x] rust-lang/stdarch#2190 (synced in #159517)
* [x] llvm/llvm-project#210025
* [x] #159391
* [x] EnzymeAD/Enzyme#2951
* [x] #159301
* [x] llvm/llvm-project#210300
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jul 24, 2026
Update to LLVM 23



Changes in this PR (apart from the LLVM update):
 * Updated cov-map tests due to minor ordering changes introduced in llvm/llvm-project@5931034. The affected tests are limited to LLVM >= 23 now.
 * Set `LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN=OFF`, which restores the previous unversioned naming of the LLVM dylib on Darwin. I expect we'll want to change this for consistency with Linux, but given the amount of trouble Darwin dylibs have caused in the past, I'm not trying to do it in this PR.
 * Distribute the llvm-project/libc subproject, which is now a build dependency of LLVM.
 * Pull in f128 Windows ABI changes from #158778. These need to land in sync with the LLVM update (as ABI of libcalls is controlled by LLVM, not our ABI lowering).
 * Disable RISCV backend on dist-i686-mingw, because the build OOMs on a large generated file. This is a temporary measure until host tools are removed by rust-lang/compiler-team#1020.
 * The llvm-project fork includes a new downstream patch for mingw: rust-lang/llvm-project@b89cd8e It works around mingw having broken TLS prior to GCC 16. (We're currently on GCC 14.)

Issues:
* [x] llvm/llvm-project#209512
* [x] llvm/llvm-project#209714
* [x] llvm/llvm-project#209718
* [x] rust-lang/stdarch#2190 (synced in #159517)
* [x] llvm/llvm-project#210025
* [x] #159391
* [x] EnzymeAD/Enzyme#2951
* [x] #159301
* [x] llvm/llvm-project#210300
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jul 25, 2026
Update to LLVM 23



Changes in this PR (apart from the LLVM update):
 * Updated cov-map tests due to minor ordering changes introduced in llvm/llvm-project@5931034. The affected tests are limited to LLVM >= 23 now.
 * Set `LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN=OFF`, which restores the previous unversioned naming of the LLVM dylib on Darwin. I expect we'll want to change this for consistency with Linux, but given the amount of trouble Darwin dylibs have caused in the past, I'm not trying to do it in this PR.
 * Distribute the llvm-project/libc subproject, which is now a build dependency of LLVM.
 * Pull in f128 Windows ABI changes from #158778. These need to land in sync with the LLVM update (as ABI of libcalls is controlled by LLVM, not our ABI lowering).
 * Disable RISCV backend on dist-i686-mingw, because the build OOMs on a large generated file. This is a temporary measure until host tools are removed by rust-lang/compiler-team#1020.
 * The llvm-project fork includes a new downstream patch for mingw: rust-lang/llvm-project@b89cd8e It works around mingw having broken TLS prior to GCC 16. (We're currently on GCC 14.)

Issues:
* [x] llvm/llvm-project#209512
* [x] llvm/llvm-project#209714
* [x] llvm/llvm-project#209718
* [x] rust-lang/stdarch#2190 (synced in #159517)
* [x] llvm/llvm-project#210025
* [x] #159391
* [x] EnzymeAD/Enzyme#2951
* [x] #159301
* [x] llvm/llvm-project#210300
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jul 25, 2026
Update to LLVM 23



Changes in this PR (apart from the LLVM update):
 * Updated cov-map tests due to minor ordering changes introduced in llvm/llvm-project@5931034. The affected tests are limited to LLVM >= 23 now.
 * Set `LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN=OFF`, which restores the previous unversioned naming of the LLVM dylib on Darwin. I expect we'll want to change this for consistency with Linux, but given the amount of trouble Darwin dylibs have caused in the past, I'm not trying to do it in this PR.
 * Distribute the llvm-project/libc subproject, which is now a build dependency of LLVM.
 * Pull in f128 Windows ABI changes from #158778. These need to land in sync with the LLVM update (as ABI of libcalls is controlled by LLVM, not our ABI lowering).
 * Disable RISCV backend on dist-i686-mingw, because the build OOMs on a large generated file. This is a temporary measure until host tools are removed by rust-lang/compiler-team#1020.
 * The llvm-project fork includes a new downstream patch for mingw: rust-lang/llvm-project@b89cd8e It works around mingw having broken TLS prior to GCC 16. (We're currently on GCC 14.)

Issues:
* [x] llvm/llvm-project#209512
* [x] llvm/llvm-project#209714
* [x] llvm/llvm-project#209718
* [x] rust-lang/stdarch#2190 (synced in #159517)
* [x] llvm/llvm-project#210025
* [x] #159391
* [x] EnzymeAD/Enzyme#2951
* [x] #159301
* [x] llvm/llvm-project#210300
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Jul 25, 2026
Update to LLVM 23



Changes in this PR (apart from the LLVM update):
 * Updated cov-map tests due to minor ordering changes introduced in llvm/llvm-project@5931034. The affected tests are limited to LLVM >= 23 now.
 * Set `LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN=OFF`, which restores the previous unversioned naming of the LLVM dylib on Darwin. I expect we'll want to change this for consistency with Linux, but given the amount of trouble Darwin dylibs have caused in the past, I'm not trying to do it in this PR.
 * Distribute the llvm-project/libc subproject, which is now a build dependency of LLVM.
 * Pull in f128 Windows ABI changes from #158778. These need to land in sync with the LLVM update (as ABI of libcalls is controlled by LLVM, not our ABI lowering).
 * Disable RISCV backend on dist-i686-mingw, because the build OOMs on a large generated file. This is a temporary measure until host tools are removed by rust-lang/compiler-team#1020.
 * The llvm-project fork includes a new downstream patch for mingw: rust-lang/llvm-project@b89cd8e It works around mingw having broken TLS prior to GCC 16. (We're currently on GCC 14.)

Issues:
* [x] llvm/llvm-project#209512
* [x] llvm/llvm-project#209714
* [x] llvm/llvm-project#209718
* [x] rust-lang/stdarch#2190 (synced in #159517)
* [x] llvm/llvm-project#210025
* [x] #159391
* [x] EnzymeAD/Enzyme#2951
* [x] #159301
* [x] llvm/llvm-project#210300
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LTO Link time optimization (regular/full LTO or ThinLTO)

Projects

Development

Successfully merging this pull request may close these issues.

4 participants