[PATCH] D36546: Garbage-collect common symbols.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 9 15:49:32 PDT 2017


LGTM

Rui Ueyama via Phabricator via llvm-commits
<llvm-commits at lists.llvm.org> writes:

> ruiu updated this revision to Diff 110474.
> ruiu added a comment.
>
> - Address review comment.
>
>
> https://reviews.llvm.org/D36546
>
> Files:
>   lld/ELF/MarkLive.cpp
>   lld/ELF/Symbols.cpp
>   lld/ELF/Symbols.h
>   lld/ELF/SyntheticSections.cpp
>   lld/ELF/Writer.cpp
>   lld/test/ELF/common-gc.s
>   lld/test/ELF/common-gc2.s
>
> Index: lld/test/ELF/common-gc2.s
> ===================================================================
> --- /dev/null
> +++ lld/test/ELF/common-gc2.s
> @@ -0,0 +1,15 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
> +# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1
> +# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s
> +
> +# CHECK: Name: bar@
> +# CHECK: Name: foo@
> +
> +.comm foo,4,4
> +.comm bar,4,4
> +
> +.text
> +.globl _start
> +_start:
> + .quad foo
> Index: lld/test/ELF/common-gc.s
> ===================================================================
> --- /dev/null
> +++ lld/test/ELF/common-gc.s
> @@ -0,0 +1,41 @@
> +# REQUIRES: x86
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
> +
> +# RUN: ld.lld %t -o %t2
> +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck %s --check-prefix=NOGC
> +
> +# NOGC:      Name: .bss
> +# NOGC-NEXT: Type:
> +# NOGC-NEXT: Flags [
> +# NOGC-NEXT:   SHF_ALLOC
> +# NOGC-NEXT:   SHF_WRITE
> +# NOGC-NEXT: ]
> +# NOGC-NEXT: Address:
> +# NOGC-NEXT: Offset:
> +# NOGC-NEXT: Size: 8
> +
> +# NOGC: Name: bar
> +# NOGC: Name: foo
> +
> +# RUN: ld.lld -gc-sections %t -o %t1
> +# RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s --check-prefix=GC
> +
> +# GC:      Name: .bss
> +# GC-NEXT: Type:
> +# GC-NEXT: Flags [
> +# GC-NEXT:   SHF_ALLOC
> +# GC-NEXT:   SHF_WRITE
> +# GC-NEXT: ]
> +# GC-NEXT: Address:
> +# GC-NEXT: Offset:
> +# GC-NEXT: Size: 4
> +
> +# GC-NOT: Name: bar
> +
> +.comm foo,4,4
> +.comm bar,4,4
> +
> +.text
> +.globl _start
> +_start:
> + .quad foo
> Index: lld/ELF/Writer.cpp
> ===================================================================
> --- lld/ELF/Writer.cpp
> +++ lld/ELF/Writer.cpp
> @@ -451,7 +451,11 @@
>      if (auto *S = dyn_cast<MergeInputSection>(Sec))
>        if (!S->getSectionPiece(D->Value)->Live)
>          return false;
> +    return true;
>    }
> +
> +  if (auto *Sym = dyn_cast<DefinedCommon>(&B))
> +    return Sym->Live;
>    return true;
>  }
>  
> Index: lld/ELF/SyntheticSections.cpp
> ===================================================================
> --- lld/ELF/SyntheticSections.cpp
> +++ lld/ELF/SyntheticSections.cpp
> @@ -77,9 +77,11 @@
>                       return A->Alignment > B->Alignment;
>                     });
>  
> +  // Allocate space for common symbols.
>    BssSection *Sec = make<BssSection>("COMMON");
>    for (DefinedCommon *Sym : Syms)
> -    Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
> +    if (Sym->Live)
> +      Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
>    return Sec;
>  }
>  
> Index: lld/ELF/Symbols.h
> ===================================================================
> --- lld/ELF/Symbols.h
> +++ lld/ELF/Symbols.h
> @@ -159,13 +159,17 @@
>      return S->kind() == SymbolBody::DefinedCommonKind;
>    }
>  
> -  // The output offset of this common symbol in the output bss. Computed by the
> -  // writer.
> -  uint64_t Offset;
> +  // True if this symbol is not GC'ed. Liveness is usually a notion of
> +  // input sections and not of symbols, but since common symbols don't
> +  // belong to any input section, their liveness is managed by this bit.
> +  bool Live;
>  
>    // The maximum alignment we have seen for this symbol.
>    uint32_t Alignment;
>  
> +  // The output offset of this common symbol in the output bss.
> +  // Computed by the writer.
> +  uint64_t Offset;
>    uint64_t Size;
>  };
>  
> Index: lld/ELF/Symbols.cpp
> ===================================================================
> --- lld/ELF/Symbols.cpp
> +++ lld/ELF/Symbols.cpp
> @@ -307,7 +307,7 @@
>                               uint8_t StOther, uint8_t Type)
>      : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
>                Type),
> -      Alignment(Alignment), Size(Size) {}
> +      Live(!Config->GcSections), Alignment(Alignment), Size(Size) {}
>  
>  // If a shared symbol is referred via a copy relocation, its alignment
>  // becomes part of the ABI. This function returns a symbol alignment.
> Index: lld/ELF/MarkLive.cpp
> ===================================================================
> --- lld/ELF/MarkLive.cpp
> +++ lld/ELF/MarkLive.cpp
> @@ -72,17 +72,25 @@
>  static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
>                           std::function<void(ResolvedReloc)> Fn) {
>    SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
> +
> +  if (auto *Sym = dyn_cast<DefinedCommon>(&B)) {
> +    Sym->Live = true;
> +    return;
> +  }
> +
>    if (auto *D = dyn_cast<DefinedRegular>(&B)) {
>      if (!D->Section)
>        return;
>      typename ELFT::uint Offset = D->Value;
>      if (D->isSection())
>        Offset += getAddend<ELFT>(Sec, Rel);
>      Fn({cast<InputSectionBase>(D->Section), Offset});
> -  } else if (auto *U = dyn_cast<Undefined>(&B)) {
> +    return;
> +  }
> +
> +  if (auto *U = dyn_cast<Undefined>(&B))
>      for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
>        Fn({Sec, 0});
> -  }
>  }
>  
>  // Calls Fn for each section that Sec refers to via relocations.
> @@ -218,10 +226,14 @@
>        Q.push_back(S);
>    };
>  
> -  auto MarkSymbol = [&](const SymbolBody *Sym) {
> -    if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
> +  auto MarkSymbol = [&](SymbolBody *Sym) {
> +    if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym)) {
>        if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
>          Enqueue({IS, D->Value});
> +      return;
> +    }
> +    if (auto *S = dyn_cast_or_null<DefinedCommon>(Sym))
> +      S->Live = true;
>    };
>  
>    // Add GC root symbols.
> @@ -235,7 +247,7 @@
>  
>    // Preserve externally-visible symbols if the symbols defined by this
>    // file can interrupt other ELF file's symbols at runtime.
> -  for (const Symbol *S : Symtab->getSymbols())
> +  for (Symbol *S : Symtab->getSymbols())
>      if (S->includeInDynsym())
>        MarkSymbol(S->body());
>  
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list