From: H.J. Lu Date: Tue, 2 Feb 2016 16:14:43 +0000 (-0800) Subject: Store estimated distances in compressed_size X-Git-Tag: users/ARM/embedded-binutils-2_26-branch-2016q1~20^2~56 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cc2d819b58fd5d60dfef34007662535f9e142c16;p=thirdparty%2Fbinutils-gdb.git Store estimated distances in compressed_size elf_x86_64_convert_load is very time consuming since it is called on each input section and has a loop over input text sections to estimate the branch distrance. We can store the estimated distances in the compressed_size field of the output section, which is only used to decompress the compressed input section. Before the patch, linking clang 3.9 takes 52 seconds. After the patch, it only takes 2.5 seconds. Backport from master PR ld/19542 * elf64-x86-64.c (elf_x86_64_convert_load): Store the estimated distances in the compressed_size field of the output section. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7f09156ac1b..1704438c229 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2016-02-02 H.J. Lu + + Backport from master + 2016-02-02 H.J. Lu + + PR ld/19542 + * elf64-x86-64.c (elf_x86_64_convert_load): Store the estimated + distances in the compressed_size field of the output section. + 2016-02-01 John David Anglin PR ld/19526 diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 63957bbd1c3..156734b7ab7 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -3190,35 +3190,43 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec, } else { - asection *asect; - bfd_size_type size; + bfd_signed_vma distance; /* At this point, we don't know the load addresses of TSEC section nor SEC section. We estimate the distrance between - SEC and TSEC. */ - size = 0; - for (asect = sec->output_section; - asect != NULL && asect != tsec->output_section; - asect = asect->next) + SEC and TSEC. We store the estimated distances in the + compressed_size field of the output section, which is only + used to decompress the compressed input section. */ + if (sec->output_section->compressed_size == 0) { - asection *i; - for (i = asect->output_section->map_head.s; - i != NULL; - i = i->map_head.s) + asection *asect; + bfd_size_type size = 0; + for (asect = link_info->output_bfd->sections; + asect != NULL; + asect = asect->next) { - size = align_power (size, i->alignment_power); - size += i->size; + asection *i; + for (i = asect->map_head.s; + i != NULL; + i = i->map_head.s) + { + size = align_power (size, i->alignment_power); + size += i->size; + } + asect->compressed_size = size; } } /* Don't convert GOTPCREL relocations if TSEC isn't placed after SEC. */ - if (asect == NULL) + distance = (tsec->output_section->compressed_size + - sec->output_section->compressed_size); + if (distance < 0) continue; /* Take PT_GNU_RELRO segment into account by adding maxpagesize. */ - if ((toff + size + maxpagesize - roff + 0x80000000) + if ((toff + distance + maxpagesize - roff + 0x80000000) > 0xffffffff) continue; }