]> granicus.if.org Git - llvm/commitdiff
LTO: Mark undefined module asm symbols as used.
authorPeter Collingbourne <peter@pcc.me.uk>
Wed, 26 Apr 2017 17:53:39 +0000 (17:53 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Wed, 26 Apr 2017 17:53:39 +0000 (17:53 +0000)
Marking them as used causes them to be considered visible outside of LTO. This
prevents the symbols from being internalized or discarded, either by GlobalDCE
or by summary-based dead stripping in ThinLTO.

This change makes it unnecessary to add these symbols to llvm.compiler.used
in the backend, as the symbols are kept alive by virtue of being external,
so remove the backend code that handles that.

Fixes PR32798.

Differential Revision: https://reviews.llvm.org/D32544

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301438 91177308-0d34-0410-b5e6-96231b3b80d8

lib/LTO/LTO.cpp
lib/LTO/LTOBackend.cpp
lib/Object/IRSymtab.cpp
test/LTO/Resolution/X86/Inputs/mod-asm-used.ll [new file with mode: 0644]
test/LTO/Resolution/X86/mod-asm-used.ll [new file with mode: 0644]
test/tools/gold/X86/asm_undefined2.ll

index 9782c898bf503bade6aba2c391e6f7ddf5b26b9b..1bc0d7361d4c6a419292d29096b41d797119880f 100644 (file)
@@ -415,7 +415,8 @@ void LTO::addSymbolToGlobalRes(const InputFile::Symbol &Sym,
   // Flag as visible outside of ThinLTO if visible from a regular object or
   // if this is a reference in the regular LTO partition.
   GlobalRes.VisibleOutsideThinLTO |=
-      (Res.VisibleToRegularObj || (Partition == GlobalResolution::RegularLTO));
+      (Res.VisibleToRegularObj || Sym.isUsed() ||
+       Partition == GlobalResolution::RegularLTO);
 }
 
 static void writeToResolutionFile(raw_ostream &OS, InputFile *Input,
index 4bd251f727a4353da699102e9c1ee4e0b5bdac18..30447c528af1a551930be5efd798f2f2150c0f34 100644 (file)
@@ -25,7 +25,6 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/LTO/LTO.h"
-#include "llvm/LTO/legacy/UpdateCompilerUsed.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Object/ModuleSymbolTable.h"
 #include "llvm/Passes/PassBuilder.h"
@@ -353,19 +352,6 @@ finalizeOptimizationRemarks(std::unique_ptr<tool_output_file> DiagOutputFile) {
   DiagOutputFile->os().flush();
 }
 
-static void handleAsmUndefinedRefs(Module &Mod, TargetMachine &TM) {
-  // Collect the list of undefined symbols used in asm and update
-  // llvm.compiler.used to prevent optimization to drop these from the output.
-  StringSet<> AsmUndefinedRefs;
-  ModuleSymbolTable::CollectAsmSymbols(
-      Mod,
-      [&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) {
-        if (Flags & object::BasicSymbolRef::SF_Undefined)
-          AsmUndefinedRefs.insert(Name);
-      });
-  updateCompilerUsed(Mod, TM, AsmUndefinedRefs);
-}
-
 Error lto::backend(Config &C, AddStreamFn AddStream,
                    unsigned ParallelCodeGenParallelismLevel,
                    std::unique_ptr<Module> Mod,
@@ -377,8 +363,6 @@ Error lto::backend(Config &C, AddStreamFn AddStream,
   std::unique_ptr<TargetMachine> TM =
       createTargetMachine(C, Mod->getTargetTriple(), *TOrErr);
 
-  handleAsmUndefinedRefs(*Mod, *TM);
-
   // Setup optimization remarks.
   auto DiagFileOrErr = lto::setupOptimizationRemarks(
       Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness);
@@ -416,8 +400,6 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,
   std::unique_ptr<TargetMachine> TM =
       createTargetMachine(Conf, Mod.getTargetTriple(), *TOrErr);
 
-  handleAsmUndefinedRefs(Mod, *TM);
-
   if (Conf.CodeGenOnly) {
     codegen(Conf, TM.get(), AddStream, Task, Mod);
     return Error::success();
index 367b1e8fb63530320ee55fe1334b98f3369c8394..5f0837882d60002374d7d0303d4394d2e3b81900 100644 (file)
@@ -163,6 +163,9 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
   Sym.ComdatIndex = -1;
   auto *GV = Msym.dyn_cast<GlobalValue *>();
   if (!GV) {
+    // Undefined module asm symbols act as GC roots and are implicitly used.
+    if (Flags & object::BasicSymbolRef::SF_Undefined)
+      Sym.Flags |= 1 << storage::Symbol::FB_used;
     setStr(Sym.IRName, "");
     return Error::success();
   }
diff --git a/test/LTO/Resolution/X86/Inputs/mod-asm-used.ll b/test/LTO/Resolution/X86/Inputs/mod-asm-used.ll
new file mode 100644 (file)
index 0000000..3b1988b
--- /dev/null
@@ -0,0 +1,4 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@foo = global i32 1, align 4
diff --git a/test/LTO/Resolution/X86/mod-asm-used.ll b/test/LTO/Resolution/X86/mod-asm-used.ll
new file mode 100644 (file)
index 0000000..01befca
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: opt -module-summary -o %t.bc %s
+; RUN: opt -module-summary -o %t2.bc %S/Inputs/mod-asm-used.ll
+; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,l %t2.bc -r %t2.bc,foo,pl -o %t3
+; RUN: llvm-nm %t3.1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: D foo
+module asm ".quad foo"
index 6cb7a1cf3d06043cf7d813853a30ad40b0bc39ce..a170f45a55a16cf58ef0fccfbabaf4e90a364359 100644 (file)
@@ -11,8 +11,8 @@
 ; RUN:     --plugin-opt=thinlto -o %t2 %t.o
 ; RUN: llvm-dis < %t.o.5.precodegen.bc | FileCheck %s
 
-; Check that foo is properly appended to llvm.compiler.used
-; CHECK: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata"
+; Check that foo is not internalized
+; CHECK: define void @foo
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"