aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2022-10-11 15:30:07 -0700
committerFangrui Song <i@maskray.me>2022-10-11 15:30:07 -0700
commit8ef3fd8d59ba0100bc6e83350ab1e978536aa531 (patch)
treeda49d891d20c744701a11ce827d0a68ffa2236aa /llvm/lib/LTO/LTO.cpp
parent67f61b0863d07e3f4f1f112ab899e1f1bca80572 (diff)
downloadllvm-8ef3fd8d59ba0100bc6e83350ab1e978536aa531.zip
llvm-8ef3fd8d59ba0100bc6e83350ab1e978536aa531.tar.gz
llvm-8ef3fd8d59ba0100bc6e83350ab1e978536aa531.tar.bz2
[LTO] Make local linkage GlobalValue in non-prevailing COMDAT available_externally
For a local linkage GlobalObject in a non-prevailing COMDAT, it remains defined while its leader has been made available_externally. This violates the COMDAT rule that its members must be retained or discarded as a unit. To fix this, update the regular LTO change D34803 to track local linkage GlobalValues, and port the code to ThinLTO (GlobalAliases are not handled.) This fixes two problems. (a) `__cxx_global_var_init` in a non-prevailing COMDAT group used to linger around (unreferenced, hence benign), and is now correctly discarded. ``` int foo(); inline int v = foo(); ``` (b) Fix https://github.com/llvm/llvm-project/issues/58215: as a size optimization, we place private `__profd_` in a COMDAT with a `__profc_` key. When FuncImport.cpp makes `__profc_` available_externally due to a non-prevailing COMDAT, `__profd_` incorrectly remains private. This change makes the `__profd_` available_externally. ``` cat > c.h <<'eof' extern void bar(); inline __attribute__((noinline)) void foo() {} eof cat > m1.cc <<'eof' int main() { bar(); foo(); } eof cat > m2.cc <<'eof' __attribute__((noinline)) void bar() { foo(); } eof clang -O2 -fprofile-generate=./t m1.cc m2.cc -flto -fuse-ld=lld -o t_gen rm -fr t && ./t_gen && llvm-profdata show -function=foo t/default_*.profraw clang -O2 -fprofile-generate=./t m1.cc m2.cc -flto=thin -fuse-ld=lld -o t_gen rm -fr t && ./t_gen && llvm-profdata show -function=foo t/default_*.profraw ``` Reviewed By: tejohnson Differential Revision: https://reviews.llvm.org/D135427
Diffstat (limited to 'llvm/lib/LTO/LTO.cpp')
-rw-r--r--llvm/lib/LTO/LTO.cpp10
1 files changed, 5 insertions, 5 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 10ca98f..0ce8519 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -696,11 +696,11 @@ handleNonPrevailingComdat(GlobalValue &GV,
if (!NonPrevailingComdats.count(C))
return;
- // Additionally need to drop externally visible global values from the comdat
- // to available_externally, so that there aren't multiply defined linker
- // errors.
- if (!GV.hasLocalLinkage())
- GV.setLinkage(GlobalValue::AvailableExternallyLinkage);
+ // Additionally need to drop all global values from the comdat to
+ // available_externally, to satisfy the COMDAT requirement that all members
+ // are discarded as a unit. The non-local linkage global values avoid
+ // duplicate definition linker errors.
+ GV.setLinkage(GlobalValue::AvailableExternallyLinkage);
if (auto GO = dyn_cast<GlobalObject>(&GV))
GO->setComdat(nullptr);