Skip to content

Conversation

@teresajohnson
Copy link
Contributor

@teresajohnson teresajohnson commented Oct 22, 2025

Add a flag to the GlobalValueSummaryInfo indicating whether the
associated SummaryList (all summaries with the same GUID) contains any
summaries with local linkage. This flag is set when building the index,
so it is associated with the original linkage type before
internalization and promotion. Consumers should check the
withInternalizeAndPromote() flag on the index before using it.

In most cases we expect a 1-1 mapping between a GUID and a summary with
local linkage, because for locals the GUID is computed from the hash of
"modulepath;name". However, there can be multiple locals with the same
GUID if translation units are not compiled with enough path. And in rare
but theoretically possible cases, there can be hash collisions on the
underlying MD5 computation. So to be safe when looking for local
summaries, analyses currently look through all summaries in the list.
These lists can be extremely long in the case of large binaries with
template function defs in widely used headers (i.e. linkonce_odr).

A follow on change will use this flag to reduce ThinLTO analysis time in
WPD by 5-6% for a large target (details in PR164046 which will be
reworked to use this flag).

Note that in the past we have tried to keep bits related to the GUID in
the ValueInfo (which has a pointer to the associated
GlobalValueSummaryInfo), via its PointerIntPair. However, we are out of
bits there. This change does add a byte to every GlobalValueSummaryInfo
instance, which I measured as a little under 0.90% overhead in a large
target. However, it enables adding 7 bits of other per-GUID flags in the
future without adding more overhead. Note that it was lower overhead to
add this to the GlobalValueSummaryInfo than the ValueInfo, which tends
to be copied into other maps.

Add a flag to the GlobalValueSummaryInfo indicating whether the
associated SummaryList (all summaries with the same GUID) contains any
summaries with local linkage. This flag is set when building the index,
so it is associated with the original linkage type before
internalization and promotion. Consumers should check the
withInternalizeAndPromote() flag on the index before using it.

In most cases we expect a 1-1 mapping between a GUID and a summary with
local linkage, because for locals the GUID is computed from the hash of
"modulepath:name". However, there can be multiple locals with the same
GUID if translation units are not compiled with enough path. And in rare
but theoretically possible cases, there can be hash collisions on the
underlying MD5 computation. So to be safe when looking for local
summaries, analyses currently look through all summaries in the list.
These lists can be extremely long in the case of large binaries with
template function defs in widely used headers (i.e. linkonce_odr).

A follow on change will use this flag to reduce ThinLTO analysis time in
WPD by 5-6% for a large target (details in PR164046 which will be
reworked to use this flag).

Note that in the past we have tried to keep bits related to the GUID in
the ValueInfo (which has a pointer to the associated
GlobalValueSummaryInfo), via its PointerIntPair. However, we are out of
bits there. This change does add a byte to every GlobalValueSummaryInfo
instance, which I measured as a little under 0.90% overhead in a large
target. However, it enables adding 7 bits of other per-GUID flags in the
future without adding more overhead. Note that it was lower overhead to
add this to the GlobalValueSummaryInfo than the ValueInfo, which tends
to be copied into other maps.
@llvmbot llvmbot added LTO Link time optimization (regular/full LTO or ThinLTO) llvm:ir labels Oct 22, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 22, 2025

@llvm/pr-subscribers-lto

@llvm/pr-subscribers-llvm-ir

Author: Teresa Johnson (teresajohnson)

Changes

Add a flag to the GlobalValueSummaryInfo indicating whether the
associated SummaryList (all summaries with the same GUID) contains any
summaries with local linkage. This flag is set when building the index,
so it is associated with the original linkage type before
internalization and promotion. Consumers should check the
withInternalizeAndPromote() flag on the index before using it.

In most cases we expect a 1-1 mapping between a GUID and a summary with
local linkage, because for locals the GUID is computed from the hash of
"modulepath:name". However, there can be multiple locals with the same
GUID if translation units are not compiled with enough path. And in rare
but theoretically possible cases, there can be hash collisions on the
underlying MD5 computation. So to be safe when looking for local
summaries, analyses currently look through all summaries in the list.
These lists can be extremely long in the case of large binaries with
template function defs in widely used headers (i.e. linkonce_odr).

A follow on change will use this flag to reduce ThinLTO analysis time in
WPD by 5-6% for a large target (details in PR164046 which will be
reworked to use this flag).

Note that in the past we have tried to keep bits related to the GUID in
the ValueInfo (which has a pointer to the associated
GlobalValueSummaryInfo), via its PointerIntPair. However, we are out of
bits there. This change does add a byte to every GlobalValueSummaryInfo
instance, which I measured as a little under 0.90% overhead in a large
target. However, it enables adding 7 bits of other per-GUID flags in the
future without adding more overhead. Note that it was lower overhead to
add this to the GlobalValueSummaryInfo than the ValueInfo, which tends
to be copied into other maps.


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

2 Files Affected:

  • (modified) llvm/include/llvm/IR/ModuleSummaryIndex.h (+40-4)
  • (modified) llvm/lib/LTO/LTO.cpp (+4)
diff --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index 98df06ae43ad0..fb1f5c3bc0440 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -172,9 +172,11 @@ struct alignas(8) GlobalValueSummaryInfo {
 
   /// Add a summary corresponding to a global value definition in a module with
   /// the corresponding GUID.
-  void addSummary(std::unique_ptr<GlobalValueSummary> Summary) {
-    return SummaryList.push_back(std::move(Summary));
-  }
+  inline void addSummary(std::unique_ptr<GlobalValueSummary> Summary);
+
+  /// Verify that the HasLocal flag is consistent with the SummaryList. Should
+  /// only be called prior to index-based internalization and promotion.
+  inline void verifyLocal() const;
 
 private:
   /// List of global value summary structures for a particular value held
@@ -183,6 +185,22 @@ struct alignas(8) GlobalValueSummaryInfo {
   /// compiling without sufficient distinguishing path, or (theoretically) hash
   /// collisions. Each summary is from a different module.
   GlobalValueSummaryList SummaryList;
+
+  /// True if the SummaryList contains at least one summary with local linkage.
+  /// In most cases there should be only one, unless translation units with
+  /// same-named locals were compiled without distinguishing path. And generally
+  /// there should not be a mix of local and non-local summaries, because the
+  /// GUID for a local is computed with the path prepended and a ':' delimiter.
+  /// In extremely rare cases there could be a GUID hash collision. Having the
+  /// flag saves having to walk through all summaries to prove the existence or
+  /// not of any locals.
+  /// NOTE: this flag is set when the index is built. It does not reflect
+  /// index-based internalization and promotion decisions. Generally most
+  /// index-based analysis occurs before then, but any users should assert that
+  /// the withInternalizeAndPromote() flag is not set on the index.
+  /// TODO: Replace checks in various ThinLTO analyses that loop through all
+  /// summaries to handle the local case with a check of the flag.
+  bool HasLocal : 1;
 };
 
 /// Map from global value GUID to corresponding summary structures. Use a
@@ -219,6 +237,8 @@ struct ValueInfo {
     return getRef()->second.getSummaryList();
   }
 
+  void verifyLocal() const { getRef()->second.verifyLocal(); }
+
   // Even if the index is built with GVs available, we may not have one for
   // summary entries synthesized for profiled indirect call targets.
   bool hasName() const { return !haveGVs() || getValue(); }
@@ -649,7 +669,23 @@ class GlobalValueSummary {
   friend class ModuleSummaryIndex;
 };
 
-GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs) : U(HaveGVs) {}
+GlobalValueSummaryInfo::GlobalValueSummaryInfo(bool HaveGVs)
+    : U(HaveGVs), HasLocal(false) {}
+
+void GlobalValueSummaryInfo::addSummary(
+    std::unique_ptr<GlobalValueSummary> Summary) {
+  if (GlobalValue::isLocalLinkage(Summary->linkage()))
+    HasLocal = true;
+  return SummaryList.push_back(std::move(Summary));
+}
+
+void GlobalValueSummaryInfo::verifyLocal() const {
+  assert(HasLocal ==
+         llvm::any_of(SummaryList,
+                      [](const std::unique_ptr<GlobalValueSummary> &Summary) {
+                        return GlobalValue::isLocalLinkage(Summary->linkage());
+                      }));
+}
 
 /// Alias summary information.
 class AliasSummary : public GlobalValueSummary {
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 72ae064e46a0c..86780e19f22b8 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -477,6 +477,10 @@ static void thinLTOInternalizeAndPromoteGUID(
                        return !GlobalValue::isLocalLinkage(Summary->linkage());
                      });
 
+  // Before performing index-based internalization and promotion for this GUID,
+  // the local flag should be consistent with the summary list linkage types.
+  VI.verifyLocal();
+
   for (auto &S : VI.getSummaryList()) {
     // First see if we need to promote an internal value because it is not
     // exported.

/// In most cases there should be only one, unless translation units with
/// same-named locals were compiled without distinguishing path. And generally
/// there should not be a mix of local and non-local summaries, because the
/// GUID for a local is computed with the path prepended and a ':' delimiter.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// GUID for a local is computed with the path prepended and a ':' delimiter.
/// GUID for a local is computed with the path prepended and a ';' delimiter.

nit pick: PGO name delimiter is semicolon (code); Clang's frontend code coverage still uses ':' (code)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, forgot about that change. I'll update the comment and PR description accordingly

@teresajohnson teresajohnson merged commit 25a915a into llvm:main Oct 22, 2025
10 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 22, 2025

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux running on sanitizer-buildbot1 while building llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/66/builds/21126

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/i386-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:237: warning: Compiler lib dir != compiler-rt lib dir
Compiler libdir:     "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/i386-unknown-linux-gnu"
compiler-rt libdir:  "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 4658 of 10443 tests, 64 workers --
Testing:  0.. 10..
FAIL: ORC-x86_64-linux :: TestCases/Linux/x86-64/priority-static-initializer.S (895 of 4658)
******************** TEST 'ORC-x86_64-linux :: TestCases/Linux/x86-64/priority-static-initializer.S' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -c -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S # RUN: at line 4
+ /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -c -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink -orc-runtime=/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu/liborc_rt.a /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp | FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S # RUN: at line 5
+ FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S
+ /home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink -orc-runtime=/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu/liborc_rt.a /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
#0 0x00005c0158157558 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink+0x2b48558)
#1 0x00005c0158154b55 llvm::sys::RunSignalHandlers() (/home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink+0x2b45b55)
#2 0x00005c0158158321 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x00007b3cd68458d0 (/lib/x86_64-linux-gnu/libc.so.6+0x458d0)
#4 0x00005c0157f552ef llvm::orc::AsynchronousSymbolQuery::handleComplete(llvm::orc::ExecutionSession&)::RunQueryCompleteTask::run() Core.cpp:0:0
#5 0x00005c0158032071 std::thread::_State_impl<std::thread::_Invoker<std::tuple<llvm::orc::DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<llvm::orc::Task, std::default_delete<llvm::orc::Task>>)::$_0>>>::_M_run() TaskDispatch.cpp:0:0
#6 0x00007b3cd6cf2324 (/lib/x86_64-linux-gnu/libstdc++.so.6+0xf2324)
#7 0x00007b3cd68a27f1 (/lib/x86_64-linux-gnu/libc.so.6+0xa27f1)
#8 0x00007b3cd6933b5c (/lib/x86_64-linux-gnu/libc.so.6+0x133b5c)
FileCheck error: '<stdin>' is empty.
FileCheck command line:  FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 

8 warning(s) in tests
Slowest Tests:
--------------------------------------------------------------------------
68.26s: ThreadSanitizer-x86_64 :: deadlock_detector_stress_test.cpp
52.72s: ThreadSanitizer-x86_64 :: restore_stack.cpp
44.88s: ThreadSanitizer-x86_64 :: bench_threads.cpp
43.20s: libFuzzer-i386-default-Linux :: fork.test
42.34s: libFuzzer-i386-static-libcxx-Linux :: fork.test
42.32s: libFuzzer-i386-libcxx-Linux :: fork_corpus_groups.test
41.98s: libFuzzer-i386-default-Linux :: fork_corpus_groups.test
Step 11 (test compiler-rt debug) failure: test compiler-rt debug (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/i386-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:237: warning: Compiler lib dir != compiler-rt lib dir
Compiler libdir:     "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/i386-unknown-linux-gnu"
compiler-rt libdir:  "/home/b/sanitizer-x86_64-linux/build/build_default/lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:248: warning: COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=ON, but this test suite does not support testing the just-built runtime libraries when the test compiler is configured to use different runtime libraries. Either modify this test suite to support this test configuration, or set COMPILER_RT_TEST_STANDALONE_BUILD_LIBS=OFF to test the runtime libraries included in the compiler instead.
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/lit.common.cfg.py:259: note: Testing using libraries in "/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu"
llvm-lit: /home/b/sanitizer-x86_64-linux/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 4658 of 10443 tests, 64 workers --
Testing:  0.. 10..
FAIL: ORC-x86_64-linux :: TestCases/Linux/x86-64/priority-static-initializer.S (895 of 4658)
******************** TEST 'ORC-x86_64-linux :: TestCases/Linux/x86-64/priority-static-initializer.S' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang   -m64  -c -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S # RUN: at line 4
+ /home/b/sanitizer-x86_64-linux/build/build_default/./bin/clang -m64 -c -o /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S
/home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink -orc-runtime=/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu/liborc_rt.a /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp | FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S # RUN: at line 5
+ FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S
+ /home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink -orc-runtime=/home/b/sanitizer-x86_64-linux/build/build_default/./lib/../lib/clang/22/lib/x86_64-unknown-linux-gnu/liborc_rt.a /home/b/sanitizer-x86_64-linux/build/build_default/runtimes/runtimes-bins/compiler-rt/test/orc/X86_64LinuxConfig/TestCases/Linux/x86-64/Output/priority-static-initializer.S.tmp
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
#0 0x00005c0158157558 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink+0x2b48558)
#1 0x00005c0158154b55 llvm::sys::RunSignalHandlers() (/home/b/sanitizer-x86_64-linux/build/build_default/./bin/llvm-jitlink+0x2b45b55)
#2 0x00005c0158158321 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x00007b3cd68458d0 (/lib/x86_64-linux-gnu/libc.so.6+0x458d0)
#4 0x00005c0157f552ef llvm::orc::AsynchronousSymbolQuery::handleComplete(llvm::orc::ExecutionSession&)::RunQueryCompleteTask::run() Core.cpp:0:0
#5 0x00005c0158032071 std::thread::_State_impl<std::thread::_Invoker<std::tuple<llvm::orc::DynamicThreadPoolTaskDispatcher::dispatch(std::unique_ptr<llvm::orc::Task, std::default_delete<llvm::orc::Task>>)::$_0>>>::_M_run() TaskDispatch.cpp:0:0
#6 0x00007b3cd6cf2324 (/lib/x86_64-linux-gnu/libstdc++.so.6+0xf2324)
#7 0x00007b3cd68a27f1 (/lib/x86_64-linux-gnu/libc.so.6+0xa27f1)
#8 0x00007b3cd6933b5c (/lib/x86_64-linux-gnu/libc.so.6+0x133b5c)
FileCheck error: '<stdin>' is empty.
FileCheck command line:  FileCheck /home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/test/orc/TestCases/Linux/x86-64/priority-static-initializer.S

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..

8 warning(s) in tests
Slowest Tests:
--------------------------------------------------------------------------
68.26s: ThreadSanitizer-x86_64 :: deadlock_detector_stress_test.cpp
52.72s: ThreadSanitizer-x86_64 :: restore_stack.cpp
44.88s: ThreadSanitizer-x86_64 :: bench_threads.cpp
43.20s: libFuzzer-i386-default-Linux :: fork.test
42.34s: libFuzzer-i386-static-libcxx-Linux :: fork.test
42.32s: libFuzzer-i386-libcxx-Linux :: fork_corpus_groups.test
41.98s: libFuzzer-i386-default-Linux :: fork_corpus_groups.test

dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
Add a flag to the GlobalValueSummaryInfo indicating whether the
associated SummaryList (all summaries with the same GUID) contains any
summaries with local linkage. This flag is set when building the index,
so it is associated with the original linkage type before
internalization and promotion. Consumers should check the
withInternalizeAndPromote() flag on the index before using it.

In most cases we expect a 1-1 mapping between a GUID and a summary with
local linkage, because for locals the GUID is computed from the hash of
"modulepath;name". However, there can be multiple locals with the same
GUID if translation units are not compiled with enough path. And in rare
but theoretically possible cases, there can be hash collisions on the
underlying MD5 computation. So to be safe when looking for local
summaries, analyses currently look through all summaries in the list.
These lists can be extremely long in the case of large binaries with
template function defs in widely used headers (i.e. linkonce_odr).

A follow on change will use this flag to reduce ThinLTO analysis time in
WPD by 5-6% for a large target (details in PR164046 which will be
reworked to use this flag).

Note that in the past we have tried to keep bits related to the GUID in
the ValueInfo (which has a pointer to the associated
GlobalValueSummaryInfo), via its PointerIntPair. However, we are out of
bits there. This change does add a byte to every GlobalValueSummaryInfo
instance, which I measured as a little under 0.90% overhead in a large
target. However, it enables adding 7 bits of other per-GUID flags in the
future without adding more overhead. Note that it was lower overhead to
add this to the GlobalValueSummaryInfo than the ValueInfo, which tends
to be copied into other maps.
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
Add a flag to the GlobalValueSummaryInfo indicating whether the
associated SummaryList (all summaries with the same GUID) contains any
summaries with local linkage. This flag is set when building the index,
so it is associated with the original linkage type before
internalization and promotion. Consumers should check the
withInternalizeAndPromote() flag on the index before using it.

In most cases we expect a 1-1 mapping between a GUID and a summary with
local linkage, because for locals the GUID is computed from the hash of
"modulepath;name". However, there can be multiple locals with the same
GUID if translation units are not compiled with enough path. And in rare
but theoretically possible cases, there can be hash collisions on the
underlying MD5 computation. So to be safe when looking for local
summaries, analyses currently look through all summaries in the list.
These lists can be extremely long in the case of large binaries with
template function defs in widely used headers (i.e. linkonce_odr).

A follow on change will use this flag to reduce ThinLTO analysis time in
WPD by 5-6% for a large target (details in PR164046 which will be
reworked to use this flag).

Note that in the past we have tried to keep bits related to the GUID in
the ValueInfo (which has a pointer to the associated
GlobalValueSummaryInfo), via its PointerIntPair. However, we are out of
bits there. This change does add a byte to every GlobalValueSummaryInfo
instance, which I measured as a little under 0.90% overhead in a large
target. However, it enables adding 7 bits of other per-GUID flags in the
future without adding more overhead. Note that it was lower overhead to
add this to the GlobalValueSummaryInfo than the ValueInfo, which tends
to be copied into other maps.
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
Add a flag to the GlobalValueSummaryInfo indicating whether the
associated SummaryList (all summaries with the same GUID) contains any
summaries with local linkage. This flag is set when building the index,
so it is associated with the original linkage type before
internalization and promotion. Consumers should check the
withInternalizeAndPromote() flag on the index before using it.

In most cases we expect a 1-1 mapping between a GUID and a summary with
local linkage, because for locals the GUID is computed from the hash of
"modulepath;name". However, there can be multiple locals with the same
GUID if translation units are not compiled with enough path. And in rare
but theoretically possible cases, there can be hash collisions on the
underlying MD5 computation. So to be safe when looking for local
summaries, analyses currently look through all summaries in the list.
These lists can be extremely long in the case of large binaries with
template function defs in widely used headers (i.e. linkonce_odr).

A follow on change will use this flag to reduce ThinLTO analysis time in
WPD by 5-6% for a large target (details in PR164046 which will be
reworked to use this flag).

Note that in the past we have tried to keep bits related to the GUID in
the ValueInfo (which has a pointer to the associated
GlobalValueSummaryInfo), via its PointerIntPair. However, we are out of
bits there. This change does add a byte to every GlobalValueSummaryInfo
instance, which I measured as a little under 0.90% overhead in a large
target. However, it enables adding 7 bits of other per-GUID flags in the
future without adding more overhead. Note that it was lower overhead to
add this to the GlobalValueSummaryInfo than the ValueInfo, which tends
to be copied into other maps.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:ir LTO Link time optimization (regular/full LTO or ThinLTO)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants