[lld] r305177 - ELF: Teach ICF about relocations referring to merge input sections.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 12 13:17:58 PDT 2017


This is really nice!

Thanks,
Rafael

Peter Collingbourne via llvm-commits <llvm-commits at lists.llvm.org>
writes:

> Author: pcc
> Date: Sun Jun 11 19:05:54 2017
> New Revision: 305177
>
> URL: http://llvm.org/viewvc/llvm-project?rev=305177&view=rev
> Log:
> ELF: Teach ICF about relocations referring to merge input sections.
>
> Relocations referring to merge sections are considered equal if they
> resolve to the same offset in the same output section.
>
> Differential Revision: https://reviews.llvm.org/D34094
>
> Added:
>     lld/trunk/test/ELF/Inputs/icf-merge-sec.s
>     lld/trunk/test/ELF/Inputs/icf-merge.s
>     lld/trunk/test/ELF/Inputs/icf-merge2.s
>     lld/trunk/test/ELF/Inputs/icf-merge3.s
>     lld/trunk/test/ELF/icf-merge-sec.s
>     lld/trunk/test/ELF/icf-merge.s
> Modified:
>     lld/trunk/ELF/ICF.cpp
>
> Modified: lld/trunk/ELF/ICF.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=305177&r1=305176&r2=305177&view=diff
> ==============================================================================
> --- lld/trunk/ELF/ICF.cpp (original)
> +++ lld/trunk/ELF/ICF.cpp Sun Jun 11 19:05:54 2017
> @@ -98,7 +98,8 @@ private:
>    void segregate(size_t Begin, size_t End, bool Constant);
>  
>    template <class RelTy>
> -  bool constantEq(ArrayRef<RelTy> RelsA, ArrayRef<RelTy> RelsB);
> +  bool constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
> +                  const InputSection *B, ArrayRef<RelTy> RelsB);
>  
>    template <class RelTy>
>    bool variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
> @@ -206,11 +207,53 @@ void ICF<ELFT>::segregate(size_t Begin,
>  // Compare two lists of relocations.
>  template <class ELFT>
>  template <class RelTy>
> -bool ICF<ELFT>::constantEq(ArrayRef<RelTy> RelsA, ArrayRef<RelTy> RelsB) {
> -  auto Eq = [](const RelTy &A, const RelTy &B) {
> -    return A.r_offset == B.r_offset &&
> -           A.getType(Config->IsMips64EL) == B.getType(Config->IsMips64EL) &&
> -           getAddend<ELFT>(A) == getAddend<ELFT>(B);
> +bool ICF<ELFT>::constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
> +                           const InputSection *B, ArrayRef<RelTy> RelsB) {
> +  auto Eq = [&](const RelTy &RA, const RelTy &RB) {
> +    if (RA.r_offset != RB.r_offset ||
> +        RA.getType(Config->IsMips64EL) != RB.getType(Config->IsMips64EL))
> +      return false;
> +    uint64_t AddA = getAddend<ELFT>(RA);
> +    uint64_t AddB = getAddend<ELFT>(RB);
> +
> +    SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA);
> +    SymbolBody &SB = B->template getFile<ELFT>()->getRelocTargetSym(RB);
> +    if (&SA == &SB)
> +      return AddA == AddB;
> +
> +    auto *DA = dyn_cast<DefinedRegular>(&SA);
> +    auto *DB = dyn_cast<DefinedRegular>(&SB);
> +    if (!DA || !DB)
> +      return false;
> +
> +    // Relocations referring to absolute symbols are constant-equal if their
> +    // values are equal.
> +    if (!DA->Section || !DB->Section)
> +      return !DA->Section && !DB->Section &&
> +             DA->Value + AddA == DB->Value + AddB;
> +
> +    if (DA->Section->kind() != DB->Section->kind())
> +      return false;
> +
> +    // Relocations referring to InputSections are constant-equal if their
> +    // section offsets are equal.
> +    if (isa<InputSection>(DA->Section))
> +      return DA->Value + AddA == DB->Value + AddB;
> +
> +    // Relocations referring to MergeInputSections are constant-equal if their
> +    // offsets in the output section are equal.
> +    auto *X = dyn_cast<MergeInputSection>(DA->Section);
> +    if (!X)
> +      return false;
> +    auto *Y = cast<MergeInputSection>(DB->Section);
> +    if (X->getParent() != Y->getParent())
> +      return false;
> +
> +    uint64_t OffsetA =
> +        SA.isSection() ? X->getOffset(AddA) : X->getOffset(DA->Value) + AddA;
> +    uint64_t OffsetB =
> +        SB.isSection() ? Y->getOffset(AddB) : Y->getOffset(DB->Value) + AddB;
> +    return OffsetA == OffsetB;
>    };
>  
>    return RelsA.size() == RelsB.size() &&
> @@ -226,8 +269,9 @@ bool ICF<ELFT>::equalsConstant(const Inp
>      return false;
>  
>    if (A->AreRelocsRela)
> -    return constantEq(A->template relas<ELFT>(), B->template relas<ELFT>());
> -  return constantEq(A->template rels<ELFT>(), B->template rels<ELFT>());
> +    return constantEq(A, A->template relas<ELFT>(), B,
> +                      B->template relas<ELFT>());
> +  return constantEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
>  }
>  
>  // Compare two lists of relocations. Returns true if all pairs of
> @@ -243,22 +287,18 @@ bool ICF<ELFT>::variableEq(const InputSe
>      if (&SA == &SB)
>        return true;
>  
> -    auto *DA = dyn_cast<DefinedRegular>(&SA);
> -    auto *DB = dyn_cast<DefinedRegular>(&SB);
> -    if (!DA || !DB)
> -      return false;
> -    if (DA->Value != DB->Value)
> -      return false;
> -
> -    // Either both symbols must be absolute...
> -    if (!DA->Section || !DB->Section)
> -      return !DA->Section && !DB->Section;
> +    auto *DA = cast<DefinedRegular>(&SA);
> +    auto *DB = cast<DefinedRegular>(&SB);
>  
> -    // Or the two sections must be in the same equivalence class.
> +    // We already dealt with absolute and non-InputSection symbols in
> +    // constantEq, and for InputSections we have already checked everything
> +    // except the equivalence class.
> +    if (!DA->Section)
> +      return true;
>      auto *X = dyn_cast<InputSection>(DA->Section);
> -    auto *Y = dyn_cast<InputSection>(DB->Section);
> -    if (!X || !Y)
> -      return false;
> +    if (!X)
> +      return true;
> +    auto *Y = cast<InputSection>(DB->Section);
>  
>      // Ineligible sections are in the special equivalence class 0.
>      // They can never be the same in terms of the equivalence class.
>
> Added: lld/trunk/test/ELF/Inputs/icf-merge-sec.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/icf-merge-sec.s?rev=305177&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/Inputs/icf-merge-sec.s (added)
> +++ lld/trunk/test/ELF/Inputs/icf-merge-sec.s Sun Jun 11 19:05:54 2017
> @@ -0,0 +1,9 @@
> +.section .rodata.str,"aMS", at progbits,1
> +.asciz "bar"
> +.asciz "baz"
> +.asciz "foo"
> +
> +.section .text.f2,"ax"
> +.globl f2
> +f2:
> +.quad .rodata.str+8
>
> Added: lld/trunk/test/ELF/Inputs/icf-merge.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/icf-merge.s?rev=305177&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/Inputs/icf-merge.s (added)
> +++ lld/trunk/test/ELF/Inputs/icf-merge.s Sun Jun 11 19:05:54 2017
> @@ -0,0 +1,10 @@
> +.section .rodata.str,"aMS", at progbits,1
> +.asciz "bar"
> +.asciz "baz"
> +foo:
> +.asciz "foo"
> +
> +.section .text.f2,"ax"
> +.globl f2
> +f2:
> +lea foo+42(%rip), %rax
>
> Added: lld/trunk/test/ELF/Inputs/icf-merge2.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/icf-merge2.s?rev=305177&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/Inputs/icf-merge2.s (added)
> +++ lld/trunk/test/ELF/Inputs/icf-merge2.s Sun Jun 11 19:05:54 2017
> @@ -0,0 +1,10 @@
> +.section .rodata.str,"aMS", at progbits,1
> +.asciz "bar"
> +.asciz "baz"
> +boo:
> +.asciz "boo"
> +
> +.section .text.f2,"ax"
> +.globl f2
> +f2:
> +lea boo+42(%rip), %rax
>
> Added: lld/trunk/test/ELF/Inputs/icf-merge3.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/icf-merge3.s?rev=305177&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/Inputs/icf-merge3.s (added)
> +++ lld/trunk/test/ELF/Inputs/icf-merge3.s Sun Jun 11 19:05:54 2017
> @@ -0,0 +1,10 @@
> +.section .rodata.str,"aMS", at progbits,1
> +.asciz "bar"
> +.asciz "baz"
> +foo:
> +.asciz "foo"
> +
> +.section .text.f2,"ax"
> +.globl f2
> +f2:
> +lea foo+43(%rip), %rax
>
> Added: lld/trunk/test/ELF/icf-merge-sec.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/icf-merge-sec.s?rev=305177&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/icf-merge-sec.s (added)
> +++ lld/trunk/test/ELF/icf-merge-sec.s Sun Jun 11 19:05:54 2017
> @@ -0,0 +1,18 @@
> +# REQUIRES: x86
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge-sec.s -o %t2
> +# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose | FileCheck %s
> +
> +# CHECK: selected .text.f1
> +# CHECK:   removed .text.f2
> +
> +.section .rodata.str,"aMS", at progbits,1
> +.asciz "foo"
> +.asciz "string 1"
> +.asciz "string 2"
> +
> +.section .text.f1,"ax"
> +.globl f1
> +f1:
> +.quad .rodata.str
>
> Added: lld/trunk/test/ELF/icf-merge.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/icf-merge.s?rev=305177&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/icf-merge.s (added)
> +++ lld/trunk/test/ELF/icf-merge.s Sun Jun 11 19:05:54 2017
> @@ -0,0 +1,27 @@
> +# REQUIRES: x86
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge.s -o %t1
> +# RUN: ld.lld %t %t1 -o %t1.out --icf=all --verbose | FileCheck %s
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge2.s -o %t2
> +# RUN: ld.lld %t %t2 -o %t3.out --icf=all --verbose | FileCheck --check-prefix=NOMERGE %s
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge3.s -o %t3
> +# RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose | FileCheck --check-prefix=NOMERGE %s
> +
> +# CHECK: selected .text.f1
> +# CHECK:   removed .text.f2
> +
> +# NOMERGE-NOT: selected .text.f
> +
> +.section .rodata.str,"aMS", at progbits,1
> +foo:
> +.asciz "foo"
> +.asciz "string 1"
> +.asciz "string 2"
> +
> +.section .text.f1,"ax"
> +.globl f1
> +f1:
> +lea foo+42(%rip), %rax
>
>
> _______________________________________________
> 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