[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