From 052412f4f5d512f4f7db833f6afbf83fe453c087 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 26 Apr 2017 17:53:39 +0000 Subject: [PATCH] LTO: Mark undefined module asm symbols as used. 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 | 3 ++- lib/LTO/LTOBackend.cpp | 18 ------------------ lib/Object/IRSymtab.cpp | 3 +++ test/LTO/Resolution/X86/Inputs/mod-asm-used.ll | 4 ++++ test/LTO/Resolution/X86/mod-asm-used.ll | 10 ++++++++++ test/tools/gold/X86/asm_undefined2.ll | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 test/LTO/Resolution/X86/Inputs/mod-asm-used.ll create mode 100644 test/LTO/Resolution/X86/mod-asm-used.ll diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index 9782c898bf5..1bc0d7361d4 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -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, diff --git a/lib/LTO/LTOBackend.cpp b/lib/LTO/LTOBackend.cpp index 4bd251f727a..30447c528af 100644 --- a/lib/LTO/LTOBackend.cpp +++ b/lib/LTO/LTOBackend.cpp @@ -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 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 Mod, @@ -377,8 +363,6 @@ Error lto::backend(Config &C, AddStreamFn AddStream, std::unique_ptr 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 TM = createTargetMachine(Conf, Mod.getTargetTriple(), *TOrErr); - handleAsmUndefinedRefs(Mod, *TM); - if (Conf.CodeGenOnly) { codegen(Conf, TM.get(), AddStream, Task, Mod); return Error::success(); diff --git a/lib/Object/IRSymtab.cpp b/lib/Object/IRSymtab.cpp index 367b1e8fb63..5f0837882d6 100644 --- a/lib/Object/IRSymtab.cpp +++ b/lib/Object/IRSymtab.cpp @@ -163,6 +163,9 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab, Sym.ComdatIndex = -1; auto *GV = Msym.dyn_cast(); 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 index 00000000000..3b1988bb54d --- /dev/null +++ b/test/LTO/Resolution/X86/Inputs/mod-asm-used.ll @@ -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 index 00000000000..01befca84d0 --- /dev/null +++ b/test/LTO/Resolution/X86/mod-asm-used.ll @@ -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" diff --git a/test/tools/gold/X86/asm_undefined2.ll b/test/tools/gold/X86/asm_undefined2.ll index 6cb7a1cf3d0..a170f45a55a 100644 --- a/test/tools/gold/X86/asm_undefined2.ll +++ b/test/tools/gold/X86/asm_undefined2.ll @@ -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" -- 2.40.0