[lld] r267063 - Internalize linkonce_odr more often.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 14:44:25 PDT 2016


Author: rafael
Date: Thu Apr 21 16:44:25 2016
New Revision: 267063

URL: http://llvm.org/viewvc/llvm-project?rev=267063&view=rev
Log:
Internalize linkonce_odr more often.

Since there is a copy in every translation unit that uses them, they can
be omitted from the symbol table if the address is not significant.

This still doesn't catch as many cases as the gold plugin. The
difference is that we check canBeOmittedFromSymbolTable in each file and
use lazy loading which limits what it can do. Gold checks it in the merged file.

I think the correct way of getting the same results as gold is just to
cache in the IR the result of canBeOmittedFromSymbolTable.

Added:
    lld/trunk/test/ELF/lto/Inputs/internalize-exportdyn.ll
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/test/ELF/lto/internalize-exportdyn.ll

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=267063&r1=267062&r2=267063&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Apr 21 16:44:25 2016
@@ -12,6 +12,7 @@
 #include "InputSection.h"
 #include "Symbols.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/Analysis.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Object/IRObjectFile.h"
@@ -498,8 +499,11 @@ BitcodeFile::createSymbolBody(const Dens
     Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
   }
   // FIXME: Expose a thread-local flag for module asm symbols.
-  if (GV && GV->isThreadLocal())
-    Body->Type = STT_TLS;
+  if (GV) {
+    if (GV->isThreadLocal())
+      Body->Type = STT_TLS;
+    Body->CanOmitFromDynSym = canBeOmittedFromSymbolTable(GV);
+  }
   return Body;
 }
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=267063&r1=267062&r2=267063&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Apr 21 16:44:25 2016
@@ -109,6 +109,7 @@ void SymbolBody::init() {
                        K == DefinedSyntheticKind || K == UndefinedElfKind;
   CanKeepUndefined = false;
   MustBeInDynSym = false;
+  CanOmitFromDynSym = false;
   NeedsCopyOrPltAddr = false;
 }
 
@@ -241,6 +242,9 @@ int SymbolBody::compare(SymbolBody *Othe
   if (IsUsedInRegularObj || Other->IsUsedInRegularObj)
     IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
 
+  if (!CanOmitFromDynSym || !Other->CanOmitFromDynSym)
+    CanOmitFromDynSym = Other->CanOmitFromDynSym = false;
+
   if (L != R)
     return -1;
   if (!isDefined() || isShared() || isWeak())
@@ -360,7 +364,9 @@ bool SymbolBody::includeInDynsym() const
   uint8_t V = getVisibility();
   if (V != STV_DEFAULT && V != STV_PROTECTED)
     return false;
-  return Config->ExportDynamic || Config->Shared;
+  if (!Config->ExportDynamic && !Config->Shared)
+    return false;
+  return !CanOmitFromDynSym;
 }
 
 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=267063&r1=267062&r2=267063&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Apr 21 16:44:25 2016
@@ -147,6 +147,12 @@ protected:
   unsigned IsUsedInRegularObj : 1;
 
 public:
+  // True if this symbol can be omitted from the symbol table if nothing else
+  // requires it to be there. Right now this is only used for linkonce_odr in
+  // LTO, but we could add the feature to ELF. It would be similar to
+  // MachO's .weak_def_can_be_hidden.
+  unsigned CanOmitFromDynSym : 1;
+
   // If true, the symbol is added to .dynsym symbol table.
   unsigned MustBeInDynSym : 1;
 

Added: lld/trunk/test/ELF/lto/Inputs/internalize-exportdyn.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/Inputs/internalize-exportdyn.ll?rev=267063&view=auto
==============================================================================
--- lld/trunk/test/ELF/lto/Inputs/internalize-exportdyn.ll (added)
+++ lld/trunk/test/ELF/lto/Inputs/internalize-exportdyn.ll Thu Apr 21 16:44:25 2016
@@ -0,0 +1,6 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define weak_odr void @bah() {
+  ret void
+}

Modified: lld/trunk/test/ELF/lto/internalize-exportdyn.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/internalize-exportdyn.ll?rev=267063&r1=267062&r2=267063&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/internalize-exportdyn.ll (original)
+++ lld/trunk/test/ELF/lto/internalize-exportdyn.ll Thu Apr 21 16:44:25 2016
@@ -1,6 +1,7 @@
 ; REQUIRES: x86
 ; RUN: llvm-as %s -o %t.o
-; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --export-dynamic -save-temps
+; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps
 ; RUN: llvm-dis < %t2.lto.bc | FileCheck %s
 
 target triple = "x86_64-unknown-linux-gnu"
@@ -18,7 +19,24 @@ define hidden void @bar() {
   ret void
 }
 
-; Check that _start and foo are not internalized, but bar is.
+define linkonce_odr void @zed() unnamed_addr {
+  ret void
+}
+
+define linkonce_odr void @bah() {
+  ret void
+}
+
+define linkonce_odr void @baz() {
+  ret void
+}
+
+ at use_baz = global void ()* @baz
+
+; Check what gets internalized.
 ; CHECK: define void @_start()
 ; CHECK: define void @foo()
 ; CHECK: define internal void @bar()
+; CHECK: define internal void @zed()
+; CHECK: define weak_odr void @bah()
+; CHECK: define weak_odr void @baz()




More information about the llvm-commits mailing list