diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2018-07-27 19:10:44 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2018-07-27 19:10:44 +0000 |
commit | e6c78eafdedfa419d72bc978d124d14bef56ff8e (patch) | |
tree | da3d47efc76dd049e55a5d9e1d960937701a4d0f /lld | |
parent | f611ce82c07ee5b8d4e31da7688360b104f2f2b4 (diff) | |
download | bcm5719-llvm-e6c78eafdedfa419d72bc978d124d14bef56ff8e.tar.gz bcm5719-llvm-e6c78eafdedfa419d72bc978d124d14bef56ff8e.zip |
Reland r338088, "ELF: Make --print-icf-sections output deterministic."
The xxHash64 function has been made unsigned-char-independent, so
we can reland this change now.
Original commit message:
> The icf-safe.s test currently fails on 32-bit platforms because it uses
> the --print-icf-sections flag and depends on the output appearing in
> a specific order. However, this flag causes the output to depend on
> the order of the sections in the Sections array, which depends on the
> hash values returned from hash_combine, which happen to be different
> for that test between 32-bit and 64-bit platforms.
>
> This change makes the output deterministic by using xxHash64 instead of
> hash_combine.
Differential Revision: https://reviews.llvm.org/D49877
llvm-svn: 338153
Diffstat (limited to 'lld')
-rw-r--r-- | lld/ELF/ICF.cpp | 11 | ||||
-rw-r--r-- | lld/test/ELF/icf-safe.s | 48 |
2 files changed, 27 insertions, 32 deletions
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index ba413b13265..53569c27544 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -80,9 +80,10 @@ #include "SyntheticSections.h" #include "Writer.h" #include "lld/Common/Threads.h" -#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELF.h" +#include "llvm/Support/xxhash.h" #include <algorithm> #include <atomic> @@ -155,12 +156,6 @@ private: }; } -// Returns a hash value for S. Note that the information about -// relocation targets is not included in the hash value. -template <class ELFT> static uint32_t getHash(InputSection *S) { - return hash_combine(S->Flags, S->getSize(), S->NumRelocations, S->Data); -} - // Returns true if section S is subject of ICF. static bool isEligible(InputSection *S) { if (!S->Live || S->KeepUnique || !(S->Flags & SHF_ALLOC)) @@ -441,7 +436,7 @@ template <class ELFT> void ICF<ELFT>::run() { // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { // Set MSB to 1 to avoid collisions with non-hash IDs. - S->Class[0] = getHash<ELFT>(S) | (1U << 31); + S->Class[0] = xxHash64(toStringRef(S->Data)) | (1U << 31); }); // From now on, sections in Sections vector are ordered so that sections diff --git a/lld/test/ELF/icf-safe.s b/lld/test/ELF/icf-safe.s index b001fcc82ce..2ced78fbcdc 100644 --- a/lld/test/ELF/icf-safe.s +++ b/lld/test/ELF/icf-safe.s @@ -10,10 +10,6 @@ # RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections --export-dynamic | FileCheck --check-prefix=ALL-EXPORT %s # RUN: ld.lld %t1copy.o -o %t4 --icf=safe 2>&1 | FileCheck --check-prefix=OBJCOPY %s -# CHECK-NOT: selected section {{.*}}:(.rodata.l1) -# CHECK: selected section {{.*}}:(.rodata.l3) -# CHECK: removing identical section {{.*}}:(.rodata.l4) - # CHECK-NOT: selected section {{.*}}:(.text.f1) # CHECK: selected section {{.*}}:(.text.f3) # CHECK: removing identical section {{.*}}:(.text.f4) @@ -22,6 +18,10 @@ # CHECK: selected section {{.*}}:(.rodata.h3) # CHECK: removing identical section {{.*}}:(.rodata.h4) +# CHECK-NOT: selected section {{.*}}:(.rodata.l1) +# CHECK: selected section {{.*}}:(.rodata.l3) +# CHECK: removing identical section {{.*}}:(.rodata.l4) + # CHECK-NOT: selected section {{.*}}:(.rodata.g1) # CHECK: selected section {{.*}}:(.rodata.g3) # CHECK: removing identical section {{.*}}:(.rodata.g4) @@ -30,26 +30,26 @@ # With --icf=all address-significance implies keep-unique only for rodata, not # text. -# ALL-NOT: selected section {{.*}}:(.rodata.l1) -# ALL: selected section {{.*}}:(.rodata.l3) -# ALL: removing identical section {{.*}}:(.rodata.l4) - # ALL: selected section {{.*}}:(.text.f3) # ALL: removing identical section {{.*}}:(.text.f4) -# ALL: selected section {{.*}}:(.text.f1) -# ALL: removing identical section {{.*}}:(.text.f2) -# ALL: removing identical section {{.*}}:(.text.non_addrsig1) -# ALL: removing identical section {{.*}}:(.text.non_addrsig2) - # ALL-NOT: selected section {{.*}}:(.rodata.h1) # ALL: selected section {{.*}}:(.rodata.h3) # ALL: removing identical section {{.*}}:(.rodata.h4) +# ALL-NOT: selected section {{.*}}:(.rodata.l1) +# ALL: selected section {{.*}}:(.rodata.l3) +# ALL: removing identical section {{.*}}:(.rodata.l4) + # ALL-NOT: selected section {{.*}}:(.rodata.g1) # ALL: selected section {{.*}}:(.rodata.g3) # ALL: removing identical section {{.*}}:(.rodata.g4) +# ALL: selected section {{.*}}:(.text.f1) +# ALL: removing identical section {{.*}}:(.text.f2) +# ALL: removing identical section {{.*}}:(.text.non_addrsig1) +# ALL: removing identical section {{.*}}:(.text.non_addrsig2) + # llvm-mc normally emits an empty .text section into every object file. Since # nothing actually refers to it via a relocation, it doesn't have any associated # symbols (thus nor can anything refer to it via a relocation, making it safe to @@ -58,36 +58,36 @@ # STB_LOCAL or STV_HIDDEN symbols. The dynsym entries should have prevented # anything else from being merged. # EXPORT-NOT: selected section -# EXPORT: selected section {{.*}}:(.rodata.l3) -# EXPORT: removing identical section {{.*}}:(.rodata.l4) -# EXPORT-NOT: selected section # EXPORT: selected section {{.*}}:(.rodata.h3) # EXPORT: removing identical section {{.*}}:(.rodata.h4) # EXPORT-NOT: selected section # EXPORT: selected section {{.*}}:(.text) # EXPORT: removing identical section {{.*}}:(.text) # EXPORT-NOT: selected section +# EXPORT: selected section {{.*}}:(.rodata.l3) +# EXPORT: removing identical section {{.*}}:(.rodata.l4) +# EXPORT-NOT: selected section # If --icf=all is specified when exporting we can also merge the exported text # sections, but not the exported rodata. # ALL-EXPORT-NOT: selected section -# ALL-EXPORT: selected section {{.*}}:(.rodata.l3) -# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4) -# ALL-EXPORT-NOT: selected section # ALL-EXPORT: selected section {{.*}}:(.text.f3) # ALL-EXPORT: removing identical section {{.*}}:(.text.f4) # ALL-EXPORT-NOT: selected section -# ALL-EXPORT: selected section {{.*}}:(.text.f1) -# ALL-EXPORT: removing identical section {{.*}}:(.text.f2) -# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1) -# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2) -# ALL-EXPORT-NOT: selected section # ALL-EXPORT: selected section {{.*}}:(.rodata.h3) # ALL-EXPORT: removing identical section {{.*}}:(.rodata.h4) # ALL-EXPORT-NOT: selected section # ALL-EXPORT: selected section {{.*}}:(.text) # ALL-EXPORT: removing identical section {{.*}}:(.text) # ALL-EXPORT-NOT: selected section +# ALL-EXPORT: selected section {{.*}}:(.rodata.l3) +# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4) +# ALL-EXPORT-NOT: selected section +# ALL-EXPORT: selected section {{.*}}:(.text.f1) +# ALL-EXPORT: removing identical section {{.*}}:(.text.f2) +# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1) +# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2) +# ALL-EXPORT-NOT: selected section # OBJCOPY: --icf=safe is incompatible with object files created using objcopy or ld -r |