* [PATCH] add section caches to coff_data_type @ 2023-04-29 11:19 Oleg Tolmatcev 2023-05-04 11:29 ` Nick Clifton 2023-05-04 12:16 ` Tom Tromey 0 siblings, 2 replies; 6+ messages in thread From: Oleg Tolmatcev @ 2023-04-29 11:19 UTC (permalink / raw) To: binutils Hello all, final patch to ld. All the patches together improve linking performance from 9 minutes to 1 minute when linking rpcs3 in debug mode with BUILD_LLVM=ON. --- bfd/coff-x86_64.c | 35 +++++++++++++++++++++++------------ bfd/coffgen.c | 27 +++++++++++++++++++++++++-- bfd/libcoff-in.h | 6 ++++++ bfd/libcoff.h | 6 ++++++ bfd/peicode.h | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 14 deletions(-) diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c index 822504a339..09291e2455 100644 --- a/bfd/coff-x86_64.c +++ b/bfd/coff-x86_64.c @@ -745,23 +745,34 @@ coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, if (rel->r_type == R_AMD64_SECREL) { - bfd_vma osect_vma; + bfd_vma osect_vma = 0; if (h && (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak)) osect_vma = h->root.u.def.section->output_section->vma; else - { - asection *s; - int i; - - /* Sigh, the only way to get the section to offset against - is to find it the hard way. */ - for (s = abfd->sections, i = 1; i < sym->n_scnum; i++) - s = s->next; - - osect_vma = s->output_section->vma; - } + { + asection *s; + + /* Sigh, the only way to get the section to offset against + is to find it the hard way. */ + + if (htab_elements (coff_data (abfd)->section_by_index) == 0) + { + for (s = abfd->sections; s != NULL; s = s->next) + { + void **slot + = htab_find_slot (coff_data (abfd)->section_by_index, s, INSERT); + if (slot != NULL) + *slot = s; + } + } + struct bfd_section needle; + needle.index = sym->n_scnum - 1; + s = htab_find (coff_data (abfd)->section_by_index, &needle); + if (s != NULL) + osect_vma = s->output_section->vma; + } *addendp -= osect_vma; } diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 05f2640abe..326a7dbd88 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -42,6 +42,7 @@ #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" +#include "hashtab.h" /* Take a section header read from a coff file (in HOST byte order), and make a BFD "section" out of it. This is used by ECOFF. */ @@ -360,8 +361,6 @@ coff_object_p (bfd *abfd) asection * coff_section_from_bfd_index (bfd *abfd, int section_index) { - struct bfd_section *answer = abfd->sections; - if (section_index == N_ABS) return bfd_abs_section_ptr; if (section_index == N_UNDEF) @@ -369,6 +368,30 @@ coff_section_from_bfd_index (bfd *abfd, int section_index) if (section_index == N_DEBUG) return bfd_abs_section_ptr; + struct bfd_section *answer; + + if (htab_elements (coff_data (abfd)->section_by_target_index) == 0) + { + answer = abfd->sections; + while (answer) + { + void **slot + = htab_find_slot (coff_data (abfd)->section_by_target_index, answer, INSERT); + if (slot == NULL) + return bfd_und_section_ptr; + *slot = answer; + answer = answer->next; + } + } + + struct bfd_section needle; + needle.target_index = section_index; + + answer = htab_find (coff_data (abfd)->section_by_target_index, &needle); + if (answer != NULL) + return answer; + + answer = abfd->sections; while (answer) { if (answer->target_index == section_index) diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index cdd504605b..6f4109931c 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -130,6 +130,12 @@ typedef struct coff_tdata COFF object into memory. */ char * stub; bfd_size_type stub_size; + + /* hash table containing sections by target index */ + htab_t section_by_target_index; + + /* hash table containing sections by index */ + htab_t section_by_index; } coff_data_type; /* Tdata for pe image files. */ diff --git a/bfd/libcoff.h b/bfd/libcoff.h index b58ee8aded..0cb335ee8d 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -133,6 +133,12 @@ typedef struct coff_tdata COFF object into memory. */ char * stub; bfd_size_type stub_size; + + /* hash table containing sections by target index */ + htab_t section_by_target_index; + + /* hash table containing sections by index */ + htab_t section_by_index; } coff_data_type; /* Tdata for pe image files. */ diff --git a/bfd/peicode.h b/bfd/peicode.h index df1e678b5a..c60961be9f 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -274,6 +274,36 @@ htab_eq_flags (const void *e1, const void *e2) && fe1->target_index == fe2->target_index; } +static hashval_t +htab_hash_section_index (const void *entry) +{ + const struct bfd_section *sec = entry; + return sec->index; +} + +static int +htab_eq_section_index (const void *e1, const void *e2) +{ + const struct bfd_section *sec1 = e1; + const struct bfd_section *sec2 = e2; + return sec1->index == sec2->index; +} + +static hashval_t +htab_hash_section_target_index (const void *entry) +{ + const struct bfd_section *sec = entry; + return sec->target_index; +} + +static int +htab_eq_section_target_index (const void *e1, const void *e2) +{ + const struct bfd_section *sec1 = e1; + const struct bfd_section *sec2 = e2; + return sec1->target_index == sec2->target_index; +} + static bool pe_mkobject (bfd * abfd) { @@ -373,6 +403,11 @@ pe_mkobject_hook (bfd * abfd, memcpy (pe->dos_message, internal_f->pe.dos_message, sizeof (pe->dos_message)); + pe->coff.section_by_index + = htab_create (10, htab_hash_section_index, htab_eq_section_index, NULL); + pe->coff.section_by_target_index = htab_create ( + 10, htab_hash_section_target_index, htab_eq_section_target_index, NULL); + return (void *) pe; } -- 2.40.0.windows.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] add section caches to coff_data_type 2023-04-29 11:19 [PATCH] add section caches to coff_data_type Oleg Tolmatcev @ 2023-05-04 11:29 ` Nick Clifton 2023-05-15 18:47 ` Oleg Tolmatcev 2023-05-04 12:16 ` Tom Tromey 1 sibling, 1 reply; 6+ messages in thread From: Nick Clifton @ 2023-05-04 11:29 UTC (permalink / raw) To: Oleg Tolmatcev, binutils Hi Oleg, > final patch to ld. All the patches together improve linking > performance from 9 minutes to 1 minute when linking rpcs3 in debug > mode with BUILD_LLVM=ON. Unfortunately there are two problems with this patch: 1. It does not initialise the new fields in the coff_tdata structure for targets that just use the COFF file format rather than the PE file format. (ie you need to duplicate the patch to peicode.h in the coffcode.h file). 2. (Actually more important): We either need a copyright assignment from you, or else you need to sign off on the patch before we can accept it. To assign the copyright you should fill out one of the forms here and then send it off to the FSF: https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=tree;f=doc/Copyright;h=22db9a802b4da96ad455cd933351c1359108f95d;hb=HEAD Alternatively you can attach a developer's certificate of origin to your patch, which is easier in the short term, but does need to be done with every patch submission. More details here: https://sourceware.org/binutils/wiki/HowToContribute Cheers Nick PS. For your other two patches, I decided to treat them as "obvious" so no copyright assignment or DCO was needed. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] add section caches to coff_data_type 2023-05-04 11:29 ` Nick Clifton @ 2023-05-15 18:47 ` Oleg Tolmatcev 2023-05-16 13:27 ` Nick Clifton 0 siblings, 1 reply; 6+ messages in thread From: Oleg Tolmatcev @ 2023-05-15 18:47 UTC (permalink / raw) To: Nick Clifton; +Cc: binutils Am Do., 4. Mai 2023 um 13:29 Uhr schrieb Nick Clifton <nickc@redhat.com>: > > Hi Oleg, > > > final patch to ld. All the patches together improve linking > > performance from 9 minutes to 1 minute when linking rpcs3 in debug > > mode with BUILD_LLVM=ON. > > Unfortunately there are two problems with this patch: > > 1. It does not initialise the new fields in the coff_tdata > structure for targets that just use the COFF file format > rather than the PE file format. (ie you need to duplicate > the patch to peicode.h in the coffcode.h file). > > 2. (Actually more important): We either need a copyright > assignment from you, or else you need to sign off on the > patch before we can accept it. To assign the copyright > you should fill out one of the forms here and then send > it off to the FSF: > > https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=tree;f=doc/Copyright;h=22db9a802b4da96ad455cd933351c1359108f95d;hb=HEAD > > Alternatively you can attach a developer's certificate of > origin to your patch, which is easier in the short term, but > does need to be done with every patch submission. More details > here: > > https://sourceware.org/binutils/wiki/HowToContribute Thanks for the review. I have attached the certificate and signed the patch. I don't know where to free the hash tables, that's why I didn't do it. The new patch is below. Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com> --- bfd/coff-x86_64.c | 21 ++++++++++++++++----- bfd/coffcode.h | 35 +++++++++++++++++++++++++++++++++++ bfd/coffgen.c | 27 +++++++++++++++++++++++++-- bfd/libcoff-in.h | 7 +++++++ bfd/peicode.h | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 7 deletions(-) diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c index 822504a339..c62802bdf4 100644 --- a/bfd/coff-x86_64.c +++ b/bfd/coff-x86_64.c @@ -745,7 +745,7 @@ coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, if (rel->r_type == R_AMD64_SECREL) { - bfd_vma osect_vma; + bfd_vma osect_vma = 0; if (h && (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak)) @@ -753,14 +753,25 @@ coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, else { asection *s; - int i; /* Sigh, the only way to get the section to offset against is to find it the hard way. */ - for (s = abfd->sections, i = 1; i < sym->n_scnum; i++) - s = s->next; - osect_vma = s->output_section->vma; + if (htab_elements (coff_data (abfd)->section_by_index) == 0) + { + for (s = abfd->sections; s != NULL; s = s->next) + { + void **slot = htab_find_slot ( + coff_data (abfd)->section_by_index, s, INSERT); + if (slot != NULL) + *slot = s; + } + } + struct bfd_section needle; + needle.index = sym->n_scnum - 1; + s = htab_find (coff_data (abfd)->section_by_index, &needle); + if (s != NULL) + osect_vma = s->output_section->vma; } *addendp -= osect_vma; diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 974c8ad985..3792c84ab1 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -731,6 +731,36 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags) #ifndef COFF_WITH_PE +static hashval_t +htab_hash_section_index (const void *entry) +{ + const struct bfd_section *sec = entry; + return sec->index; +} + +static int +htab_eq_section_index (const void *e1, const void *e2) +{ + const struct bfd_section *sec1 = e1; + const struct bfd_section *sec2 = e2; + return sec1->index == sec2->index; +} + +static hashval_t +htab_hash_section_target_index (const void *entry) +{ + const struct bfd_section *sec = entry; + return sec->target_index; +} + +static int +htab_eq_section_target_index (const void *e1, const void *e2) +{ + const struct bfd_section *sec1 = e1; + const struct bfd_section *sec2 = e2; + return sec1->target_index == sec2->target_index; +} + static bool styp_to_sec_flags (bfd *abfd, void * hdr, @@ -2154,6 +2184,11 @@ coff_mkobject_hook (bfd * abfd, abfd->flags |= HAS_DEBUG; #endif + coff->section_by_index + = htab_create (10, htab_hash_section_index, htab_eq_section_index, NULL); + coff->section_by_target_index = htab_create ( + 10, htab_hash_section_target_index, htab_eq_section_target_index, NULL); + return coff; } #endif diff --git a/bfd/coffgen.c b/bfd/coffgen.c index ac936def56..d11bc03f56 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -42,6 +42,7 @@ #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" +#include "hashtab.h" /* Take a section header read from a coff file (in HOST byte order), and make a BFD "section" out of it. This is used by ECOFF. */ @@ -360,8 +361,6 @@ coff_object_p (bfd *abfd) asection * coff_section_from_bfd_index (bfd *abfd, int section_index) { - struct bfd_section *answer = abfd->sections; - if (section_index == N_ABS) return bfd_abs_section_ptr; if (section_index == N_UNDEF) @@ -369,6 +368,30 @@ coff_section_from_bfd_index (bfd *abfd, int section_index) if (section_index == N_DEBUG) return bfd_abs_section_ptr; + struct bfd_section *answer; + + if (htab_elements (coff_data (abfd)->section_by_target_index) == 0) + { + answer = abfd->sections; + while (answer) + { + void **slot = htab_find_slot ( + coff_data (abfd)->section_by_target_index, answer, INSERT); + if (slot == NULL) + return bfd_und_section_ptr; + *slot = answer; + answer = answer->next; + } + } + + struct bfd_section needle; + needle.target_index = section_index; + + answer = htab_find (coff_data (abfd)->section_by_target_index, &needle); + if (answer != NULL) + return answer; + + answer = abfd->sections; while (answer) { if (answer->target_index == section_index) diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index d0839c76e9..ecd19397cb 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -24,6 +24,7 @@ #include "bfdlink.h" #include "coff-bfd.h" +#include "hashtab.h" #ifdef __cplusplus extern "C" { @@ -129,6 +130,12 @@ typedef struct coff_tdata COFF object into memory. */ char * stub; bfd_size_type stub_size; + + /* hash table containing sections by target index */ + htab_t section_by_target_index; + + /* hash table containing sections by index */ + htab_t section_by_index; } coff_data_type; /* Tdata for pe image files. */ diff --git a/bfd/peicode.h b/bfd/peicode.h index e2e2be65b5..e0b89d33ff 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -255,6 +255,36 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in) #endif } +static hashval_t +htab_hash_section_index (const void *entry) +{ + const struct bfd_section *sec = entry; + return sec->index; +} + +static int +htab_eq_section_index (const void *e1, const void *e2) +{ + const struct bfd_section *sec1 = e1; + const struct bfd_section *sec2 = e2; + return sec1->index == sec2->index; +} + +static hashval_t +htab_hash_section_target_index (const void *entry) +{ + const struct bfd_section *sec = entry; + return sec->target_index; +} + +static int +htab_eq_section_target_index (const void *e1, const void *e2) +{ + const struct bfd_section *sec1 = e1; + const struct bfd_section *sec2 = e2; + return sec1->target_index == sec2->target_index; +} + static bool pe_mkobject (bfd * abfd) { @@ -352,6 +382,11 @@ pe_mkobject_hook (bfd * abfd, memcpy (pe->dos_message, internal_f->pe.dos_message, sizeof (pe->dos_message)); + pe->coff.section_by_index + = htab_create (10, htab_hash_section_index, htab_eq_section_index, NULL); + pe->coff.section_by_target_index = htab_create ( + 10, htab_hash_section_target_index, htab_eq_section_target_index, NULL); + return (void *) pe; } -- 2.40.1.windows.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] add section caches to coff_data_type 2023-05-15 18:47 ` Oleg Tolmatcev @ 2023-05-16 13:27 ` Nick Clifton 2023-05-16 14:36 ` Oleg Tolmatcev 0 siblings, 1 reply; 6+ messages in thread From: Nick Clifton @ 2023-05-16 13:27 UTC (permalink / raw) To: Oleg Tolmatcev; +Cc: binutils Hi Oleg, > Thanks for the review. I have attached the certificate and signed the > patch. I don't know where to free the hash tables, that's why I didn't > do it. The new patch is below. I have gone ahead and applied your patch, with the addition of some extra code to bfd/coffgen.c:_bfd_coff_close_and_cleanup() to free the hash tables. Cheers Nick ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] add section caches to coff_data_type 2023-05-16 13:27 ` Nick Clifton @ 2023-05-16 14:36 ` Oleg Tolmatcev 0 siblings, 0 replies; 6+ messages in thread From: Oleg Tolmatcev @ 2023-05-16 14:36 UTC (permalink / raw) To: Nick Clifton; +Cc: binutils Am Di., 16. Mai 2023 um 15:28 Uhr schrieb Nick Clifton <nickc@redhat.com>: > > Hi Oleg, > > > Thanks for the review. I have attached the certificate and signed the > > patch. I don't know where to free the hash tables, that's why I didn't > > do it. The new patch is below. > > I have gone ahead and applied your patch, with the addition of some extra > code to bfd/coffgen.c:_bfd_coff_close_and_cleanup() to free the hash tables. Thanks a lot Nick. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] add section caches to coff_data_type 2023-04-29 11:19 [PATCH] add section caches to coff_data_type Oleg Tolmatcev 2023-05-04 11:29 ` Nick Clifton @ 2023-05-04 12:16 ` Tom Tromey 1 sibling, 0 replies; 6+ messages in thread From: Tom Tromey @ 2023-05-04 12:16 UTC (permalink / raw) To: Oleg Tolmatcev via Binutils; +Cc: Oleg Tolmatcev >>>>> Oleg Tolmatcev via Binutils <binutils@sourceware.org> writes: > Hello all, > final patch to ld. All the patches together improve linking > performance from 9 minutes to 1 minute when linking rpcs3 in debug > mode with BUILD_LLVM=ON. > + pe->coff.section_by_index > + = htab_create (10, htab_hash_section_index, htab_eq_section_index, NULL); > + pe->coff.section_by_target_index = htab_create ( > + 10, htab_hash_section_target_index, htab_eq_section_target_index, NULL); I think something has to call htab_delete on these to avoid a memory leak. Tom ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-05-16 14:36 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-04-29 11:19 [PATCH] add section caches to coff_data_type Oleg Tolmatcev 2023-05-04 11:29 ` Nick Clifton 2023-05-15 18:47 ` Oleg Tolmatcev 2023-05-16 13:27 ` Nick Clifton 2023-05-16 14:36 ` Oleg Tolmatcev 2023-05-04 12:16 ` Tom Tromey
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).