aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/LTO/LTO.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2022-10-08 11:09:42 -0700
committerFangrui Song <i@maskray.me>2022-10-08 11:09:43 -0700
commit4fbe33593c8132fdc48647c06f4d1455bfff1c88 (patch)
treefe3028c2d7afa300f786976908a5797ced93cbba /llvm/lib/LTO/LTO.cpp
parent39532ea0735ff2ced1a0bf706dcdc523e8fcec82 (diff)
downloadllvm-4fbe33593c8132fdc48647c06f4d1455bfff1c88.zip
llvm-4fbe33593c8132fdc48647c06f4d1455bfff1c88.tar.gz
llvm-4fbe33593c8132fdc48647c06f4d1455bfff1c88.tar.bz2
[LTO] Make local linkage GlobalValue in non-prevailing COMDAT available_externally
See the updated linkonce_resolution_comdat.ll. For a local linkage GV 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.) 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' #include "c.h" int main() { bar(); foo(); } eof cat > m2.cc <<'eof' #include "c.h" __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 # one _Z3foov 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 # one _Z3foov ``` 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);