[llvm] r267644 - LTOCodeGenerator: turns linkonce(_odr) into weak_(odr) when present "MustPreserve" set

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 17:32:02 PDT 2016


Author: mehdi_amini
Date: Tue Apr 26 19:32:02 2016
New Revision: 267644

URL: http://llvm.org/viewvc/llvm-project?rev=267644&view=rev
Log:
LTOCodeGenerator: turns linkonce(_odr) into weak_(odr) when present "MustPreserve" set

Summary:
If the linker requested to preserve a linkonce function, we should
honor this even if we drop all uses.

Reviewers: dexonsmith

Subscribers: llvm-commits, joker.eph

Differential Revision: http://reviews.llvm.org/D19527

From: Mehdi Amini <mehdi.amini at apple.com>

Modified:
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
    llvm/trunk/test/tools/lto/hide-linkonce-odr.ll

Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=267644&r1=267643&r2=267644&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Tue Apr 26 19:32:02 2016
@@ -348,14 +348,58 @@ std::unique_ptr<TargetMachine> LTOCodeGe
                                  RelocModel, CodeModel::Default, CGOptLevel));
 }
 
+// If a linkonce global is present in the MustPreserveSymbols, we need to make
+// sure we honor this. To force the compiler to not drop it, we turn its linkage
+// to the weak equivalent.
+static void
+preserveDiscardableGVs(Module &TheModule,
+                       function_ref<bool(const GlobalValue &)> mustPreserveGV) {
+  auto mayPreserveGlobal = [&](GlobalValue &GV) {
+    if (!GV.isDiscardableIfUnused() || GV.isDeclaration())
+      return;
+    if (!mustPreserveGV(GV))
+      return;
+    if (GV.hasAvailableExternallyLinkage() || GV.hasLocalLinkage())
+      report_fatal_error("The linker asked LTO to preserve a symbol with an"
+                         "unexpected linkage");
+    GV.setLinkage(GlobalValue::getWeakLinkage(GV.hasLinkOnceODRLinkage()));
+  };
+
+  for (auto &GV : TheModule)
+    mayPreserveGlobal(GV);
+  for (auto &GV : TheModule.globals())
+    mayPreserveGlobal(GV);
+  for (auto &GV : TheModule.aliases())
+    mayPreserveGlobal(GV);
+}
+
 void LTOCodeGenerator::applyScopeRestrictions() {
-  if (ScopeRestrictionsDone || !ShouldInternalize)
+  if (ScopeRestrictionsDone)
+    return;
+
+  // Declare a callback for the internalize pass that will ask for every
+  // candidate GlobalValue if it can be internalized or not.
+  SmallString<64> MangledName;
+  auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
+    // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
+    // with the linker supplied name, which on Darwin includes a leading
+    // underscore.
+    MangledName.clear();
+    MangledName.reserve(GV.getName().size() + 1);
+    Mangler::getNameWithPrefix(MangledName, GV.getName(),
+                               MergedModule->getDataLayout());
+    return MustPreserveSymbols.count(MangledName);
+  };
+
+  // Preserve linkonce value on linker request
+  preserveDiscardableGVs(*MergedModule, mustPreserveGV);
+
+  if (!ShouldInternalize)
     return;
 
   if (ShouldRestoreGlobalsLinkage) {
     // Record the linkage type of non-local symbols so they can be restored
-    // prior
-    // to module splitting.
+    // prior to module splitting.
     auto RecordLinkage = [&](const GlobalValue &GV) {
       if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() &&
           GV.hasName())
@@ -373,22 +417,7 @@ void LTOCodeGenerator::applyScopeRestric
   // symbols referenced from asm
   UpdateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs);
 
-  // Declare a callback for the internalize pass that will ask for every
-  // candidate GlobalValue if it can be internalized or not.
-  Mangler Mangler;
-  SmallString<64> MangledName;
-  auto MustPreserveGV = [&](const GlobalValue &GV) -> bool {
-    // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled
-    // with the linker supplied name, which on Darwin includes a leading
-    // underscore.
-    MangledName.clear();
-    MangledName.reserve(GV.getName().size() + 1);
-    Mangler::getNameWithPrefix(MangledName, GV.getName(),
-                               MergedModule->getDataLayout());
-    return MustPreserveSymbols.count(MangledName);
-  };
-
-  internalizeModule(*MergedModule, MustPreserveGV);
+  internalizeModule(*MergedModule, mustPreserveGV);
 
   ScopeRestrictionsDone = true;
 }

Modified: llvm/trunk/test/tools/lto/hide-linkonce-odr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/lto/hide-linkonce-odr.ll?rev=267644&r1=267643&r2=267644&view=diff
==============================================================================
--- llvm/trunk/test/tools/lto/hide-linkonce-odr.ll (original)
+++ llvm/trunk/test/tools/lto/hide-linkonce-odr.ll Tue Apr 26 19:32:02 2016
@@ -1,9 +1,11 @@
 ; RUN: llvm-as %s -o %t.o
-; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -lSystem -o %t.dylib %t.o -save-temps  -undefined dynamic_lookup
+; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -lSystem -o %t.dylib %t.o -save-temps  -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b
 
 ; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=IR %s
-; check that @a is still a linkonce_odr definition
-; IR: define linkonce_odr void @a()
+; check that @a is no longer a linkonce_odr definition
+; IR-NOT: define linkonce_odr void @a()
+; check that @b is turned into weak because it is exported
+; IR: define weak_odr void @b() #1 {
 
 ; RUN: llvm-nm %t.dylib | FileCheck --check-prefix=NM %s
 ; check that the linker can hide @a but not @b




More information about the llvm-commits mailing list