Redo gas local symbol support
authorAlan Modra <amodra@gmail.com>
Thu, 20 Aug 2020 06:06:46 +0000 (15:36 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 21 Aug 2020 09:09:54 +0000 (18:39 +0930)
commit5014c2d22b2627eb1ac88a4763a58d431fe064a7
treea2bc2b7bf9565f4f6826af556162a606966eb7a9
parent3c0d9d71db89b5b55ae7f6cb180f4f548efa4bef
Redo gas local symbol support

gas handles local symbols specially in order to save memory, but the
implementation using two separate hash tables is inefficient,
particularly the scheme of duplicating a struct local_symbol when it
needs to be converted to a full struct symbol.  Also, updating symbol
pointers with LOCAL_SYMBOL_CHECK is horrible and has led to some hard
to find bugs.

This changes the implementation to use a single hash table and avoids
another copy of the symbol name in symbol_entry_t.  When converting
local symbols the struct local_symbol memory is reused.  Not only
does that save memory, but there is no need to twiddle symbol pointers
with LOCAL_SYMBOL_CHECK.

Assembling gcc-10 -g -Og gold/powerpc.cc output shows the following:

old:
symbol table hash statistics:
1371192 searches
1290398 collisions
143585 elements
262139 table size
mini local symbol table hash statistics:
2966204 searches
2707489 collisions
523533 elements
1048573 table size
523533 mini local symbols created, 140453 converted

new:
symbol table hash statistics:
2828883 searches
2453138 collisions
526665 elements
1048573 table size
523533 mini local symbols created, 140453 converted

* symbols.c (struct local_symbol): Add "hash" entry.  Reorder fields.
Delete union.  Adjust code throughout file.
(struct symbol): Add "hash", "name" and "x" entries.  Reorder fields.
Split off some to..
(struct xsymbol): ..this.  New struct.  Adjust code throughout file
accessing these fields.
(struct symbol_entry): Delete.
(union symbol_entry): New.
(hash_symbol_entry): Adjust for symbol_entry_t change.
(symbol_entry_find): Likewise.
(eq_symbol_entry): Compare hash values too.
(symbol_entry_alloc): Delete.
(local_symbol_converted_p, local_symbol_mark_converted): Delete.
(local_symbol_get_real_symbol, local_symbol_set_real_symbol): Delete.
(local_hash): Delete.
(abs_symbol_x, dot_symbol_x): New static var.
(symbol_init): New function.
(symbol_create): Rewrite.
(LOCAL_SYMBOL_CHECK): Delete.  Replace uses throughout with simple
test of flags.local_symbol.
(local_symbol_make): Adjust for struct local_symbol changes.
(local_symbol_convert): Rewrite.  Adjust all callers.
(symbol_table_insert): Simplify.
(symbol_clone): Comment on local sym cloning.  Handle split symbol
struct.
(get_real_sym): Delete.  Remove all uses.
(symbol_find_exact_noref): Simplify.
(resolve_local_symbol): Don't resolve non-locals.
(S_SET_SEGMENT): Don't special case reg_section.
(S_SET_NAME): Set both name and bsym->name.
(symbol_mark_resolved, symbol_resolved_p): Simplify.
(symbol_symbolS): Update comment.
(symbol_begin): Don't create local_hash.  Adjust abs_symbol setup.
(dot_symbol_init): Adjust dot_symbol setup.
(symbol_print_statistics): Delete local_hash stats.
gas/ChangeLog
gas/symbols.c