summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-ia64-speedup.patch')
-rw-r--r--sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-ia64-speedup.patch314
1 files changed, 314 insertions, 0 deletions
diff --git a/sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-ia64-speedup.patch b/sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-ia64-speedup.patch
new file mode 100644
index 000000000000..d93f6e98c351
--- /dev/null
+++ b/sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-ia64-speedup.patch
@@ -0,0 +1,314 @@
+2003-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c: Include objalloc.h, hashtab.h.
+ (struct elfNN_ia64_local_hash_entry): Remove root. Add id and r_sym
+ fields.
+ (struct elfNN_ia64_local_hash_table): Remove.
+ (struct elfNN_ia64_link_hash_table): Change loc_hash_table's type
+ to htab_t. Add loc_hash_memory field.
+ (elfNN_ia64_local_hash_table_init, elfNN_ia64_new_loc_hash_entry):
+ Removed.
+ (elfNN_ia64_local_htab_hash, elfNN_ia64_local_htab_eq): New
+ functions.
+ (elfNN_ia64_hash_table_create): Use hashtab.h hashtable for
+ loc_hash_table. Initialize loc_hash_memory.
+ (elfNN_ia64_hash_table_free): New function.
+ (elfNN_ia64_local_hash_lookup): Remove.
+ (elfNN_ia64_local_dyn_sym_thunk): Change into htab_traverse
+ callback.
+ (elfNN_ia64_dyn_sym_traverse): Use htab_traverse.
+ (get_local_sym_hash): Use hashtab.h hashtable for loc_hash_table.
+ (bfd_elfNN_bfd_link_hash_table_free): Define.
+
+--- bfd/elfxx-ia64.c.jj 2003-09-18 05:30:39.000000000 -0400
++++ bfd/elfxx-ia64.c 2003-09-18 07:37:36.000000000 -0400
+@@ -24,6 +24,8 @@
+ #include "elf-bfd.h"
+ #include "opcode/ia64.h"
+ #include "elf/ia64.h"
++#include "objalloc.h"
++#include "hashtab.h"
+
+ /* THE RULES for all the stuff the linker creates --
+
+@@ -115,7 +117,8 @@ struct elfNN_ia64_dyn_sym_info
+
+ struct elfNN_ia64_local_hash_entry
+ {
+- struct bfd_hash_entry root;
++ int id;
++ unsigned int r_sym;
+ struct elfNN_ia64_dyn_sym_info *info;
+
+ /* TRUE if this hash entry's addends was translated for
+@@ -123,12 +126,6 @@ struct elfNN_ia64_local_hash_entry
+ unsigned sec_merge_done : 1;
+ };
+
+-struct elfNN_ia64_local_hash_table
+-{
+- struct bfd_hash_table root;
+- /* No additional fields for now. */
+-};
+-
+ struct elfNN_ia64_link_hash_entry
+ {
+ struct elf_link_hash_entry root;
+@@ -153,7 +150,8 @@ struct elfNN_ia64_link_hash_table
+ unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
+ bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
+
+- struct elfNN_ia64_local_hash_table loc_hash_table;
++ htab_t loc_hash_table;
++ void *loc_hash_memory;
+ };
+
+ struct elfNN_ia64_allocate_data
+@@ -201,12 +199,6 @@ static bfd_boolean elfNN_ia64_is_local_l
+ PARAMS ((bfd *abfd, const char *name));
+ static bfd_boolean elfNN_ia64_dynamic_symbol_p
+ PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
+-static bfd_boolean elfNN_ia64_local_hash_table_init
+- PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
+- new_hash_entry_func new));
+-static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
+- PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+- const char *string));
+ static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
+ PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string));
+@@ -215,15 +207,17 @@ static void elfNN_ia64_hash_copy_indirec
+ struct elf_link_hash_entry *));
+ static void elfNN_ia64_hash_hide_symbol
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
++static hashval_t elfNN_ia64_local_htab_hash PARAMS ((const void *));
++static int elfNN_ia64_local_htab_eq PARAMS ((const void *ptr1,
++ const void *ptr2));
+ static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
+ PARAMS ((bfd *abfd));
+-static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
+- PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
+- bfd_boolean create, bfd_boolean copy));
++static void elfNN_ia64_hash_table_free
++ PARAMS ((struct bfd_link_hash_table *hash));
+ static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
+ PARAMS ((struct bfd_hash_entry *, PTR));
+-static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
+- PARAMS ((struct bfd_hash_entry *, PTR));
++static int elfNN_ia64_local_dyn_sym_thunk
++ PARAMS ((void **, PTR));
+ static void elfNN_ia64_dyn_sym_traverse
+ PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
+ bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
+@@ -1520,44 +1514,6 @@ elfNN_ia64_dynamic_symbol_p (h, info, r_
+ return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
+ }
+
+-static bfd_boolean
+-elfNN_ia64_local_hash_table_init (ht, abfd, new)
+- struct elfNN_ia64_local_hash_table *ht;
+- bfd *abfd ATTRIBUTE_UNUSED;
+- new_hash_entry_func new;
+-{
+- memset (ht, 0, sizeof (*ht));
+- return bfd_hash_table_init (&ht->root, new);
+-}
+-
+-static struct bfd_hash_entry*
+-elfNN_ia64_new_loc_hash_entry (entry, table, string)
+- struct bfd_hash_entry *entry;
+- struct bfd_hash_table *table;
+- const char *string;
+-{
+- struct elfNN_ia64_local_hash_entry *ret;
+- ret = (struct elfNN_ia64_local_hash_entry *) entry;
+-
+- /* Allocate the structure if it has not already been allocated by a
+- subclass. */
+- if (!ret)
+- ret = bfd_hash_allocate (table, sizeof (*ret));
+-
+- if (!ret)
+- return 0;
+-
+- /* Initialize our local data. All zeros, and definitely easier
+- than setting a handful of bit fields. */
+- memset (ret, 0, sizeof (*ret));
+-
+- /* Call the allocation method of the superclass. */
+- ret = ((struct elfNN_ia64_local_hash_entry *)
+- bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+-
+- return (struct bfd_hash_entry *) ret;
+-}
+-
+ static struct bfd_hash_entry*
+ elfNN_ia64_new_elf_hash_entry (entry, table, string)
+ struct bfd_hash_entry *entry;
+@@ -1657,6 +1613,33 @@ elfNN_ia64_hash_hide_symbol (info, xh, f
+ }
+ }
+
++/* Compute a hash of a local hash entry. */
++
++static hashval_t
++elfNN_ia64_local_htab_hash (ptr)
++ const void *ptr;
++{
++ struct elfNN_ia64_local_hash_entry *entry
++ = (struct elfNN_ia64_local_hash_entry *) ptr;
++
++ return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
++ ^ entry->r_sym ^ (entry->id >> 16);
++}
++
++/* Compare local hash entries. */
++
++static int
++elfNN_ia64_local_htab_eq (ptr1, ptr2)
++ const void *ptr1, *ptr2;
++{
++ struct elfNN_ia64_local_hash_entry *entry1
++ = (struct elfNN_ia64_local_hash_entry *) ptr1;
++ struct elfNN_ia64_local_hash_entry *entry2
++ = (struct elfNN_ia64_local_hash_entry *) ptr2;
++
++ return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
++}
++
+ /* Create the derived linker hash table. The IA-64 ELF port uses this
+ derived hash table to keep information specific to the IA-64 ElF
+ linker (without using static variables). */
+@@ -1678,8 +1661,10 @@ elfNN_ia64_hash_table_create (abfd)
+ return 0;
+ }
+
+- if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
+- elfNN_ia64_new_loc_hash_entry))
++ ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
++ elfNN_ia64_local_htab_eq, NULL);
++ ret->loc_hash_memory = objalloc_create ();
++ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ free (ret);
+ return 0;
+@@ -1688,16 +1673,19 @@ elfNN_ia64_hash_table_create (abfd)
+ return &ret->root.root;
+ }
+
+-/* Look up an entry in a Alpha ELF linker hash table. */
++/* Destroy IA-64 linker hash table. */
+
+-static INLINE struct elfNN_ia64_local_hash_entry *
+-elfNN_ia64_local_hash_lookup(table, string, create, copy)
+- struct elfNN_ia64_local_hash_table *table;
+- const char *string;
+- bfd_boolean create, copy;
++static void
++elfNN_ia64_hash_table_free (hash)
++ struct bfd_link_hash_table *hash;
+ {
+- return ((struct elfNN_ia64_local_hash_entry *)
+- bfd_hash_lookup (&table->root, string, create, copy));
++ struct elfNN_ia64_link_hash_table *ia64_info
++ = (struct elfNN_ia64_link_hash_table *) hash;
++ if (ia64_info->loc_hash_table)
++ htab_delete (ia64_info->loc_hash_table);
++ if (ia64_info->loc_hash_memory)
++ objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
++ _bfd_generic_link_hash_table_free (hash);
+ }
+
+ /* Traverse both local and global hash tables. */
+@@ -1729,20 +1717,20 @@ elfNN_ia64_global_dyn_sym_thunk (xentry,
+ }
+
+ static bfd_boolean
+-elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
+- struct bfd_hash_entry *xentry;
++elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
++ void **slot;
+ PTR xdata;
+ {
+ struct elfNN_ia64_local_hash_entry *entry
+- = (struct elfNN_ia64_local_hash_entry *) xentry;
++ = (struct elfNN_ia64_local_hash_entry *) *slot;
+ struct elfNN_ia64_dyn_sym_traverse_data *data
+ = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+
+ for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
+ if (! (*data->func) (dyn_i, data->data))
+- return FALSE;
+- return TRUE;
++ return 0;
++ return 1;
+ }
+
+ static void
+@@ -1758,8 +1746,8 @@ elfNN_ia64_dyn_sym_traverse (ia64_info,
+
+ elf_link_hash_traverse (&ia64_info->root,
+ elfNN_ia64_global_dyn_sym_thunk, &xdata);
+- bfd_hash_traverse (&ia64_info->loc_hash_table.root,
+- elfNN_ia64_local_dyn_sym_thunk, &xdata);
++ htab_traverse (ia64_info->loc_hash_table,
++ elfNN_ia64_local_dyn_sym_thunk, &xdata);
+ }
+
+ static bfd_boolean
+@@ -1819,22 +1807,33 @@ get_local_sym_hash (ia64_info, abfd, rel
+ const Elf_Internal_Rela *rel;
+ bfd_boolean create;
+ {
+- struct elfNN_ia64_local_hash_entry *ret;
++ struct elfNN_ia64_local_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+- char addr_name [34];
++ hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
++ ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
++ void **slot;
++
++ e.id = sec->id;
++ e.r_sym = ELFNN_R_SYM (rel->r_info);
++ slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
++ create ? INSERT : NO_INSERT);
+
+- BFD_ASSERT ((sizeof (sec->id)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
+- BFD_ASSERT (sec);
+-
+- /* Construct a string for use in the elfNN_ia64_local_hash_table.
+- name describes what was once anonymous memory. */
++ if (!slot)
++ return NULL;
+
+- sprintf (addr_name, "%x:%lx",
+- sec->id, (unsigned long) ELFNN_R_SYM (rel->r_info));
++ if (*slot)
++ return (struct elfNN_ia64_local_hash_entry *) *slot;
+
+- /* Collect the canonical entry data for this address. */
+- ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
+- addr_name, create, create);
++ ret = (struct elfNN_ia64_local_hash_entry *)
++ objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
++ sizeof (struct elfNN_ia64_local_hash_entry));
++ if (ret)
++ {
++ memset (ret, 0, sizeof (*ret));
++ ret->id = sec->id;
++ ret->r_sym = ELFNN_R_SYM (rel->r_info);
++ *slot = ret;
++ }
+ return ret;
+ }
+
+@@ -4823,6 +4822,8 @@ elfNN_hpux_backend_section_from_bfd_sect
+ /* Stuff for the BFD linker: */
+ #define bfd_elfNN_bfd_link_hash_table_create \
+ elfNN_ia64_hash_table_create
++#define bfd_elfNN_bfd_link_hash_table_free \
++ elfNN_ia64_hash_table_free
+ #define elf_backend_create_dynamic_sections \
+ elfNN_ia64_create_dynamic_sections
+ #define elf_backend_check_relocs \