diff options
author | crowl <crowl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-26 00:28:35 +0000 |
---|---|---|
committer | crowl <crowl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-26 00:28:35 +0000 |
commit | d9dd21a8b41029862ef23f68421a4b5bcfe72183 (patch) | |
tree | 5115f0a81b7cea52ab7997ce3322160f2baf2374 /gcc | |
parent | 0aeec17dae90b4fd400009f1e83e85e07ee5bb92 (diff) | |
download | gcc-d9dd21a8b41029862ef23f68421a4b5bcfe72183.tar.gz |
This patch is the main part of a consolodation of the hash_table
patches to the cxx-conversion branch for files not under gcc/config.
Update various hash tables from htab_t to hash_table.
Modify types and calls to match.
* tree-parloops.c'reduction
* tree-parloops.c'name_to_copy
Fold reduction_info_hash and reduction_info_eq into new struct
reduction_hasher. Fold name_to_copy_elt_eq and name_to_copy_elt_hash
into new struct name_to_copy_hasher.
* trans-mem.c'tm_log
Fold tm_log_hash, tm_log_eq, tm_log_free into new struct log_entry_hasher.
* trans-mem.c'tm_memopt_value_numbers
Fold tm_memop_hash, tm_memop_eq into new struct tm_memop_hasher.
* tree-ssa-strlen.c'decl_to_stridxlist_htab
Fold decl_to_stridxlist_hash into new struct stridxlist_hasher.
* tree-ssa-loop-ivopts.c'ivopts_data::inv_expr_tab
Fold htab_inv_expr_hash and htab_inv_expr_eq into new struct
iv_inv_expr_hasher.
* tree-ssa-uncprop.c'equiv
Equiv renamed to val_ssa_equiv because of name ambiguity with local variables.
Fold equiv_hash, equiv_eq and equiv_free into new struct val_ssa_equiv_hasher.
Renamed variables equiv_hash_elt to an_equiv_elt because of name ambiguity
with struct type. Changed equiv_hash_elt_p to an_equiv_elt_p to match.
* tree-ssa-phiopt.c'seen_ssa_names
Fold name_to_bb_hash and name_to_bb_eq into new struct ssa_names_hasher.
* tree-ssa-structalias.c'pointer_equiv_class_table
* tree-ssa-structalias.c'location_equiv_class_table
Fold equiv_class_label_hash and equiv_class_label_eq into new
struct equiv_class_hasher.
* tree-ssa-structalias.c'shared_bitmap_table
Fold shared_bitmap_hash and shared_bitmap_eq into new struct
shared_bitmap_hasher.
* tree-ssa-live.c'var_map_base_init::tree_to_index
New struct tree_int_map_hasher.
* tree-sra.c'candidates
Fold uid_decl_map_hash and uid_decl_map_eq into new struct
uid_decl_hasher. This change moves the definitions from tree-ssa.c
into tree-sra.c and removes the declarations from tree-flow.h
tree-browser.c
Remove stale declaration of removed TB_parent_eq.
Fix template parameter for base class to match value_type.
gimple.h
Use gimplify_hasher::hash rather than gimple_tree_hash in the
assertion check.
Change return values to match return type. (I.e. no conversions.)
* graphite-clast-to-gimple.c'ivs_params::newivs_index
* graphite-clast-to-gimple.c'ivs_params::params_index
* graphite-clast-to-gimple.c'print_generated_program::params_index
* graphite-clast-to-gimple.c'gloog::newivs_index
* graphite-clast-to-gimple.c'gloog::params_index
* graphite.c graphite_transform_loops::bb_pbb_mapping
* sese.c copy_bb_and_scalar_dependences::rename_map
Move hash table declarations to a new graphite-htab.h, because they
are used in few places.
Remove unused:
htab_t scop::original_pddrs
SCOP_ORIGINAL_PDDRS
Remove unused:
insert_loop_close_phis
insert_guard_phis
debug_ivtype_map
ivtype_map_elt_info
new_ivtype_map_elt
* gimplify.c'gimplify_ctx::temp_htab
Move struct gimple_temp_hash_elt and struct gimplify_ctx to a new
gimplify-ctx.h, because they are used few places.
* cselib.c'cselib_hash_table
* gcse.c'pre_ldst_table
* gimple-ssa-strength-reduction.c'base_cand_map
* haifa-sched.c'delay_htab
* haifa-sched.c'delay_htab_i2
* ira-color.c'allocno_hard_regs_htab
* ira-costs.c'cost_classes_htab
* loop-invariant.c'merge_identical_invariants::eq
* loop-iv.c'bivs
* loop-unroll.c'opt_info::insns_to_split
* loop-unroll.c'opt_info::insns_with_var_to_expand
* passes.c'name_to_pass_map
* plugin.c'event_tab
* postreload-gcse.c'expr_table
* store-motion.c'store_motion_mems_table
* tree-cfg.c'discriminator_per_locus
* tree-scalar-evolution.c'resolve_mixers::cache
* tree-ssa-dom.c'avail_exprs
Remove unused:
dse.c bitmap clear_alias_sets
dse.c bitmap disqualified_clear_alias_sets
dse.c alloc_pool clear_alias_mode_pool
dse.c dse_step2_spill
dse.c dse_step5_spill
graphds.h htab_t graph::indices
* attribs.c'scoped_attributes::attribute_hash
* bitmap.c'bitmap_desc_hash
* dwarf2cfi.c'trace_index
* dwarf2out.c'break_out_includes::cu_hash_table
* dwarf2out.c'copy_decls_for_unworthy_types::decl_table
* dwarf2out.c'optimize_external_refs::map
* dwarf2out.c'output_comp_unit::extern_map
* dwarf2out.c'output_comdat_type_unit::extern_map
* dwarf2out.c'output_macinfo::macinfo_htab
* dwarf2out.c'optimize_location_lists::htab
* dwarf2out.c'dwarf2out_finish::comdat_type_table
* except.c'ehspec_hash_type
* except.c'assign_filter_values::ttypes
* except.c'assign_filter_values::ehspec
* except.c'sjlj_assign_call_site_values::ar_hash
* except.c'convert_to_eh_region_ranges::ar_hash
* trans-mem.c'tm_new_mem_hash
* tree-browser.c'TB_up_ht
* tree-eh.c'finally_tree
Move the declaration of hash_table <alloc_pool_hasher> alloc_pool_hash
in alloc-pool.c to after the method definitions for its parameter
class.
* ggc-common.c'loc_hash
* ggc-common.c'ptr_hash
Add a new hash_table method elements_with_deleted to meet the needs of
gcc-common.c.
Correct many methods with parameter types compare_type to the correct
value_type. (Correct code was unlikely to notice the change, but
incorrect code will.)
* tree-complex.c'complex_variable_components
* tree-parloops.c'eliminate_local_variables_stmt::decl_address
* tree-parloops.c'separate_decls_in_region::decl_copies
Move hash table declarations to a new tree-hasher.h, to resolve
compilation dependences and because they are used in few places.
* lto-streamer.h'output_block::string_hash_table
* lto-streamer-in.c'file_name_hash_table
* lto-streamer.c'tree_htab
The struct string_slot moves from data-streamer.h to lto-streamer.h to
resolve compilation dependences.
Tested on x86_64.
Index: gcc/ChangeLog
2013-04-25 Lawrence Crowl <crowl@google.com>
* Makefile.in: Update as needed below.
* alloc-pool.c (static hash_table <alloc_pool_hasher> alloc_pool_hash):
Move declaration to after the type's method definitons.
* attribs.c (htab_t scoped_attributes::attribute_hash):
Change type to hash_table. Update dependent calls and types.
* bitmap.c (htab_t bitmap_desc_hash):
Change type to hash_table. Update dependent calls and types.
* cselib.c (htab_t cselib_hash_table):
Change type to hash_table. Update dependent calls and types.
* data-streamer.h (struct string_slot): Move to lto-streamer.h.
(hash_string_slot_node): Move implementation into lto-streamer.h
struct string_slot_hasher.
(eq_string_slot_node): Likewise.
* data-streamer-out.c: Update output_block::string_hash_table
dependent calls and types.
* dwarf2cfi.c (htab_t trace_index):
Change type to hash_table. Update dependent calls and types.
* dwarf2out.c (htab_t break_out_includes::cu_hash_table):
Change type to hash_table. Update dependent calls and types.
(htab_t copy_decls_for_unworthy_types::decl_table): Likewise.
(htab_t optimize_external_refs::map): Likewise.
(htab_t output_comp_unit::extern_map): Likewise.
(htab_t output_comdat_type_unit::extern_map): Likewise.
(htab_t output_macinfo::macinfo_htab): Likewise.
(htab_t optimize_location_lists::htab): Likewise.
(htab_t dwarf2out_finish::comdat_type_table): Likewise.
* except.c (htab_t ehspec_hash_type):
Change type to hash_table. Update dependent calls and types.
(assign_filter_values::ttypes): Likewise.
(assign_filter_values::ehspec): Likewise.
(sjlj_assign_call_site_values::ar_hash): Likewise.
(convert_to_eh_region_ranges::ar_hash): Likewise.
* gcse.c (htab_t pre_ldst_table):
Change type to hash_table. Update dependent calls and types.
* ggc-common.c (htab_t saving_htab):
Change type to hash_table. Update dependent calls and types.
(htab_t loc_hash): Likewise.
(htab_t ptr_hash): Likewise.
(call_count): Rename ggc_call_count.
(call_alloc): Rename ggc_call_alloc.
(loc_descriptor): Rename make_loc_descriptor.
(add_statistics): Rename ggc_add_statistics.
* ggc-common.c (saving_htab):
Change type to hash_table. Update dependent calls and types.
* gimple.h (struct gimplify_ctx): Move to gimplify-ctx.h.
(push_gimplify_context): Likewise.
(pop_gimplify_context): Likewise.
(struct gimple_temp_hash_elt): Added.
(struct gimplify_hasher): Likewise.
(struct gimplify_ctx.temp_htab):
Change type to hash_table. Update dependent calls and types.
* gimple-fold.c: Include gimplify-ctx.h.
* gimple-ssa-strength-reduction.c (htab_t base_cand_map):
Change type to hash_table. Update dependent calls and types.
(base_cand_dump_callback): Rename to ssa_base_cand_dump_callback to
avoid potential global name collision.
* gimplify.c: Include gimplify-ctx.h.
(struct gimple_temp_hash_elt): Move to gimplify-ctx.h.
(htab_t gimplify_ctx::temp_htab):
Update dependent calls and types for new type hash_table.
(gimple_tree_hash): Move into gimplify_hasher in gimplify-ctx.h.
(gimple_tree_eq): Move into gimplify_hasher in gimplify-ctx.h.
* gimplify-ctx.h: New.
(struct gimple_temp_hash_elt): Move from gimplify.c.
(class gimplify_hasher): New.
(struct gimplify_ctx): Move from gimple.h.
(htab_t gimplify_ctx::temp_htab):
Change type to hash_table. Update dependent calls and types.
* graphite-clast-to-gimple.c: Include graphite-htab.h.
(htab_t ivs_params::newivs_index):
Change type to hash_table. Update dependent calls and types.
(htab_t ivs_params::params_index): Likewise.
(htab_t print_generated_program::params_index): Likewise.
(htab_t gloog::newivs_index): Likewise.
(htab_t gloog::params_index): Likewise.
* graphite.c: Include graphite-htab.h.
4htab_t graphite_transform_loops::bb_pbb_mapping):
Change type to hash_table. Update dependent calls and types.
* graphite-clast-to-gimple.h: (extern gloog) Move to graphite-htab.h.
(bb_pbb_map_hash): Fold into bb_pbb_htab_type in graphite-htab.h.
(eq_bb_pbb_map): Fold into bb_pbb_htab_type in graphite-htab.h.
* graphite-dependences.c: Include graphite-htab.h.
(loop_is_parallel_p): Change hash table type of parameter.
* graphite-htab.h: New.
(typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type): New.
(extern find_pbb_via_hash): Move from graphite-poly.h.
(extern loop_is_parallel_p): Move from graphite-poly.h.
(extern get_loop_body_pbbs): Move from graphite-poly.h.
* graphite-poly.h (extern find_pbb_via_hash): Move to graphite-htab.h.
(extern loop_is_parallel_p): Move to graphite-htab.h.
(extern get_loop_body_pbbs): Move to graphite-htab.h.
* haifa-sched.c (htab_t delay_htab):
Change type to hash_table. Update dependent calls and types.
(htab_t delay_htab_i2): Likewise.
* ira-color.c (htab_t allocno_hard_regs_htab):
Change type to hash_table. Update dependent calls and types.
* ira-costs.c (htab_t cost_classes_htab):
Change type to hash_table. Update dependent calls and types.
* loop-invariant.c (htab_t merge_identical_invariants::eq):
Change type to hash_table. Update dependent calls and types.
* loop-iv.c (htab_t bivs):
Change type to hash_table. Update dependent calls and types.
* loop-unroll.c (htab_t opt_info::insns_to_split):
Change type to hash_table. Update dependent calls and types.
(htab_t opt_info::insns_with_var_to_expand): Likewise.
* lto-streamer.h (struct string_slot): Move from data-streamer.h
(struct string_slot_hasher): New.
(htab_t output_block::string_hash_table):
Change type to hash_table. Update dependent calls and types.
* lto-streamer-in.c (freeing_string_slot_hasher): New.
(htab_t file_name_hash_table):
Change type to hash_table. Update dependent calls and types.
* lto-streamer-out.c: Update output_block::string_hash_table dependent
calls and types.
* lto-streamer.c (htab_t tree_htab):
Change type to hash_table. Update dependent calls and types.
* omp-low.c: Include gimplify-ctx.h.
* passes.c (htab_t name_to_pass_map):
Change type to hash_table. Update dependent calls and types.
(pass_traverse): Rename to passes_pass_traverse.
* plugin.c (htab_t event_tab):
Change type to hash_table. Update dependent calls and types.
* postreload-gcse.c (htab_t expr_table):
Change type to hash_table. Update dependent calls and types.
(dump_hash_table_entry): Rename dump_expr_hash_table_entry.
* sese.c (debug_rename_map_1): Make extern.
(htab_t copy_bb_and_scalar_dependences::rename_map):
Change type to hash_table. Update dependent calls and types.
* sese.h (extern debug_rename_map): Move to .c file.
* store-motion.c (htab_t store_motion_mems_table):
Change type to hash_table. Update dependent calls and types.
* trans-mem.c (htab_t tm_new_mem_hash):
Change type to hash_table. Update dependent calls and types.
* tree-browser.c (htab_t TB_up_ht):
Change type to hash_table. Update dependent calls and types.
* tree-cfg.c (htab_t discriminator_per_locus):
Change type to hash_table. Update dependent calls and types.
* tree-complex.c: Include tree-hasher.h
(htab_t complex_variable_components):
Change type to hash_table. Update dependent calls and types.
* tree-eh.c (htab_t finally_tree):
Change type to hash_table. Update dependent calls and types.
* tree-flow.h (extern int_tree_map_hash): Moved into tree-hasher
struct int_tree_hasher.
(extern int_tree_map_eq): Likewise.
(uid_decl_map_hash): Removed.
(extern decl_tree_map_eq): Likewise.
* tree-hasher.h: New.
(struct int_tree_hasher): New.
(typedef int_tree_htab_type): New.
* tree-inline.c: Include gimplify-ctx.h.
* tree-mudflap.c: Include gimplify-ctx.h.
* tree-parloops.c: Include tree-hasher.h.
(htab_t eliminate_local_variables_stmt::decl_address):
Change type to hash_table. Update dependent calls and types.
(htab_t separate_decls_in_region::decl_copies): Likewise.
* tree-scalar-evolution.c (htab_t resolve_mixers::cache):
Change type to hash_table. Update dependent calls and types.
* tree-sra.c (candidates):
Change type to hash_table. Update dependent calls and types.
* tree-ssa.c (int_tree_map_eq): Moved into struct int_tree_hasher
in tree-flow.h.
(int_tree_map_hash): Likewise.
* tree-ssa-dom.c (htab_t avail_exprs):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-live.c (var_map_base_init::tree_to_index):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-loop-ivopts.c (struct ivopts_data.inv_expr_tab):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-phiopt.c (seen_ssa_names):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-strlen.c (decl_to_stridxlist_htab):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-uncprop.c (equiv):
Change type to hash_table. Update dependent calls and types.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198329 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
55 files changed, 2572 insertions, 1843 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 847b1e6128e..c63c9e08f7c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,240 @@ +2013-04-25 Lawrence Crowl <crowl@google.com> + + * Makefile.in: Update as needed below. + + * alloc-pool.c (static hash_table <alloc_pool_hasher> alloc_pool_hash): + Move declaration to after the type's method definitons. + + * attribs.c (htab_t scoped_attributes::attribute_hash): + Change type to hash_table. Update dependent calls and types. + + * bitmap.c (htab_t bitmap_desc_hash): + Change type to hash_table. Update dependent calls and types. + + * cselib.c (htab_t cselib_hash_table): + Change type to hash_table. Update dependent calls and types. + + * data-streamer.h (struct string_slot): Move to lto-streamer.h. + (hash_string_slot_node): Move implementation into lto-streamer.h + struct string_slot_hasher. + (eq_string_slot_node): Likewise. + + * data-streamer-out.c: Update output_block::string_hash_table + dependent calls and types. + + * dwarf2cfi.c (htab_t trace_index): + Change type to hash_table. Update dependent calls and types. + + * dwarf2out.c (htab_t break_out_includes::cu_hash_table): + Change type to hash_table. Update dependent calls and types. + (htab_t copy_decls_for_unworthy_types::decl_table): Likewise. + (htab_t optimize_external_refs::map): Likewise. + (htab_t output_comp_unit::extern_map): Likewise. + (htab_t output_comdat_type_unit::extern_map): Likewise. + (htab_t output_macinfo::macinfo_htab): Likewise. + (htab_t optimize_location_lists::htab): Likewise. + (htab_t dwarf2out_finish::comdat_type_table): Likewise. + + * except.c (htab_t ehspec_hash_type): + Change type to hash_table. Update dependent calls and types. + (assign_filter_values::ttypes): Likewise. + (assign_filter_values::ehspec): Likewise. + (sjlj_assign_call_site_values::ar_hash): Likewise. + (convert_to_eh_region_ranges::ar_hash): Likewise. + + * gcse.c (htab_t pre_ldst_table): + Change type to hash_table. Update dependent calls and types. + + * ggc-common.c (htab_t saving_htab): + Change type to hash_table. Update dependent calls and types. + (htab_t loc_hash): Likewise. + (htab_t ptr_hash): Likewise. + (call_count): Rename ggc_call_count. + (call_alloc): Rename ggc_call_alloc. + (loc_descriptor): Rename make_loc_descriptor. + (add_statistics): Rename ggc_add_statistics. + + * ggc-common.c (saving_htab): + Change type to hash_table. Update dependent calls and types. + + * gimple.h (struct gimplify_ctx): Move to gimplify-ctx.h. + (push_gimplify_context): Likewise. + (pop_gimplify_context): Likewise. + (struct gimple_temp_hash_elt): Added. + (struct gimplify_hasher): Likewise. + (struct gimplify_ctx.temp_htab): + Change type to hash_table. Update dependent calls and types. + + * gimple-fold.c: Include gimplify-ctx.h. + + * gimple-ssa-strength-reduction.c (htab_t base_cand_map): + Change type to hash_table. Update dependent calls and types. + (base_cand_dump_callback): Rename to ssa_base_cand_dump_callback to + avoid potential global name collision. + + * gimplify.c: Include gimplify-ctx.h. + (struct gimple_temp_hash_elt): Move to gimplify-ctx.h. + (htab_t gimplify_ctx::temp_htab): + Update dependent calls and types for new type hash_table. + (gimple_tree_hash): Move into gimplify_hasher in gimplify-ctx.h. + (gimple_tree_eq): Move into gimplify_hasher in gimplify-ctx.h. + + * gimplify-ctx.h: New. + (struct gimple_temp_hash_elt): Move from gimplify.c. + (class gimplify_hasher): New. + (struct gimplify_ctx): Move from gimple.h. + (htab_t gimplify_ctx::temp_htab): + Change type to hash_table. Update dependent calls and types. + + * graphite-clast-to-gimple.c: Include graphite-htab.h. + (htab_t ivs_params::newivs_index): + Change type to hash_table. Update dependent calls and types. + (htab_t ivs_params::params_index): Likewise. + (htab_t print_generated_program::params_index): Likewise. + (htab_t gloog::newivs_index): Likewise. + (htab_t gloog::params_index): Likewise. + + * graphite.c: Include graphite-htab.h. + 4htab_t graphite_transform_loops::bb_pbb_mapping): + Change type to hash_table. Update dependent calls and types. + + * graphite-clast-to-gimple.h: (extern gloog) Move to graphite-htab.h. + (bb_pbb_map_hash): Fold into bb_pbb_htab_type in graphite-htab.h. + (eq_bb_pbb_map): Fold into bb_pbb_htab_type in graphite-htab.h. + + * graphite-dependences.c: Include graphite-htab.h. + (loop_is_parallel_p): Change hash table type of parameter. + + * graphite-htab.h: New. + (typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type): New. + (extern find_pbb_via_hash): Move from graphite-poly.h. + (extern loop_is_parallel_p): Move from graphite-poly.h. + (extern get_loop_body_pbbs): Move from graphite-poly.h. + + * graphite-poly.h (extern find_pbb_via_hash): Move to graphite-htab.h. + (extern loop_is_parallel_p): Move to graphite-htab.h. + (extern get_loop_body_pbbs): Move to graphite-htab.h. + + * haifa-sched.c (htab_t delay_htab): + Change type to hash_table. Update dependent calls and types. + (htab_t delay_htab_i2): Likewise. + + * ira-color.c (htab_t allocno_hard_regs_htab): + Change type to hash_table. Update dependent calls and types. + + * ira-costs.c (htab_t cost_classes_htab): + Change type to hash_table. Update dependent calls and types. + + * loop-invariant.c (htab_t merge_identical_invariants::eq): + Change type to hash_table. Update dependent calls and types. + + * loop-iv.c (htab_t bivs): + Change type to hash_table. Update dependent calls and types. + + * loop-unroll.c (htab_t opt_info::insns_to_split): + Change type to hash_table. Update dependent calls and types. + (htab_t opt_info::insns_with_var_to_expand): Likewise. + + * lto-streamer.h (struct string_slot): Move from data-streamer.h + (struct string_slot_hasher): New. + (htab_t output_block::string_hash_table): + Change type to hash_table. Update dependent calls and types. + + * lto-streamer-in.c (freeing_string_slot_hasher): New. + (htab_t file_name_hash_table): + Change type to hash_table. Update dependent calls and types. + + * lto-streamer-out.c: Update output_block::string_hash_table dependent + calls and types. + + * lto-streamer.c (htab_t tree_htab): + Change type to hash_table. Update dependent calls and types. + + * omp-low.c: Include gimplify-ctx.h. + + * passes.c (htab_t name_to_pass_map): + Change type to hash_table. Update dependent calls and types. + (pass_traverse): Rename to passes_pass_traverse. + + * plugin.c (htab_t event_tab): + Change type to hash_table. Update dependent calls and types. + + * postreload-gcse.c (htab_t expr_table): + Change type to hash_table. Update dependent calls and types. + (dump_hash_table_entry): Rename dump_expr_hash_table_entry. + + * sese.c (debug_rename_map_1): Make extern. + (htab_t copy_bb_and_scalar_dependences::rename_map): + Change type to hash_table. Update dependent calls and types. + + * sese.h (extern debug_rename_map): Move to .c file. + + * store-motion.c (htab_t store_motion_mems_table): + Change type to hash_table. Update dependent calls and types. + + * trans-mem.c (htab_t tm_new_mem_hash): + Change type to hash_table. Update dependent calls and types. + + * tree-browser.c (htab_t TB_up_ht): + Change type to hash_table. Update dependent calls and types. + + * tree-cfg.c (htab_t discriminator_per_locus): + Change type to hash_table. Update dependent calls and types. + + * tree-complex.c: Include tree-hasher.h + (htab_t complex_variable_components): + Change type to hash_table. Update dependent calls and types. + + * tree-eh.c (htab_t finally_tree): + Change type to hash_table. Update dependent calls and types. + + * tree-flow.h (extern int_tree_map_hash): Moved into tree-hasher + struct int_tree_hasher. + (extern int_tree_map_eq): Likewise. + (uid_decl_map_hash): Removed. + (extern decl_tree_map_eq): Likewise. + + * tree-hasher.h: New. + (struct int_tree_hasher): New. + (typedef int_tree_htab_type): New. + + * tree-inline.c: Include gimplify-ctx.h. + + * tree-mudflap.c: Include gimplify-ctx.h. + + * tree-parloops.c: Include tree-hasher.h. + (htab_t eliminate_local_variables_stmt::decl_address): + Change type to hash_table. Update dependent calls and types. + (htab_t separate_decls_in_region::decl_copies): Likewise. + + * tree-scalar-evolution.c (htab_t resolve_mixers::cache): + Change type to hash_table. Update dependent calls and types. + + * tree-sra.c (candidates): + Change type to hash_table. Update dependent calls and types. + + * tree-ssa.c (int_tree_map_eq): Moved into struct int_tree_hasher + in tree-flow.h. + (int_tree_map_hash): Likewise. + + * tree-ssa-dom.c (htab_t avail_exprs): + Change type to hash_table. Update dependent calls and types. + + * tree-ssa-live.c (var_map_base_init::tree_to_index): + Change type to hash_table. Update dependent calls and types. + + * tree-ssa-loop-ivopts.c (struct ivopts_data.inv_expr_tab): + Change type to hash_table. Update dependent calls and types. + + * tree-ssa-phiopt.c (seen_ssa_names): + Change type to hash_table. Update dependent calls and types. + + * tree-ssa-strlen.c (decl_to_stridxlist_htab): + Change type to hash_table. Update dependent calls and types. + + * tree-ssa-uncprop.c (equiv): + Change type to hash_table. Update dependent calls and types. + 2013-04-25 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/57003 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 84d96d29a1e..a3105b1ab86 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -875,7 +875,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \ cfg-flags.def cfghooks.h GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \ $(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \ - tree-ssa-alias.h $(INTERNAL_FN_H) + tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H) TRANS_MEM_H = trans-mem.h GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h COVERAGE_H = coverage.h $(GCOV_IO_H) @@ -938,6 +938,7 @@ TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \ $(BITMAP_H) sbitmap.h $(BASIC_BLOCK_H) $(GIMPLE_H) \ $(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) \ tree-ssa-alias.h +TREE_HASHER_H = tree-hasher.h $(HASH_TABLE_H) $(TREE_FLOW_H) TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) SSAEXPAND_H = ssaexpand.h $(TREE_SSA_LIVE_H) PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H) @@ -958,7 +959,7 @@ LRA_INT_H = lra.h $(BITMAP_H) $(RECOG_H) $(INSN_ATTR_H) insn-codes.h \ insn-config.h $(REGS_H) lra-int.h DBGCNT_H = dbgcnt.h dbgcnt.def LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \ - $(CGRAPH_H) $(VEC_H) $(TREE_H) $(GIMPLE_H) \ + $(CGRAPH_H) $(VEC_H) $(HASH_TABLE_H) $(TREE_H) $(GIMPLE_H) \ $(GCOV_IO_H) $(DIAGNOSTIC_H) alloc-pool.h DATA_STREAMER_H = data-streamer.h $(VEC_H) $(LTO_STREAMER_H) GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \ @@ -977,6 +978,7 @@ GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h plugin.def \ PLUGIN_H = plugin.h $(GCC_PLUGIN_H) PLUGIN_VERSION_H = plugin-version.h configargs.h LIBFUNCS_H = libfuncs.h $(HASHTAB_H) +GRAPHITE_HTAB_H = graphite-htab.h graphite-clast-to-gimple.h $(HASH_TABLE_H) # # Now figure out from those variables how to compile and link. @@ -2016,7 +2018,7 @@ default-c.o: config/default-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ # Files used by all variants of C and some other languages. attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ - $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \ + $(HASH_TABLE_H) $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \ $(TARGET_H) langhooks.h $(CPPLIB_H) $(PLUGIN_H) incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \ @@ -2108,7 +2110,7 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(CFGLOOP_H) $(TARGET_H) $(IPA_PROP_H) $(LTO_STREAMER_H) \ target-globals.h -trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ +trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \ $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \ $(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \ $(PARAMS_H) $(TARGET_H) langhooks.h \ @@ -2116,7 +2118,7 @@ trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ gt-trans-mem.h ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(GGC_H) $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \ + $(GGC_H) $(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \ $(HOSTHOOKS_DEF_H) $(VEC_H) $(PLUGIN_H) $(GGC_INTERNAL_H) $(TIMEVAR_H) ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ @@ -2252,8 +2254,8 @@ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \ $(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) -tree-ssa-structalias.o: tree-ssa-structalias.c \ - $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \ +tree-ssa-structalias.o: tree-ssa-structalias.c $(SYSTEM_H) $(CONFIG_H) \ + coretypes.h $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \ $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \ $(GIMPLE_H) $(HASH_TABLE_H) $(FUNCTION_H) $(CGRAPH_H) \ @@ -2266,7 +2268,7 @@ tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(FLAGS_H) $(HASHTAB_H) pointer-set.h \ $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ - $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \ + $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \ toplev.h $(FUNCTION_H) $(TM_H) coretypes.h \ langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \ $(FLAGS_H) $(GGC_H) $(HASHTAB_H) pointer-set.h \ @@ -2308,7 +2310,7 @@ tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ $(TREE_PRETTY_PRINT_H) tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ + $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \ $(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ $(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \ @@ -2329,13 +2331,13 @@ tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-ssa-propagate.h $(VEC_H) value-prof.h gt-tree-ssa-propagate.h $(FLAGS_H) \ $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ - $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \ + $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \ $(FUNCTION_H) $(TM_H) coretypes.h \ $(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ tree-ssa-propagate.h $(CFGLOOP_H) $(PARAMS_H) \ $(GIMPLE_PRETTY_PRINT_H) tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \ - $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ + $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) \ tree-ssa-propagate.h @@ -2358,7 +2360,7 @@ domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(BASIC_BLOCK_H) domwalk.h sbitmap.h tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) $(TIMEVAR_H) \ - $(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) \ + $(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) $(HASH_TABLE_H) \ $(GIMPLE_PRETTY_PRINT_H) $(GIMPLE_H) tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) \ @@ -2380,7 +2382,7 @@ tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(TREE_H) $(GIMPLE_H) $(BASIC_BLOCK_H) \ - $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \ + $(HASH_TABLE_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \ $(GIMPLE_PRETTY_PRINT_H) alloc-pool.h $(TREE_FLOW_H) domwalk.h \ pointer-set.h expmed.h tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ @@ -2388,7 +2390,7 @@ tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \ $(CFGLOOP_H) $(SCEV_H) intl.h \ $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h $(OPTABS_H) $(EXPR_H) -tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) $(HASH_TABLE_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) $(FLAGS_H) $(TARGET_H) \ $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(TREE_DUMP_H) $(EXCEPT_H) $(CFGLOOP_H) $(TREE_PASS_H) \ @@ -2433,7 +2435,7 @@ tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \ langhooks.h $(IPA_REFERENCE_H) $(GIMPLE_PRETTY_PRINT_H) tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \ - $(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \ + $(HASH_TABLE_H) $(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \ $(TREE_INLINE_H) tree-iterator.h toplev.h \ $(DIAGNOSTIC_CORE_H) $(TARGET_H) $(CFGLOOP_H) tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ @@ -2479,7 +2481,7 @@ tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \ $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ - $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \ + $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASH_TABLE_H) $(SCEV_H) \ $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) \ tree-affine.h pointer-set.h $(TARGET_H) \ $(GIMPLE_PRETTY_PRINT_H) tree-ssa-propagate.h @@ -2493,7 +2495,7 @@ tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \ $(CFGLOOP_H) $(TREE_PASS_H) \ $(SCEV_H) $(PARAMS_H) $(TREE_INLINE_H) langhooks.h tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \ - $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \ + $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \ $(PARAMS_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \ pointer-set.h tree-affine.h tree-ssa-propagate.h $(GIMPLE_PRETTY_PRINT_H) @@ -2546,15 +2548,15 @@ omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \ $(CFGLOOP_H) tree-iterator.h gt-omp-low.h tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_H) $(TREE_PRETTY_PRINT_H) + coretypes.h $(HASH_TABLE_H) $(TREE_H) $(TREE_PRETTY_PRINT_H) omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TREE_H) $(DIAGNOSTIC_CORE_H) tree-chrec.o : tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TREE_PRETTY_PRINT_H) $(CFGLOOP_H) $(TREE_FLOW_H) $(SCEV_H) \ $(PARAMS_H) tree-scalar-evolution.o : tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(DUMPFILE_H) $(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) \ - $(CFGLOOP_H) $(SCEV_H) $(PARAMS_H) gt-tree-scalar-evolution.h + coretypes.h $(DUMPFILE_H) $(HASH_TABLE_H) $(GIMPLE_PRETTY_PRINT_H) \ + $(TREE_FLOW_H) $(CFGLOOP_H) $(SCEV_H) $(PARAMS_H) gt-tree-scalar-evolution.h tree-data-ref.o : tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) \ $(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ @@ -2563,18 +2565,18 @@ sese.o : sese.c sese.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_PRETTY_PRINT_H $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) value-prof.h graphite.o : graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) \ $(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \ - $(DBGCNT_H) graphite-poly.h graphite-scop-detection.h \ + $(DBGCNT_H) $(GRAPHITE_HTAB_H) graphite-poly.h graphite-scop-detection.h \ graphite-clast-to-gimple.h graphite-sese-to-poly.h graphite-blocking.o : graphite-blocking.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ sese.h graphite-poly.h graphite-clast-to-gimple.o : graphite-clast-to-gimple.c $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ - $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \ + $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h $(GRAPHITE_HTAB_H) \ graphite-poly.h graphite-clast-to-gimple.h graphite-dependences.o : graphite-dependences.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TREE_FLOW_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ - sese.h graphite-poly.h + sese.h $(GRAPHITE_HTAB_H) graphite-poly.h graphite-interchange.o : graphite-interchange.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ sese.h graphite-poly.h @@ -2628,7 +2630,8 @@ tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GIMPLE_PRETTY_PRINT_H) \ + $(TREE_FLOW_H) $(TREE_HASHER_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + $(GIMPLE_PRETTY_PRINT_H) $(HASH_TABLE_H) \ $(TREE_PASS_H) langhooks.h gt-tree-parloops.h $(TREE_VECTORIZER_H) tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(FUNCTION_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ @@ -2647,8 +2650,9 @@ gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) \ $(TM_H) $(GIMPLE_H) value-prof.h \ $(TRANS_MEM_H) $(GIMPLE_PRETTY_PRINT_H) -tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \ - $(GIMPLE_H) $(DIAGNOSTIC_H) $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \ +tree-mudflap.o : tree-mudflap.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ + $(TREE_INLINE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) \ + $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \ $(TM_H) coretypes.h $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \ gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \ $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h @@ -2729,7 +2733,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(PLUGIN_H) $(IPA_UTILS_H) plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H) + $(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) \ + intl.h $(PLUGIN_VERSION_H) $(GGC_H) main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) @@ -2777,7 +2782,8 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) \ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) $(LIBFUNCS_H) \ langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ - dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) intl.h $(GGC_H) \ + dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) \ + intl.h $(GGC_H) \ gt-except.h $(CGRAPH_H) $(DIAGNOSTIC_H) $(DWARF2_H) \ $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TREE_FLOW_H) \ $(TREE_PRETTY_PRINT_H) sbitmap.h $(COMMON_TARGET_H) $(CFGLOOP_H) @@ -2831,12 +2837,12 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TM_H) $(TREE_H) version.h $(RTL_H) $(DWARF2_H) debug.h $(FLAGS_H) \ insn-config.h output.h $(DIAGNOSTIC_H) hard-reg-set.h $(REGS_H) $(EXPR_H) \ toplev.h $(DIAGNOSTIC_CORE_H) $(DWARF2OUT_H) reload.h \ - $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \ + $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASH_TABLE_H) \ gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \ $(GIMPLE_H) ira.h lra.h $(TREE_FLOW_H) \ $(TREE_PRETTY_PRINT_H) $(COMMON_TARGET_H) $(OPTS_H) -dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \ +dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \ + $(TM_H) version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \ gt-dwarf2cfi.h debug.h $(DWARF2_H) dwarf2asm.h $(DWARF2OUT_H) $(COMMON_TARGET_H) \ $(GGC_H) $(TM_P_H) $(TARGET_H) $(TREE_PASS_H) $(BASIC_BLOCK_H) $(EXCEPT_H) dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ @@ -2965,7 +2971,7 @@ coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \ tree-iterator.h $(CGRAPH_H) gcov-io.c $(TM_P_H) \ $(DIAGNOSTIC_CORE_H) intl.h gt-coverage.h $(TARGET_H) $(HASH_TABLE_H) cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ - $(TM_H) $(RTL_H) \ + $(HASH_TABLE_H) $(TM_H) $(RTL_H) \ $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) \ $(EMIT_RTL_H) $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) \ cselib.h gt-cselib.h $(GGC_H) $(TM_P_H) $(PARAMS_H) alloc-pool.h \ @@ -3005,12 +3011,13 @@ cprop.o : cprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \ $(DF_H) $(CFGLOOP_H) gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ - $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \ + $(HASH_TABLE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) toplev.h $(DIAGNOSTIC_CORE_H) \ $(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) gt-gcse.h $(TREE_H) \ intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \ $(DF_H) gcse.h -store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ +store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(HASH_TABLE_H) $(TM_H) $(RTL_H) \ $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) toplev.h $(DIAGNOSTIC_CORE_H) \ $(TM_P_H) $(EXCEPT_H) $(TREE_H) \ @@ -3043,9 +3050,9 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \ $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h tree-ssa-strlen.o : tree-ssa-strlen.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h alloc-pool.h tree-ssa-propagate.h \ - $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H) + $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H) $(HASH_TABLE_H) tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \ - $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \ + $(HASH_TABLE_H) $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \ $(IPA_PROP_H) $(DIAGNOSTIC_H) statistics.h \ $(PARAMS_H) $(TARGET_H) $(FLAGS_H) \ $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) @@ -3056,7 +3063,7 @@ tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \ $(GIMPLE_PRETTY_PRINT_H) langhooks.h tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ - $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \ + $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(TREE_HASHER_H) $(GIMPLE_H) \ tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \ @@ -3114,7 +3121,7 @@ loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) $(TM_H) \ $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \ $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) $(PARAMS_H) $(TARGET_H) -alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H) +alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASH_TABLE_H) auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \ $(REGS_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) \ @@ -3162,12 +3169,12 @@ graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) $(BITMAP_H) $(OBSTACK_H) loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(RTL_H) $(BASIC_BLOCK_H) \ hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(TM_H) $(OBSTACK_H) \ - intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASHTAB_H) + intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASH_TABLE_H) loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) \ $(RTL_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) \ $(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(TARGET_H) \ - $(OBSTACK_H) $(HASHTAB_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h + $(OBSTACK_H) $(HASH_TABLE_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \ coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_FLOW_H) @@ -3181,8 +3188,7 @@ loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(EXPR_H) $(TM_H) $(OBSTACK_H) loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(RTL_H) $(TM_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(PARAMS_H) \ - $(EXPR_H) $(TM_H) $(HASHTAB_H) $(RECOG_H) \ - $(OBSTACK_H) + $(EXPR_H) $(TM_H) $(HASH_TABLE_H) $(RECOG_H) $(OBSTACK_H) dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) \ $(TIMEVAR_H) graphds.h pointer-set.h $(BITMAP_H) @@ -3201,7 +3207,7 @@ reginfo.o : reginfo.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FUNCTION_H) output.h $(TM_P_H) $(EXPR_H) $(HASHTAB_H) \ $(TARGET_H) $(TREE_PASS_H) $(DF_H) ira.h bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) \ - $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASHTAB_H) + $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASH_TABLE_H) vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) $(GGC_H) \ $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) hash-table.o : hash-table.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ @@ -3226,8 +3232,8 @@ postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) $(DIAGNOSTIC_CORE_H) \ - $(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \ - $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) + $(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TARGET_H) $(HASH_TABLE_H) intl.h \ + $(OBSTACK_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) $(TM_H) $(RTL_H) \ $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \ @@ -3261,14 +3267,14 @@ ira-build.o: ira-build.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(PARAMS_H) $(DF_H) sparseset.h $(IRA_INT_H) reload.h ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ hard-reg-set.h $(RTL_H) $(EXPR_H) $(TM_P_H) $(FLAGS_H) $(BASIC_BLOCK_H) \ - $(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) $(TARGET_H) \ - $(PARAMS_H) $(IRA_INT_H) reload.h + $(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) \ + $(HASH_TABLE_H) $(TARGET_H) $(PARAMS_H) $(IRA_INT_H) reload.h ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(TREE_H) $(FLAGS_H) \ insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(PARAMS_H) \ $(DF_H) sparseset.h addresses.h $(IRA_INT_H) ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ + $(HASH_TABLE_H) $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ $(EXPR_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) reload.h $(PARAMS_H) \ $(DF_H) $(IRA_INT_H) ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ @@ -3348,7 +3354,7 @@ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \ $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) \ $(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) $(COMMON_TARGET_H) \ - $(HASHTAB_H) + $(HASH_TABLE_H) sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) cselib.h \ diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c index 1989d86aadc..65907544565 100644 --- a/gcc/alloc-pool.c +++ b/gcc/alloc-pool.c @@ -82,6 +82,7 @@ struct alloc_pool_descriptor int elt_size; }; +/* Hashtable helpers. */ struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor> { typedef alloc_pool_descriptor value_type; @@ -90,10 +91,6 @@ struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor> static inline bool equal (const value_type *, const compare_type *); }; -/* Hashtable mapping alloc_pool names to descriptors. */ -static hash_table <alloc_pool_hasher> alloc_pool_hash; - -/* Hashtable helpers. */ inline hashval_t alloc_pool_hasher::hash (const value_type *d) { @@ -107,6 +104,9 @@ alloc_pool_hasher::equal (const value_type *d, return d->name == p2; } +/* Hashtable mapping alloc_pool names to descriptors. */ +static hash_table <alloc_pool_hasher> alloc_pool_hash; + /* For given name, return descriptor, create new if needed. */ static struct alloc_pool_descriptor * allocate_pool_descriptor (const char *name) diff --git a/gcc/attribs.c b/gcc/attribs.c index 08ebfe10a8f..164385b2b3c 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "cpplib.h" #include "target.h" #include "langhooks.h" -#include "hashtab.h" +#include "hash-table.h" #include "plugin.h" /* Table of the tables of attributes (common, language, format, machine) @@ -44,13 +44,45 @@ struct substring int length; }; +/* Simple hash function to avoid need to scan whole string. */ + +static inline hashval_t +substring_hash (const char *str, int l) +{ + return str[0] + str[l - 1] * 256 + l * 65536; +} + +/* Used for attribute_hash. */ + +struct attribute_hasher : typed_noop_remove <attribute_spec> +{ + typedef attribute_spec value_type; + typedef substring compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +attribute_hasher::hash (const value_type *spec) +{ + const int l = strlen (spec->name); + return substring_hash (spec->name, l); +} + +inline bool +attribute_hasher::equal (const value_type *spec, const compare_type *str) +{ + return (strncmp (spec->name, str->str, str->length) == 0 + && !spec->name[str->length]); +} + /* Scoped attribute name representation. */ struct scoped_attributes { const char *ns; vec<attribute_spec> attributes; - htab_t attribute_hash; + hash_table <attribute_hasher> attribute_hash; }; /* The table of scope attributes. */ @@ -83,36 +115,6 @@ extract_attribute_substring (struct substring *str) } } -/* Simple hash function to avoid need to scan whole string. */ - -static inline hashval_t -substring_hash (const char *str, int l) -{ - return str[0] + str[l - 1] * 256 + l * 65536; -} - -/* Used for attribute_hash. */ - -static hashval_t -hash_attr (const void *p) -{ - const struct attribute_spec *const spec = (const struct attribute_spec *) p; - const int l = strlen (spec->name); - - return substring_hash (spec->name, l); -} - -/* Used for attribute_hash. */ - -static int -eq_attr (const void *p, const void *q) -{ - const struct attribute_spec *const spec = (const struct attribute_spec *) p; - const struct substring *const str = (const struct substring *) q; - - return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]); -} - /* Insert an array of attributes ATTRIBUTES into a namespace. This array must be NULL terminated. NS is the name of attribute namespace. The function returns the namespace into which the @@ -139,7 +141,7 @@ register_scoped_attributes (const struct attribute_spec * attributes, sa.ns = ns; sa.attributes.create (64); result = attributes_table.safe_push (sa); - result->attribute_hash = htab_create (200, hash_attr, eq_attr, NULL); + result->attribute_hash.create (200); } /* Really add the attributes to their namespace now. */ @@ -272,11 +274,11 @@ register_scoped_attribute (const struct attribute_spec *attr, scoped_attributes *name_space) { struct substring str; - void **slot; + attribute_spec **slot; gcc_assert (attr != NULL && name_space != NULL); - gcc_assert (name_space->attribute_hash != NULL); + gcc_assert (name_space->attribute_hash.is_created ()); str.str = attr->name; str.length = strlen (str.str); @@ -285,11 +287,11 @@ register_scoped_attribute (const struct attribute_spec *attr, in the form '__text__'. */ gcc_assert (str.length > 0 && str.str[0] != '_'); - slot = htab_find_slot_with_hash (name_space->attribute_hash, &str, - substring_hash (str.str, str.length), - INSERT); + slot = name_space->attribute_hash + .find_slot_with_hash (&str, substring_hash (str.str, str.length), + INSERT); gcc_assert (!*slot || attr->name[0] == '*'); - *slot = (void *) CONST_CAST (struct attribute_spec *, attr); + *slot = CONST_CAST (struct attribute_spec *, attr); } /* Return the spec for the scoped attribute with namespace NS and @@ -311,8 +313,7 @@ lookup_scoped_attribute_spec (const_tree ns, const_tree name) attr.str = IDENTIFIER_POINTER (name); attr.length = IDENTIFIER_LENGTH (name); extract_attribute_substring (&attr); - return (const struct attribute_spec *) - htab_find_with_hash (attrs->attribute_hash, &attr, + return attrs->attribute_hash.find_with_hash (&attr, substring_hash (attr.str, attr.length)); } diff --git a/gcc/bitmap.c b/gcc/bitmap.c index f0fba9cec05..2c5d228fdd1 100644 --- a/gcc/bitmap.c +++ b/gcc/bitmap.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "obstack.h" #include "ggc.h" #include "bitmap.h" -#include "hashtab.h" +#include "hash-table.h" #include "vec.h" /* Store information about each particular bitmap, per allocation site. */ @@ -50,48 +50,55 @@ static int next_bitmap_desc_id = 0; /* Vector mapping descriptor ids to descriptors. */ static vec<bitmap_descriptor> bitmap_descriptors; -/* Hashtable mapping bitmap names to descriptors. */ -static htab_t bitmap_desc_hash; - /* Hashtable helpers. */ -static hashval_t -hash_descriptor (const void *p) -{ - const_bitmap_descriptor d = (const_bitmap_descriptor) p; - return htab_hash_pointer (d->file) + d->line; -} + struct loc { const char *file; const char *function; int line; }; -static int -eq_descriptor (const void *p1, const void *p2) + +struct bitmap_desc_hasher : typed_noop_remove <bitmap_descriptor_d> +{ + typedef bitmap_descriptor_d value_type; + typedef loc compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +bitmap_desc_hasher::hash (const value_type *d) +{ + return htab_hash_pointer (d->file) + d->line; +} + +inline bool +bitmap_desc_hasher::equal (const value_type *d, const compare_type *l) { - const_bitmap_descriptor d = (const_bitmap_descriptor) p1; - const struct loc *const l = (const struct loc *) p2; return d->file == l->file && d->function == l->function && d->line == l->line; } +/* Hashtable mapping bitmap names to descriptors. */ +static hash_table <bitmap_desc_hasher> bitmap_desc_hash; + /* For given file and line, return descriptor, create new if needed. */ static bitmap_descriptor get_bitmap_descriptor (const char *file, int line, const char *function) { - bitmap_descriptor *slot; + bitmap_descriptor_d **slot; struct loc loc; loc.file = file; loc.function = function; loc.line = line; - if (!bitmap_desc_hash) - bitmap_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL); + if (!bitmap_desc_hash.is_created ()) + bitmap_desc_hash.create (10); - slot = (bitmap_descriptor *) - htab_find_slot_with_hash (bitmap_desc_hash, &loc, - htab_hash_pointer (file) + line, - INSERT); + slot = bitmap_desc_hash.find_slot_with_hash (&loc, + htab_hash_pointer (file) + line, + INSERT); if (*slot) return *slot; @@ -2141,13 +2148,12 @@ struct output_info unsigned HOST_WIDEST_INT count; }; -/* Called via htab_traverse. Output bitmap descriptor pointed out by SLOT - and update statistics. */ -static int -print_statistics (void **slot, void *b) +/* Called via hash_table::traverse. Output bitmap descriptor pointed out by + SLOT and update statistics. */ +int +print_statistics (bitmap_descriptor_d **slot, output_info *i) { - bitmap_descriptor d = (bitmap_descriptor) *slot; - struct output_info *i = (struct output_info *) b; + bitmap_descriptor d = *slot; char s[4096]; if (d->allocated) @@ -2181,7 +2187,7 @@ dump_bitmap_statistics (void) if (! GATHER_STATISTICS) return; - if (!bitmap_desc_hash) + if (!bitmap_desc_hash.is_created ()) return; fprintf (stderr, @@ -2192,7 +2198,7 @@ dump_bitmap_statistics (void) fprintf (stderr, "---------------------------------------------------------------------------------\n"); info.count = 0; info.size = 0; - htab_traverse (bitmap_desc_hash, print_statistics, &info); + bitmap_desc_hash.traverse <output_info *, print_statistics> (&info); fprintf (stderr, "---------------------------------------------------------------------------------\n"); fprintf (stderr, "%-41s %9"HOST_WIDEST_INT_PRINT"d %15"HOST_WIDEST_INT_PRINT"d\n", diff --git a/gcc/cselib.c b/gcc/cselib.c index dcad97417d8..589e41ed3df 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "emit-rtl.h" #include "diagnostic-core.h" #include "ggc.h" -#include "hashtab.h" +#include "hash-table.h" #include "dumpfile.h" #include "cselib.h" #include "valtrack.h" @@ -49,18 +49,18 @@ struct elt_list { cselib_val *elt; }; +/* See the documentation of cselib_find_slot below. */ +static enum machine_mode find_slot_memmode; + static bool cselib_record_memory; static bool cselib_preserve_constants; static bool cselib_any_perm_equivs; -static int entry_and_rtx_equal_p (const void *, const void *); -static hashval_t get_value_hash (const void *); +static inline void promote_debug_loc (struct elt_loc_list *l); static struct elt_list *new_elt_list (struct elt_list *, cselib_val *); static void new_elt_loc_list (cselib_val *, rtx); static void unchain_one_value (cselib_val *); static void unchain_one_elt_list (struct elt_list **); static void unchain_one_elt_loc_list (struct elt_loc_list **); -static int discard_useless_locs (void **, void *); -static int discard_useless_values (void **, void *); static void remove_useless_values (void); static int rtx_equal_for_cselib_1 (rtx, rtx, enum machine_mode); static unsigned int cselib_hash_rtx (rtx, int, enum machine_mode); @@ -91,8 +91,61 @@ static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int); this involves walking the table entries for a given value and comparing the locations of the entries with the rtx we are looking up. */ +struct cselib_hasher : typed_noop_remove <cselib_val> +{ + typedef cselib_val value_type; + typedef rtx_def compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* The hash function for our hash table. The value is always computed with + cselib_hash_rtx when adding an element; this function just extracts the + hash value from a cselib_val structure. */ + +inline hashval_t +cselib_hasher::hash (const value_type *v) +{ + return v->hash; +} + +/* The equality test for our hash table. The first argument V is a table + element (i.e. a cselib_val), while the second arg X is an rtx. We know + that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a + CONST of an appropriate mode. */ + +inline bool +cselib_hasher::equal (const value_type *v, const compare_type *x_arg) +{ + struct elt_loc_list *l; + rtx x = CONST_CAST_RTX (x_arg); + enum machine_mode mode = GET_MODE (x); + + gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED); + + if (mode != GET_MODE (v->val_rtx)) + return false; + + /* Unwrap X if necessary. */ + if (GET_CODE (x) == CONST + && (CONST_SCALAR_INT_P (XEXP (x, 0)) + || GET_CODE (XEXP (x, 0)) == CONST_FIXED)) + x = XEXP (x, 0); + + /* We don't guarantee that distinct rtx's have different hash values, + so we need to do a comparison. */ + for (l = v->locs; l; l = l->next) + if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode)) + { + promote_debug_loc (l); + return true; + } + + return false; +} + /* A table that enables us to look up elts by their value. */ -static htab_t cselib_hash_table; +static hash_table <cselib_hasher> cselib_hash_table; /* This is a global so we don't have to pass this through every function. It is used in new_elt_loc_list to set SETTING_INSN. */ @@ -432,13 +485,13 @@ invariant_or_equiv_p (cselib_val *v) /* Remove from hash table all VALUEs except constants, function invariants and VALUE equivalences. */ -static int -preserve_constants_and_equivs (void **x, void *info ATTRIBUTE_UNUSED) +int +preserve_constants_and_equivs (cselib_val **x, void *info ATTRIBUTE_UNUSED) { - cselib_val *v = (cselib_val *)*x; + cselib_val *v = *x; if (!invariant_or_equiv_p (v)) - htab_clear_slot (cselib_hash_table, x); + cselib_hash_table.clear_slot (x); return 1; } @@ -478,10 +531,10 @@ cselib_reset_table (unsigned int num) } if (cselib_preserve_constants) - htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL); + cselib_hash_table.traverse <void *, preserve_constants_and_equivs> (NULL); else { - htab_empty (cselib_hash_table); + cselib_hash_table.empty (); gcc_checking_assert (!cselib_any_perm_equivs); } @@ -502,73 +555,23 @@ cselib_get_next_uid (void) return next_uid; } -/* See the documentation of cselib_find_slot below. */ -static enum machine_mode find_slot_memmode; - /* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE, INSERTing if requested. When X is part of the address of a MEM, MEMMODE should specify the mode of the MEM. While searching the table, MEMMODE is held in FIND_SLOT_MEMMODE, so that autoinc RTXs in X can be resolved. */ -static void ** +static cselib_val ** cselib_find_slot (rtx x, hashval_t hash, enum insert_option insert, enum machine_mode memmode) { - void **slot; + cselib_val **slot; find_slot_memmode = memmode; - slot = htab_find_slot_with_hash (cselib_hash_table, x, hash, insert); + slot = cselib_hash_table.find_slot_with_hash (x, hash, insert); find_slot_memmode = VOIDmode; return slot; } -/* The equality test for our hash table. The first argument ENTRY is a table - element (i.e. a cselib_val), while the second arg X is an rtx. We know - that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a - CONST of an appropriate mode. */ - -static int -entry_and_rtx_equal_p (const void *entry, const void *x_arg) -{ - struct elt_loc_list *l; - const cselib_val *const v = (const cselib_val *) entry; - rtx x = CONST_CAST_RTX ((const_rtx)x_arg); - enum machine_mode mode = GET_MODE (x); - - gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED); - - if (mode != GET_MODE (v->val_rtx)) - return 0; - - /* Unwrap X if necessary. */ - if (GET_CODE (x) == CONST - && (CONST_SCALAR_INT_P (XEXP (x, 0)) - || GET_CODE (XEXP (x, 0)) == CONST_FIXED)) - x = XEXP (x, 0); - - /* We don't guarantee that distinct rtx's have different hash values, - so we need to do a comparison. */ - for (l = v->locs; l; l = l->next) - if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode)) - { - promote_debug_loc (l); - return 1; - } - - return 0; -} - -/* The hash function for our hash table. The value is always computed with - cselib_hash_rtx when adding an element; this function just extracts the - hash value from a cselib_val structure. */ - -static hashval_t -get_value_hash (const void *entry) -{ - const cselib_val *const v = (const cselib_val *) entry; - return v->hash; -} - /* Return true if X contains a VALUE rtx. If ONLY_USELESS is set, we only return true for values which point to a cselib_val whose value element has been set to zero, which implies the cselib_val will be @@ -603,10 +606,10 @@ references_value_p (const_rtx x, int only_useless) values (i.e. values without any location). Called through htab_traverse. */ -static int -discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED) +int +discard_useless_locs (cselib_val **x, void *info ATTRIBUTE_UNUSED) { - cselib_val *v = (cselib_val *)*x; + cselib_val *v = *x; struct elt_loc_list **p = &v->locs; bool had_locs = v->locs != NULL; rtx setting_insn = v->locs ? v->locs->setting_insn : NULL; @@ -632,10 +635,10 @@ discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED) /* If X is a value with no locations, remove it from the hashtable. */ -static int -discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED) +int +discard_useless_values (cselib_val **x, void *info ATTRIBUTE_UNUSED) { - cselib_val *v = (cselib_val *)*x; + cselib_val *v = *x; if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx)) { @@ -643,7 +646,7 @@ discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED) cselib_discard_hook (v); CSELIB_VAL_PTR (v->val_rtx) = NULL; - htab_clear_slot (cselib_hash_table, x); + cselib_hash_table.clear_slot (x); unchain_one_value (v); n_useless_values--; } @@ -664,7 +667,7 @@ remove_useless_values (void) do { values_became_useless = 0; - htab_traverse (cselib_hash_table, discard_useless_locs, 0); + cselib_hash_table.traverse <void *, discard_useless_locs> (NULL); } while (values_became_useless); @@ -683,7 +686,7 @@ remove_useless_values (void) n_debug_values -= n_useless_debug_values; n_useless_debug_values = 0; - htab_traverse (cselib_hash_table, discard_useless_values, 0); + cselib_hash_table.traverse <void *, discard_useless_values> (NULL); gcc_assert (!n_useless_values); } @@ -1352,7 +1355,7 @@ cselib_lookup_mem (rtx x, int create) { enum machine_mode mode = GET_MODE (x); enum machine_mode addr_mode; - void **slot; + cselib_val **slot; cselib_val *addr; cselib_val *mem_elt; struct elt_list *l; @@ -1958,7 +1961,7 @@ static cselib_val * cselib_lookup_1 (rtx x, enum machine_mode mode, int create, enum machine_mode memmode) { - void **slot; + cselib_val **slot; cselib_val *e; unsigned int hashval; @@ -2069,7 +2072,7 @@ cselib_lookup_1 (rtx x, enum machine_mode mode, /* We have to fill the slot before calling cselib_subst_to_values: the hash table is inconsistent until we do so, and cselib_subst_to_values will need to do lookups. */ - *slot = (void *) e; + *slot = e; new_elt_loc_list (e, cselib_subst_to_values (x, memmode)); return e; } @@ -2695,9 +2698,7 @@ cselib_process_insn (rtx insn) quadratic behavior for very large hashtables with very few useless elements. */ && ((unsigned int)n_useless_values - > (cselib_hash_table->n_elements - - cselib_hash_table->n_deleted - - n_debug_values) / 4)) + > (cselib_hash_table.elements () - n_debug_values) / 4)) remove_useless_values (); } @@ -2738,8 +2739,7 @@ cselib_init (int record_what) } used_regs = XNEWVEC (unsigned int, cselib_nregs); n_used_regs = 0; - cselib_hash_table = htab_create (31, get_value_hash, - entry_and_rtx_equal_p, NULL); + cselib_hash_table.create (31); next_uid = 1; } @@ -2758,23 +2758,21 @@ cselib_finish (void) free_alloc_pool (cselib_val_pool); free_alloc_pool (value_pool); cselib_clear_table (); - htab_delete (cselib_hash_table); + cselib_hash_table.dispose (); free (used_regs); used_regs = 0; - cselib_hash_table = 0; n_useless_values = 0; n_useless_debug_values = 0; n_debug_values = 0; next_uid = 0; } -/* Dump the cselib_val *X to FILE *info. */ +/* Dump the cselib_val *X to FILE *OUT. */ -static int -dump_cselib_val (void **x, void *info) +int +dump_cselib_val (cselib_val **x, FILE *out) { - cselib_val *v = (cselib_val *)*x; - FILE *out = (FILE *)info; + cselib_val *v = *x; bool need_lf = true; print_inline_rtx (out, v->val_rtx, 0); @@ -2849,7 +2847,7 @@ void dump_cselib_table (FILE *out) { fprintf (out, "cselib hash table:\n"); - htab_traverse (cselib_hash_table, dump_cselib_val, out); + cselib_hash_table.traverse <FILE *, dump_cselib_val> (out); if (first_containing_mem != &dummy_val) { fputs ("first mem ", out); diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c index 72f4f72e1bb..4165b8747fc 100644 --- a/gcc/data-streamer-out.c +++ b/gcc/data-streamer-out.c @@ -42,8 +42,7 @@ streamer_string_index (struct output_block *ob, const char *s, unsigned int len, s_slot.len = len; s_slot.slot_num = 0; - slot = (struct string_slot **) htab_find_slot (ob->string_hash_table, - &s_slot, INSERT); + slot = ob->string_hash_table.find_slot (&s_slot, INSERT); if (*slot == NULL) { struct lto_output_stream *string_stream = ob->string_stream; diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h index e2ab7adfad6..b79abd9fd92 100644 --- a/gcc/data-streamer.h +++ b/gcc/data-streamer.h @@ -44,15 +44,6 @@ struct bitpack_d void *stream; }; - -/* String hashing. */ -struct string_slot -{ - const char *s; - int len; - unsigned int slot_num; -}; - /* In data-streamer.c */ void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT); void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT); @@ -93,35 +84,6 @@ unsigned HOST_WIDE_INT streamer_read_uhwi (struct lto_input_block *); HOST_WIDE_INT streamer_read_hwi (struct lto_input_block *); gcov_type streamer_read_gcov_count (struct lto_input_block *); -/* Returns a hash code for P. Adapted from libiberty's htab_hash_string - to support strings that may not end in '\0'. */ - -static inline hashval_t -hash_string_slot_node (const void *p) -{ - const struct string_slot *ds = (const struct string_slot *) p; - hashval_t r = ds->len; - int i; - - for (i = 0; i < ds->len; i++) - r = r * 67 + (unsigned)ds->s[i] - 113; - return r; -} - -/* Returns nonzero if P1 and P2 are equal. */ - -static inline int -eq_string_slot_node (const void *p1, const void *p2) -{ - const struct string_slot *ds1 = (const struct string_slot *) p1; - const struct string_slot *ds2 = (const struct string_slot *) p2; - - if (ds1->len == ds2->len) - return memcmp (ds1->s, ds2->s, ds1->len) == 0; - - return 0; -} - /* Returns a new bit-packing context for bit-packing into S. */ static inline struct bitpack_d bitpack_create (struct lto_output_stream *s) diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 9f0a594183a..29779d6ad6a 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "dwarf2out.h" #include "dwarf2asm.h" #include "ggc.h" +#include "hash-table.h" #include "tm_p.h" #include "target.h" #include "common/common-target.h" @@ -153,10 +154,33 @@ typedef struct typedef dw_trace_info *dw_trace_info_ref; +/* Hashtable helpers. */ + +struct trace_info_hasher : typed_noop_remove <dw_trace_info> +{ + typedef dw_trace_info value_type; + typedef dw_trace_info compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +trace_info_hasher::hash (const value_type *ti) +{ + return INSN_UID (ti->head); +} + +inline bool +trace_info_hasher::equal (const value_type *a, const compare_type *b) +{ + return a->head == b->head; +} + + /* The variables making up the pseudo-cfg, as described above. */ static vec<dw_trace_info> trace_info; static vec<dw_trace_info_ref> trace_work_list; -static htab_t trace_index; +static hash_table <trace_info_hasher> trace_index; /* A vector of call frame insns for the CIE. */ cfi_vec cie_cfi_vec; @@ -275,28 +299,12 @@ expand_builtin_init_dwarf_reg_sizes (tree address) } -static hashval_t -dw_trace_info_hash (const void *ptr) -{ - const dw_trace_info *ti = (const dw_trace_info *) ptr; - return INSN_UID (ti->head); -} - -static int -dw_trace_info_eq (const void *ptr_a, const void *ptr_b) -{ - const dw_trace_info *a = (const dw_trace_info *) ptr_a; - const dw_trace_info *b = (const dw_trace_info *) ptr_b; - return a->head == b->head; -} - static dw_trace_info * get_trace_info (rtx insn) { dw_trace_info dummy; dummy.head = insn; - return (dw_trace_info *) - htab_find_with_hash (trace_index, &dummy, INSN_UID (insn)); + return trace_index.find_with_hash (&dummy, INSN_UID (insn)); } static bool @@ -2744,22 +2752,20 @@ create_pseudo_cfg (void) /* Create the trace index after we've finished building trace_info, avoiding stale pointer problems due to reallocation. */ - trace_index = htab_create (trace_info.length (), - dw_trace_info_hash, dw_trace_info_eq, NULL); + trace_index.create (trace_info.length ()); dw_trace_info *tp; FOR_EACH_VEC_ELT (trace_info, i, tp) { - void **slot; + dw_trace_info **slot; if (dump_file) fprintf (dump_file, "Creating trace %u : start at %s %d%s\n", i, rtx_name[(int) GET_CODE (tp->head)], INSN_UID (tp->head), tp->switch_sections ? " (section switch)" : ""); - slot = htab_find_slot_with_hash (trace_index, tp, - INSN_UID (tp->head), INSERT); + slot = trace_index.find_slot_with_hash (tp, INSN_UID (tp->head), INSERT); gcc_assert (*slot == NULL); - *slot = (void *) tp; + *slot = tp; } } @@ -2908,8 +2914,7 @@ execute_dwarf2_frame (void) } trace_info.release (); - htab_delete (trace_index); - trace_index = NULL; + trace_index.dispose (); return 0; } diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b4e5313ee45..de69cc8d7a7 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -84,7 +84,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "common/common-target.h" #include "langhooks.h" -#include "hashtab.h" +#include "hash-table.h" #include "cgraph.h" #include "input.h" #include "gimple.h" @@ -3038,17 +3038,9 @@ static dw_die_ref remove_child_or_replace_with_skeleton (dw_die_ref, dw_die_ref, dw_die_ref); static void break_out_comdat_types (dw_die_ref); -static dw_die_ref copy_ancestor_tree (dw_die_ref, dw_die_ref, htab_t); -static void copy_decls_walk (dw_die_ref, dw_die_ref, htab_t); static void copy_decls_for_unworthy_types (dw_die_ref); -static hashval_t htab_cu_hash (const void *); -static int htab_cu_eq (const void *, const void *); -static void htab_cu_del (void *); -static int check_duplicate_cu (dw_die_ref, htab_t, unsigned *); -static void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned); static void add_sibling_attributes (dw_die_ref); -static void build_abbrev_table (dw_die_ref, htab_t); static void output_location_lists (dw_die_ref); static int constant_size (unsigned HOST_WIDE_INT); static unsigned long size_of_die (dw_die_ref); @@ -6539,31 +6531,34 @@ struct cu_hash_table_entry struct cu_hash_table_entry *next; }; -/* Routines to manipulate hash table of CUs. */ -static hashval_t -htab_cu_hash (const void *of) +/* Helpers to manipulate hash table of CUs. */ + +struct cu_hash_table_entry_hasher { - const struct cu_hash_table_entry *const entry = - (const struct cu_hash_table_entry *) of; + typedef cu_hash_table_entry value_type; + typedef die_struct compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; +inline hashval_t +cu_hash_table_entry_hasher::hash (const value_type *entry) +{ return htab_hash_string (entry->cu->die_id.die_symbol); } -static int -htab_cu_eq (const void *of1, const void *of2) +inline bool +cu_hash_table_entry_hasher::equal (const value_type *entry1, + const compare_type *entry2) { - const struct cu_hash_table_entry *const entry1 = - (const struct cu_hash_table_entry *) of1; - const struct die_struct *const entry2 = (const struct die_struct *) of2; - return !strcmp (entry1->cu->die_id.die_symbol, entry2->die_id.die_symbol); } -static void -htab_cu_del (void *what) +inline void +cu_hash_table_entry_hasher::remove (value_type *entry) { - struct cu_hash_table_entry *next, - *entry = (struct cu_hash_table_entry *) what; + struct cu_hash_table_entry *next; while (entry) { @@ -6573,19 +6568,21 @@ htab_cu_del (void *what) } } +typedef hash_table <cu_hash_table_entry_hasher> cu_hash_type; + /* Check whether we have already seen this CU and set up SYM_NUM accordingly. */ static int -check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num) +check_duplicate_cu (dw_die_ref cu, cu_hash_type htable, unsigned int *sym_num) { struct cu_hash_table_entry dummy; struct cu_hash_table_entry **slot, *entry, *last = &dummy; dummy.max_comdat_num = 0; - slot = (struct cu_hash_table_entry **) - htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_id.die_symbol), - INSERT); + slot = htable.find_slot_with_hash (cu, + htab_hash_string (cu->die_id.die_symbol), + INSERT); entry = *slot; for (; entry; last = entry, entry = entry->next) @@ -6611,13 +6608,14 @@ check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num) /* Record SYM_NUM to record of CU in HTABLE. */ static void -record_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num) +record_comdat_symbol_number (dw_die_ref cu, cu_hash_type htable, + unsigned int sym_num) { struct cu_hash_table_entry **slot, *entry; - slot = (struct cu_hash_table_entry **) - htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_id.die_symbol), - NO_INSERT); + slot = htable.find_slot_with_hash (cu, + htab_hash_string (cu->die_id.die_symbol), + NO_INSERT); entry = *slot; entry->max_comdat_num = sym_num; @@ -6633,7 +6631,7 @@ break_out_includes (dw_die_ref die) dw_die_ref c; dw_die_ref unit = NULL; limbo_die_node *node, **pnode; - htab_t cu_hash_table; + cu_hash_type cu_hash_table; c = die->die_child; if (c) do { @@ -6666,7 +6664,7 @@ break_out_includes (dw_die_ref die) #endif assign_symbol_names (die); - cu_hash_table = htab_create (10, htab_cu_hash, htab_cu_eq, htab_cu_del); + cu_hash_table.create (10); for (node = limbo_die_list, pnode = &limbo_die_list; node; node = node->next) @@ -6686,7 +6684,7 @@ break_out_includes (dw_die_ref die) comdat_symbol_number); } } - htab_delete (cu_hash_table); + cu_hash_table.dispose (); } /* Return non-zero if this DIE is a declaration. */ @@ -6861,6 +6859,94 @@ clone_as_declaration (dw_die_ref die) return clone; } + +/* Structure to map a DIE in one CU to its copy in a comdat type unit. */ + +struct decl_table_entry +{ + dw_die_ref orig; + dw_die_ref copy; +}; + +/* Helpers to manipulate hash table of copied declarations. */ + +/* Hashtable helpers. */ + +struct decl_table_entry_hasher : typed_free_remove <decl_table_entry> +{ + typedef decl_table_entry value_type; + typedef die_struct compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +decl_table_entry_hasher::hash (const value_type *entry) +{ + return htab_hash_pointer (entry->orig); +} + +inline bool +decl_table_entry_hasher::equal (const value_type *entry1, + const compare_type *entry2) +{ + return entry1->orig == entry2; +} + +typedef hash_table <decl_table_entry_hasher> decl_hash_type; + +/* Copy DIE and its ancestors, up to, but not including, the compile unit + or type unit entry, to a new tree. Adds the new tree to UNIT and returns + a pointer to the copy of DIE. If DECL_TABLE is provided, it is used + to check if the ancestor has already been copied into UNIT. */ + +static dw_die_ref +copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table) +{ + dw_die_ref parent = die->die_parent; + dw_die_ref new_parent = unit; + dw_die_ref copy; + decl_table_entry **slot = NULL; + struct decl_table_entry *entry = NULL; + + if (decl_table.is_created ()) + { + /* Check if the entry has already been copied to UNIT. */ + slot = decl_table.find_slot_with_hash (die, htab_hash_pointer (die), + INSERT); + if (*slot != HTAB_EMPTY_ENTRY) + { + entry = *slot; + return entry->copy; + } + + /* Record in DECL_TABLE that DIE has been copied to UNIT. */ + entry = XCNEW (struct decl_table_entry); + entry->orig = die; + entry->copy = NULL; + *slot = entry; + } + + if (parent != NULL) + { + dw_die_ref spec = get_AT_ref (parent, DW_AT_specification); + if (spec != NULL) + parent = spec; + if (!is_unit_die (parent)) + new_parent = copy_ancestor_tree (unit, parent, decl_table); + } + + copy = clone_as_declaration (die); + add_child_die (new_parent, copy); + + if (decl_table.is_created ()) + { + /* Record the pointer to the copy. */ + entry->copy = copy; + } + + return copy; +} /* Copy the declaration context to the new type unit DIE. This includes any surrounding namespace or type declarations. If the DIE has an AT_specification attribute, it also includes attributes and children @@ -6908,7 +6994,7 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die) if (decl->die_parent != NULL && !is_unit_die (decl->die_parent)) { - new_decl = copy_ancestor_tree (unit, decl, NULL); + new_decl = copy_ancestor_tree (unit, decl, decl_hash_type ()); if (new_decl != NULL) { remove_AT (new_decl, DW_AT_signature); @@ -7107,106 +7193,16 @@ break_out_comdat_types (dw_die_ref die) } while (next != NULL); } -/* Structure to map a DIE in one CU to its copy in a comdat type unit. */ - -struct decl_table_entry -{ - dw_die_ref orig; - dw_die_ref copy; -}; - -/* Routines to manipulate hash table of copied declarations. */ - -static hashval_t -htab_decl_hash (const void *of) -{ - const struct decl_table_entry *const entry = - (const struct decl_table_entry *) of; - - return htab_hash_pointer (entry->orig); -} - -static int -htab_decl_eq (const void *of1, const void *of2) -{ - const struct decl_table_entry *const entry1 = - (const struct decl_table_entry *) of1; - const struct die_struct *const entry2 = (const struct die_struct *) of2; - - return entry1->orig == entry2; -} - -static void -htab_decl_del (void *what) -{ - struct decl_table_entry *entry = (struct decl_table_entry *) what; - - free (entry); -} - -/* Copy DIE and its ancestors, up to, but not including, the compile unit - or type unit entry, to a new tree. Adds the new tree to UNIT and returns - a pointer to the copy of DIE. If DECL_TABLE is provided, it is used - to check if the ancestor has already been copied into UNIT. */ - -static dw_die_ref -copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, htab_t decl_table) -{ - dw_die_ref parent = die->die_parent; - dw_die_ref new_parent = unit; - dw_die_ref copy; - void **slot = NULL; - struct decl_table_entry *entry = NULL; - - if (decl_table) - { - /* Check if the entry has already been copied to UNIT. */ - slot = htab_find_slot_with_hash (decl_table, die, - htab_hash_pointer (die), INSERT); - if (*slot != HTAB_EMPTY_ENTRY) - { - entry = (struct decl_table_entry *) *slot; - return entry->copy; - } - - /* Record in DECL_TABLE that DIE has been copied to UNIT. */ - entry = XCNEW (struct decl_table_entry); - entry->orig = die; - entry->copy = NULL; - *slot = entry; - } - - if (parent != NULL) - { - dw_die_ref spec = get_AT_ref (parent, DW_AT_specification); - if (spec != NULL) - parent = spec; - if (!is_unit_die (parent)) - new_parent = copy_ancestor_tree (unit, parent, decl_table); - } - - copy = clone_as_declaration (die); - add_child_die (new_parent, copy); - - if (decl_table != NULL) - { - /* Record the pointer to the copy. */ - entry->copy = copy; - } - - return copy; -} - /* Like clone_tree, but additionally enter all the children into the hash table decl_table. */ static dw_die_ref -clone_tree_hash (dw_die_ref die, htab_t decl_table) +clone_tree_hash (dw_die_ref die, decl_hash_type decl_table) { dw_die_ref c; dw_die_ref clone = clone_die (die); struct decl_table_entry *entry; - void **slot = htab_find_slot_with_hash (decl_table, die, + decl_table_entry **slot = decl_table.find_slot_with_hash (die, htab_hash_pointer (die), INSERT); /* Assert that DIE isn't in the hash table yet. If it would be there before, the ancestors would be necessarily there as well, therefore @@ -7228,7 +7224,7 @@ clone_tree_hash (dw_die_ref die, htab_t decl_table) type_unit). */ static void -copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table) +copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table) { dw_die_ref c; dw_attr_ref a; @@ -7239,20 +7235,20 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table) if (AT_class (a) == dw_val_class_die_ref) { dw_die_ref targ = AT_ref (a); - void **slot; + decl_table_entry **slot; struct decl_table_entry *entry; if (targ->die_mark != 0 || targ->comdat_type_p) continue; - slot = htab_find_slot_with_hash (decl_table, targ, - htab_hash_pointer (targ), INSERT); + slot = decl_table.find_slot_with_hash (targ, htab_hash_pointer (targ), + INSERT); if (*slot != HTAB_EMPTY_ENTRY) { /* TARG has already been copied, so we just need to modify the reference to point to the copy. */ - entry = (struct decl_table_entry *) *slot; + entry = *slot; a->dw_attr_val.v.val_die_ref.die = entry->copy; } else @@ -7319,12 +7315,12 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table) static void copy_decls_for_unworthy_types (dw_die_ref unit) { - htab_t decl_table; + decl_hash_type decl_table; mark_dies (unit); - decl_table = htab_create (10, htab_decl_hash, htab_decl_eq, htab_decl_del); + decl_table.create (10); copy_decls_walk (unit, unit, decl_table); - htab_delete (decl_table); + decl_table.dispose (); unmark_dies (unit); } @@ -7379,37 +7375,42 @@ struct external_ref unsigned n_refs; }; -/* Hash an external_ref. */ +/* Hashtable helpers. */ -static hashval_t -hash_external_ref (const void *p) +struct external_ref_hasher : typed_free_remove <external_ref> +{ + typedef external_ref value_type; + typedef external_ref compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +external_ref_hasher::hash (const value_type *r) { - const struct external_ref *r = (const struct external_ref *)p; return htab_hash_pointer (r->type); } -/* Compare external_refs. */ - -static int -external_ref_eq (const void *p1, const void *p2) +inline bool +external_ref_hasher::equal (const value_type *r1, const compare_type *r2) { - const struct external_ref *r1 = (const struct external_ref *)p1; - const struct external_ref *r2 = (const struct external_ref *)p2; return r1->type == r2->type; } +typedef hash_table <external_ref_hasher> external_ref_hash_type; + /* Return a pointer to the external_ref for references to DIE. */ static struct external_ref * -lookup_external_ref (htab_t map, dw_die_ref die) +lookup_external_ref (external_ref_hash_type map, dw_die_ref die) { struct external_ref ref, *ref_p; - void ** slot; + external_ref **slot; ref.type = die; - slot = htab_find_slot (map, &ref, INSERT); + slot = map.find_slot (&ref, INSERT); if (*slot != HTAB_EMPTY_ENTRY) - return (struct external_ref *) *slot; + return *slot; ref_p = XCNEW (struct external_ref); ref_p->type = die; @@ -7423,7 +7424,7 @@ lookup_external_ref (htab_t map, dw_die_ref die) references, remember how many we've seen. */ static void -optimize_external_refs_1 (dw_die_ref die, htab_t map) +optimize_external_refs_1 (dw_die_ref die, external_ref_hash_type map) { dw_die_ref c; dw_attr_ref a; @@ -7456,17 +7457,17 @@ optimize_external_refs_1 (dw_die_ref die, htab_t map) points to an external_ref, DATA is the CU we're processing. If we don't already have a local stub, and we have multiple refs, build a stub. */ -static int -build_local_stub (void **slot, void *data) +int +dwarf2_build_local_stub (external_ref **slot, dw_die_ref data) { - struct external_ref *ref_p = (struct external_ref *)*slot; + struct external_ref *ref_p = *slot; if (ref_p->stub == NULL && ref_p->n_refs > 1 && !dwarf_strict) { /* We have multiple references to this type, so build a small stub. Both of these forms are a bit dodgy from the perspective of the DWARF standard, since technically they should have names. */ - dw_die_ref cu = (dw_die_ref) data; + dw_die_ref cu = data; dw_die_ref type = ref_p->type; dw_die_ref stub = NULL; @@ -7494,12 +7495,13 @@ build_local_stub (void **slot, void *data) them which will be applied in build_abbrev_table. This is useful because references to local DIEs are smaller. */ -static htab_t +static external_ref_hash_type optimize_external_refs (dw_die_ref die) { - htab_t map = htab_create (10, hash_external_ref, external_ref_eq, free); + external_ref_hash_type map; + map.create (10); optimize_external_refs_1 (die, map); - htab_traverse (map, build_local_stub, die); + map.traverse <dw_die_ref, dwarf2_build_local_stub> (die); return map; } @@ -7509,7 +7511,7 @@ optimize_external_refs (dw_die_ref die) die are visited recursively. */ static void -build_abbrev_table (dw_die_ref die, htab_t extern_map) +build_abbrev_table (dw_die_ref die, external_ref_hash_type extern_map) { unsigned long abbrev_id; unsigned int n_alloc; @@ -8640,7 +8642,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty) { const char *secname, *oldsym; char *tmp; - htab_t extern_map; + external_ref_hash_type extern_map; /* Unless we are outputting main CU, we may throw away empty ones. */ if (!output_if_empty && die->die_child == NULL) @@ -8657,7 +8659,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty) build_abbrev_table (die, extern_map); - htab_delete (extern_map); + extern_map.dispose (); /* Initialize the beginning DIE offset - and calculate sizes/offsets. */ next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE; @@ -8830,7 +8832,7 @@ output_comdat_type_unit (comdat_type_node *node) #if defined (OBJECT_FORMAT_ELF) tree comdat_key; #endif - htab_t extern_map; + external_ref_hash_type extern_map; /* First mark all the DIEs in this CU so we know which get local refs. */ mark_dies (node->root_die); @@ -8839,7 +8841,7 @@ output_comdat_type_unit (comdat_type_node *node) build_abbrev_table (node->root_die, extern_map); - htab_delete (extern_map); + extern_map.dispose (); /* Initialize the beginning DIE offset - and calculate sizes/offsets. */ next_die_offset = DWARF_COMDAT_TYPE_UNIT_HEADER_SIZE; @@ -21326,26 +21328,31 @@ dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED, } } -/* Routines to manipulate hash table of CUs. */ +/* Helpers to manipulate hash table of CUs. */ -static hashval_t -htab_macinfo_hash (const void *of) +struct macinfo_entry_hasher : typed_noop_remove <macinfo_entry> { - const macinfo_entry *const entry = - (const macinfo_entry *) of; + typedef macinfo_entry value_type; + typedef macinfo_entry compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; +inline hashval_t +macinfo_entry_hasher::hash (const value_type *entry) +{ return htab_hash_string (entry->info); } -static int -htab_macinfo_eq (const void *of1, const void *of2) +inline bool +macinfo_entry_hasher::equal (const value_type *entry1, + const compare_type *entry2) { - const macinfo_entry *const entry1 = (const macinfo_entry *) of1; - const macinfo_entry *const entry2 = (const macinfo_entry *) of2; - return !strcmp (entry1->info, entry2->info); } +typedef hash_table <macinfo_entry_hasher> macinfo_hash_type; + /* Output a single .debug_macinfo entry. */ static void @@ -21434,7 +21441,7 @@ output_macinfo_op (macinfo_entry *ref) static unsigned optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files, - htab_t *macinfo_htab) + macinfo_hash_type *macinfo_htab) { macinfo_entry *first, *second, *cur, *inc; char linebuf[sizeof (HOST_WIDE_INT) * 3 + 1]; @@ -21443,7 +21450,7 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files, char *grp_name, *tail; const char *base; unsigned int i, count, encoded_filename_len, linebuf_len; - void **slot; + macinfo_entry **slot; first = &(*macinfo_table)[idx]; second = &(*macinfo_table)[idx + 1]; @@ -21521,17 +21528,17 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files, inc->code = DW_MACRO_GNU_transparent_include; inc->lineno = 0; inc->info = ggc_strdup (grp_name); - if (*macinfo_htab == NULL) - *macinfo_htab = htab_create (10, htab_macinfo_hash, htab_macinfo_eq, NULL); + if (!macinfo_htab->is_created ()) + macinfo_htab->create (10); /* Avoid emitting duplicates. */ - slot = htab_find_slot (*macinfo_htab, inc, INSERT); + slot = macinfo_htab->find_slot (inc, INSERT); if (*slot != NULL) { inc->code = 0; inc->info = NULL; /* If such an entry has been used before, just emit a DW_MACRO_GNU_transparent_include op. */ - inc = (macinfo_entry *) *slot; + inc = *slot; output_macinfo_op (inc); /* And clear all macinfo_entry in the range to avoid emitting them in the second pass. */ @@ -21544,7 +21551,7 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files, else { *slot = inc; - inc->lineno = htab_elements (*macinfo_htab); + inc->lineno = macinfo_htab->elements (); output_macinfo_op (inc); } return count; @@ -21595,7 +21602,7 @@ output_macinfo (void) unsigned long length = vec_safe_length (macinfo_table); macinfo_entry *ref; vec<macinfo_entry, va_gc> *files = NULL; - htab_t macinfo_htab = NULL; + macinfo_hash_type macinfo_htab; if (! length) return; @@ -21668,10 +21675,10 @@ output_macinfo (void) ref->code = 0; } - if (macinfo_htab == NULL) + if (!macinfo_htab.is_created ()) return; - htab_delete (macinfo_htab); + macinfo_htab.dispose (); /* If any DW_MACRO_GNU_transparent_include were used, on those DW_MACRO_GNU_transparent_include entries terminate the @@ -22410,24 +22417,28 @@ file_table_relative_p (void ** slot, void *param) return 1; } -/* Routines to manipulate hash table of comdat type units. */ +/* Helpers to manipulate hash table of comdat type units. */ -static hashval_t -htab_ct_hash (const void *of) +struct comdat_type_hasher : typed_noop_remove <comdat_type_node> { - hashval_t h; - const comdat_type_node *const type_node = (const comdat_type_node *) of; + typedef comdat_type_node value_type; + typedef comdat_type_node compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; +inline hashval_t +comdat_type_hasher::hash (const value_type *type_node) +{ + hashval_t h; memcpy (&h, type_node->signature, sizeof (h)); return h; } -static int -htab_ct_eq (const void *of1, const void *of2) +inline bool +comdat_type_hasher::equal (const value_type *type_node_1, + const compare_type *type_node_2) { - const comdat_type_node *const type_node_1 = (const comdat_type_node *) of1; - const comdat_type_node *const type_node_2 = (const comdat_type_node *) of2; - return (! memcmp (type_node_1->signature, type_node_2->signature, DWARF_TYPE_SIGNATURE_SIZE)); } @@ -23491,21 +23502,29 @@ compare_locs (dw_loc_descr_ref x, dw_loc_descr_ref y) return x == NULL && y == NULL; } +/* Hashtable helpers. */ + +struct loc_list_hasher : typed_noop_remove <dw_loc_list_struct> +{ + typedef dw_loc_list_struct value_type; + typedef dw_loc_list_struct compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + /* Return precomputed hash of location list X. */ -static hashval_t -loc_list_hash (const void *x) +inline hashval_t +loc_list_hasher::hash (const value_type *x) { - return ((const struct dw_loc_list_struct *) x)->hash; + return x->hash; } -/* Return 1 if location lists X and Y are the same. */ +/* Return true if location lists A and B are the same. */ -static int -loc_list_eq (const void *x, const void *y) +inline bool +loc_list_hasher::equal (const value_type *a, const compare_type *b) { - const struct dw_loc_list_struct *a = (const struct dw_loc_list_struct *) x; - const struct dw_loc_list_struct *b = (const struct dw_loc_list_struct *) y; if (a == b) return 1; if (a->hash != b->hash) @@ -23520,16 +23539,19 @@ loc_list_eq (const void *x, const void *y) return a == NULL && b == NULL; } +typedef hash_table <loc_list_hasher> loc_list_hash_type; + + /* Recursively optimize location lists referenced from DIE children and share them whenever possible. */ static void -optimize_location_lists_1 (dw_die_ref die, htab_t htab) +optimize_location_lists_1 (dw_die_ref die, loc_list_hash_type htab) { dw_die_ref c; dw_attr_ref a; unsigned ix; - void **slot; + dw_loc_list_struct **slot; FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) if (AT_class (a) == dw_val_class_loc_list) @@ -23538,12 +23560,11 @@ optimize_location_lists_1 (dw_die_ref die, htab_t htab) /* TODO: perform some optimizations here, before hashing it and storing into the hash table. */ hash_loc_list (list); - slot = htab_find_slot_with_hash (htab, list, list->hash, - INSERT); + slot = htab.find_slot_with_hash (list, list->hash, INSERT); if (*slot == NULL) - *slot = (void *) list; + *slot = list; else - a->dw_attr_val.v.val_loc_list = (dw_loc_list_ref) *slot; + a->dw_attr_val.v.val_loc_list = *slot; } FOR_EACH_CHILD (die, c, optimize_location_lists_1 (c, htab)); @@ -23588,9 +23609,10 @@ index_location_lists (dw_die_ref die) static void optimize_location_lists (dw_die_ref die) { - htab_t htab = htab_create (500, loc_list_hash, loc_list_eq, NULL); + loc_list_hash_type htab; + htab.create (500); optimize_location_lists_1 (die, htab); - htab_delete (htab); + htab.dispose (); } /* Output stuff that dwarf requires at the end of every file, @@ -23601,7 +23623,7 @@ dwarf2out_finish (const char *filename) { limbo_die_node *node, *next_node; comdat_type_node *ctnode; - htab_t comdat_type_table; + hash_table <comdat_type_hasher> comdat_type_table; unsigned int i; dw_die_ref main_comp_unit_die; @@ -23870,10 +23892,10 @@ dwarf2out_finish (const char *filename) for (node = limbo_die_list; node; node = node->next) output_comp_unit (node->die, 0); - comdat_type_table = htab_create (100, htab_ct_hash, htab_ct_eq, NULL); + comdat_type_table.create (100); for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next) { - void **slot = htab_find_slot (comdat_type_table, ctnode, INSERT); + comdat_type_node **slot = comdat_type_table.find_slot (ctnode, INSERT); /* Don't output duplicate types. */ if (*slot != HTAB_EMPTY_ENTRY) @@ -23891,7 +23913,7 @@ dwarf2out_finish (const char *filename) output_comdat_type_unit (ctnode); *slot = ctnode; } - htab_delete (comdat_type_table); + comdat_type_table.dispose (); /* The AT_pubnames attribute needs to go in all skeleton dies, including both the main_cu and all skeleton TUs. Making this call unconditional diff --git a/gcc/except.c b/gcc/except.c index 4e85f731837..b25207b4c87 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -128,7 +128,7 @@ along with GCC; see the file COPYING3. If not see #include "dwarf2out.h" #include "dwarf2.h" #include "toplev.h" -#include "hashtab.h" +#include "hash-table.h" #include "intl.h" #include "ggc.h" #include "tm_p.h" @@ -166,6 +166,49 @@ struct GTY(()) call_site_record_d rtx landing_pad; int action; }; + +/* In the following structure and associated functions, + we represent entries in the action table as 1-based indices. + Special cases are: + + 0: null action record, non-null landing pad; implies cleanups + -1: null action record, null landing pad; implies no action + -2: no call-site entry; implies must_not_throw + -3: we have yet to process outer regions + + Further, no special cases apply to the "next" field of the record. + For next, 0 means end of list. */ + +struct action_record +{ + int offset; + int filter; + int next; +}; + +/* Hashtable helpers. */ + +struct action_record_hasher : typed_free_remove <action_record> +{ + typedef action_record value_type; + typedef action_record compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +action_record_hasher::hash (const value_type *entry) +{ + return entry->next * 1009 + entry->filter; +} + +inline bool +action_record_hasher::equal (const value_type *entry, const compare_type *data) +{ + return entry->filter == data->filter && entry->next == data->next; +} + +typedef hash_table <action_record_hasher> action_hash_type; static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *, eh_landing_pad *); @@ -173,18 +216,9 @@ static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *, static int t2r_eq (const void *, const void *); static hashval_t t2r_hash (const void *); -static int ttypes_filter_eq (const void *, const void *); -static hashval_t ttypes_filter_hash (const void *); -static int ehspec_filter_eq (const void *, const void *); -static hashval_t ehspec_filter_hash (const void *); -static int add_ttypes_entry (htab_t, tree); -static int add_ehspec_entry (htab_t, htab_t, tree); static void dw2_build_landing_pads (void); -static int action_record_eq (const void *, const void *); -static hashval_t action_record_hash (const void *); -static int add_action_record (htab_t, int, int); -static int collect_one_action_chain (htab_t, eh_region); +static int collect_one_action_chain (action_hash_type, eh_region); static int add_call_site (rtx, int, int); static void push_uleb128 (vec<uchar, va_gc> **, unsigned int); @@ -687,46 +721,60 @@ struct ttypes_filter { int filter; }; +/* Helper for ttypes_filter hashing. */ + +struct ttypes_filter_hasher : typed_free_remove <ttypes_filter> +{ + typedef ttypes_filter value_type; + typedef tree_node compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA (a tree) for a @TTypes type node we are thinking about adding. */ -static int -ttypes_filter_eq (const void *pentry, const void *pdata) +inline bool +ttypes_filter_hasher::equal (const value_type *entry, const compare_type *data) { - const struct ttypes_filter *const entry - = (const struct ttypes_filter *) pentry; - const_tree const data = (const_tree) pdata; - return entry->t == data; } -static hashval_t -ttypes_filter_hash (const void *pentry) +inline hashval_t +ttypes_filter_hasher::hash (const value_type *entry) { - const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; return TREE_HASH (entry->t); } +typedef hash_table <ttypes_filter_hasher> ttypes_hash_type; + + +/* Helper for ehspec hashing. */ + +struct ehspec_hasher : typed_free_remove <ttypes_filter> +{ + typedef ttypes_filter value_type; + typedef ttypes_filter compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes exception specification list we are thinking about adding. */ /* ??? Currently we use the type lists in the order given. Someone should put these in some canonical order. */ -static int -ehspec_filter_eq (const void *pentry, const void *pdata) +inline bool +ehspec_hasher::equal (const value_type *entry, const compare_type *data) { - const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; - const struct ttypes_filter *data = (const struct ttypes_filter *) pdata; - return type_list_equal (entry->t, data->t); } /* Hash function for exception specification lists. */ -static hashval_t -ehspec_filter_hash (const void *pentry) +inline hashval_t +ehspec_hasher::hash (const value_type *entry) { - const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry; hashval_t h = 0; tree list; @@ -735,16 +783,19 @@ ehspec_filter_hash (const void *pentry) return h; } +typedef hash_table <ehspec_hasher> ehspec_hash_type; + + /* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH to speed up the search. Return the filter value to be used. */ static int -add_ttypes_entry (htab_t ttypes_hash, tree type) +add_ttypes_entry (ttypes_hash_type ttypes_hash, tree type) { struct ttypes_filter **slot, *n; - slot = (struct ttypes_filter **) - htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT); + slot = ttypes_hash.find_slot_with_hash (type, (hashval_t) TREE_HASH (type), + INSERT); if ((n = *slot) == NULL) { @@ -765,14 +816,14 @@ add_ttypes_entry (htab_t ttypes_hash, tree type) to speed up the search. Return the filter value to be used. */ static int -add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list) +add_ehspec_entry (ehspec_hash_type ehspec_hash, ttypes_hash_type ttypes_hash, + tree list) { struct ttypes_filter **slot, *n; struct ttypes_filter dummy; dummy.t = list; - slot = (struct ttypes_filter **) - htab_find_slot (ehspec_hash, &dummy, INSERT); + slot = ehspec_hash.find_slot (&dummy, INSERT); if ((n = *slot) == NULL) { @@ -821,7 +872,8 @@ void assign_filter_values (void) { int i; - htab_t ttypes, ehspec; + ttypes_hash_type ttypes; + ehspec_hash_type ehspec; eh_region r; eh_catch c; @@ -831,8 +883,8 @@ assign_filter_values (void) else vec_alloc (cfun->eh->ehspec_data.other, 64); - ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free); - ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free); + ttypes.create (31); + ehspec.create (31); for (i = 1; vec_safe_iterate (cfun->eh->region_array, i, &r); ++i) { @@ -886,8 +938,8 @@ assign_filter_values (void) } } - htab_delete (ttypes); - htab_delete (ehspec); + ttypes.dispose (); + ehspec.dispose (); } /* Emit SEQ into basic block just before INSN (that is assumed to be @@ -1009,12 +1061,12 @@ static vec<int> sjlj_lp_call_site_index; static int sjlj_assign_call_site_values (void) { - htab_t ar_hash; + action_hash_type ar_hash; int i, disp_index; eh_landing_pad lp; vec_alloc (crtl->eh.action_record_data, 64); - ar_hash = htab_create (31, action_record_hash, action_record_eq, free); + ar_hash.create (31); disp_index = 0; call_site_base = 1; @@ -1043,7 +1095,7 @@ sjlj_assign_call_site_values (void) disp_index++; } - htab_delete (ar_hash); + ar_hash.dispose (); return disp_index; } @@ -2236,47 +2288,14 @@ expand_builtin_extend_pointer (tree addr_tree) return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend); } -/* In the following functions, we represent entries in the action table - as 1-based indices. Special cases are: - - 0: null action record, non-null landing pad; implies cleanups - -1: null action record, null landing pad; implies no action - -2: no call-site entry; implies must_not_throw - -3: we have yet to process outer regions - - Further, no special cases apply to the "next" field of the record. - For next, 0 means end of list. */ - -struct action_record -{ - int offset; - int filter; - int next; -}; - -static int -action_record_eq (const void *pentry, const void *pdata) -{ - const struct action_record *entry = (const struct action_record *) pentry; - const struct action_record *data = (const struct action_record *) pdata; - return entry->filter == data->filter && entry->next == data->next; -} - -static hashval_t -action_record_hash (const void *pentry) -{ - const struct action_record *entry = (const struct action_record *) pentry; - return entry->next * 1009 + entry->filter; -} - static int -add_action_record (htab_t ar_hash, int filter, int next) +add_action_record (action_hash_type ar_hash, int filter, int next) { struct action_record **slot, *new_ar, tmp; tmp.filter = filter; tmp.next = next; - slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT); + slot = ar_hash.find_slot (&tmp, INSERT); if ((new_ar = *slot) == NULL) { @@ -2301,7 +2320,7 @@ add_action_record (htab_t ar_hash, int filter, int next) } static int -collect_one_action_chain (htab_t ar_hash, eh_region region) +collect_one_action_chain (action_hash_type ar_hash, eh_region region) { int next; @@ -2430,7 +2449,7 @@ static unsigned int convert_to_eh_region_ranges (void) { rtx insn, iter, note; - htab_t ar_hash; + action_hash_type ar_hash; int last_action = -3; rtx last_action_insn = NULL_RTX; rtx last_landing_pad = NULL_RTX; @@ -2444,7 +2463,7 @@ convert_to_eh_region_ranges (void) vec_alloc (crtl->eh.action_record_data, 64); - ar_hash = htab_create (31, action_record_hash, action_record_eq, free); + ar_hash.create (31); for (iter = get_insns (); iter ; iter = NEXT_INSN (iter)) if (INSN_P (iter)) @@ -2581,7 +2600,7 @@ convert_to_eh_region_ranges (void) call_site_base = saved_call_site_base; - htab_delete (ar_hash); + ar_hash.dispose (); return 0; } diff --git a/gcc/gcse.c b/gcc/gcse.c index e1daf18f8b0..07043f76a4d 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -158,7 +158,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "obstack.h" #include "tree-pass.h" -#include "hashtab.h" +#include "hash-table.h" #include "df.h" #include "dbgcnt.h" #include "target.h" @@ -359,8 +359,34 @@ struct ls_expr /* Head of the list of load/store memory refs. */ static struct ls_expr * pre_ldst_mems = NULL; +struct pre_ldst_expr_hasher : typed_noop_remove <ls_expr> +{ + typedef ls_expr value_type; + typedef value_type compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hashtable helpers. */ +inline hashval_t +pre_ldst_expr_hasher::hash (const value_type *x) +{ + int do_not_record_p = 0; + return + hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false); +} + +static int expr_equiv_p (const_rtx, const_rtx); + +inline bool +pre_ldst_expr_hasher::equal (const value_type *ptr1, + const compare_type *ptr2) +{ + return expr_equiv_p (ptr1->pattern, ptr2->pattern); +} + /* Hashtable for the load/store memory refs. */ -static htab_t pre_ldst_table = NULL; +static hash_table <pre_ldst_expr_hasher> pre_ldst_table; /* Bitmap containing one bit for each register in the program. Used when performing GCSE to track which registers have been set since @@ -447,7 +473,6 @@ static int oprs_available_p (const_rtx, const_rtx); static void insert_expr_in_table (rtx, enum machine_mode, rtx, int, int, int, struct hash_table_d *); static unsigned int hash_expr (const_rtx, enum machine_mode, int *, int); -static int expr_equiv_p (const_rtx, const_rtx); static void record_last_reg_set_info (rtx, int); static void record_last_mem_set_info (rtx); static void record_last_set_info (rtx, const_rtx, void *); @@ -3652,23 +3677,6 @@ one_code_hoisting_pass (void) load towards the exit, and we end up with no loads or stores of 'i' in the loop. */ -static hashval_t -pre_ldst_expr_hash (const void *p) -{ - int do_not_record_p = 0; - const struct ls_expr *const x = (const struct ls_expr *) p; - return - hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false); -} - -static int -pre_ldst_expr_eq (const void *p1, const void *p2) -{ - const struct ls_expr *const ptr1 = (const struct ls_expr *) p1, - *const ptr2 = (const struct ls_expr *) p2; - return expr_equiv_p (ptr1->pattern, ptr2->pattern); -} - /* This will search the ldst list for a matching expression. If it doesn't find one, we create one and initialize it. */ @@ -3678,16 +3686,16 @@ ldst_entry (rtx x) int do_not_record_p = 0; struct ls_expr * ptr; unsigned int hash; - void **slot; + ls_expr **slot; struct ls_expr e; hash = hash_rtx (x, GET_MODE (x), &do_not_record_p, NULL, /*have_reg_qty=*/false); e.pattern = x; - slot = htab_find_slot_with_hash (pre_ldst_table, &e, hash, INSERT); + slot = pre_ldst_table.find_slot_with_hash (&e, hash, INSERT); if (*slot) - return (struct ls_expr *)*slot; + return *slot; ptr = XNEW (struct ls_expr); @@ -3723,9 +3731,8 @@ free_ldst_entry (struct ls_expr * ptr) static void free_ld_motion_mems (void) { - if (pre_ldst_table) - htab_delete (pre_ldst_table); - pre_ldst_table = NULL; + if (pre_ldst_table.is_created ()) + pre_ldst_table.dispose (); while (pre_ldst_mems) { @@ -3780,14 +3787,14 @@ static struct ls_expr * find_rtx_in_ldst (rtx x) { struct ls_expr e; - void **slot; - if (!pre_ldst_table) + ls_expr **slot; + if (!pre_ldst_table.is_created ()) return NULL; e.pattern = x; - slot = htab_find_slot (pre_ldst_table, &e, NO_INSERT); - if (!slot || ((struct ls_expr *)*slot)->invalid) + slot = pre_ldst_table.find_slot (&e, NO_INSERT); + if (!slot || (*slot)->invalid) return NULL; - return (struct ls_expr *) *slot; + return *slot; } /* Load Motion for loads which only kill themselves. */ @@ -3875,8 +3882,7 @@ compute_ld_motion_mems (void) rtx insn; pre_ldst_mems = NULL; - pre_ldst_table - = htab_create (13, pre_ldst_expr_hash, pre_ldst_expr_eq, NULL); + pre_ldst_table.create (13); FOR_EACH_BB (bb) { @@ -3967,7 +3973,7 @@ trim_ld_motion_mems (void) else { *last = ptr->next; - htab_remove_elt_with_hash (pre_ldst_table, ptr, ptr->hash_index); + pre_ldst_table.remove_elt_with_hash (ptr, ptr->hash_index); free_ldst_entry (ptr); ptr = * last; } diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 91c8249f3ae..0bb2eb19f23 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "hashtab.h" +#include "hash-table.h" #include "ggc.h" #include "ggc-internal.h" #include "diagnostic-core.h" @@ -46,10 +46,6 @@ static ggc_statistics *ggc_stats; struct traversal_state; static int ggc_htab_delete (void **, void *); -static hashval_t saving_htab_hash (const void *); -static int saving_htab_eq (const void *, const void *); -static int call_count (void **, void *); -static int call_alloc (void **, void *); static int compare_ptr_data (const void *, const void *); static void relocate_ptrs (void *, void *); static void write_pch_globals (const struct ggc_root_tab * const *tab, @@ -289,8 +285,6 @@ ggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED, /* Functions for saving and restoring GCable memory to disk. */ -static htab_t saving_htab; - struct ptr_data { void *obj; @@ -303,6 +297,30 @@ struct ptr_data #define POINTER_HASH(x) (hashval_t)((intptr_t)x >> 3) +/* Helper for hashing saving_htab. */ + +struct saving_hasher : typed_free_remove <ptr_data> +{ + typedef ptr_data value_type; + typedef void compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +saving_hasher::hash (const value_type *p) +{ + return POINTER_HASH (p->obj); +} + +inline bool +saving_hasher::equal (const value_type *p1, const compare_type *p2) +{ + return p1->obj == p2; +} + +static hash_table <saving_hasher> saving_htab; + /* Register an object in the hash table. */ int @@ -315,8 +333,7 @@ gt_pch_note_object (void *obj, void *note_ptr_cookie, return 0; slot = (struct ptr_data **) - htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj), - INSERT); + saving_htab.find_slot_with_hash (obj, POINTER_HASH (obj), INSERT); if (*slot != NULL) { gcc_assert ((*slot)->note_ptr_fn == note_ptr_fn @@ -347,26 +364,12 @@ gt_pch_note_reorder (void *obj, void *note_ptr_cookie, return; data = (struct ptr_data *) - htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj)); + saving_htab.find_with_hash (obj, POINTER_HASH (obj)); gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie); data->reorder_fn = reorder_fn; } -/* Hash and equality functions for saving_htab, callbacks for htab_create. */ - -static hashval_t -saving_htab_hash (const void *p) -{ - return POINTER_HASH (((const struct ptr_data *)p)->obj); -} - -static int -saving_htab_eq (const void *p1, const void *p2) -{ - return ((const struct ptr_data *)p1)->obj == p2; -} - /* Handy state for the traversal functions. */ struct traversal_state @@ -380,11 +383,10 @@ struct traversal_state /* Callbacks for htab_traverse. */ -static int -call_count (void **slot, void *state_p) +int +ggc_call_count (ptr_data **slot, traversal_state *state) { - struct ptr_data *d = (struct ptr_data *)*slot; - struct traversal_state *state = (struct traversal_state *)state_p; + struct ptr_data *d = *slot; ggc_pch_count_object (state->d, d->obj, d->size, d->note_ptr_fn == gt_pch_p_S); @@ -392,11 +394,10 @@ call_count (void **slot, void *state_p) return 1; } -static int -call_alloc (void **slot, void *state_p) +int +ggc_call_alloc (ptr_data **slot, traversal_state *state) { - struct ptr_data *d = (struct ptr_data *)*slot; - struct traversal_state *state = (struct traversal_state *)state_p; + struct ptr_data *d = *slot; d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size, d->note_ptr_fn == gt_pch_p_S); @@ -429,7 +430,7 @@ relocate_ptrs (void *ptr_p, void *state_p) return; result = (struct ptr_data *) - htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr)); + saving_htab.find_with_hash (*ptr, POINTER_HASH (*ptr)); gcc_assert (result); *ptr = result->new_addr; } @@ -458,7 +459,7 @@ write_pch_globals (const struct ggc_root_tab * const *tab, else { new_ptr = (struct ptr_data *) - htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr)); + saving_htab.find_with_hash (ptr, POINTER_HASH (ptr)); if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f) != 1) fatal_error ("can%'t write PCH file: %m"); @@ -492,7 +493,7 @@ gt_pch_save (FILE *f) gt_pch_save_stringpool (); timevar_push (TV_PCH_PTR_REALLOC); - saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free); + saving_htab.create (50000); for (rt = gt_ggc_rtab; *rt; rt++) for (rti = *rt; rti->base != NULL; rti++) @@ -508,7 +509,7 @@ gt_pch_save (FILE *f) state.f = f; state.d = init_ggc_pch (); state.count = 0; - htab_traverse (saving_htab, call_count, &state); + saving_htab.traverse <traversal_state *, ggc_call_count> (&state); mmi.size = ggc_pch_total_size (state.d); @@ -524,7 +525,7 @@ gt_pch_save (FILE *f) state.ptrs = XNEWVEC (struct ptr_data *, state.count); state.ptrs_i = 0; - htab_traverse (saving_htab, call_alloc, &state); + saving_htab.traverse <traversal_state *, ggc_call_alloc> (&state); timevar_pop (TV_PCH_PTR_REALLOC); timevar_push (TV_PCH_PTR_SORT); @@ -653,7 +654,7 @@ gt_pch_save (FILE *f) XDELETE (state.ptrs); XDELETE (this_object); - htab_delete (saving_htab); + saving_htab.dispose (); } /* Read the state of the compiler back in from F. */ @@ -913,30 +914,32 @@ struct loc_descriptor size_t collected; }; -/* Hashtable used for statistics. */ -static htab_t loc_hash; +/* Hash table helper. */ -/* Hash table helpers functions. */ -static hashval_t -hash_descriptor (const void *p) +struct loc_desc_hasher : typed_noop_remove <loc_descriptor> { - const struct loc_descriptor *const d = (const struct loc_descriptor *) p; + typedef loc_descriptor value_type; + typedef loc_descriptor compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; +inline hashval_t +loc_desc_hasher::hash (const value_type *d) +{ return htab_hash_pointer (d->function) | d->line; } -static int -eq_descriptor (const void *p1, const void *p2) +inline bool +loc_desc_hasher::equal (const value_type *d, const compare_type *d2) { - const struct loc_descriptor *const d = (const struct loc_descriptor *) p1; - const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2; - return (d->file == d2->file && d->line == d2->line && d->function == d2->function); } -/* Hashtable converting address of allocated field to loc descriptor. */ -static htab_t ptr_hash; +/* Hashtable used for statistics. */ +static hash_table <loc_desc_hasher> loc_hash; + struct ptr_hash_entry { void *ptr; @@ -944,26 +947,34 @@ struct ptr_hash_entry size_t size; }; -/* Hash table helpers functions. */ -static hashval_t -hash_ptr (const void *p) +/* Helper for ptr_hash table. */ + +struct ptr_hash_hasher : typed_noop_remove <ptr_hash_entry> { - const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p; + typedef ptr_hash_entry value_type; + typedef void compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; +inline hashval_t +ptr_hash_hasher::hash (const value_type *d) +{ return htab_hash_pointer (d->ptr); } -static int -eq_ptr (const void *p1, const void *p2) +inline bool +ptr_hash_hasher::equal (const value_type *p, const compare_type *p2) { - const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1; - return (p->ptr == p2); } +/* Hashtable converting address of allocated field to loc descriptor. */ +static hash_table <ptr_hash_hasher> ptr_hash; + /* Return descriptor for given call site, create new one if needed. */ static struct loc_descriptor * -loc_descriptor (const char *name, int line, const char *function) +make_loc_descriptor (const char *name, int line, const char *function) { struct loc_descriptor loc; struct loc_descriptor **slot; @@ -971,10 +982,10 @@ loc_descriptor (const char *name, int line, const char *function) loc.file = name; loc.line = line; loc.function = function; - if (!loc_hash) - loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL); + if (!loc_hash.is_created ()) + loc_hash.create (10); - slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, INSERT); + slot = loc_hash.find_slot (&loc, INSERT); if (*slot) return *slot; *slot = XCNEW (struct loc_descriptor); @@ -989,16 +1000,16 @@ void ggc_record_overhead (size_t allocated, size_t overhead, void *ptr, const char *name, int line, const char *function) { - struct loc_descriptor *loc = loc_descriptor (name, line, function); + struct loc_descriptor *loc = make_loc_descriptor (name, line, function); struct ptr_hash_entry *p = XNEW (struct ptr_hash_entry); - PTR *slot; + ptr_hash_entry **slot; p->ptr = ptr; p->loc = loc; p->size = allocated + overhead; - if (!ptr_hash) - ptr_hash = htab_create (10, hash_ptr, eq_ptr, NULL); - slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), INSERT); + if (!ptr_hash.is_created ()) + ptr_hash.create (10); + slot = ptr_hash.find_slot_with_hash (ptr, htab_hash_pointer (ptr), INSERT); gcc_assert (!*slot); *slot = p; @@ -1009,14 +1020,14 @@ ggc_record_overhead (size_t allocated, size_t overhead, void *ptr, /* Helper function for prune_overhead_list. See if SLOT is still marked and remove it from hashtable if it is not. */ -static int -ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED) +int +ggc_prune_ptr (ptr_hash_entry **slot, void *b ATTRIBUTE_UNUSED) { - struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot; + struct ptr_hash_entry *p = *slot; if (!ggc_marked_p (p->ptr)) { p->loc->collected += p->size; - htab_clear_slot (ptr_hash, slot); + ptr_hash.clear_slot (slot); free (p); } return 1; @@ -1027,15 +1038,15 @@ ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED) void ggc_prune_overhead_list (void) { - htab_traverse (ptr_hash, ggc_prune_ptr, NULL); + ptr_hash.traverse <void *, ggc_prune_ptr> (NULL); } /* Notice that the pointer has been freed. */ void ggc_free_overhead (void *ptr) { - PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), - NO_INSERT); + ptr_hash_entry **slot; + slot = ptr_hash.find_slot_with_hash (ptr, htab_hash_pointer (ptr), NO_INSERT); struct ptr_hash_entry *p; /* The pointer might be not found if a PCH read happened between allocation and ggc_free () call. FIXME: account memory properly in the presence of @@ -1044,7 +1055,7 @@ ggc_free_overhead (void *ptr) return; p = (struct ptr_hash_entry *) *slot; p->loc->freed += p->size; - htab_clear_slot (ptr_hash, slot); + ptr_hash.clear_slot (slot); free (p); } @@ -1083,11 +1094,10 @@ cmp_statistic (const void *loc1, const void *loc2) /* Collect array of the descriptors from hashtable. */ static struct loc_descriptor **loc_array; -static int -add_statistics (void **slot, void *b) +int +ggc_add_statistics (loc_descriptor **slot, int *n) { - int *n = (int *)b; - loc_array[*n] = (struct loc_descriptor *) *slot; + loc_array[*n] = *slot; (*n)++; return 1; } @@ -1108,12 +1118,13 @@ dump_ggc_loc_statistics (bool final) ggc_force_collect = true; ggc_collect (); - loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements); + loc_array = XCNEWVEC (struct loc_descriptor *, + loc_hash.elements_with_deleted ()); fprintf (stderr, "-------------------------------------------------------\n"); fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n", "source location", "Garbage", "Freed", "Leak", "Overhead", "Times"); fprintf (stderr, "-------------------------------------------------------\n"); - htab_traverse (loc_hash, add_statistics, &nentries); + loc_hash.traverse <int *, ggc_add_statistics> (&nentries); qsort (loc_array, nentries, sizeof (*loc_array), final ? final_cmp_statistic : cmp_statistic); for (i = 0; i < nentries; i++) diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 57b343ab5cf..9f4902d424f 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see #include "pointer-set.h" #include "expmed.h" #include "params.h" +#include "hash-table.h" /* Information about a strength reduction candidate. Each statement in the candidate table represents an expression of one of the @@ -287,9 +288,6 @@ static struct pointer_map_t *stmt_cand_map; /* Obstack for candidates. */ static struct obstack cand_obstack; -/* Hash table embodying a mapping from base exprs to chains of candidates. */ -static htab_t base_cand_map; - /* Obstack for candidate chains. */ static struct obstack chain_obstack; @@ -311,32 +309,31 @@ lookup_cand (cand_idx idx) return cand_vec[idx - 1]; } -/* Callback to produce a hash value for a candidate chain header. */ +/* Helper for hashing a candidate chain header. */ -static hashval_t -base_cand_hash (const void *p) +struct cand_chain_hasher : typed_noop_remove <cand_chain> { - tree base_expr = ((const_cand_chain_t) p)->base_expr; - return iterative_hash_expr (base_expr, 0); -} - -/* Callback when an element is removed from the hash table. - We never remove entries until the entire table is released. */ + typedef cand_chain value_type; + typedef cand_chain compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; -static void -base_cand_free (void *p ATTRIBUTE_UNUSED) +inline hashval_t +cand_chain_hasher::hash (const value_type *p) { + tree base_expr = p->base_expr; + return iterative_hash_expr (base_expr, 0); } -/* Callback to return true if two candidate chain headers are equal. */ - -static int -base_cand_eq (const void *p1, const void *p2) +inline bool +cand_chain_hasher::equal (const value_type *chain1, const compare_type *chain2) { - const_cand_chain_t const chain1 = (const_cand_chain_t) p1; - const_cand_chain_t const chain2 = (const_cand_chain_t) p2; return operand_equal_p (chain1->base_expr, chain2->base_expr, 0); } + +/* Hash table embodying a mapping from base exprs to chains of candidates. */ +static hash_table <cand_chain_hasher> base_cand_map; /* Use the base expr from candidate C to look for possible candidates that can serve as a basis for C. Each potential basis must also @@ -357,7 +354,7 @@ find_basis_for_candidate (slsr_cand_t c) int max_iters = PARAM_VALUE (PARAM_MAX_SLSR_CANDIDATE_SCAN); mapping_key.base_expr = c->base_expr; - chain = (cand_chain_t) htab_find (base_cand_map, &mapping_key); + chain = base_cand_map.find (&mapping_key); for (; chain && iters < max_iters; chain = chain->next, ++iters) { @@ -393,13 +390,13 @@ static void record_potential_basis (slsr_cand_t c) { cand_chain_t node; - void **slot; + cand_chain **slot; node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain)); node->base_expr = c->base_expr; node->cand = c; node->next = NULL; - slot = htab_find_slot (base_cand_map, node, INSERT); + slot = base_cand_map.find_slot (node, INSERT); if (*slot) { @@ -1435,10 +1432,10 @@ dump_cand_vec (void) /* Callback used to dump the candidate chains hash table. */ -static int -base_cand_dump_callback (void **slot, void *ignored ATTRIBUTE_UNUSED) +int +ssa_base_cand_dump_callback (cand_chain **slot, void *ignored ATTRIBUTE_UNUSED) { - const_cand_chain_t chain = *((const_cand_chain_t *) slot); + const_cand_chain_t chain = *slot; cand_chain_t p; print_generic_expr (dump_file, chain->base_expr, 0); @@ -1457,7 +1454,7 @@ static void dump_cand_chains (void) { fprintf (dump_file, "\nStrength reduction candidate chains:\n\n"); - htab_traverse_noresize (base_cand_map, base_cand_dump_callback, NULL); + base_cand_map.traverse_noresize <void *, ssa_base_cand_dump_callback> (NULL); fputs ("\n", dump_file); } @@ -2641,8 +2638,7 @@ execute_strength_reduction (void) gcc_obstack_init (&chain_obstack); /* Allocate the mapping from base expressions to candidate chains. */ - base_cand_map = htab_create (500, base_cand_hash, - base_cand_eq, base_cand_free); + base_cand_map.create (500); /* Initialize the loop optimizer. We need to detect flow across back edges, and this gives us dominator information as well. */ @@ -2673,7 +2669,7 @@ execute_strength_reduction (void) /* Free resources. */ fini_walk_dominator_tree (&walk_data); loop_optimizer_finalize (); - htab_delete (base_cand_map); + base_cand_map.dispose (); obstack_free (&chain_obstack, NULL); pointer_map_destroy (stmt_cand_map); cand_vec.release (); diff --git a/gcc/gimple.h b/gcc/gimple.h index 76da6d2bcd7..b4de403e65c 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_GIMPLE_H #include "pointer-set.h" +#include "hash-table.h" #include "vec.h" #include "ggc.h" #include "basic-block.h" @@ -959,6 +960,55 @@ enum gimplify_status { GS_ALL_DONE = 1 /* The expression is fully gimplified. */ }; +/* Formal (expression) temporary table handling: multiple occurrences of + the same scalar expression are evaluated into the same temporary. */ + +typedef struct gimple_temp_hash_elt +{ + tree val; /* Key */ + tree temp; /* Value */ +} elt_t; + +/* Gimplify hashtable helper. */ + +struct gimplify_hasher : typed_free_remove <elt_t> +{ + typedef elt_t value_type; + typedef elt_t compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +gimplify_hasher::hash (const value_type *p) +{ + tree t = p->val; + return iterative_hash_expr (t, 0); +} + +inline bool +gimplify_hasher::equal (const value_type *p1, const compare_type *p2) +{ + tree t1 = p1->val; + tree t2 = p2->val; + enum tree_code code = TREE_CODE (t1); + + if (TREE_CODE (t2) != code + || TREE_TYPE (t1) != TREE_TYPE (t2)) + return false; + + if (!operand_equal_p (t1, t2, 0)) + return false; + +#ifdef ENABLE_CHECKING + /* Only allow them to compare equal if they also hash equal; otherwise + results are nondeterminate, and we fail bootstrap comparison. */ + gcc_assert (hash (p1) == hash (p2)); +#endif + + return true; +} + struct gimplify_ctx { struct gimplify_ctx *prev_context; @@ -971,7 +1021,7 @@ struct gimplify_ctx vec<tree> case_labels; /* The formal temporary table. Should this be persistent? */ - htab_t temp_htab; + hash_table <gimplify_hasher> temp_htab; int conditions; bool save_stack; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 3a90588424c..fc7bfcf251c 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -87,15 +87,6 @@ static struct gimplify_ctx *gimplify_ctxp; static struct gimplify_omp_ctx *gimplify_omp_ctxp; -/* Formal (expression) temporary table handling: multiple occurrences of - the same scalar expression are evaluated into the same temporary. */ - -typedef struct gimple_temp_hash_elt -{ - tree val; /* Key */ - tree temp; /* Value */ -} elt_t; - /* Forward declaration. */ static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool); @@ -130,40 +121,6 @@ mark_addressable (tree x) } } -/* Return a hash value for a formal temporary table entry. */ - -static hashval_t -gimple_tree_hash (const void *p) -{ - tree t = ((const elt_t *) p)->val; - return iterative_hash_expr (t, 0); -} - -/* Compare two formal temporary table entries. */ - -static int -gimple_tree_eq (const void *p1, const void *p2) -{ - tree t1 = ((const elt_t *) p1)->val; - tree t2 = ((const elt_t *) p2)->val; - enum tree_code code = TREE_CODE (t1); - - if (TREE_CODE (t2) != code - || TREE_TYPE (t1) != TREE_TYPE (t2)) - return 0; - - if (!operand_equal_p (t1, t2, 0)) - return 0; - -#ifdef ENABLE_CHECKING - /* Only allow them to compare equal if they also hash equal; otherwise - results are nondeterminate, and we fail bootstrap comparison. */ - gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2)); -#endif - - return 1; -} - /* Link gimple statement GS to the end of the sequence *SEQ_P. If *SEQ_P is NULL, a new sequence is allocated. This function is similar to gimple_seq_add_stmt, but does not scan the operands. @@ -241,8 +198,8 @@ pop_gimplify_context (gimple body) else record_vars (c->temps); - if (c->temp_htab) - htab_delete (c->temp_htab); + if (c->temp_htab.is_created ()) + c->temp_htab.dispose (); } /* Push a GIMPLE_BIND tuple onto the stack of bindings. */ @@ -585,23 +542,22 @@ lookup_tmp_var (tree val, bool is_formal) else { elt_t elt, *elt_p; - void **slot; + elt_t **slot; elt.val = val; - if (gimplify_ctxp->temp_htab == NULL) - gimplify_ctxp->temp_htab - = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free); - slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT); + if (!gimplify_ctxp->temp_htab.is_created ()) + gimplify_ctxp->temp_htab.create (1000); + slot = gimplify_ctxp->temp_htab.find_slot (&elt, INSERT); if (*slot == NULL) { elt_p = XNEW (elt_t); elt_p->val = val; elt_p->temp = ret = create_tmp_from_val (val, is_formal); - *slot = (void *) elt_p; + *slot = elt_p; } else { - elt_p = (elt_t *) *slot; + elt_p = *slot; ret = elt_p->temp; } } diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c index 58a69ed0b4b..dcf8b94eaa1 100644 --- a/gcc/graphite-clast-to-gimple.c +++ b/gcc/graphite-clast-to-gimple.c @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "cloog/cloog.h" #include "graphite-poly.h" #include "graphite-clast-to-gimple.h" +#include "graphite-htab.h" typedef const struct clast_expr *clast_name_p; @@ -124,6 +125,55 @@ typedef struct clast_name_index { char *free_name; } *clast_name_index_p; +/* Helper for hashing clast_name_index. */ + +struct clast_index_hasher +{ + typedef clast_name_index value_type; + typedef clast_name_index compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +/* Computes a hash function for database element E. */ + +inline hashval_t +clast_index_hasher::hash (const value_type *e) +{ + hashval_t hash = 0; + + int length = strlen (e->name); + int i; + + for (i = 0; i < length; ++i) + hash = hash | (e->name[i] << (i % 4)); + + return hash; +} + +/* Compares database elements ELT1 and ELT2. */ + +inline bool +clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2) +{ + return strcmp (elt1->name, elt2->name) == 0; +} + +/* Free the memory taken by a clast_name_index struct. */ + +inline void +clast_index_hasher::remove (value_type *c) +{ + if (c->free_name) + free (c->free_name); + mpz_clear (c->bound_one); + mpz_clear (c->bound_two); + free (c); +} + +typedef hash_table <clast_index_hasher> clast_index_htab_type; + /* Returns a pointer to a new element of type clast_name_index_p built from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */ @@ -146,35 +196,22 @@ new_clast_name_index (const char *name, int index, int level, return res; } -/* Free the memory taken by a clast_name_index struct. */ - -static void -free_clast_name_index (void *ptr) -{ - struct clast_name_index *c = (struct clast_name_index *) ptr; - if (c->free_name) - free (c->free_name); - mpz_clear (c->bound_one); - mpz_clear (c->bound_two); - free (ptr); -} - /* For a given clast NAME, returns -1 if NAME is not in the INDEX_TABLE, otherwise returns the loop level for the induction variable NAME, or if it is a parameter, the parameter number in the vector of parameters. */ static inline int -clast_name_to_level (clast_name_p name, htab_t index_table) +clast_name_to_level (clast_name_p name, clast_index_htab_type index_table) { struct clast_name_index tmp; - PTR *slot; + clast_name_index **slot; gcc_assert (name->type == clast_expr_name); tmp.name = ((const struct clast_name *) name)->name; tmp.free_name = NULL; - slot = htab_find_slot (index_table, &tmp, NO_INSERT); + slot = index_table.find_slot (&tmp, NO_INSERT); if (slot && *slot) return ((struct clast_name_index *) *slot)->level; @@ -187,18 +224,18 @@ clast_name_to_level (clast_name_p name, htab_t index_table) SCATTERING_DIMENSIONS vector. */ static inline int -clast_name_to_index (struct clast_name *name, htab_t index_table) +clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table) { struct clast_name_index tmp; - PTR *slot; + clast_name_index **slot; tmp.name = ((const struct clast_name *) name)->name; tmp.free_name = NULL; - slot = htab_find_slot (index_table, &tmp, NO_INSERT); + slot = index_table.find_slot (&tmp, NO_INSERT); if (slot && *slot) - return ((struct clast_name_index *) *slot)->index; + return (*slot)->index; return -1; } @@ -208,16 +245,16 @@ clast_name_to_index (struct clast_name *name, htab_t index_table) found in the INDEX_TABLE, false otherwise. */ static inline bool -clast_name_to_lb_ub (struct clast_name *name, htab_t index_table, +clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table, mpz_t bound_one, mpz_t bound_two) { struct clast_name_index tmp; - PTR *slot; + clast_name_index **slot; tmp.name = name->name; tmp.free_name = NULL; - slot = htab_find_slot (index_table, &tmp, NO_INSERT); + slot = index_table.find_slot (&tmp, NO_INSERT); if (slot && *slot) { @@ -232,15 +269,15 @@ clast_name_to_lb_ub (struct clast_name *name, htab_t index_table, /* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */ static inline void -save_clast_name_index (htab_t index_table, const char *name, +save_clast_name_index (clast_index_htab_type index_table, const char *name, int index, int level, mpz_t bound_one, mpz_t bound_two) { struct clast_name_index tmp; - PTR *slot; + clast_name_index **slot; tmp.name = name; tmp.free_name = NULL; - slot = htab_find_slot (index_table, &tmp, INSERT); + slot = index_table.find_slot (&tmp, INSERT); if (slot) { @@ -249,35 +286,6 @@ save_clast_name_index (htab_t index_table, const char *name, *slot = new_clast_name_index (name, index, level, bound_one, bound_two); } } - -/* Computes a hash function for database element ELT. */ - -static inline hashval_t -clast_name_index_elt_info (const void *elt) -{ - const struct clast_name_index *e = ((const struct clast_name_index *) elt); - hashval_t hash = 0; - - int length = strlen (e->name); - int i; - - for (i = 0; i < length; ++i) - hash = hash | (e->name[i] << (i % 4)); - - return hash; -} - -/* Compares database elements E1 and E2. */ - -static inline int -eq_clast_name_indexes (const void *e1, const void *e2) -{ - const struct clast_name_index *elt1 = (const struct clast_name_index *) e1; - const struct clast_name_index *elt2 = (const struct clast_name_index *) e2; - - return strcmp (elt1->name, elt2->name) == 0; -} - /* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree @@ -288,7 +296,7 @@ eq_clast_name_indexes (const void *e1, const void *e2) typedef struct ivs_params { vec<tree> params, *newivs; - htab_t newivs_index, params_index; + clast_index_htab_type newivs_index, params_index; sese region; } *ivs_params_p; @@ -300,7 +308,7 @@ clast_name_to_gcc (struct clast_name *name, ivs_params_p ip) { int index; - if (ip->params.exists () && ip->params_index) + if (ip->params.exists () && ip->params_index.is_created ()) { index = clast_name_to_index (name, ip->params_index); @@ -308,7 +316,7 @@ clast_name_to_gcc (struct clast_name *name, ivs_params_p ip) return ip->params[index]; } - gcc_assert (ip->newivs && ip->newivs_index); + gcc_assert (ip->newivs && ip->newivs_index.is_created ()); index = clast_name_to_index (name, ip->newivs_index); gcc_assert (index >= 0); @@ -699,12 +707,12 @@ type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one, { bool found = false; - if (ip->params.exists () && ip->params_index) + if (ip->params.exists () && ip->params_index.is_created ()) found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two); if (!found) { - gcc_assert (ip->newivs && ip->newivs_index); + gcc_assert (ip->newivs && ip->newivs_index.is_created ()); found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one, bound_two); gcc_assert (found); @@ -1009,13 +1017,14 @@ new_bb_pbb_def (basic_block bb, poly_bb_p pbb) /* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */ static void -mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping) +mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, + bb_pbb_htab_type bb_pbb_mapping) { bb_pbb_def tmp; - PTR *x; + bb_pbb_def **x; tmp.bb = bb; - x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT); + x = bb_pbb_mapping.find_slot (&tmp, INSERT); if (x && !*x) *x = new_bb_pbb_def (bb, pbb); @@ -1024,13 +1033,13 @@ mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping) /* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */ poly_bb_p -find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb) +find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb) { bb_pbb_def tmp; - PTR *slot; + bb_pbb_def **slot; tmp.bb = bb; - slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT); + slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT); if (slot && *slot) return ((bb_pbb_def *) *slot)->pbb; @@ -1044,7 +1053,7 @@ find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb) related poly_bb_p. */ scop_p -get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping, +get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping, vec<poly_bb_p> *pbbs) { unsigned i; @@ -1074,7 +1083,7 @@ get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping, static edge translate_clast_user (struct clast_user_stmt *stmt, edge next_e, - htab_t bb_pbb_mapping, ivs_params_p ip) + bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip) { int i, nb_loops; basic_block new_bb; @@ -1143,7 +1152,8 @@ graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt, } static edge -translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p); +translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type, + int, ivs_params_p); /* Create the loop for a clast for statement. @@ -1152,8 +1162,9 @@ translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p); static edge translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt, - edge next_e, htab_t bb_pbb_mapping, int level, - tree type, tree lb, tree ub, ivs_params_p ip) + edge next_e, bb_pbb_htab_type bb_pbb_mapping, + int level, tree type, tree lb, tree ub, + ivs_params_p ip) { struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop, type, lb, ub, level, ip); @@ -1186,7 +1197,8 @@ translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt, static edge translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e, - htab_t bb_pbb_mapping, int level, ivs_params_p ip) + bb_pbb_htab_type bb_pbb_mapping, int level, + ivs_params_p ip) { tree type, lb, ub; edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type, @@ -1244,7 +1256,7 @@ translate_clast_assignment (struct clast_assignment *stmt, edge next_e, static edge translate_clast_guard (loop_p context_loop, struct clast_guard *stmt, - edge next_e, htab_t bb_pbb_mapping, int level, + edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip) { edge last_e = graphite_create_new_guard (next_e, stmt, ip); @@ -1263,7 +1275,7 @@ translate_clast_guard (loop_p context_loop, struct clast_guard *stmt, static edge translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e, - htab_t bb_pbb_mapping, int level, ivs_params_p ip) + bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip) { if (!stmt) return next_e; @@ -1304,7 +1316,8 @@ translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e, static CloogUnionDomain * add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain, - int nb_scattering_dims, htab_t params_index) + int nb_scattering_dims, + clast_index_htab_type params_index) { sese region = SCOP_REGION (scop); int i; @@ -1547,7 +1560,7 @@ int get_max_scattering_dimensions (scop_p scop) } static CloogInput * -generate_cloog_input (scop_p scop, htab_t params_index) +generate_cloog_input (scop_p scop, clast_index_htab_type params_index) { CloogUnionDomain *union_domain; CloogInput *cloog_input; @@ -1570,7 +1583,7 @@ generate_cloog_input (scop_p scop, htab_t params_index) without a program. */ static struct clast_stmt * -scop_to_clast (scop_p scop, htab_t params_index) +scop_to_clast (scop_p scop, clast_index_htab_type params_index) { CloogInput *cloog_input; struct clast_stmt *clast; @@ -1599,11 +1612,10 @@ void print_generated_program (FILE *file, scop_p scop) { CloogOptions *options = set_cloog_options (); - htab_t params_index; + clast_index_htab_type params_index; struct clast_stmt *clast; - params_index = htab_create (10, clast_name_index_elt_info, - eq_clast_name_indexes, free_clast_name_index); + params_index.create (10); clast = scop_to_clast (scop, params_index); @@ -1629,22 +1641,21 @@ debug_generated_program (scop_p scop) */ bool -gloog (scop_p scop, htab_t bb_pbb_mapping) +gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping) { vec<tree> newivs; newivs.create (10); loop_p context_loop; sese region = SCOP_REGION (scop); ifsese if_region = NULL; - htab_t newivs_index, params_index; + clast_index_htab_type newivs_index, params_index; struct clast_stmt *clast; struct ivs_params ip; timevar_push (TV_GRAPHITE_CODE_GEN); gloog_error = false; - params_index = htab_create (10, clast_name_index_elt_info, - eq_clast_name_indexes, free_clast_name_index); + params_index.create (10); clast = scop_to_clast (scop, params_index); @@ -1667,8 +1678,7 @@ gloog (scop_p scop, htab_t bb_pbb_mapping) graphite_verify (); context_loop = SESE_ENTRY (region)->src->loop_father; - newivs_index = htab_create (10, clast_name_index_elt_info, - eq_clast_name_indexes, free_clast_name_index); + newivs_index.create (10); ip.newivs = &newivs; ip.newivs_index = newivs_index; @@ -1690,8 +1700,8 @@ gloog (scop_p scop, htab_t bb_pbb_mapping) free (if_region->region); free (if_region); - htab_delete (newivs_index); - htab_delete (params_index); + newivs_index.dispose (); + params_index.dispose (); newivs.release (); cloog_clast_free (clast); timevar_pop (TV_GRAPHITE_CODE_GEN); diff --git a/gcc/graphite-clast-to-gimple.h b/gcc/graphite-clast-to-gimple.h index 737cbd0584c..78e60e2dafa 100644 --- a/gcc/graphite-clast-to-gimple.h +++ b/gcc/graphite-clast-to-gimple.h @@ -38,26 +38,7 @@ typedef struct bb_pbb_def poly_bb_p pbb; } bb_pbb_def; -extern bool gloog (scop_p, htab_t); extern void debug_clast_stmt (struct clast_stmt *); extern void print_clast_stmt (FILE *, struct clast_stmt *); -/* Hash function for data base element BB_PBB. */ - -static inline hashval_t -bb_pbb_map_hash (const void *bb_pbb) -{ - return (hashval_t)(((const bb_pbb_def *)bb_pbb)->bb->index); -} - -/* Compare data base element BB_PBB1 and BB_PBB2. */ - -static inline int -eq_bb_pbb_map (const void *bb_pbb1, const void *bb_pbb2) -{ - const bb_pbb_def *bp1 = (const bb_pbb_def *) bb_pbb1; - const bb_pbb_def *bp2 = (const bb_pbb_def *) bb_pbb2; - return (bp1->bb->index == bp2->bb->index); -} - #endif diff --git a/gcc/graphite-dependences.c b/gcc/graphite-dependences.c index 2f65c46d49f..366588b3595 100644 --- a/gcc/graphite-dependences.c +++ b/gcc/graphite-dependences.c @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #ifdef HAVE_cloog #include "graphite-poly.h" +#include "graphite-htab.h" /* Add the constraints from the set S to the domain of MAP. */ @@ -579,7 +580,7 @@ loop_level_carries_dependences (scop_p scop, vec<poly_bb_p> body, poly_bb_p. */ bool -loop_is_parallel_p (loop_p loop, htab_t bb_pbb_mapping, int depth) +loop_is_parallel_p (loop_p loop, bb_pbb_htab_type bb_pbb_mapping, int depth) { bool dependences; scop_p scop; diff --git a/gcc/graphite-htab.h b/gcc/graphite-htab.h new file mode 100644 index 00000000000..022b7698791 --- /dev/null +++ b/gcc/graphite-htab.h @@ -0,0 +1,60 @@ +/* Translation of CLAST (CLooG AST) to Gimple. + Copyright (C) 2012 Free Software Foundation, Inc. + Contributed by Sebastian Pop <sebastian.pop@amd.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_GRAPHITE_HTAB_H +#define GCC_GRAPHITE_HTAB_H + +#include "hash-table.h" +#include "graphite-clast-to-gimple.h" + +/* Hashtable helpers. */ + +struct bb_pbb_hasher : typed_free_remove <bb_pbb_def> +{ + typedef bb_pbb_def value_type; + typedef bb_pbb_def compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hash function for data base element BB_PBB. */ + +inline hashval_t +bb_pbb_hasher::hash (const value_type *bb_pbb) +{ + return (hashval_t)(bb_pbb->bb->index); +} + +/* Compare data base element PB1 and PB2. */ + +inline bool +bb_pbb_hasher::equal (const value_type *bp1, const compare_type *bp2) +{ + return (bp1->bb->index == bp2->bb->index); +} + +typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type; + +extern bool gloog (scop_p, bb_pbb_htab_type); +poly_bb_p find_pbb_via_hash (bb_pbb_htab_type, basic_block); +bool loop_is_parallel_p (loop_p, bb_pbb_htab_type, int); +scop_p get_loop_body_pbbs (loop_p, bb_pbb_htab_type, vec<poly_bb_p> *); + +#endif diff --git a/gcc/graphite-poly.h b/gcc/graphite-poly.h index 6ac8406c1f7..52d6b1cdc53 100644 --- a/gcc/graphite-poly.h +++ b/gcc/graphite-poly.h @@ -1531,9 +1531,6 @@ restore_scattering (scop_p scop) } bool graphite_legal_transform (scop_p); -poly_bb_p find_pbb_via_hash (htab_t, basic_block); -bool loop_is_parallel_p (loop_p, htab_t, int); -scop_p get_loop_body_pbbs (loop_p, htab_t, vec<poly_bb_p> *); isl_map *reverse_loop_at_level (poly_bb_p, int); isl_union_map *reverse_loop_for_pbbs (scop_p, vec<poly_bb_p> , int); __isl_give isl_union_map *extend_schedule (__isl_take isl_union_map *); diff --git a/gcc/graphite.c b/gcc/graphite.c index 7511527de0b..10d1dd510c9 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "graphite-scop-detection.h" #include "graphite-clast-to-gimple.h" #include "graphite-sese-to-poly.h" +#include "graphite-htab.h" CloogState *cloog_state; @@ -255,7 +256,7 @@ graphite_transform_loops (void) scop_p scop; bool need_cfg_cleanup_p = false; vec<scop_p> scops = vNULL; - htab_t bb_pbb_mapping; + bb_pbb_htab_type bb_pbb_mapping; isl_ctx *ctx; /* If a function is parallel it was most probably already run through graphite @@ -277,7 +278,7 @@ graphite_transform_loops (void) print_global_statistics (dump_file); } - bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free); + bb_pbb_mapping.create (10); FOR_EACH_VEC_ELT (scops, i, scop) if (dbg_cnt (graphite_scop)) @@ -291,7 +292,7 @@ graphite_transform_loops (void) need_cfg_cleanup_p = true; } - htab_delete (bb_pbb_mapping); + bb_pbb_mapping.dispose (); free_scops (scops); graphite_finalize (need_cfg_cleanup_p); the_isl_ctx = NULL; diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 16094b231b2..15ddedbe113 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -145,7 +145,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "ira.h" #include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */ -#include "hashtab.h" +#include "hash-table.h" #include "dumpfile.h" #ifdef INSN_SCHEDULING @@ -581,22 +581,72 @@ struct delay_pair int stages; }; +/* Helpers for delay hashing. */ + +struct delay_i1_hasher : typed_noop_remove <delay_pair> +{ + typedef delay_pair value_type; + typedef void compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Returns a hash value for X, based on hashing just I1. */ + +inline hashval_t +delay_i1_hasher::hash (const value_type *x) +{ + return htab_hash_pointer (x->i1); +} + +/* Return true if I1 of pair X is the same as that of pair Y. */ + +inline bool +delay_i1_hasher::equal (const value_type *x, const compare_type *y) +{ + return x->i1 == y; +} + +struct delay_i2_hasher : typed_free_remove <delay_pair> +{ + typedef delay_pair value_type; + typedef void compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Returns a hash value for X, based on hashing just I2. */ + +inline hashval_t +delay_i2_hasher::hash (const value_type *x) +{ + return htab_hash_pointer (x->i2); +} + +/* Return true if I2 of pair X is the same as that of pair Y. */ + +inline bool +delay_i2_hasher::equal (const value_type *x, const compare_type *y) +{ + return x->i2 == y; +} + /* Two hash tables to record delay_pairs, one indexed by I1 and the other indexed by I2. */ -static htab_t delay_htab; -static htab_t delay_htab_i2; +static hash_table <delay_i1_hasher> delay_htab; +static hash_table <delay_i2_hasher> delay_htab_i2; /* Called through htab_traverse. Walk the hashtable using I2 as index, and delete all elements involving an UID higher than that pointed to by *DATA. */ -static int -htab_i2_traverse (void **slot, void *data) +int +haifa_htab_i2_traverse (delay_pair **slot, int *data) { - int maxuid = *(int *)data; - struct delay_pair *p = *(struct delay_pair **)slot; + int maxuid = *data; + struct delay_pair *p = *slot; if (INSN_UID (p->i2) >= maxuid || INSN_UID (p->i1) >= maxuid) { - htab_clear_slot (delay_htab_i2, slot); + delay_htab_i2.clear_slot (slot); } return 1; } @@ -604,16 +654,15 @@ htab_i2_traverse (void **slot, void *data) /* Called through htab_traverse. Walk the hashtable using I2 as index, and delete all elements involving an UID higher than that pointed to by *DATA. */ -static int -htab_i1_traverse (void **slot, void *data) +int +haifa_htab_i1_traverse (delay_pair **pslot, int *data) { - int maxuid = *(int *)data; - struct delay_pair **pslot = (struct delay_pair **)slot; + int maxuid = *data; struct delay_pair *p, *first, **pprev; if (INSN_UID ((*pslot)->i1) >= maxuid) { - htab_clear_slot (delay_htab, slot); + delay_htab.clear_slot (pslot); return 1; } pprev = &first; @@ -627,7 +676,7 @@ htab_i1_traverse (void **slot, void *data) } *pprev = NULL; if (first == NULL) - htab_clear_slot (delay_htab, slot); + delay_htab.clear_slot (pslot); else *pslot = first; return 1; @@ -638,38 +687,8 @@ htab_i1_traverse (void **slot, void *data) void discard_delay_pairs_above (int max_uid) { - htab_traverse (delay_htab, htab_i1_traverse, &max_uid); - htab_traverse (delay_htab_i2, htab_i2_traverse, &max_uid); -} - -/* Returns a hash value for X (which really is a delay_pair), based on - hashing just I1. */ -static hashval_t -delay_hash_i1 (const void *x) -{ - return htab_hash_pointer (((const struct delay_pair *) x)->i1); -} - -/* Returns a hash value for X (which really is a delay_pair), based on - hashing just I2. */ -static hashval_t -delay_hash_i2 (const void *x) -{ - return htab_hash_pointer (((const struct delay_pair *) x)->i2); -} - -/* Return nonzero if I1 of pair X is the same as that of pair Y. */ -static int -delay_i1_eq (const void *x, const void *y) -{ - return ((const struct delay_pair *) x)->i1 == y; -} - -/* Return nonzero if I2 of pair X is the same as that of pair Y. */ -static int -delay_i2_eq (const void *x, const void *y) -{ - return ((const struct delay_pair *) x)->i2 == y; + delay_htab.traverse <int *, haifa_htab_i1_traverse> (&max_uid); + delay_htab_i2.traverse <int *, haifa_htab_i2_traverse> (&max_uid); } /* This function can be called by a port just before it starts the final @@ -699,19 +718,15 @@ record_delay_slot_pair (rtx i1, rtx i2, int cycles, int stages) p->cycles = cycles; p->stages = stages; - if (!delay_htab) + if (!delay_htab.is_created ()) { - delay_htab = htab_create (10, delay_hash_i1, delay_i1_eq, NULL); - delay_htab_i2 = htab_create (10, delay_hash_i2, delay_i2_eq, free); + delay_htab.create (10); + delay_htab_i2.create (10); } - slot = ((struct delay_pair **) - htab_find_slot_with_hash (delay_htab, i1, htab_hash_pointer (i1), - INSERT)); + slot = delay_htab.find_slot_with_hash (i1, htab_hash_pointer (i1), INSERT); p->next_same_i1 = *slot; *slot = p; - slot = ((struct delay_pair **) - htab_find_slot_with_hash (delay_htab_i2, i2, htab_hash_pointer (i2), - INSERT)); + slot = delay_htab_i2.find_slot_with_hash (i2, htab_hash_pointer (i2), INSERT); *slot = p; } @@ -722,12 +737,10 @@ real_insn_for_shadow (rtx insn) { struct delay_pair *pair; - if (delay_htab == NULL) + if (!delay_htab.is_created ()) return NULL_RTX; - pair - = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, insn, - htab_hash_pointer (insn)); + pair = delay_htab_i2.find_with_hash (insn, htab_hash_pointer (insn)); if (!pair || pair->stages > 0) return NULL_RTX; return pair->i1; @@ -755,12 +768,10 @@ add_delay_dependencies (rtx insn) sd_iterator_def sd_it; dep_t dep; - if (!delay_htab) + if (!delay_htab.is_created ()) return; - pair - = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, insn, - htab_hash_pointer (insn)); + pair = delay_htab_i2.find_with_hash (insn, htab_hash_pointer (insn)); if (!pair) return; add_dependence (insn, pair->i1, REG_DEP_ANTI); @@ -771,8 +782,7 @@ add_delay_dependencies (rtx insn) { rtx pro = DEP_PRO (dep); struct delay_pair *other_pair - = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, pro, - htab_hash_pointer (pro)); + = delay_htab_i2.find_with_hash (pro, htab_hash_pointer (pro)); if (!other_pair || other_pair->stages) continue; if (pair_delay (other_pair) >= pair_delay (pair)) @@ -1395,12 +1405,11 @@ dep_cost_1 (dep_t link, dw_t dw) if (DEP_COST (link) != UNKNOWN_DEP_COST) return DEP_COST (link); - if (delay_htab) + if (delay_htab.is_created ()) { struct delay_pair *delay_entry; delay_entry - = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, used, - htab_hash_pointer (used)); + = delay_htab_i2.find_with_hash (used, htab_hash_pointer (used)); if (delay_entry) { if (delay_entry->i1 == insn) @@ -5726,12 +5735,12 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p, { int delay_cost = 0; - if (delay_htab) + if (delay_htab.is_created ()) { struct delay_pair *delay_entry; delay_entry - = (struct delay_pair *)htab_find_with_hash (delay_htab, insn, - htab_hash_pointer (insn)); + = delay_htab.find_with_hash (insn, + htab_hash_pointer (insn)); while (delay_entry && delay_cost == 0) { delay_cost = estimate_shadow_tick (delay_entry); @@ -6189,14 +6198,13 @@ schedule_block (basic_block *target_bb, state_t init_state) goto restart_choose_ready; } - if (delay_htab) + if (delay_htab.is_created ()) { /* If this insn is the first part of a delay-slot pair, record a backtrack point. */ struct delay_pair *delay_entry; delay_entry - = (struct delay_pair *)htab_find_with_hash (delay_htab, insn, - htab_hash_pointer (insn)); + = delay_htab.find_with_hash (insn, htab_hash_pointer (insn)); if (delay_entry) { save_backtrack_point (delay_entry, ls); @@ -6761,10 +6769,10 @@ sched_finish (void) void free_delay_pairs (void) { - if (delay_htab) + if (delay_htab.is_created ()) { - htab_empty (delay_htab); - htab_empty (delay_htab_i2); + delay_htab.empty (); + delay_htab_i2.empty (); } } diff --git a/gcc/ira-color.c b/gcc/ira-color.c index dea47fef2d7..0ee31573e2e 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "sbitmap.h" #include "bitmap.h" +#include "hash-table.h" #include "hard-reg-set.h" #include "basic-block.h" #include "expr.h" @@ -173,33 +174,36 @@ static vec<ira_allocno_t> allocno_stack_vec; /* Vector of unique allocno hard registers. */ static vec<allocno_hard_regs_t> allocno_hard_regs_vec; -/* Returns hash value for allocno hard registers V. */ -static hashval_t -allocno_hard_regs_hash (const void *v) +struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs> { - const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v; + typedef allocno_hard_regs value_type; + typedef allocno_hard_regs compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; +/* Returns hash value for allocno hard registers V. */ +inline hashval_t +allocno_hard_regs_hasher::hash (const value_type *hv) +{ return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0); } /* Compares allocno hard registers V1 and V2. */ -static int -allocno_hard_regs_eq (const void *v1, const void *v2) +inline bool +allocno_hard_regs_hasher::equal (const value_type *hv1, const compare_type *hv2) { - const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1; - const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2; - return hard_reg_set_equal_p (hv1->set, hv2->set); } /* Hash table of unique allocno hard registers. */ -static htab_t allocno_hard_regs_htab; +static hash_table <allocno_hard_regs_hasher> allocno_hard_regs_htab; /* Return allocno hard registers in the hash table equal to HV. */ static allocno_hard_regs_t find_hard_regs (allocno_hard_regs_t hv) { - return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv); + return allocno_hard_regs_htab.find (hv); } /* Insert allocno hard registers HV in the hash table (if it is not @@ -207,11 +211,11 @@ find_hard_regs (allocno_hard_regs_t hv) static allocno_hard_regs_t insert_hard_regs (allocno_hard_regs_t hv) { - PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT); + allocno_hard_regs **slot = allocno_hard_regs_htab.find_slot (hv, INSERT); if (*slot == NULL) *slot = hv; - return (allocno_hard_regs_t) *slot; + return *slot; } /* Initialize data concerning allocno hard registers. */ @@ -219,8 +223,7 @@ static void init_allocno_hard_regs (void) { allocno_hard_regs_vec.create (200); - allocno_hard_regs_htab - = htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL); + allocno_hard_regs_htab.create (200); } /* Add (or update info about) allocno hard registers with SET and @@ -258,7 +261,7 @@ finish_allocno_hard_regs (void) allocno_hard_regs_vec.iterate (i, &hv); i++) ira_free (hv); - htab_delete (allocno_hard_regs_htab); + allocno_hard_regs_htab.dispose (); allocno_hard_regs_vec.release (); } diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 508394e2962..5f998f7aefb 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +#include "hash-table.h" #include "hard-reg-set.h" #include "rtl.h" #include "expr.h" @@ -131,35 +132,41 @@ typedef const struct cost_classes *const_cost_classes_t; /* Info about cost classes for each pseudo. */ static cost_classes_t *regno_cost_classes; -/* Returns hash value for cost classes info V. */ -static hashval_t -cost_classes_hash (const void *v) +/* Helper for cost_classes hashing. */ + +struct cost_classes_hasher { - const_cost_classes_t hv = (const_cost_classes_t) v; + typedef cost_classes value_type; + typedef cost_classes compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; +/* Returns hash value for cost classes info HV. */ +inline hashval_t +cost_classes_hasher::hash (const value_type *hv) +{ return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0); } -/* Compares cost classes info V1 and V2. */ -static int -cost_classes_eq (const void *v1, const void *v2) +/* Compares cost classes info HV1 and HV2. */ +inline bool +cost_classes_hasher::equal (const value_type *hv1, const compare_type *hv2) { - const_cost_classes_t hv1 = (const_cost_classes_t) v1; - const_cost_classes_t hv2 = (const_cost_classes_t) v2; - return hv1->num == hv2->num && memcmp (hv1->classes, hv2->classes, sizeof (enum reg_class) * hv1->num); } /* Delete cost classes info V from the hash table. */ -static void -cost_classes_del (void *v) +inline void +cost_classes_hasher::remove (value_type *v) { ira_free (v); } /* Hash table of unique cost classes. */ -static htab_t cost_classes_htab; +static hash_table <cost_classes_hasher> cost_classes_htab; /* Map allocno class -> cost classes for pseudo of given allocno class. */ @@ -180,8 +187,7 @@ initiate_regno_cost_classes (void) sizeof (cost_classes_t) * N_REG_CLASSES); memset (cost_classes_mode_cache, 0, sizeof (cost_classes_t) * MAX_MACHINE_MODE); - cost_classes_htab - = htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del); + cost_classes_htab.create (200); } /* Create new cost classes from cost classes FROM and set up members @@ -229,7 +235,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) cost_classes_t classes_ptr; enum reg_class cl; int i; - PTR *slot; + cost_classes **slot; HARD_REG_SET temp, temp2; bool exclude_p; @@ -255,7 +261,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) } classes.classes[classes.num++] = cl; } - slot = htab_find_slot (cost_classes_htab, &classes, INSERT); + slot = cost_classes_htab.find_slot (&classes, INSERT); if (*slot == NULL) { classes_ptr = setup_cost_classes (&classes); @@ -279,7 +285,7 @@ setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode) cost_classes_t classes_ptr; enum reg_class cl; int i; - PTR *slot; + cost_classes **slot; HARD_REG_SET temp; if ((classes_ptr = cost_classes_mode_cache[mode]) == NULL) @@ -294,7 +300,7 @@ setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode) continue; classes.classes[classes.num++] = cl; } - slot = htab_find_slot (cost_classes_htab, &classes, INSERT); + slot = cost_classes_htab.find_slot (&classes, INSERT); if (*slot == NULL) { classes_ptr = setup_cost_classes (&classes); @@ -312,7 +318,7 @@ static void finish_regno_cost_classes (void) { ira_free (regno_cost_classes); - htab_delete (cost_classes_htab); + cost_classes_htab.dispose (); } diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index f8a1b0ed846..73200e199b2 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "flags.h" #include "df.h" -#include "hashtab.h" +#include "hash-table.h" #include "except.h" #include "params.h" #include "regs.h" @@ -424,27 +424,28 @@ invariant_expr_equal_p (rtx insn1, rtx e1, rtx insn2, rtx e2) return true; } -/* Returns hash value for invariant expression entry E. */ - -static hashval_t -hash_invariant_expr (const void *e) +struct invariant_expr_hasher : typed_free_remove <invariant_expr_entry> { - const struct invariant_expr_entry *const entry = - (const struct invariant_expr_entry *) e; + typedef invariant_expr_entry value_type; + typedef invariant_expr_entry compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Returns hash value for invariant expression entry ENTRY. */ +inline hashval_t +invariant_expr_hasher::hash (const value_type *entry) +{ return entry->hash; } -/* Compares invariant expression entries E1 and E2. */ +/* Compares invariant expression entries ENTRY1 and ENTRY2. */ -static int -eq_invariant_expr (const void *e1, const void *e2) +inline bool +invariant_expr_hasher::equal (const value_type *entry1, + const compare_type *entry2) { - const struct invariant_expr_entry *const entry1 = - (const struct invariant_expr_entry *) e1; - const struct invariant_expr_entry *const entry2 = - (const struct invariant_expr_entry *) e2; - if (entry1->mode != entry2->mode) return 0; @@ -452,24 +453,26 @@ eq_invariant_expr (const void *e1, const void *e2) entry2->inv->insn, entry2->expr); } +typedef hash_table <invariant_expr_hasher> invariant_htab_type; + /* Checks whether invariant with value EXPR in machine mode MODE is recorded in EQ. If this is the case, return the invariant. Otherwise insert INV to the table for this expression and return INV. */ static struct invariant * -find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode, +find_or_insert_inv (invariant_htab_type eq, rtx expr, enum machine_mode mode, struct invariant *inv) { hashval_t hash = hash_invariant_expr_1 (inv->insn, expr); struct invariant_expr_entry *entry; struct invariant_expr_entry pentry; - PTR *slot; + invariant_expr_entry **slot; pentry.expr = expr; pentry.inv = inv; pentry.mode = mode; - slot = htab_find_slot_with_hash (eq, &pentry, hash, INSERT); - entry = (struct invariant_expr_entry *) *slot; + slot = eq.find_slot_with_hash (&pentry, hash, INSERT); + entry = *slot; if (entry) return entry->inv; @@ -488,7 +491,7 @@ find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode, hash table of the invariants. */ static void -find_identical_invariants (htab_t eq, struct invariant *inv) +find_identical_invariants (invariant_htab_type eq, struct invariant *inv) { unsigned depno; bitmap_iterator bi; @@ -525,13 +528,13 @@ merge_identical_invariants (void) { unsigned i; struct invariant *inv; - htab_t eq = htab_create (invariants.length (), - hash_invariant_expr, eq_invariant_expr, free); + invariant_htab_type eq; + eq.create (invariants.length ()); FOR_EACH_VEC_ELT (invariants, i, inv) find_identical_invariants (eq, inv); - htab_delete (eq); + eq.dispose (); } /* Determines the basic blocks inside LOOP that are always executed and diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 5695e298256..3248b56c0a5 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -60,7 +60,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "diagnostic-core.h" #include "df.h" -#include "hashtab.h" +#include "hash-table.h" #include "dumpfile.h" /* Possible return values of iv_get_reaching_def. */ @@ -106,9 +106,35 @@ static struct rtx_iv ** iv_ref_table; static struct loop *current_loop; +/* Hashtable helper. */ + +struct biv_entry_hasher : typed_free_remove <biv_entry> +{ + typedef biv_entry value_type; + typedef rtx_def compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Returns hash value for biv B. */ + +inline hashval_t +biv_entry_hasher::hash (const value_type *b) +{ + return b->regno; +} + +/* Compares biv B and register R. */ + +inline bool +biv_entry_hasher::equal (const value_type *b, const compare_type *r) +{ + return b->regno == REGNO (r); +} + /* Bivs of the current loop. */ -static htab_t bivs; +static hash_table <biv_entry_hasher> bivs; static bool iv_analyze_op (rtx, rtx, struct rtx_iv *); @@ -243,24 +269,9 @@ clear_iv_info (void) } } - htab_empty (bivs); -} - -/* Returns hash value for biv B. */ - -static hashval_t -biv_hash (const void *b) -{ - return ((const struct biv_entry *) b)->regno; + bivs.empty (); } -/* Compares biv B and register R. */ - -static int -biv_eq (const void *b, const void *r) -{ - return ((const struct biv_entry *) b)->regno == REGNO ((const_rtx) r); -} /* Prepare the data for an induction variable analysis of a LOOP. */ @@ -277,7 +288,7 @@ iv_analysis_loop_init (struct loop *loop) if (clean_slate) { df_set_flags (DF_EQ_NOTES + DF_DEFER_INSN_RESCAN); - bivs = htab_create (10, biv_hash, biv_eq, free); + bivs.create (10); clean_slate = false; } else @@ -837,8 +848,7 @@ record_iv (df_ref def, struct rtx_iv *iv) static bool analyzed_for_bivness_p (rtx def, struct rtx_iv *iv) { - struct biv_entry *biv = - (struct biv_entry *) htab_find_with_hash (bivs, def, REGNO (def)); + struct biv_entry *biv = bivs.find_with_hash (def, REGNO (def)); if (!biv) return false; @@ -851,7 +861,7 @@ static void record_biv (rtx def, struct rtx_iv *iv) { struct biv_entry *biv = XNEW (struct biv_entry); - void **slot = htab_find_slot_with_hash (bivs, def, REGNO (def), INSERT); + biv_entry **slot = bivs.find_slot_with_hash (def, REGNO (def), INSERT); biv->regno = REGNO (def); biv->iv = *iv; @@ -1293,11 +1303,10 @@ iv_analysis_done (void) clear_iv_info (); clean_slate = true; df_finish_pass (true); - htab_delete (bivs); + bivs.dispose (); free (iv_ref_table); iv_ref_table = NULL; iv_ref_table_size = 0; - bivs = NULL; } } diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index 1eb904b5061..41d9e5f0fad 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "params.h" #include "expr.h" -#include "hashtab.h" +#include "hash-table.h" #include "recog.h" #include "target.h" #include "dumpfile.h" @@ -102,16 +102,70 @@ struct var_to_expand var_expansions[REUSE_EXPANSION - 1]. */ }; +/* Hashtable helper for iv_to_split. */ + +struct iv_split_hasher : typed_free_remove <iv_to_split> +{ + typedef iv_to_split value_type; + typedef iv_to_split compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + + +/* A hash function for information about insns to split. */ + +inline hashval_t +iv_split_hasher::hash (const value_type *ivts) +{ + return (hashval_t) INSN_UID (ivts->insn); +} + +/* An equality functions for information about insns to split. */ + +inline bool +iv_split_hasher::equal (const value_type *i1, const compare_type *i2) +{ + return i1->insn == i2->insn; +} + +/* Hashtable helper for iv_to_split. */ + +struct var_expand_hasher : typed_free_remove <var_to_expand> +{ + typedef var_to_expand value_type; + typedef var_to_expand compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Return a hash for VES. */ + +inline hashval_t +var_expand_hasher::hash (const value_type *ves) +{ + return (hashval_t) INSN_UID (ves->insn); +} + +/* Return true if I1 and I2 refer to the same instruction. */ + +inline bool +var_expand_hasher::equal (const value_type *i1, const compare_type *i2) +{ + return i1->insn == i2->insn; +} + /* Information about optimization applied in the unrolled loop. */ struct opt_info { - htab_t insns_to_split; /* A hashtable of insns to split. */ + hash_table <iv_split_hasher> insns_to_split; /* A hashtable of insns to + split. */ struct iv_to_split *iv_to_split_head; /* The first iv to split. */ struct iv_to_split **iv_to_split_tail; /* Pointer to the tail of the list. */ - htab_t insns_with_var_to_expand; /* A hashtable of insns with accumulators - to expand. */ + hash_table <var_expand_hasher> insns_with_var_to_expand; /* A hashtable of + insns with accumulators to expand. */ struct var_to_expand *var_to_expand_head; /* The first var to expand. */ struct var_to_expand **var_to_expand_tail; /* Pointer to the tail of the list. */ unsigned first_new_block; /* The first basic block that was @@ -1585,45 +1639,6 @@ unroll_loop_stupid (struct loop *loop) nunroll, num_loop_insns (loop)); } -/* A hash function for information about insns to split. */ - -static hashval_t -si_info_hash (const void *ivts) -{ - return (hashval_t) INSN_UID (((const struct iv_to_split *) ivts)->insn); -} - -/* An equality functions for information about insns to split. */ - -static int -si_info_eq (const void *ivts1, const void *ivts2) -{ - const struct iv_to_split *const i1 = (const struct iv_to_split *) ivts1; - const struct iv_to_split *const i2 = (const struct iv_to_split *) ivts2; - - return i1->insn == i2->insn; -} - -/* Return a hash for VES, which is really a "var_to_expand *". */ - -static hashval_t -ve_info_hash (const void *ves) -{ - return (hashval_t) INSN_UID (((const struct var_to_expand *) ves)->insn); -} - -/* Return true if IVTS1 and IVTS2 (which are really both of type - "var_to_expand *") refer to the same instruction. */ - -static int -ve_info_eq (const void *ivts1, const void *ivts2) -{ - const struct var_to_expand *const i1 = (const struct var_to_expand *) ivts1; - const struct var_to_expand *const i2 = (const struct var_to_expand *) ivts2; - - return i1->insn == i2->insn; -} - /* Returns true if REG is referenced in one nondebug insn in LOOP. Set *DEBUG_USES to the number of debug insns that reference the variable. */ @@ -1908,8 +1923,8 @@ analyze_insns_in_loop (struct loop *loop) rtx insn; struct iv_to_split *ivts = NULL; struct var_to_expand *ves = NULL; - PTR *slot1; - PTR *slot2; + iv_to_split **slot1; + var_to_expand **slot2; vec<edge> edges = get_loop_exit_edges (loop); edge exit; bool can_apply = false; @@ -1920,8 +1935,7 @@ analyze_insns_in_loop (struct loop *loop) if (flag_split_ivs_in_unroller) { - opt_info->insns_to_split = htab_create (5 * loop->num_nodes, - si_info_hash, si_info_eq, free); + opt_info->insns_to_split.create (5 * loop->num_nodes); opt_info->iv_to_split_head = NULL; opt_info->iv_to_split_tail = &opt_info->iv_to_split_head; } @@ -1942,9 +1956,7 @@ analyze_insns_in_loop (struct loop *loop) if (flag_variable_expansion_in_unroller && can_apply) { - opt_info->insns_with_var_to_expand = htab_create (5 * loop->num_nodes, - ve_info_hash, - ve_info_eq, free); + opt_info->insns_with_var_to_expand.create (5 * loop->num_nodes); opt_info->var_to_expand_head = NULL; opt_info->var_to_expand_tail = &opt_info->var_to_expand_head; } @@ -1960,12 +1972,12 @@ analyze_insns_in_loop (struct loop *loop) if (!INSN_P (insn)) continue; - if (opt_info->insns_to_split) + if (opt_info->insns_to_split.is_created ()) ivts = analyze_iv_to_split_insn (insn); if (ivts) { - slot1 = htab_find_slot (opt_info->insns_to_split, ivts, INSERT); + slot1 = opt_info->insns_to_split.find_slot (ivts, INSERT); gcc_assert (*slot1 == NULL); *slot1 = ivts; *opt_info->iv_to_split_tail = ivts; @@ -1973,12 +1985,12 @@ analyze_insns_in_loop (struct loop *loop) continue; } - if (opt_info->insns_with_var_to_expand) + if (opt_info->insns_with_var_to_expand.is_created ()) ves = analyze_insn_to_expand_var (loop, insn); if (ves) { - slot2 = htab_find_slot (opt_info->insns_with_var_to_expand, ves, INSERT); + slot2 = opt_info->insns_with_var_to_expand.find_slot (ves, INSERT); gcc_assert (*slot2 == NULL); *slot2 = ves; *opt_info->var_to_expand_tail = ves; @@ -2356,7 +2368,7 @@ apply_opt_in_copies (struct opt_info *opt_info, gcc_assert (!unrolling || rewrite_original_loop); /* Allocate the basic variables (i0). */ - if (opt_info->insns_to_split) + if (opt_info->insns_to_split.is_created ()) for (ivts = opt_info->iv_to_split_head; ivts; ivts = ivts->next) allocate_basic_variable (ivts); @@ -2388,12 +2400,11 @@ apply_opt_in_copies (struct opt_info *opt_info, ve_templ.insn = orig_insn; /* Apply splitting iv optimization. */ - if (opt_info->insns_to_split) + if (opt_info->insns_to_split.is_created ()) { maybe_strip_eq_note_for_split_iv (opt_info, insn); - ivts = (struct iv_to_split *) - htab_find (opt_info->insns_to_split, &ivts_templ); + ivts = opt_info->insns_to_split.find (&ivts_templ); if (ivts) { @@ -2406,10 +2417,10 @@ apply_opt_in_copies (struct opt_info *opt_info, } } /* Apply variable expansion optimization. */ - if (unrolling && opt_info->insns_with_var_to_expand) + if (unrolling && opt_info->insns_with_var_to_expand.is_created ()) { ves = (struct var_to_expand *) - htab_find (opt_info->insns_with_var_to_expand, &ve_templ); + opt_info->insns_with_var_to_expand.find (&ve_templ); if (ves) { gcc_assert (GET_CODE (PATTERN (insn)) @@ -2426,7 +2437,7 @@ apply_opt_in_copies (struct opt_info *opt_info, /* Initialize the variable expansions in the loop preheader and take care of combining them at the loop exit. */ - if (opt_info->insns_with_var_to_expand) + if (opt_info->insns_with_var_to_expand.is_created ()) { for (ves = opt_info->var_to_expand_head; ves; ves = ves->next) insert_var_expansion_initialization (ves, opt_info->loop_preheader); @@ -2455,12 +2466,12 @@ apply_opt_in_copies (struct opt_info *opt_info, continue; ivts_templ.insn = orig_insn; - if (opt_info->insns_to_split) + if (opt_info->insns_to_split.is_created ()) { maybe_strip_eq_note_for_split_iv (opt_info, orig_insn); ivts = (struct iv_to_split *) - htab_find (opt_info->insns_to_split, &ivts_templ); + opt_info->insns_to_split.find (&ivts_templ); if (ivts) { if (!delta) @@ -2479,15 +2490,15 @@ apply_opt_in_copies (struct opt_info *opt_info, static void free_opt_info (struct opt_info *opt_info) { - if (opt_info->insns_to_split) - htab_delete (opt_info->insns_to_split); - if (opt_info->insns_with_var_to_expand) + if (opt_info->insns_to_split.is_created ()) + opt_info->insns_to_split.dispose (); + if (opt_info->insns_with_var_to_expand.is_created ()) { struct var_to_expand *ves; for (ves = opt_info->var_to_expand_head; ves; ves = ves->next) ves->var_expansions.release (); - htab_delete (opt_info->insns_with_var_to_expand); + opt_info->insns_with_var_to_expand.dispose (); } free (opt_info); } diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 982d3574ee8..c4daa30c581 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -49,8 +49,19 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "streamer-hooks.h" +struct freeing_string_slot_hasher : string_slot_hasher +{ + static inline void remove (value_type *); +}; + +inline void +freeing_string_slot_hasher::remove (value_type *v) +{ + free (v); +} + /* The table to hold the file names. */ -static htab_t file_name_hash_table; +static hash_table <freeing_string_slot_hasher> file_name_hash_table; /* Check that tag ACTUAL has one of the given values. NUM_TAGS is the @@ -94,14 +105,14 @@ lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length) static const char * canon_file_name (const char *string) { - void **slot; + string_slot **slot; struct string_slot s_slot; size_t len = strlen (string); s_slot.s = string; s_slot.len = len; - slot = htab_find_slot (file_name_hash_table, &s_slot, INSERT); + slot = file_name_hash_table.find_slot (&s_slot, INSERT); if (*slot == NULL) { char *saved_string; @@ -117,7 +128,7 @@ canon_file_name (const char *string) } else { - struct string_slot *old_slot = (struct string_slot *) *slot; + struct string_slot *old_slot = *slot; return old_slot->s; } } @@ -1137,8 +1148,7 @@ void lto_reader_init (void) { lto_streamer_init (); - file_name_hash_table = htab_create (37, hash_string_slot_node, - eq_string_slot_node, free); + file_name_hash_table.create (37); } diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index f9184c3c16f..ad620c66d3b 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -77,8 +77,7 @@ create_output_block (enum lto_section_type section_type) clear_line_info (ob); - ob->string_hash_table = htab_create (37, hash_string_slot_node, - eq_string_slot_node, NULL); + ob->string_hash_table.create (37); gcc_obstack_init (&ob->obstack); return ob; @@ -92,7 +91,7 @@ destroy_output_block (struct output_block *ob) { enum lto_section_type section_type = ob->section_type; - htab_delete (ob->string_hash_table); + ob->string_hash_table.dispose (); free (ob->main_stream); free (ob->string_stream); diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index 5ff8a6dac16..89320381b6e 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -253,28 +253,33 @@ print_lto_report (const char *s) #ifdef LTO_STREAMER_DEBUG -static htab_t tree_htab; - struct tree_hash_entry { tree key; intptr_t value; }; -static hashval_t -hash_tree (const void *p) +struct tree_entry_hasher : typed_noop_remove <tree_hash_entry> +{ + typedef tree_hash_entry value_type; + typedef tree_hash_entry compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +tree_entry_hasher::hash (const value_type *e) { - const struct tree_hash_entry *e = (const struct tree_hash_entry *) p; return htab_hash_pointer (e->key); } -static int -eq_tree (const void *p1, const void *p2) +inline bool +tree_entry_hasher::equal (const value_type *e1, const compare_type *e2) { - const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1; - const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2; return (e1->key == e2->key); } + +static hash_table <tree_hash_entry> tree_htab; #endif /* Initialization common to the LTO reader and writer. */ @@ -289,7 +294,7 @@ lto_streamer_init (void) streamer_check_handled_ts_structures (); #ifdef LTO_STREAMER_DEBUG - tree_htab = htab_create (31, hash_tree, eq_tree, NULL); + tree_htab.create (31); #endif } @@ -324,8 +329,7 @@ lto_orig_address_map (tree t, intptr_t orig_t) ent.key = t; ent.value = orig_t; - slot - = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT); + slot = tree_htab.find_slot (&ent, INSERT); gcc_assert (!*slot); *slot = XNEW (struct tree_hash_entry); **slot = ent; @@ -342,8 +346,7 @@ lto_orig_address_get (tree t) struct tree_hash_entry **slot; ent.key = t; - slot - = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT); + slot = tree_htab.find_slot (&ent, NO_INSERT); return (slot ? (*slot)->value : 0); } @@ -357,11 +360,10 @@ lto_orig_address_remove (tree t) struct tree_hash_entry **slot; ent.key = t; - slot - = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT); + slot = tree_htab.find_slot (&ent, NO_INSERT); gcc_assert (slot); free (*slot); - htab_clear_slot (tree_htab, (PTR *)slot); + tree_htab.clear_slot (slot); } #endif diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 95fe33ae1a7..e0db8b10a70 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_LTO_STREAMER_H #include "plugin-api.h" +#include "hash-table.h" #include "tree.h" #include "gimple.h" #include "target.h" @@ -627,6 +628,50 @@ struct lto_simple_output_block struct lto_output_stream *main_stream; }; +/* String hashing. */ + +struct string_slot +{ + const char *s; + int len; + unsigned int slot_num; +}; + +/* Hashtable helpers. */ + +struct string_slot_hasher : typed_noop_remove <string_slot> +{ + typedef string_slot value_type; + typedef string_slot compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Returns a hash code for DS. Adapted from libiberty's htab_hash_string + to support strings that may not end in '\0'. */ + +inline hashval_t +string_slot_hasher::hash (const value_type *ds) +{ + hashval_t r = ds->len; + int i; + + for (i = 0; i < ds->len; i++) + r = r * 67 + (unsigned)ds->s[i] - 113; + return r; +} + +/* Returns nonzero if DS1 and DS2 are equal. */ + +inline bool +string_slot_hasher::equal (const value_type *ds1, const compare_type *ds2) +{ + if (ds1->len == ds2->len) + return memcmp (ds1->s, ds2->s, ds1->len) == 0; + + return 0; +} + /* Data structure holding all the data and descriptors used when writing an LTO file. */ struct output_block @@ -645,7 +690,7 @@ struct output_block /* The hash table that contains the set of strings we have seen so far and the indexes assigned to them. */ - htab_t string_hash_table; + hash_table <string_slot_hasher> string_hash_table; /* The current cgraph_node that we are currently serializing. Null if we are serializing something else. */ diff --git a/gcc/passes.c b/gcc/passes.c index 47dca568c3a..45e79ccc166 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "line-map.h" +#include "hash-table.h" #include "input.h" #include "tree.h" #include "rtl.h" @@ -579,27 +580,33 @@ struct pass_registry struct opt_pass *pass; }; +/* Helper for pass_registry hash table. */ + +struct pass_registry_hasher : typed_noop_remove <pass_registry> +{ + typedef pass_registry value_type; + typedef pass_registry compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + /* Pass registry hash function. */ -static hashval_t -passr_hash (const void *p) +inline hashval_t +pass_registry_hasher::hash (const value_type *s) { - const struct pass_registry *const s = (const struct pass_registry *const) p; return htab_hash_string (s->unique_name); } /* Hash equal function */ -static int -passr_eq (const void *p1, const void *p2) +inline bool +pass_registry_hasher::equal (const value_type *s1, const compare_type *s2) { - const struct pass_registry *const s1 = (const struct pass_registry *const) p1; - const struct pass_registry *const s2 = (const struct pass_registry *const) p2; - return !strcmp (s1->unique_name, s2->unique_name); } -static htab_t name_to_pass_map = NULL; +static hash_table <pass_registry_hasher> name_to_pass_map; /* Register PASS with NAME. */ @@ -609,11 +616,11 @@ register_pass_name (struct opt_pass *pass, const char *name) struct pass_registry **slot; struct pass_registry pr; - if (!name_to_pass_map) - name_to_pass_map = htab_create (256, passr_hash, passr_eq, NULL); + if (!name_to_pass_map.is_created ()) + name_to_pass_map.create (256); pr.unique_name = name; - slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, &pr, INSERT); + slot = name_to_pass_map.find_slot (&pr, INSERT); if (!*slot) { struct pass_registry *new_pr; @@ -634,10 +641,9 @@ static vec<char_ptr> pass_tab = vNULL; /* Callback function for traversing NAME_TO_PASS_MAP. */ -static int -pass_traverse (void **slot, void *data ATTRIBUTE_UNUSED) +int +passes_pass_traverse (pass_registry **p, void *data ATTRIBUTE_UNUSED) { - struct pass_registry **p = (struct pass_registry **)slot; struct opt_pass *pass = (*p)->pass; gcc_assert (pass->static_pass_number > 0); @@ -658,7 +664,7 @@ create_pass_tab (void) return; pass_tab.safe_grow_cleared (passes_by_id_size + 1); - htab_traverse (name_to_pass_map, pass_traverse, NULL); + name_to_pass_map.traverse <void *, passes_pass_traverse> (NULL); } static bool override_gate_status (struct opt_pass *, tree, bool); @@ -743,8 +749,7 @@ get_pass_by_name (const char *name) struct pass_registry **slot, pr; pr.unique_name = name; - slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, - &pr, NO_INSERT); + slot = name_to_pass_map.find_slot (&pr, NO_INSERT); if (!slot || !*slot) return NULL; diff --git a/gcc/plugin.c b/gcc/plugin.c index 846055afe8b..b269dfa3971 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "diagnostic-core.h" #include "tree.h" #include "tree-pass.h" @@ -50,9 +51,36 @@ static const char *plugin_event_name_init[] = const char **plugin_event_name = plugin_event_name_init; +/* Event hashtable helpers. */ + +struct event_hasher : typed_noop_remove <const char *> +{ + typedef const char *value_type; + typedef const char *compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Helper function for the event hash table that hashes the entry V. */ + +inline hashval_t +event_hasher::hash (const value_type *v) +{ + return htab_hash_string (*v); +} + +/* Helper function for the event hash table that compares the name of an + existing entry (S1) with the given string (S2). */ + +inline bool +event_hasher::equal (const value_type *s1, const compare_type *s2) +{ + return !strcmp (*s1, *s2); +} + /* A hash table to map event names to the position of the names in the plugin_event_name table. */ -static htab_t event_tab; +static hash_table <event_hasher> event_tab; /* Keep track of the limit of allocated events and space ready for allocating events. */ @@ -312,41 +340,31 @@ register_plugin_info (const char* name, struct plugin_info *info) plugin->help = info->help; } -/* Helper function for the event hash table that compares the name of an - existing entry (E1) with the given string (S2). */ - -static int -htab_event_eq (const void *e1, const void *s2) -{ - const char *s1= *(const char * const *) e1; - return !strcmp (s1, (const char *) s2); -} - /* Look up the event id for NAME. If the name is not found, return -1 if INSERT is NO_INSERT. */ int get_named_event_id (const char *name, enum insert_option insert) { - void **slot; + const char ***slot; - if (!event_tab) + if (!event_tab.is_created ()) { int i; - event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL); + event_tab.create (150); for (i = 0; i < event_last; i++) { - slot = htab_find_slot (event_tab, plugin_event_name[i], INSERT); + slot = event_tab.find_slot (&plugin_event_name[i], INSERT); gcc_assert (*slot == HTAB_EMPTY_ENTRY); *slot = &plugin_event_name[i]; } } - slot = htab_find_slot (event_tab, name, insert); + slot = event_tab.find_slot (&name, insert); if (slot == NULL) return -1; if (*slot != HTAB_EMPTY_ENTRY) - return (const char **) *slot - &plugin_event_name[0]; + return *slot - &plugin_event_name[0]; if (event_last >= event_horizon) { @@ -368,8 +386,7 @@ get_named_event_id (const char *name, enum insert_option insert) plugin_callbacks, event_horizon); } /* All the pointers in the hash table will need to be updated. */ - htab_delete (event_tab); - event_tab = NULL; + event_tab.dispose (); } else *slot = &plugin_event_name[event_last]; diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index b9befe0e9e8..aeffc14435e 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "diagnostic-core.h" +#include "hash-table.h" #include "rtl.h" #include "tree.h" #include "tm_p.h" @@ -87,9 +88,6 @@ static struct type 'struct expr', and for each expression there is a single linked list of occurrences. */ -/* The table itself. */ -static htab_t expr_table; - /* Expression elements in the hash table. */ struct expr { @@ -103,6 +101,56 @@ struct expr struct occr *avail_occr; }; +/* Hashtable helpers. */ + +struct expr_hasher : typed_noop_remove <expr> +{ + typedef expr value_type; + typedef expr compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + + +/* Hash expression X. + DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found + or if the expression contains something we don't want to insert in the + table. */ + +static hashval_t +hash_expr (rtx x, int *do_not_record_p) +{ + *do_not_record_p = 0; + return hash_rtx (x, GET_MODE (x), do_not_record_p, + NULL, /*have_reg_qty=*/false); +} + +/* Callback for hashtab. + Return the hash value for expression EXP. We don't actually hash + here, we just return the cached hash value. */ + +inline hashval_t +expr_hasher::hash (const value_type *exp) +{ + return exp->hash; +} + +/* Callback for hashtab. + Return nonzero if exp1 is equivalent to exp2. */ + +inline bool +expr_hasher::equal (const value_type *exp1, const compare_type *exp2) +{ + int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true); + + gcc_assert (!equiv_p || exp1->hash == exp2->hash); + return equiv_p; +} + +/* The table itself. */ +static hash_table <expr_hasher> expr_table; + + static struct obstack expr_obstack; /* Occurrence of an expression. @@ -183,11 +231,8 @@ static void reset_opr_set_tables (void); /* Hash table support. */ static hashval_t hash_expr (rtx, int *); -static hashval_t hash_expr_for_htab (const void *); -static int expr_equiv_p (const void *, const void *); static void insert_expr_in_table (rtx, rtx); static struct expr *lookup_expr_in_table (rtx); -static int dump_hash_table_entry (void **, void *); static void dump_hash_table (FILE *); /* Helpers for eliminate_partially_redundant_load. */ @@ -234,8 +279,7 @@ alloc_mem (void) make the hash table too small, but unnecessarily making it too large also doesn't help. The i/4 is a gcse.c relic, and seems like a reasonable choice. */ - expr_table = htab_create (MAX (i / 4, 13), - hash_expr_for_htab, expr_equiv_p, NULL); + expr_table.create (MAX (i / 4, 13)); /* We allocate everything on obstacks because we often can roll back the whole obstack to some point. Freeing obstacks is very fast. */ @@ -262,7 +306,7 @@ free_mem (void) { free (uid_cuid); - htab_delete (expr_table); + expr_table.dispose (); obstack_free (&expr_obstack, NULL); obstack_free (&occr_obstack, NULL); @@ -273,45 +317,6 @@ free_mem (void) } -/* Hash expression X. - DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found - or if the expression contains something we don't want to insert in the - table. */ - -static hashval_t -hash_expr (rtx x, int *do_not_record_p) -{ - *do_not_record_p = 0; - return hash_rtx (x, GET_MODE (x), do_not_record_p, - NULL, /*have_reg_qty=*/false); -} - -/* Callback for hashtab. - Return the hash value for expression EXP. We don't actually hash - here, we just return the cached hash value. */ - -static hashval_t -hash_expr_for_htab (const void *expp) -{ - const struct expr *const exp = (const struct expr *) expp; - return exp->hash; -} - -/* Callback for hashtab. - Return nonzero if exp1 is equivalent to exp2. */ - -static int -expr_equiv_p (const void *exp1p, const void *exp2p) -{ - const struct expr *const exp1 = (const struct expr *) exp1p; - const struct expr *const exp2 = (const struct expr *) exp2p; - int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true); - - gcc_assert (!equiv_p || exp1->hash == exp2->hash); - return equiv_p; -} - - /* Insert expression X in INSN in the hash TABLE. If it is already present, record it as the last occurrence in INSN's basic block. */ @@ -343,8 +348,7 @@ insert_expr_in_table (rtx x, rtx insn) cur_expr->hash = hash; cur_expr->avail_occr = NULL; - slot = (struct expr **) htab_find_slot_with_hash (expr_table, cur_expr, - hash, INSERT); + slot = expr_table.find_slot_with_hash (cur_expr, hash, INSERT); if (! (*slot)) /* The expression isn't found, so insert it. */ @@ -412,8 +416,7 @@ lookup_expr_in_table (rtx pat) tmp_expr->hash = hash; tmp_expr->avail_occr = NULL; - slot = (struct expr **) htab_find_slot_with_hash (expr_table, tmp_expr, - hash, INSERT); + slot = expr_table.find_slot_with_hash (tmp_expr, hash, INSERT); obstack_free (&expr_obstack, tmp_expr); if (!slot) @@ -427,18 +430,17 @@ lookup_expr_in_table (rtx pat) expression hash table to FILE. */ /* This helper is called via htab_traverse. */ -static int -dump_hash_table_entry (void **slot, void *filep) +int +dump_expr_hash_table_entry (expr **slot, FILE *file) { - struct expr *expr = (struct expr *) *slot; - FILE *file = (FILE *) filep; + struct expr *exprs = *slot; struct occr *occr; fprintf (file, "expr: "); - print_rtl (file, expr->expr); - fprintf (file,"\nhashcode: %u\n", expr->hash); + print_rtl (file, exprs->expr); + fprintf (file,"\nhashcode: %u\n", exprs->hash); fprintf (file,"list of occurrences:\n"); - occr = expr->avail_occr; + occr = exprs->avail_occr; while (occr) { rtx insn = occr->insn; @@ -455,13 +457,13 @@ dump_hash_table (FILE *file) { fprintf (file, "\n\nexpression hash table\n"); fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n", - (long) htab_size (expr_table), - (long) htab_elements (expr_table), - htab_collisions (expr_table)); - if (htab_elements (expr_table) > 0) + (long) expr_table.size (), + (long) expr_table.elements (), + expr_table.collisions ()); + if (expr_table.elements () > 0) { fprintf (file, "\n\ntable entries:\n"); - htab_traverse (expr_table, dump_hash_table_entry, file); + expr_table.traverse <FILE *, dump_expr_hash_table_entry> (file); } fprintf (file, "\n"); } @@ -1223,13 +1225,13 @@ eliminate_partially_redundant_loads (void) marked for later deletion. */ /* This helper is called via htab_traverse. */ -static int -delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED) +int +delete_redundant_insns_1 (expr **slot, void *data ATTRIBUTE_UNUSED) { - struct expr *expr = (struct expr *) *slot; + struct expr *exprs = *slot; struct occr *occr; - for (occr = expr->avail_occr; occr != NULL; occr = occr->next) + for (occr = exprs->avail_occr; occr != NULL; occr = occr->next) { if (occr->deleted_p && dbg_cnt (gcse2_delete)) { @@ -1251,7 +1253,7 @@ delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED) static void delete_redundant_insns (void) { - htab_traverse (expr_table, delete_redundant_insns_1, NULL); + expr_table.traverse <void *, delete_redundant_insns_1> (NULL); if (dump_file) fprintf (dump_file, "\n"); } @@ -1277,7 +1279,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED) if (dump_file) dump_hash_table (dump_file); - if (htab_elements (expr_table) > 0) + if (expr_table.elements () > 0) { eliminate_partially_redundant_loads (); delete_redundant_insns (); diff --git a/gcc/sese.c b/gcc/sese.c index 7102b60bf9e..10ccee274fb 100644 --- a/gcc/sese.c +++ b/gcc/sese.c @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tree-pretty-print.h" #include "tree-flow.h" #include "cfgloop.h" @@ -46,20 +47,50 @@ debug_rename_elt (rename_map_elt elt) /* Helper function for debug_rename_map. */ -static int -debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED) +int +debug_rename_map_1 (rename_map_elt_s **slot, void *s ATTRIBUTE_UNUSED) { - struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot; + struct rename_map_elt_s *entry = *slot; debug_rename_elt (entry); return 1; } + + +/* Hashtable helpers. */ + +struct rename_map_hasher : typed_free_remove <rename_map_elt_s> +{ + typedef rename_map_elt_s value_type; + typedef rename_map_elt_s compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Computes a hash function for database element ELT. */ + +inline hashval_t +rename_map_hasher::hash (const value_type *elt) +{ + return SSA_NAME_VERSION (elt->old_name); +} + +/* Compares database elements E1 and E2. */ + +inline bool +rename_map_hasher::equal (const value_type *elt1, const compare_type *elt2) +{ + return (elt1->old_name == elt2->old_name); +} + +typedef hash_table <rename_map_hasher> rename_map_type; + /* Print to stderr all the elements of RENAME_MAP. */ DEBUG_FUNCTION void -debug_rename_map (htab_t rename_map) +debug_rename_map (rename_map_type rename_map) { - htab_traverse (rename_map, debug_rename_map_1, NULL); + rename_map.traverse <void *, debug_rename_map_1> (NULL); } /* Computes a hash function for database element ELT. */ @@ -365,17 +396,17 @@ get_false_edge_from_guard_bb (basic_block bb) /* Returns the expression associated to OLD_NAME in RENAME_MAP. */ static tree -get_rename (htab_t rename_map, tree old_name) +get_rename (rename_map_type rename_map, tree old_name) { struct rename_map_elt_s tmp; - PTR *slot; + rename_map_elt_s **slot; gcc_assert (TREE_CODE (old_name) == SSA_NAME); tmp.old_name = old_name; - slot = htab_find_slot (rename_map, &tmp, NO_INSERT); + slot = rename_map.find_slot (&tmp, NO_INSERT); if (slot && *slot) - return ((rename_map_elt) *slot)->expr; + return (*slot)->expr; return NULL_TREE; } @@ -383,16 +414,16 @@ get_rename (htab_t rename_map, tree old_name) /* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR). */ static void -set_rename (htab_t rename_map, tree old_name, tree expr) +set_rename (rename_map_type rename_map, tree old_name, tree expr) { struct rename_map_elt_s tmp; - PTR *slot; + rename_map_elt_s **slot; if (old_name == expr) return; tmp.old_name = old_name; - slot = htab_find_slot (rename_map, &tmp, INSERT); + slot = rename_map.find_slot (&tmp, INSERT); if (!slot) return; @@ -410,7 +441,8 @@ set_rename (htab_t rename_map, tree old_name, tree expr) is set when the code generation cannot continue. */ static bool -rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, +rename_uses (gimple copy, rename_map_type rename_map, + gimple_stmt_iterator *gsi_tgt, sese region, loop_p loop, vec<tree> iv_map, bool *gloog_error) { @@ -516,7 +548,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, static void graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, - htab_t rename_map, + rename_map_type rename_map, vec<tree> iv_map, sese region, bool *gloog_error) { @@ -584,14 +616,14 @@ copy_bb_and_scalar_dependences (basic_block bb, sese region, bool *gloog_error) { basic_block new_bb = split_edge (next_e); - htab_t rename_map = htab_create (10, rename_map_elt_info, - eq_rename_map_elts, free); + rename_map_type rename_map; + rename_map.create (10); next_e = single_succ_edge (new_bb); graphite_copy_stmts_from_block (bb, new_bb, rename_map, iv_map, region, gloog_error); remove_phi_nodes (new_bb); - htab_delete (rename_map); + rename_map.dispose (); return next_e; } diff --git a/gcc/sese.h b/gcc/sese.h index 8e1f7f74772..cc28a994a6a 100644 --- a/gcc/sese.h +++ b/gcc/sese.h @@ -257,7 +257,6 @@ typedef struct rename_map_elt_s } *rename_map_elt; -extern void debug_rename_map (htab_t); extern hashval_t rename_map_elt_info (const void *); extern int eq_rename_map_elts (const void *, const void *); diff --git a/gcc/store-motion.c b/gcc/store-motion.c index 6fc072c38e6..df756707408 100644 --- a/gcc/store-motion.c +++ b/gcc/store-motion.c @@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "intl.h" #include "tree-pass.h" -#include "hashtab.h" +#include "hash-table.h" #include "df.h" #include "dbgcnt.h" @@ -90,9 +90,6 @@ struct st_expr /* Head of the list of load/store memory refs. */ static struct st_expr * store_motion_mems = NULL; -/* Hashtable for the load/store memory refs. */ -static htab_t store_motion_mems_table = NULL; - /* These bitmaps will hold the local dataflow properties per basic block. */ static sbitmap *st_kill, *st_avloc, *st_antloc, *st_transp; @@ -108,22 +105,32 @@ static int num_stores; /* Contains the edge_list returned by pre_edge_lcm. */ static struct edge_list *edge_list; -static hashval_t -pre_st_expr_hash (const void *p) +/* Hashtable helpers. */ + +struct st_expr_hasher : typed_noop_remove <st_expr> +{ + typedef st_expr value_type; + typedef st_expr compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +st_expr_hasher::hash (const value_type *x) { int do_not_record_p = 0; - const struct st_expr *const x = (const struct st_expr *) p; return hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false); } -static int -pre_st_expr_eq (const void *p1, const void *p2) +inline bool +st_expr_hasher::equal (const value_type *ptr1, const compare_type *ptr2) { - const struct st_expr *const ptr1 = (const struct st_expr *) p1, - *const ptr2 = (const struct st_expr *) p2; return exp_equiv_p (ptr1->pattern, ptr2->pattern, 0, true); } +/* Hashtable for the load/store memory refs. */ +static hash_table <st_expr_hasher> store_motion_mems_table; + /* This will search the st_expr list for a matching expression. If it doesn't find one, we create one and initialize it. */ @@ -133,16 +140,16 @@ st_expr_entry (rtx x) int do_not_record_p = 0; struct st_expr * ptr; unsigned int hash; - void **slot; + st_expr **slot; struct st_expr e; hash = hash_rtx (x, GET_MODE (x), &do_not_record_p, NULL, /*have_reg_qty=*/false); e.pattern = x; - slot = htab_find_slot_with_hash (store_motion_mems_table, &e, hash, INSERT); + slot = store_motion_mems_table.find_slot_with_hash (&e, hash, INSERT); if (*slot) - return (struct st_expr *)*slot; + return *slot; ptr = XNEW (struct st_expr); @@ -176,9 +183,8 @@ free_st_expr_entry (struct st_expr * ptr) static void free_store_motion_mems (void) { - if (store_motion_mems_table) - htab_delete (store_motion_mems_table); - store_motion_mems_table = NULL; + if (store_motion_mems_table.is_created ()) + store_motion_mems_table.dispose (); while (store_motion_mems) { @@ -645,8 +651,7 @@ compute_store_table (void) unsigned int max_gcse_regno = max_reg_num (); store_motion_mems = NULL; - store_motion_mems_table = htab_create (13, pre_st_expr_hash, - pre_st_expr_eq, NULL); + store_motion_mems_table.create (13); last_set_in = XCNEWVEC (int, max_gcse_regno); already_set = XNEWVEC (int, max_gcse_regno); @@ -708,8 +713,7 @@ compute_store_table (void) if (! ptr->avail_stores) { *prev_next_ptr_ptr = ptr->next; - htab_remove_elt_with_hash (store_motion_mems_table, - ptr, ptr->hash_index); + store_motion_mems_table.remove_elt_with_hash (ptr, ptr->hash_index); free_st_expr_entry (ptr); } else @@ -1142,8 +1146,7 @@ one_store_motion_pass (void) num_stores = compute_store_table (); if (num_stores == 0) { - htab_delete (store_motion_mems_table); - store_motion_mems_table = NULL; + store_motion_mems_table.dispose (); end_alias_analysis (); return 0; } diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index b0f18b552bb..5cb82865910 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -20,6 +20,7 @@ #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tree.h" #include "gimple.h" #include "tree-flow.h" @@ -879,47 +880,29 @@ typedef struct tm_log_entry tree save_var; } *tm_log_entry_t; -/* The actual log. */ -static htab_t tm_log; - -/* Addresses to log with a save/restore sequence. These should be in - dominator order. */ -static vec<tree> tm_log_save_addresses; - -/* Map for an SSA_NAME originally pointing to a non aliased new piece - of memory (malloc, alloc, etc). */ -static htab_t tm_new_mem_hash; -enum thread_memory_type - { - mem_non_local = 0, - mem_thread_local, - mem_transaction_local, - mem_max - }; +/* Log entry hashtable helpers. */ -typedef struct tm_new_mem_map +struct log_entry_hasher { - /* SSA_NAME being dereferenced. */ - tree val; - enum thread_memory_type local_new_memory; -} tm_new_mem_map_t; + typedef tm_log_entry value_type; + typedef tm_log_entry compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; /* Htab support. Return hash value for a `tm_log_entry'. */ -static hashval_t -tm_log_hash (const void *p) +inline hashval_t +log_entry_hasher::hash (const value_type *log) { - const struct tm_log_entry *log = (const struct tm_log_entry *) p; return iterative_hash_expr (log->addr, 0); } /* Htab support. Return true if two log entries are the same. */ -static int -tm_log_eq (const void *p1, const void *p2) +inline bool +log_entry_hasher::equal (const value_type *log1, const compare_type *log2) { - const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1; - const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2; - /* FIXME: rth: I suggest that we get rid of the component refs etc. @@ -943,20 +926,68 @@ tm_log_eq (const void *p1, const void *p2) } /* Htab support. Free one tm_log_entry. */ -static void -tm_log_free (void *p) +inline void +log_entry_hasher::remove (value_type *lp) { - struct tm_log_entry *lp = (struct tm_log_entry *) p; lp->stmts.release (); free (lp); } + +/* The actual log. */ +static hash_table <log_entry_hasher> tm_log; + +/* Addresses to log with a save/restore sequence. These should be in + dominator order. */ +static vec<tree> tm_log_save_addresses; + +enum thread_memory_type + { + mem_non_local = 0, + mem_thread_local, + mem_transaction_local, + mem_max + }; + +typedef struct tm_new_mem_map +{ + /* SSA_NAME being dereferenced. */ + tree val; + enum thread_memory_type local_new_memory; +} tm_new_mem_map_t; + +/* Hashtable helpers. */ + +struct tm_mem_map_hasher : typed_free_remove <tm_new_mem_map_t> +{ + typedef tm_new_mem_map_t value_type; + typedef tm_new_mem_map_t compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +tm_mem_map_hasher::hash (const value_type *v) +{ + return (intptr_t)v->val >> 4; +} + +inline bool +tm_mem_map_hasher::equal (const value_type *v, const compare_type *c) +{ + return v->val == c->val; +} + +/* Map for an SSA_NAME originally pointing to a non aliased new piece + of memory (malloc, alloc, etc). */ +static hash_table <tm_mem_map_hasher> tm_new_mem_hash; + /* Initialize logging data structures. */ static void tm_log_init (void) { - tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free); - tm_new_mem_hash = htab_create (5, struct_ptr_hash, struct_ptr_eq, free); + tm_log.create (10); + tm_new_mem_hash.create (5); tm_log_save_addresses.create (5); } @@ -964,8 +995,8 @@ tm_log_init (void) static void tm_log_delete (void) { - htab_delete (tm_log); - htab_delete (tm_new_mem_hash); + tm_log.dispose (); + tm_new_mem_hash.dispose (); tm_log_save_addresses.release (); } @@ -1006,11 +1037,11 @@ transaction_invariant_address_p (const_tree mem, basic_block region_entry_block) static void tm_log_add (basic_block entry_block, tree addr, gimple stmt) { - void **slot; + tm_log_entry **slot; struct tm_log_entry l, *lp; l.addr = addr; - slot = htab_find_slot (tm_log, &l, INSERT); + slot = tm_log.find_slot (&l, INSERT); if (!*slot) { tree type = TREE_TYPE (addr); @@ -1051,7 +1082,7 @@ tm_log_add (basic_block entry_block, tree addr, gimple stmt) size_t i; gimple oldstmt; - lp = (struct tm_log_entry *) *slot; + lp = *slot; /* If we're generating a save/restore sequence, we don't care about statements. */ @@ -1153,10 +1184,10 @@ tm_log_emit_stmt (tree addr, gimple stmt) static void tm_log_emit (void) { - htab_iterator hi; + hash_table <log_entry_hasher>::iterator hi; struct tm_log_entry *lp; - FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (tm_log, lp, tm_log_entry_t, hi) { size_t i; gimple stmt; @@ -1198,7 +1229,7 @@ tm_log_emit_saves (basic_block entry_block, basic_block bb) for (i = 0; i < tm_log_save_addresses.length (); ++i) { l.addr = tm_log_save_addresses[i]; - lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT); + lp = *(tm_log.find_slot (&l, NO_INSERT)); gcc_assert (lp->save_var != NULL); /* We only care about variables in the current transaction. */ @@ -1234,7 +1265,7 @@ tm_log_emit_restores (basic_block entry_block, basic_block bb) for (i = tm_log_save_addresses.length () - 1; i >= 0; i--) { l.addr = tm_log_save_addresses[i]; - lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT); + lp = *(tm_log.find_slot (&l, NO_INSERT)); gcc_assert (lp->save_var != NULL); /* We only care about variables in the current transaction. */ @@ -1271,7 +1302,7 @@ thread_private_new_memory (basic_block entry_block, tree x) { gimple stmt = NULL; enum tree_code code; - void **slot; + tm_new_mem_map_t **slot; tm_new_mem_map_t elt, *elt_p; tree val = x; enum thread_memory_type retval = mem_transaction_local; @@ -1285,8 +1316,8 @@ thread_private_new_memory (basic_block entry_block, tree x) /* Look in cache first. */ elt.val = x; - slot = htab_find_slot (tm_new_mem_hash, &elt, INSERT); - elt_p = (tm_new_mem_map_t *) *slot; + slot = tm_new_mem_hash.find_slot (&elt, INSERT); + elt_p = *slot; if (elt_p) return elt_p->local_new_memory; @@ -3146,6 +3177,35 @@ typedef struct tm_memop tree addr; } *tm_memop_t; +/* TM memory operation hashtable helpers. */ + +struct tm_memop_hasher : typed_free_remove <tm_memop> +{ + typedef tm_memop value_type; + typedef tm_memop compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Htab support. Return a hash value for a `tm_memop'. */ +inline hashval_t +tm_memop_hasher::hash (const value_type *mem) +{ + tree addr = mem->addr; + /* We drill down to the SSA_NAME/DECL for the hash, but equality is + actually done with operand_equal_p (see tm_memop_eq). */ + if (TREE_CODE (addr) == ADDR_EXPR) + addr = TREE_OPERAND (addr, 0); + return iterative_hash_expr (addr, 0); +} + +/* Htab support. Return true if two tm_memop's are the same. */ +inline bool +tm_memop_hasher::equal (const value_type *mem1, const compare_type *mem2) +{ + return operand_equal_p (mem1->addr, mem2->addr, 0); +} + /* Sets for solving data flow equations in the memory optimization pass. */ struct tm_memopt_bitmaps { @@ -3178,7 +3238,7 @@ static bitmap_obstack tm_memopt_obstack; /* Unique counter for TM loads and stores. Loads and stores of the same address get the same ID. */ static unsigned int tm_memopt_value_id; -static htab_t tm_memopt_value_numbers; +static hash_table <tm_memop_hasher> tm_memopt_value_numbers; #define STORE_AVAIL_IN(BB) \ ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in @@ -3201,29 +3261,6 @@ static htab_t tm_memopt_value_numbers; #define BB_VISITED_P(BB) \ ((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p -/* Htab support. Return a hash value for a `tm_memop'. */ -static hashval_t -tm_memop_hash (const void *p) -{ - const struct tm_memop *mem = (const struct tm_memop *) p; - tree addr = mem->addr; - /* We drill down to the SSA_NAME/DECL for the hash, but equality is - actually done with operand_equal_p (see tm_memop_eq). */ - if (TREE_CODE (addr) == ADDR_EXPR) - addr = TREE_OPERAND (addr, 0); - return iterative_hash_expr (addr, 0); -} - -/* Htab support. Return true if two tm_memop's are the same. */ -static int -tm_memop_eq (const void *p1, const void *p2) -{ - const struct tm_memop *mem1 = (const struct tm_memop *) p1; - const struct tm_memop *mem2 = (const struct tm_memop *) p2; - - return operand_equal_p (mem1->addr, mem2->addr, 0); -} - /* Given a TM load/store in STMT, return the value number for the address it accesses. */ @@ -3231,13 +3268,13 @@ static unsigned int tm_memopt_value_number (gimple stmt, enum insert_option op) { struct tm_memop tmpmem, *mem; - void **slot; + tm_memop **slot; gcc_assert (is_tm_load (stmt) || is_tm_store (stmt)); tmpmem.addr = gimple_call_arg (stmt, 0); - slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op); + slot = tm_memopt_value_numbers.find_slot (&tmpmem, op); if (*slot) - mem = (struct tm_memop *) *slot; + mem = *slot; else if (op == INSERT) { mem = XNEW (struct tm_memop); @@ -3295,11 +3332,11 @@ dump_tm_memopt_set (const char *set_name, bitmap bits) fprintf (dump_file, "TM memopt: %s: [", set_name); EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi) { - htab_iterator hi; - struct tm_memop *mem; + hash_table <tm_memop_hasher>::iterator hi; + struct tm_memop *mem = NULL; /* Yeah, yeah, yeah. Whatever. This is just for debugging. */ - FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi) + FOR_EACH_HASH_TABLE_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi) if (mem->value_id == i) break; gcc_assert (mem->value_id == i); @@ -3734,7 +3771,7 @@ execute_tm_memopt (void) vec<basic_block> bbs; tm_memopt_value_id = 0; - tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free); + tm_memopt_value_numbers.create (10); for (region = all_tm_regions; region; region = region->next) { @@ -3768,10 +3805,10 @@ execute_tm_memopt (void) tm_memopt_free_sets (bbs); bbs.release (); bitmap_obstack_release (&tm_memopt_obstack); - htab_empty (tm_memopt_value_numbers); + tm_memopt_value_numbers.empty (); } - htab_delete (tm_memopt_value_numbers); + tm_memopt_value_numbers.dispose (); return 0; } diff --git a/gcc/tree-browser.c b/gcc/tree-browser.c index ba2fe195781..b236cabd8df 100644 --- a/gcc/tree-browser.c +++ b/gcc/tree-browser.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tree.h" #include "tree-pretty-print.h" @@ -94,14 +95,45 @@ static tree TB_next_expr (tree); static tree TB_up_expr (tree); static tree TB_first_in_bind (tree); static tree TB_last_in_bind (tree); -static int TB_parent_eq (const void *, const void *); static tree TB_history_prev (void); /* FIXME: To be declared in a .h file. */ void browse_tree (tree); +/* Hashtable helpers. */ +struct tree_upper_hasher : typed_noop_remove <tree_node> +{ + typedef tree_node value_type; + typedef tree_node compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +tree_upper_hasher::hash (const value_type *v) +{ + return pointer_hash <value_type>::hash (v); +} + +inline bool +tree_upper_hasher::equal (const value_type *parent, const compare_type *node) +{ + if (parent == NULL || node == NULL) + return 0; + + if (EXPR_P (parent)) + { + int n = TREE_OPERAND_LENGTH (parent); + int i; + for (i = 0; i < n; i++) + if (node == TREE_OPERAND (parent, i)) + return true; + } + return false; +} + /* Static variables. */ -static htab_t TB_up_ht; +static hash_table <tree_upper_hasher> TB_up_ht; static vec<tree, va_gc> *TB_history_stack; static int TB_verbose = 1; @@ -134,7 +166,7 @@ browse_tree (tree begin) /* Store in a hashtable information about previous and upper statements. */ { - TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL); + TB_up_ht.create (1023); TB_update_up (head); } @@ -612,7 +644,7 @@ browse_tree (tree begin) } ret:; - htab_delete (TB_up_ht); + TB_up_ht.dispose (); return; } @@ -658,7 +690,7 @@ TB_up_expr (tree node) if (node == NULL_TREE) return NULL_TREE; - res = (tree) htab_find (TB_up_ht, node); + res = TB_up_ht.find (node); return res; } @@ -724,7 +756,7 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { tree node; - void **slot; + tree_node **slot; node = *tp; @@ -736,8 +768,8 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, for (i = 0; i < n; i++) { tree op = TREE_OPERAND (node, i); - slot = htab_find_slot (TB_up_ht, op, INSERT); - *slot = (void *) node; + slot = TB_up_ht.find_slot (op, INSERT); + *slot = node; } } @@ -745,28 +777,6 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, return NULL_TREE; } -/* Function used in TB_up_ht. */ - -static int -TB_parent_eq (const void *p1, const void *p2) -{ - const_tree const node = (const_tree)p2; - const_tree const parent = (const_tree) p1; - - if (p1 == NULL || p2 == NULL) - return 0; - - if (EXPR_P (parent)) - { - int n = TREE_OPERAND_LENGTH (parent); - int i; - for (i = 0; i < n; i++) - if (node == TREE_OPERAND (parent, i)) - return 1; - } - return 0; -} - /* Update information about upper expressions in the hash table. */ static void diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 05bac430f50..c5c25a742bc 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tm.h" #include "tree.h" #include "tm_p.h" @@ -87,7 +88,36 @@ struct locus_discrim_map location_t locus; int discriminator; }; -static htab_t discriminator_per_locus; + +/* Hashtable helpers. */ + +struct locus_descrim_hasher : typed_free_remove <locus_discrim_map> +{ + typedef locus_discrim_map value_type; + typedef locus_discrim_map compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Trivial hash function for a location_t. ITEM is a pointer to + a hash table entry that maps a location_t to a discriminator. */ + +inline hashval_t +locus_descrim_hasher::hash (const value_type *item) +{ + return item->locus; +} + +/* Equality function for the locus-to-discriminator map. A and B + point to the two hash table entries to compare. */ + +inline bool +locus_descrim_hasher::equal (const value_type *a, const compare_type *b) +{ + return a->locus == b->locus; +} + +static hash_table <locus_descrim_hasher> discriminator_per_locus; /* Basic blocks and flowgraphs. */ static void make_blocks (gimple_seq); @@ -99,8 +129,6 @@ static void make_cond_expr_edges (basic_block); static void make_gimple_switch_edges (basic_block); static void make_goto_expr_edges (basic_block); static void make_gimple_asm_edges (basic_block); -static unsigned int locus_map_hash (const void *); -static int locus_map_eq (const void *, const void *); static void assign_discriminator (location_t, basic_block); static edge gimple_redirect_edge_and_branch (edge, basic_block); static edge gimple_try_redirect_by_replacing_jump (edge, basic_block); @@ -201,11 +229,10 @@ build_gimple_cfg (gimple_seq seq) group_case_labels (); /* Create the edges of the flowgraph. */ - discriminator_per_locus = htab_create (13, locus_map_hash, locus_map_eq, - free); + discriminator_per_locus.create (13); make_edges (); cleanup_dead_labels (); - htab_delete (discriminator_per_locus); + discriminator_per_locus.dispose (); } static unsigned int @@ -675,26 +702,6 @@ make_edges (void) fold_cond_expr_cond (); } -/* Trivial hash function for a location_t. ITEM is a pointer to - a hash table entry that maps a location_t to a discriminator. */ - -static unsigned int -locus_map_hash (const void *item) -{ - return ((const struct locus_discrim_map *) item)->locus; -} - -/* Equality function for the locus-to-discriminator map. VA and VB - point to the two hash table entries to compare. */ - -static int -locus_map_eq (const void *va, const void *vb) -{ - const struct locus_discrim_map *a = (const struct locus_discrim_map *) va; - const struct locus_discrim_map *b = (const struct locus_discrim_map *) vb; - return a->locus == b->locus; -} - /* Find the next available discriminator value for LOCUS. The discriminator distinguishes among several basic blocks that share a common locus, allowing for more accurate sample-based @@ -708,9 +715,7 @@ next_discriminator_for_locus (location_t locus) item.locus = locus; item.discriminator = 0; - slot = (struct locus_discrim_map **) - htab_find_slot_with_hash (discriminator_per_locus, (void *) &item, - (hashval_t) locus, INSERT); + slot = discriminator_per_locus.find_slot_with_hash (&item, locus, INSERT); gcc_assert (slot); if (*slot == HTAB_EMPTY_ENTRY) { diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 760083b64ca..ee545682f98 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-iterator.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" +#include "tree-hasher.h" /* For each complex ssa name, a lattice value. We're interested in finding @@ -53,7 +54,7 @@ static vec<complex_lattice_t> complex_lattice_values; /* For each complex variable, a pair of variables for the components exists in the hashtable. */ -static htab_t complex_variable_components; +static int_tree_htab_type complex_variable_components; /* For each complex SSA_NAME, a pair of ssa names for the components. */ static vec<tree> complex_ssa_name_components; @@ -65,7 +66,7 @@ cvc_lookup (unsigned int uid) { struct int_tree_map *h, in; in.uid = uid; - h = (struct int_tree_map *) htab_find_with_hash (complex_variable_components, &in, uid); + h = complex_variable_components.find_with_hash (&in, uid); return h ? h->to : NULL; } @@ -75,14 +76,13 @@ static void cvc_insert (unsigned int uid, tree to) { struct int_tree_map *h; - void **loc; + int_tree_map **loc; h = XNEW (struct int_tree_map); h->uid = uid; h->to = to; - loc = htab_find_slot_with_hash (complex_variable_components, h, - uid, INSERT); - *(struct int_tree_map **) loc = h; + loc = complex_variable_components.find_slot_with_hash (h, uid, INSERT); + *loc = h; } /* Return true if T is not a zero constant. In the case of real values, @@ -1604,8 +1604,7 @@ tree_lower_complex (void) init_parameter_lattice_values (); ssa_propagate (complex_visit_stmt, complex_visit_phi); - complex_variable_components = htab_create (10, int_tree_map_hash, - int_tree_map_eq, free); + complex_variable_components.create (10); complex_ssa_name_components.create (2 * num_ssa_names); complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names); @@ -1626,7 +1625,7 @@ tree_lower_complex (void) gsi_commit_edge_inserts (); - htab_delete (complex_variable_components); + complex_variable_components.dispose (); complex_ssa_name_components.release (); complex_lattice_values.release (); return 0; diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 2eb309732a6..56132e15702 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tm.h" #include "tree.h" #include "flags.h" @@ -193,20 +194,42 @@ struct finally_tree_node gimple parent; }; +/* Hashtable helpers. */ + +struct finally_tree_hasher : typed_free_remove <finally_tree_node> +{ + typedef finally_tree_node value_type; + typedef finally_tree_node compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +finally_tree_hasher::hash (const value_type *v) +{ + return (intptr_t)v->child.t >> 4; +} + +inline bool +finally_tree_hasher::equal (const value_type *v, const compare_type *c) +{ + return v->child.t == c->child.t; +} + /* Note that this table is *not* marked GTY. It is short-lived. */ -static htab_t finally_tree; +static hash_table <finally_tree_hasher> finally_tree; static void record_in_finally_tree (treemple child, gimple parent) { struct finally_tree_node *n; - void **slot; + finally_tree_node **slot; n = XNEW (struct finally_tree_node); n->child = child; n->parent = parent; - slot = htab_find_slot (finally_tree, n, INSERT); + slot = finally_tree.find_slot (n, INSERT); gcc_assert (!*slot); *slot = n; } @@ -285,7 +308,7 @@ outside_finally_tree (treemple start, gimple target) do { n.child = start; - p = (struct finally_tree_node *) htab_find (finally_tree, &n); + p = finally_tree.find (&n); if (!p) return true; start.g = p->parent; @@ -2102,7 +2125,7 @@ lower_eh_constructs (void) if (bodyp == NULL) return 0; - finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free); + finally_tree.create (31); eh_region_may_contain_throw_map = BITMAP_ALLOC (NULL); memset (&null_state, 0, sizeof (null_state)); @@ -2120,7 +2143,7 @@ lower_eh_constructs (void) didn't change its value, and we don't have to re-set the function. */ gcc_assert (bodyp == gimple_body (current_function_decl)); - htab_delete (finally_tree); + finally_tree.dispose (); BITMAP_FREE (eh_region_may_contain_throw_map); eh_seq = NULL; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 227fe56d00e..01fe3633182 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -282,12 +282,6 @@ struct int_tree_map { tree to; }; -extern unsigned int int_tree_map_hash (const void *); -extern int int_tree_map_eq (const void *, const void *); - -extern unsigned int uid_decl_map_hash (const void *); -extern int uid_decl_map_eq (const void *, const void *); - #define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names)) #define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)]) diff --git a/gcc/tree-hasher.h b/gcc/tree-hasher.h new file mode 100644 index 00000000000..e403c9fcbe4 --- /dev/null +++ b/gcc/tree-hasher.h @@ -0,0 +1,55 @@ +/* Hash Table Helper for Trees + Copyright (C) 2012 Free Software Foundation, Inc. + Contributed by Lawrence Crowl <crowl@google.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_TREE_HASHER_H +#define GCC_TREE_HASHER_H 1 + +#include "hash-table.h" +#include "tree-flow.h" + +/* Hashtable helpers. */ + +struct int_tree_hasher : typed_free_remove <int_tree_map> +{ + typedef int_tree_map value_type; + typedef int_tree_map compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hash a UID in a int_tree_map. */ + +inline hashval_t +int_tree_hasher::hash (const value_type *item) +{ + return item->uid; +} + +/* Return true if the uid in both int tree maps are equal. */ + +inline bool +int_tree_hasher::equal (const value_type *a, const compare_type *b) +{ + return (a->uid == b->uid); +} + +typedef hash_table <int_tree_hasher> int_tree_htab_type; + +#endif /* GCC_TREE_HASHER_H */ diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 1729f230115..088fc462970 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "langhooks.h" #include "tree-vectorizer.h" +#include "tree-hasher.h" /* This pass tries to distribute iterations of loops into several threads. The implementation is straightforward -- for each loop we test whether its @@ -176,36 +177,44 @@ struct reduction_info operation. */ }; -/* Equality and hash functions for hashtab code. */ +/* Reduction info hashtable helpers. */ -static int -reduction_info_eq (const void *aa, const void *bb) +struct reduction_hasher : typed_free_remove <reduction_info> { - const struct reduction_info *a = (const struct reduction_info *) aa; - const struct reduction_info *b = (const struct reduction_info *) bb; + typedef reduction_info value_type; + typedef reduction_info compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Equality and hash functions for hashtab code. */ +inline bool +reduction_hasher::equal (const value_type *a, const compare_type *b) +{ return (a->reduc_phi == b->reduc_phi); } -static hashval_t -reduction_info_hash (const void *aa) +inline hashval_t +reduction_hasher::hash (const value_type *a) { - const struct reduction_info *a = (const struct reduction_info *) aa; - return a->reduc_version; } +typedef hash_table <reduction_hasher> reduction_info_table_type; + + static struct reduction_info * -reduction_phi (htab_t reduction_list, gimple phi) +reduction_phi (reduction_info_table_type reduction_list, gimple phi) { struct reduction_info tmpred, *red; - if (htab_elements (reduction_list) == 0 || phi == NULL) + if (reduction_list.elements () == 0 || phi == NULL) return NULL; tmpred.reduc_phi = phi; tmpred.reduc_version = gimple_uid (phi); - red = (struct reduction_info *) htab_find (reduction_list, &tmpred); + red = reduction_list.find (&tmpred); return red; } @@ -220,25 +229,32 @@ struct name_to_copy_elt value. */ }; -/* Equality and hash functions for hashtab code. */ +/* Name copies hashtable helpers. */ -static int -name_to_copy_elt_eq (const void *aa, const void *bb) +struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt> { - const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa; - const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb; + typedef name_to_copy_elt value_type; + typedef name_to_copy_elt compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Equality and hash functions for hashtab code. */ +inline bool +name_to_copy_hasher::equal (const value_type *a, const compare_type *b) +{ return a->version == b->version; } -static hashval_t -name_to_copy_elt_hash (const void *aa) +inline hashval_t +name_to_copy_hasher::hash (const value_type *a) { - const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa; - return (hashval_t) a->version; } +typedef hash_table <name_to_copy_hasher> name_to_copy_table_type; + /* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE matrix. Rather than use floats, we simply keep a single DENOMINATOR that represents the denominator for every element in the matrix. */ @@ -445,11 +461,11 @@ loop_has_blocks_with_irreducible_flag (struct loop *loop) right before GSI. */ static tree -take_address_of (tree obj, tree type, edge entry, htab_t decl_address, - gimple_stmt_iterator *gsi) +take_address_of (tree obj, tree type, edge entry, + int_tree_htab_type decl_address, gimple_stmt_iterator *gsi) { int uid; - void **dslot; + int_tree_map **dslot; struct int_tree_map ielt, *nielt; tree *var_p, name, addr; gimple stmt; @@ -472,7 +488,7 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address, on it. */ uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0)); ielt.uid = uid; - dslot = htab_find_slot_with_hash (decl_address, &ielt, uid, INSERT); + dslot = decl_address.find_slot_with_hash (&ielt, uid, INSERT); if (!*dslot) { if (gsi == NULL) @@ -490,7 +506,7 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address, *dslot = nielt; } else - name = ((struct int_tree_map *) *dslot)->to; + name = (*dslot)->to; /* Express the address in terms of the canonical SSA name. */ TREE_OPERAND (*var_p, 0) = name; @@ -517,15 +533,14 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address, for reduction described in SLOT, and place it at the preheader of the loop described in DATA. */ -static int -initialize_reductions (void **slot, void *data) +int +initialize_reductions (reduction_info **slot, struct loop *loop) { tree init, c; tree bvar, type, arg; edge e; - struct reduction_info *const reduc = (struct reduction_info *) *slot; - struct loop *loop = (struct loop *) data; + struct reduction_info *const reduc = *slot; /* Create initialization in preheader: reduction_variable = initialization value of reduction. */ @@ -567,7 +582,7 @@ struct elv_data { struct walk_stmt_info info; edge entry; - htab_t decl_address; + int_tree_htab_type decl_address; gimple_stmt_iterator *gsi; bool changed; bool reset; @@ -657,7 +672,7 @@ eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data) static void eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi, - htab_t decl_address) + int_tree_htab_type decl_address) { struct elv_data dta; gimple stmt = gsi_stmt (*gsi); @@ -709,8 +724,8 @@ eliminate_local_variables (edge entry, edge exit) unsigned i; gimple_stmt_iterator gsi; bool has_debug_stmt = false; - htab_t decl_address = htab_create (10, int_tree_map_hash, int_tree_map_eq, - free); + int_tree_htab_type decl_address; + decl_address.create (10); basic_block entry_bb = entry->src; basic_block exit_bb = exit->dest; @@ -734,7 +749,7 @@ eliminate_local_variables (edge entry, edge exit) if (gimple_debug_bind_p (gsi_stmt (gsi))) eliminate_local_variables_stmt (entry, &gsi, decl_address); - htab_delete (decl_address); + decl_address.dispose (); body.release (); } @@ -773,25 +788,25 @@ expr_invariant_in_region_p (edge entry, edge exit, tree expr) duplicated, storing the copies in DECL_COPIES. */ static tree -separate_decls_in_region_name (tree name, - htab_t name_copies, htab_t decl_copies, - bool copy_name_p) +separate_decls_in_region_name (tree name, name_to_copy_table_type name_copies, + int_tree_htab_type decl_copies, bool copy_name_p) { tree copy, var, var_copy; unsigned idx, uid, nuid; struct int_tree_map ielt, *nielt; struct name_to_copy_elt elt, *nelt; - void **slot, **dslot; + name_to_copy_elt **slot; + int_tree_map **dslot; if (TREE_CODE (name) != SSA_NAME) return name; idx = SSA_NAME_VERSION (name); elt.version = idx; - slot = htab_find_slot_with_hash (name_copies, &elt, idx, - copy_name_p ? INSERT : NO_INSERT); + slot = name_copies.find_slot_with_hash (&elt, idx, + copy_name_p ? INSERT : NO_INSERT); if (slot && *slot) - return ((struct name_to_copy_elt *) *slot)->new_name; + return (*slot)->new_name; if (copy_name_p) { @@ -814,7 +829,7 @@ separate_decls_in_region_name (tree name, uid = DECL_UID (var); ielt.uid = uid; - dslot = htab_find_slot_with_hash (decl_copies, &ielt, uid, INSERT); + dslot = decl_copies.find_slot_with_hash (&ielt, uid, INSERT); if (!*dslot) { var_copy = create_tmp_var (TREE_TYPE (var), get_name (var)); @@ -828,7 +843,7 @@ separate_decls_in_region_name (tree name, it again. */ nuid = DECL_UID (var_copy); ielt.uid = nuid; - dslot = htab_find_slot_with_hash (decl_copies, &ielt, nuid, INSERT); + dslot = decl_copies.find_slot_with_hash (&ielt, nuid, INSERT); gcc_assert (!*dslot); nielt = XNEW (struct int_tree_map); nielt->uid = nuid; @@ -851,7 +866,8 @@ separate_decls_in_region_name (tree name, static void separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt, - htab_t name_copies, htab_t decl_copies) + name_to_copy_table_type name_copies, + int_tree_htab_type decl_copies) { use_operand_p use; def_operand_p def; @@ -889,15 +905,17 @@ separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt, replacement decls are stored in DECL_COPIES. */ static bool -separate_decls_in_region_debug (gimple stmt, htab_t name_copies, - htab_t decl_copies) +separate_decls_in_region_debug (gimple stmt, + name_to_copy_table_type name_copies, + int_tree_htab_type decl_copies) { use_operand_p use; ssa_op_iter oi; tree var, name; struct int_tree_map ielt; struct name_to_copy_elt elt; - void **slot, **dslot; + name_to_copy_elt **slot; + int_tree_map **dslot; if (gimple_debug_bind_p (stmt)) var = gimple_debug_bind_get_var (stmt); @@ -909,7 +927,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies, return true; gcc_assert (DECL_P (var) && SSA_VAR_P (var)); ielt.uid = DECL_UID (var); - dslot = htab_find_slot_with_hash (decl_copies, &ielt, ielt.uid, NO_INSERT); + dslot = decl_copies.find_slot_with_hash (&ielt, ielt.uid, NO_INSERT); if (!dslot) return true; if (gimple_debug_bind_p (stmt)) @@ -924,7 +942,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies, continue; elt.version = SSA_NAME_VERSION (name); - slot = htab_find_slot_with_hash (name_copies, &elt, elt.version, NO_INSERT); + slot = name_copies.find_slot_with_hash (&elt, elt.version, NO_INSERT); if (!slot) { gimple_debug_bind_reset_value (stmt); @@ -932,7 +950,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies, break; } - SET_USE (use, ((struct name_to_copy_elt *) *slot)->new_name); + SET_USE (use, (*slot)->new_name); } return false; @@ -941,12 +959,11 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies, /* Callback for htab_traverse. Adds a field corresponding to the reduction specified in SLOT. The type is passed in DATA. */ -static int -add_field_for_reduction (void **slot, void *data) +int +add_field_for_reduction (reduction_info **slot, tree type) { - struct reduction_info *const red = (struct reduction_info *) *slot; - tree const type = (tree) data; + struct reduction_info *const red = *slot; tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt)); tree field = build_decl (gimple_location (red->reduc_stmt), FIELD_DECL, DECL_NAME (var), TREE_TYPE (var)); @@ -961,11 +978,10 @@ add_field_for_reduction (void **slot, void *data) /* Callback for htab_traverse. Adds a field corresponding to a ssa name described in SLOT. The type is passed in DATA. */ -static int -add_field_for_name (void **slot, void *data) +int +add_field_for_name (name_to_copy_elt **slot, tree type) { - struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot; - tree type = (tree) data; + struct name_to_copy_elt *const elt = *slot; tree name = ssa_name (elt->version); tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, SSA_NAME_IDENTIFIER (name), @@ -984,11 +1000,10 @@ add_field_for_name (void **slot, void *data) The phi's result will be stored in NEW_PHI field of the reduction's data structure. */ -static int -create_phi_for_local_result (void **slot, void *data) +int +create_phi_for_local_result (reduction_info **slot, struct loop *loop) { - struct reduction_info *const reduc = (struct reduction_info *) *slot; - const struct loop *const loop = (const struct loop *) data; + struct reduction_info *const reduc = *slot; edge e; gimple new_phi; basic_block store_bb; @@ -1034,11 +1049,10 @@ struct clsn_data DATA annotates the place in memory the atomic operation relates to, and the basic block it needs to be generated in. */ -static int -create_call_for_reduction_1 (void **slot, void *data) +int +create_call_for_reduction_1 (reduction_info **slot, struct clsn_data *clsn_data) { - struct reduction_info *const reduc = (struct reduction_info *) *slot; - struct clsn_data *const clsn_data = (struct clsn_data *) data; + struct reduction_info *const reduc = *slot; gimple_stmt_iterator gsi; tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi)); tree load_struct; @@ -1087,23 +1101,24 @@ create_call_for_reduction_1 (void **slot, void *data) LD_ST_DATA describes the shared data structure where shared data is stored in and loaded from. */ static void -create_call_for_reduction (struct loop *loop, htab_t reduction_list, +create_call_for_reduction (struct loop *loop, + reduction_info_table_type reduction_list, struct clsn_data *ld_st_data) { - htab_traverse (reduction_list, create_phi_for_local_result, loop); + reduction_list.traverse <struct loop *, create_phi_for_local_result> (loop); /* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */ ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest; - htab_traverse (reduction_list, create_call_for_reduction_1, ld_st_data); + reduction_list + .traverse <struct clsn_data *, create_call_for_reduction_1> (ld_st_data); } /* Callback for htab_traverse. Loads the final reduction value at the join point of all threads, and inserts it in the right place. */ -static int -create_loads_for_reductions (void **slot, void *data) +int +create_loads_for_reductions (reduction_info **slot, struct clsn_data *clsn_data) { - struct reduction_info *const red = (struct reduction_info *) *slot; - struct clsn_data *const clsn_data = (struct clsn_data *) data; + struct reduction_info *const red = *slot; gimple stmt; gimple_stmt_iterator gsi; tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt)); @@ -1137,7 +1152,7 @@ create_loads_for_reductions (void **slot, void *data) REDUCTION_LIST describes the list of reductions that the loads should be generated for. */ static void -create_final_loads_for_reduction (htab_t reduction_list, +create_final_loads_for_reduction (reduction_info_table_type reduction_list, struct clsn_data *ld_st_data) { gimple_stmt_iterator gsi; @@ -1151,7 +1166,8 @@ create_final_loads_for_reduction (htab_t reduction_list, gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); SSA_NAME_DEF_STMT (ld_st_data->load) = stmt; - htab_traverse (reduction_list, create_loads_for_reductions, ld_st_data); + reduction_list + .traverse <struct clsn_data *, create_loads_for_reductions> (ld_st_data); } @@ -1161,11 +1177,10 @@ create_final_loads_for_reduction (htab_t reduction_list, The reduction is specified in SLOT. The store information is passed in DATA. */ -static int -create_stores_for_reduction (void **slot, void *data) +int +create_stores_for_reduction (reduction_info **slot, struct clsn_data *clsn_data) { - struct reduction_info *const red = (struct reduction_info *) *slot; - struct clsn_data *const clsn_data = (struct clsn_data *) data; + struct reduction_info *const red = *slot; tree t; gimple stmt; gimple_stmt_iterator gsi; @@ -1183,11 +1198,11 @@ create_stores_for_reduction (void **slot, void *data) store to a field of STORE in STORE_BB for the ssa name and its duplicate specified in SLOT. */ -static int -create_loads_and_stores_for_name (void **slot, void *data) +int +create_loads_and_stores_for_name (name_to_copy_elt **slot, + struct clsn_data *clsn_data) { - struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot; - struct clsn_data *const clsn_data = (struct clsn_data *) data; + struct name_to_copy_elt *const elt = *slot; tree t; gimple stmt; gimple_stmt_iterator gsi; @@ -1244,17 +1259,18 @@ create_loads_and_stores_for_name (void **slot, void *data) in LOOP. */ static void -separate_decls_in_region (edge entry, edge exit, htab_t reduction_list, +separate_decls_in_region (edge entry, edge exit, + reduction_info_table_type reduction_list, tree *arg_struct, tree *new_arg_struct, struct clsn_data *ld_st_data) { basic_block bb1 = split_edge (entry); basic_block bb0 = single_pred (bb1); - htab_t name_copies = htab_create (10, name_to_copy_elt_hash, - name_to_copy_elt_eq, free); - htab_t decl_copies = htab_create (10, int_tree_map_hash, int_tree_map_eq, - free); + name_to_copy_table_type name_copies; + name_copies.create (10); + int_tree_htab_type decl_copies; + decl_copies.create (10); unsigned i; tree type, type_name, nvar; gimple_stmt_iterator gsi; @@ -1320,7 +1336,7 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list, body.release (); - if (htab_elements (name_copies) == 0 && htab_elements (reduction_list) == 0) + if (name_copies.elements () == 0 && reduction_list.elements () == 0) { /* It may happen that there is nothing to copy (if there are only loop carried and external variables in the loop). */ @@ -1336,12 +1352,11 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list, type); TYPE_NAME (type) = type_name; - htab_traverse (name_copies, add_field_for_name, type); - if (reduction_list && htab_elements (reduction_list) > 0) + name_copies.traverse <tree, add_field_for_name> (type); + if (reduction_list.is_created () && reduction_list.elements () > 0) { /* Create the fields for reductions. */ - htab_traverse (reduction_list, add_field_for_reduction, - type); + reduction_list.traverse <tree, add_field_for_reduction> (type); } layout_type (type); @@ -1355,15 +1370,17 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list, ld_st_data->store_bb = bb0; ld_st_data->load_bb = bb1; - htab_traverse (name_copies, create_loads_and_stores_for_name, - ld_st_data); + name_copies + .traverse <struct clsn_data *, create_loads_and_stores_for_name> + (ld_st_data); /* Load the calculation from memory (after the join of the threads). */ - if (reduction_list && htab_elements (reduction_list) > 0) + if (reduction_list.is_created () && reduction_list.elements () > 0) { - htab_traverse (reduction_list, create_stores_for_reduction, - ld_st_data); + reduction_list + .traverse <struct clsn_data *, create_stores_for_reduction> + (ld_st_data); clsn_data.load = make_ssa_name (nvar, NULL); clsn_data.load_bb = exit->dest; clsn_data.store = ld_st_data->store; @@ -1371,8 +1388,8 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list, } } - htab_delete (decl_copies); - htab_delete (name_copies); + decl_copies.dispose (); + name_copies.dispose (); } /* Bitmap containing uids of functions created by parallelization. We cannot @@ -1461,7 +1478,9 @@ create_loop_fn (location_t loc) REDUCTION_LIST describes the reductions in LOOP. */ static void -transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit) +transform_to_exit_first_loop (struct loop *loop, + reduction_info_table_type reduction_list, + tree nit) { basic_block *bbs, *nbbs, ex_bb, orig_header; unsigned n; @@ -1530,7 +1549,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit PHI_RESULT of this phi is the resulting value of the reduction variable when exiting the loop. */ - if (htab_elements (reduction_list) > 0) + if (reduction_list.elements () > 0) { struct reduction_info *red; @@ -1708,7 +1727,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data, REDUCTION_LIST describes the reductions existent in the LOOP. */ static void -gen_parallel_loop (struct loop *loop, htab_t reduction_list, +gen_parallel_loop (struct loop *loop, reduction_info_table_type reduction_list, unsigned n_threads, struct tree_niter_desc *niter) { loop_iterator li; @@ -1834,8 +1853,8 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list, transform_to_exit_first_loop (loop, reduction_list, nit); /* Generate initializations for reductions. */ - if (htab_elements (reduction_list) > 0) - htab_traverse (reduction_list, initialize_reductions, loop); + if (reduction_list.elements () > 0) + reduction_list.traverse <struct loop *, initialize_reductions> (loop); /* Eliminate the references to local variables from the loop. */ gcc_assert (single_exit (loop)); @@ -1855,7 +1874,7 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list, loc = gimple_location (cond_stmt); parallel_head = create_parallel_loop (loop, create_loop_fn (loc), arg_struct, new_arg_struct, n_threads, loc); - if (htab_elements (reduction_list) > 0) + if (reduction_list.elements () > 0) create_call_for_reduction (loop, reduction_list, &clsn_data); scev_reset (); @@ -1902,9 +1921,10 @@ loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED) and PHI, insert it to the REDUCTION_LIST. */ static void -build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi) +build_new_reduction (reduction_info_table_type reduction_list, + gimple reduc_stmt, gimple phi) { - PTR *slot; + reduction_info **slot; struct reduction_info *new_reduction; gcc_assert (reduc_stmt); @@ -1923,16 +1943,16 @@ build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi) new_reduction->reduc_phi = phi; new_reduction->reduc_version = SSA_NAME_VERSION (gimple_phi_result (phi)); new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt); - slot = htab_find_slot (reduction_list, new_reduction, INSERT); + slot = reduction_list.find_slot (new_reduction, INSERT); *slot = new_reduction; } /* Callback for htab_traverse. Sets gimple_uid of reduc_phi stmts. */ -static int -set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED) +int +set_reduc_phi_uids (reduction_info **slot, void *data ATTRIBUTE_UNUSED) { - struct reduction_info *const red = (struct reduction_info *) *slot; + struct reduction_info *const red = *slot; gimple_set_uid (red->reduc_phi, red->reduc_version); return 1; } @@ -1940,7 +1960,7 @@ set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED) /* Detect all reductions in the LOOP, insert them into REDUCTION_LIST. */ static void -gather_scalar_reductions (loop_p loop, htab_t reduction_list) +gather_scalar_reductions (loop_p loop, reduction_info_table_type reduction_list) { gimple_stmt_iterator gsi; loop_vec_info simple_loop_info; @@ -1972,7 +1992,7 @@ gather_scalar_reductions (loop_p loop, htab_t reduction_list) /* As gimple_uid is used by the vectorizer in between vect_analyze_loop_form and destroy_loop_vec_info, we can set gimple_uid of reduc_phi stmts only now. */ - htab_traverse (reduction_list, set_reduc_phi_uids, NULL); + reduction_list.traverse <void *, set_reduc_phi_uids> (NULL); } /* Try to initialize NITER for code generation part. */ @@ -2001,7 +2021,8 @@ try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter) REDUCTION_LIST describes the reductions. */ static bool -try_create_reduction_list (loop_p loop, htab_t reduction_list) +try_create_reduction_list (loop_p loop, + reduction_info_table_type reduction_list) { edge exit = single_dom_exit (loop); gimple_stmt_iterator gsi; @@ -2032,7 +2053,7 @@ try_create_reduction_list (loop_p loop, htab_t reduction_list) fprintf (dump_file, " checking if it a part of reduction pattern: \n"); } - if (htab_elements (reduction_list) == 0) + if (reduction_list.elements () == 0) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, @@ -2106,7 +2127,7 @@ parallelize_loops (void) struct loop *loop; struct tree_niter_desc niter_desc; loop_iterator li; - htab_t reduction_list; + reduction_info_table_type reduction_list; struct obstack parloop_obstack; HOST_WIDE_INT estimated; LOC loop_loc; @@ -2118,13 +2139,12 @@ parallelize_loops (void) return false; gcc_obstack_init (&parloop_obstack); - reduction_list = htab_create (10, reduction_info_hash, - reduction_info_eq, free); + reduction_list.create (10); init_stmt_vec_info_vec (); FOR_EACH_LOOP (li, loop, 0) { - htab_empty (reduction_list); + reduction_list.empty (); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Trying loop %d as candidate\n",loop->num); @@ -2204,7 +2224,7 @@ parallelize_loops (void) } free_stmt_vec_info_vec (); - htab_delete (reduction_list); + reduction_list.dispose (); obstack_free (&parloop_obstack, NULL); /* Parallelization will cause new function calls to be inserted through diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index a76d9aee46a..d5dde5fedb7 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -256,6 +256,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "gimple-pretty-print.h" #include "tree-flow.h" #include "cfgloop.h" @@ -317,7 +318,7 @@ new_scev_info_str (basic_block instantiated_below, tree var) /* Computes a hash function for database element ELT. */ -static hashval_t +static inline hashval_t hash_scev_info (const void *elt) { return SSA_NAME_VERSION (((const struct scev_info_str *) elt)->var); @@ -325,7 +326,7 @@ hash_scev_info (const void *elt) /* Compares database elements E1 and E2. */ -static int +static inline int eq_scev_info (const void *e1, const void *e2) { const struct scev_info_str *elt1 = (const struct scev_info_str *) e1; @@ -343,6 +344,39 @@ del_scev_info (void *e) ggc_free (e); } +/* Hashtable helpers. */ + +struct scev_info_hasher +{ + typedef scev_info_str value_type; + typedef scev_info_str compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +inline hashval_t +scev_info_hasher::hash (const value_type *elt) +{ + return hash_scev_info (elt); +} + +inline bool +scev_info_hasher::equal (const value_type *elt1, const compare_type *elt2) +{ + return eq_scev_info (elt1, elt2); +} + +/* Deletes database element E. */ + +inline void +scev_info_hasher::remove (value_type *e) +{ + del_scev_info (e); +} + +typedef hash_table <scev_info_hasher> scev_info_hash_table_type; + /* Get the scalar evolution of VAR for INSTANTIATED_BELOW basic block. A first query on VAR returns chrec_not_analyzed_yet. */ @@ -2048,14 +2082,14 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop, INSTANTIATED_BELOW block. */ static tree -get_instantiated_value (htab_t cache, basic_block instantiated_below, - tree version) +get_instantiated_value (scev_info_hash_table_type cache, + basic_block instantiated_below, tree version) { struct scev_info_str *info, pattern; pattern.var = version; pattern.instantiated_below = instantiated_below; - info = (struct scev_info_str *) htab_find (cache, &pattern); + info = cache.find (&pattern); if (info) return info->chrec; @@ -2067,19 +2101,19 @@ get_instantiated_value (htab_t cache, basic_block instantiated_below, INSTANTIATED_BELOW to VAL. */ static void -set_instantiated_value (htab_t cache, basic_block instantiated_below, - tree version, tree val) +set_instantiated_value (scev_info_hash_table_type cache, + basic_block instantiated_below, tree version, tree val) { struct scev_info_str *info, pattern; - PTR *slot; + scev_info_str **slot; pattern.var = version; pattern.instantiated_below = instantiated_below; - slot = htab_find_slot (cache, &pattern, INSERT); + slot = cache.find_slot (&pattern, INSERT); if (!*slot) *slot = new_scev_info_str (instantiated_below, version); - info = (struct scev_info_str *) *slot; + info = *slot; info->chrec = val; } @@ -2114,7 +2148,7 @@ loop_closed_phi_def (tree var) } static tree instantiate_scev_r (basic_block, struct loop *, struct loop *, - tree, bool, htab_t, int); + tree, bool, scev_info_hash_table_type, int); /* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW and EVOLUTION_LOOP, that were left under a symbolic form. @@ -2134,7 +2168,8 @@ static tree instantiate_scev_name (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree res; struct loop *def_loop; @@ -2236,7 +2271,8 @@ static tree instantiate_scev_poly (basic_block instantiate_below, struct loop *evolution_loop, struct loop *, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree op1; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, @@ -2282,7 +2318,8 @@ instantiate_scev_binary (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, enum tree_code code, tree type, tree c0, tree c1, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree op1; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, @@ -2341,7 +2378,8 @@ static tree instantiate_array_ref (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree res; tree index = TREE_OPERAND (chrec, 1); @@ -2380,7 +2418,8 @@ instantiate_scev_convert (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, tree type, tree op, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, + scev_info_hash_table_type cache, int size_expr) { tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, op, @@ -2429,7 +2468,8 @@ instantiate_scev_not (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, enum tree_code code, tree type, tree op, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, op, @@ -2478,7 +2518,8 @@ static tree instantiate_scev_3 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree op1, op2; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, @@ -2526,7 +2567,8 @@ static tree instantiate_scev_2 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree op1; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, @@ -2566,7 +2608,8 @@ static tree instantiate_scev_1 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 0), @@ -2599,7 +2642,8 @@ static tree instantiate_scev_r (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, htab_t cache, int size_expr) + bool fold_conversions, scev_info_hash_table_type cache, + int size_expr) { /* Give up if the expression is larger than the MAX that we allow. */ if (size_expr++ > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE)) @@ -2705,7 +2749,8 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, tree chrec) { tree res; - htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info); + scev_info_hash_table_type cache; + cache.create (10); if (dump_file && (dump_flags & TDF_SCEV)) { @@ -2727,7 +2772,7 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, fprintf (dump_file, "))\n"); } - htab_delete (cache); + cache.dispose (); return res; } @@ -2740,10 +2785,11 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, tree resolve_mixers (struct loop *loop, tree chrec) { - htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info); + scev_info_hash_table_type cache; + cache.create (10); tree ret = instantiate_scev_r (block_before_loop (loop), loop, NULL, chrec, true, cache, 0); - htab_delete (cache); + cache.dispose (); return ret; } diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index a148a600017..23a4f142783 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "alloc-pool.h" #include "tm.h" #include "tree.h" @@ -269,18 +270,44 @@ static alloc_pool link_pool; /* Base (tree) -> Vector (vec<access_p> *) map. */ static struct pointer_map_t *base_access_vec; +/* Candidate hash table helpers. */ + +struct uid_decl_hasher : typed_noop_remove <tree_node> +{ + typedef tree_node value_type; + typedef tree_node compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hash a tree in a uid_decl_map. */ + +inline hashval_t +uid_decl_hasher::hash (const value_type *item) +{ + return item->decl_minimal.uid; +} + +/* Return true if the DECL_UID in both trees are equal. */ + +inline bool +uid_decl_hasher::equal (const value_type *a, const compare_type *b) +{ + return (a->decl_minimal.uid == b->decl_minimal.uid); +} + /* Set of candidates. */ static bitmap candidate_bitmap; -static htab_t candidates; +static hash_table <uid_decl_hasher> candidates; /* For a candidate UID return the candidates decl. */ static inline tree candidate (unsigned uid) { - struct tree_decl_minimal t; - t.uid = uid; - return (tree) htab_find_with_hash (candidates, &t, uid); + tree_node t; + t.decl_minimal.uid = uid; + return candidates.find_with_hash (&t, static_cast <hashval_t> (uid)); } /* Bitmap of candidates which we should try to entirely scalarize away and @@ -611,8 +638,7 @@ static void sra_initialize (void) { candidate_bitmap = BITMAP_ALLOC (NULL); - candidates = htab_create (vec_safe_length (cfun->local_decls) / 2, - uid_decl_map_hash, uid_decl_map_eq, NULL); + candidates.create (vec_safe_length (cfun->local_decls) / 2); should_scalarize_away_bitmap = BITMAP_ALLOC (NULL); cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL); gcc_obstack_init (&name_obstack); @@ -642,7 +668,7 @@ static void sra_deinitialize (void) { BITMAP_FREE (candidate_bitmap); - htab_delete (candidates); + candidates.dispose (); BITMAP_FREE (should_scalarize_away_bitmap); BITMAP_FREE (cannot_scalarize_away_bitmap); free_alloc_pool (access_pool); @@ -659,9 +685,9 @@ static void disqualify_candidate (tree decl, const char *reason) { if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl))) - htab_clear_slot (candidates, - htab_find_slot_with_hash (candidates, decl, - DECL_UID (decl), NO_INSERT)); + candidates.clear_slot (candidates.find_slot_with_hash (decl, + DECL_UID (decl), + NO_INSERT)); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1680,7 +1706,7 @@ maybe_add_sra_candidate (tree var) { tree type = TREE_TYPE (var); const char *msg; - void **slot; + tree_node **slot; if (!AGGREGATE_TYPE_P (type)) { @@ -1728,8 +1754,8 @@ maybe_add_sra_candidate (tree var) } bitmap_set_bit (candidate_bitmap, DECL_UID (var)); - slot = htab_find_slot_with_hash (candidates, var, DECL_UID (var), INSERT); - *slot = (void *) var; + slot = candidates.find_slot_with_hash (var, DECL_UID (var), INSERT); + *slot = var; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3587,7 +3613,7 @@ find_param_candidates (void) parm = DECL_CHAIN (parm)) { tree type = TREE_TYPE (parm); - void **slot; + tree_node **slot; count++; @@ -3626,9 +3652,8 @@ find_param_candidates (void) continue; bitmap_set_bit (candidate_bitmap, DECL_UID (parm)); - slot = htab_find_slot_with_hash (candidates, parm, - DECL_UID (parm), INSERT); - *slot = (void *) parm; + slot = candidates.find_slot_with_hash (parm, DECL_UID (parm), INSERT); + *slot = parm; ret = true; if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index d650d95f23e..602289d7886 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tm.h" #include "tree.h" #include "flags.h" @@ -101,15 +102,6 @@ struct edge_info vec<cond_equivalence> cond_equivalences; }; -/* Hash table with expressions made available during the renaming process. - When an assignment of the form X_i = EXPR is found, the statement is - stored in this table. If the same expression EXPR is later found on the - RHS of another statement, it is replaced with X_i (thus performing - global redundancy elimination). Similarly as we pass through conditionals - we record the conditional itself as having either a true or false value - in this table. */ -static htab_t avail_exprs; - /* Stack of available expressions in AVAIL_EXPRs. Each block pushes any expressions it enters into the hash table along with a marker entry (null). When we finish processing the block, we pop off entries and @@ -140,6 +132,81 @@ struct expr_hash_elt struct expr_hash_elt *stamp; }; +/* Hashtable helpers. */ + +static bool hashable_expr_equal_p (const struct hashable_expr *, + const struct hashable_expr *); +static void free_expr_hash_elt (void *); + +struct expr_elt_hasher +{ + typedef expr_hash_elt value_type; + typedef expr_hash_elt compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; + +inline hashval_t +expr_elt_hasher::hash (const value_type *p) +{ + return p->hash; +} + +inline bool +expr_elt_hasher::equal (const value_type *p1, const compare_type *p2) +{ + gimple stmt1 = p1->stmt; + const struct hashable_expr *expr1 = &p1->expr; + const struct expr_hash_elt *stamp1 = p1->stamp; + gimple stmt2 = p2->stmt; + const struct hashable_expr *expr2 = &p2->expr; + const struct expr_hash_elt *stamp2 = p2->stamp; + + /* This case should apply only when removing entries from the table. */ + if (stamp1 == stamp2) + return true; + + /* FIXME tuples: + We add stmts to a hash table and them modify them. To detect the case + that we modify a stmt and then search for it, we assume that the hash + is always modified by that change. + We have to fully check why this doesn't happen on trunk or rewrite + this in a more reliable (and easier to understand) way. */ + if (((const struct expr_hash_elt *)p1)->hash + != ((const struct expr_hash_elt *)p2)->hash) + return false; + + /* In case of a collision, both RHS have to be identical and have the + same VUSE operands. */ + if (hashable_expr_equal_p (expr1, expr2) + && types_compatible_p (expr1->type, expr2->type)) + { + /* Note that STMT1 and/or STMT2 may be NULL. */ + return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE) + == (stmt2 ? gimple_vuse (stmt2) : NULL_TREE)); + } + + return false; +} + +/* Delete an expr_hash_elt and reclaim its storage. */ + +inline void +expr_elt_hasher::remove (value_type *element) +{ + free_expr_hash_elt (element); +} + +/* Hash table with expressions made available during the renaming process. + When an assignment of the form X_i = EXPR is found, the statement is + stored in this table. If the same expression EXPR is later found on the + RHS of another statement, it is replaced with X_i (thus performing + global redundancy elimination). Similarly as we pass through conditionals + we record the conditional itself as having either a true or false value + in this table. */ +static hash_table <expr_elt_hasher> avail_exprs; + /* Stack of dest,src pairs that need to be restored during finalization. A NULL entry is used to mark the end of pairs which need to be @@ -169,9 +236,7 @@ static struct opt_stats_d opt_stats; static void optimize_stmt (basic_block, gimple_stmt_iterator); static tree lookup_avail_expr (gimple, bool); static hashval_t avail_expr_hash (const void *); -static hashval_t real_avail_expr_hash (const void *); -static int avail_expr_eq (const void *, const void *); -static void htab_statistics (FILE *, htab_t); +static void htab_statistics (FILE *, hash_table <expr_elt_hasher>); static void record_cond (cond_equivalence *); static void record_const_or_copy (tree, tree); static void record_equality (tree, tree); @@ -722,7 +787,7 @@ tree_ssa_dominator_optimize (void) memset (&opt_stats, 0, sizeof (opt_stats)); /* Create our hash tables. */ - avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free_expr_hash_elt); + avail_exprs.create (1024); avail_exprs_stack.create (20); const_and_copies_stack.create (20); need_eh_cleanup = BITMAP_ALLOC (NULL); @@ -830,7 +895,7 @@ tree_ssa_dominator_optimize (void) loop_optimizer_finalize (); /* Delete our main hashtable. */ - htab_delete (avail_exprs); + avail_exprs.dispose (); /* And finalize the dominator walker. */ fini_walk_dominator_tree (&walk_data); @@ -935,7 +1000,7 @@ remove_local_expressions_from_table (void) while (avail_exprs_stack.length () > 0) { expr_hash_elt_t victim = avail_exprs_stack.pop (); - void **slot; + expr_hash_elt **slot; if (victim == NULL) break; @@ -949,10 +1014,9 @@ remove_local_expressions_from_table (void) print_expr_hash_elt (dump_file, victim); } - slot = htab_find_slot_with_hash (avail_exprs, - victim, victim->hash, NO_INSERT); - gcc_assert (slot && *slot == (void *) victim); - htab_clear_slot (avail_exprs, slot); + slot = avail_exprs.find_slot_with_hash (victim, victim->hash, NO_INSERT); + gcc_assert (slot && *slot == victim); + avail_exprs.clear_slot (slot); } } @@ -1203,12 +1267,12 @@ debug_dominator_optimization_stats (void) /* Dump statistics for the hash table HTAB. */ static void -htab_statistics (FILE *file, htab_t htab) +htab_statistics (FILE *file, hash_table <expr_elt_hasher> htab) { fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n", - (long) htab_size (htab), - (long) htab_elements (htab), - htab_collisions (htab)); + (long) htab.size (), + (long) htab.elements (), + htab.collisions ()); } @@ -1220,15 +1284,14 @@ static void record_cond (cond_equivalence *p) { struct expr_hash_elt *element = XCNEW (struct expr_hash_elt); - void **slot; + expr_hash_elt **slot; initialize_hash_element_from_expr (&p->cond, p->value, element); - slot = htab_find_slot_with_hash (avail_exprs, (void *)element, - element->hash, INSERT); + slot = avail_exprs.find_slot_with_hash (element, element->hash, INSERT); if (*slot == NULL) { - *slot = (void *) element; + *slot = element; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -2404,7 +2467,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si) static tree lookup_avail_expr (gimple stmt, bool insert) { - void **slot; + expr_hash_elt **slot; tree lhs; tree temp; struct expr_hash_elt element; @@ -2432,8 +2495,8 @@ lookup_avail_expr (gimple stmt, bool insert) return NULL_TREE; /* Finally try to find the expression in the main expression hash table. */ - slot = htab_find_slot_with_hash (avail_exprs, &element, element.hash, - (insert ? INSERT : NO_INSERT)); + slot = avail_exprs.find_slot_with_hash (&element, element.hash, + (insert ? INSERT : NO_INSERT)); if (slot == NULL) { free_expr_hash_elt_contents (&element); @@ -2444,7 +2507,7 @@ lookup_avail_expr (gimple stmt, bool insert) struct expr_hash_elt *element2 = XNEW (struct expr_hash_elt); *element2 = element; element2->stamp = element2; - *slot = (void *) element2; + *slot = element2; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -2511,49 +2574,6 @@ avail_expr_hash (const void *p) return val; } -static hashval_t -real_avail_expr_hash (const void *p) -{ - return ((const struct expr_hash_elt *)p)->hash; -} - -static int -avail_expr_eq (const void *p1, const void *p2) -{ - gimple stmt1 = ((const struct expr_hash_elt *)p1)->stmt; - const struct hashable_expr *expr1 = &((const struct expr_hash_elt *)p1)->expr; - const struct expr_hash_elt *stamp1 = ((const struct expr_hash_elt *)p1)->stamp; - gimple stmt2 = ((const struct expr_hash_elt *)p2)->stmt; - const struct hashable_expr *expr2 = &((const struct expr_hash_elt *)p2)->expr; - const struct expr_hash_elt *stamp2 = ((const struct expr_hash_elt *)p2)->stamp; - - /* This case should apply only when removing entries from the table. */ - if (stamp1 == stamp2) - return true; - - /* FIXME tuples: - We add stmts to a hash table and them modify them. To detect the case - that we modify a stmt and then search for it, we assume that the hash - is always modified by that change. - We have to fully check why this doesn't happen on trunk or rewrite - this in a more reliable (and easier to understand) way. */ - if (((const struct expr_hash_elt *)p1)->hash - != ((const struct expr_hash_elt *)p2)->hash) - return false; - - /* In case of a collision, both RHS have to be identical and have the - same VUSE operands. */ - if (hashable_expr_equal_p (expr1, expr2) - && types_compatible_p (expr1->type, expr2->type)) - { - /* Note that STMT1 and/or STMT2 may be NULL. */ - return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE) - == (stmt2 ? gimple_vuse (stmt2) : NULL_TREE)); - } - - return false; -} - /* PHI-ONLY copy and constant propagation. This pass is meant to clean up degenerate PHIs created by or exposed by jump threading. */ diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index c8b9ce8b016..83a52a0482c 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tm.h" #include "tree.h" #include "gimple-pretty-print.h" @@ -53,6 +54,29 @@ static void verify_live_on_entry (tree_live_info_p); ssa_name or variable, and vice versa. */ +/* Hashtable helpers. */ + +struct tree_int_map_hasher : typed_noop_remove <tree_int_map> +{ + typedef tree_int_map value_type; + typedef tree_int_map compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +inline hashval_t +tree_int_map_hasher::hash (const value_type *v) +{ + return tree_map_base_hash (v); +} + +inline bool +tree_int_map_hasher::equal (const value_type *v, const compare_type *c) +{ + return tree_int_map_eq (v, c); +} + + /* This routine will initialize the basevar fields of MAP. */ static void @@ -60,12 +84,11 @@ var_map_base_init (var_map map) { int x, num_part; tree var; - htab_t tree_to_index; + hash_table <tree_int_map_hasher> tree_to_index; struct tree_int_map *m, *mapstorage; num_part = num_var_partitions (map); - tree_to_index = htab_create (num_part, tree_map_base_hash, - tree_int_map_eq, NULL); + tree_to_index.create (num_part); /* We can have at most num_part entries in the hash tables, so it's enough to allocate so many map elements once, saving some malloc calls. */ @@ -91,8 +114,7 @@ var_map_base_init (var_map map) underlying decl. */ m->base.from = TREE_TYPE (var); /* If base variable hasn't been seen, set it up. */ - slot = (struct tree_int_map **) htab_find_slot (tree_to_index, - m, INSERT); + slot = tree_to_index.find_slot (m, INSERT); if (!*slot) { baseindex = m - mapstorage; @@ -108,7 +130,7 @@ var_map_base_init (var_map map) map->num_basevars = m - mapstorage; free (mapstorage); - htab_delete (tree_to_index); + tree_to_index. dispose (); } diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 0099275d49f..7cfe80d9213 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -75,7 +75,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "insn-config.h" #include "pointer-set.h" -#include "hashtab.h" +#include "hash-table.h" #include "tree-chrec.h" #include "tree-scalar-evolution.h" #include "cfgloop.h" @@ -236,6 +236,33 @@ typedef struct iv_use *iv_use_p; typedef struct iv_cand *iv_cand_p; +/* Hashtable helpers. */ + +struct iv_inv_expr_hasher : typed_free_remove <iv_inv_expr_ent> +{ + typedef iv_inv_expr_ent value_type; + typedef iv_inv_expr_ent compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hash function for loop invariant expressions. */ + +inline hashval_t +iv_inv_expr_hasher::hash (const value_type *expr) +{ + return expr->hash; +} + +/* Hash table equality function for expressions. */ + +inline bool +iv_inv_expr_hasher::equal (const value_type *expr1, const compare_type *expr2) +{ + return expr1->hash == expr2->hash + && operand_equal_p (expr1->expr, expr2->expr, 0); +} + struct ivopts_data { /* The currently optimized loop. */ @@ -255,7 +282,7 @@ struct ivopts_data /* The hashtable of loop invariant expressions created by ivopt. */ - htab_t inv_expr_tab; + hash_table <iv_inv_expr_hasher> inv_expr_tab; /* Loop invariant expression id. */ int inv_expr_id; @@ -814,30 +841,6 @@ niter_for_single_dom_exit (struct ivopts_data *data) return niter_for_exit (data, exit); } -/* Hash table equality function for expressions. */ - -static int -htab_inv_expr_eq (const void *ent1, const void *ent2) -{ - const struct iv_inv_expr_ent *expr1 = - (const struct iv_inv_expr_ent *)ent1; - const struct iv_inv_expr_ent *expr2 = - (const struct iv_inv_expr_ent *)ent2; - - return expr1->hash == expr2->hash - && operand_equal_p (expr1->expr, expr2->expr, 0); -} - -/* Hash function for loop invariant expressions. */ - -static hashval_t -htab_inv_expr_hash (const void *ent) -{ - const struct iv_inv_expr_ent *expr = - (const struct iv_inv_expr_ent *)ent; - return expr->hash; -} - /* Initializes data structures used by the iv optimization pass, stored in DATA. */ @@ -852,8 +855,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data) data->niters = NULL; data->iv_uses.create (20); data->iv_candidates.create (20); - data->inv_expr_tab = htab_create (10, htab_inv_expr_hash, - htab_inv_expr_eq, free); + data->inv_expr_tab.create (10); data->inv_expr_id = 0; decl_rtl_to_reset.create (20); } @@ -3850,8 +3852,7 @@ get_expr_id (struct ivopts_data *data, tree expr) ent.expr = expr; ent.hash = iterative_hash_expr (expr, 0); - slot = (struct iv_inv_expr_ent **) htab_find_slot (data->inv_expr_tab, - &ent, INSERT); + slot = data->inv_expr_tab.find_slot (&ent, INSERT); if (*slot) return (*slot)->id; @@ -6653,7 +6654,7 @@ free_loop_data (struct ivopts_data *data) decl_rtl_to_reset.truncate (0); - htab_empty (data->inv_expr_tab); + data->inv_expr_tab.empty (); data->inv_expr_id = 0; } @@ -6671,7 +6672,7 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data) decl_rtl_to_reset.release (); data->iv_uses.release (); data->iv_candidates.release (); - htab_delete (data->inv_expr_tab); + data->inv_expr_tab.dispose (); } /* Returns true if the loop body BODY includes any function calls. */ diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 91df10714e5..739e48e432b 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tm.h" #include "ggc.h" #include "tree.h" @@ -1239,8 +1240,15 @@ struct name_to_bb basic_block bb; }; -/* The hash table for remembering what we've seen. */ -static htab_t seen_ssa_names; +/* Hashtable helpers. */ + +struct ssa_names_hasher : typed_free_remove <name_to_bb> +{ + typedef name_to_bb value_type; + typedef name_to_bb compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; /* Used for quick clearing of the hash-table when we see calls. Hash entries with phase < nt_call_phase are invalid. */ @@ -1250,27 +1258,28 @@ static unsigned int nt_call_phase; static struct pointer_set_t *nontrap_set; /* The hash function. */ -static hashval_t -name_to_bb_hash (const void *p) + +inline hashval_t +ssa_names_hasher::hash (const value_type *n) { - const struct name_to_bb *n = (const struct name_to_bb *) p; return n->ssa_name_ver ^ (((hashval_t) n->store) << 31) ^ (n->offset << 6) ^ (n->size << 3); } /* The equality function of *P1 and *P2. */ -static int -name_to_bb_eq (const void *p1, const void *p2) -{ - const struct name_to_bb *n1 = (const struct name_to_bb *)p1; - const struct name_to_bb *n2 = (const struct name_to_bb *)p2; +inline bool +ssa_names_hasher::equal (const value_type *n1, const compare_type *n2) +{ return n1->ssa_name_ver == n2->ssa_name_ver && n1->store == n2->store && n1->offset == n2->offset && n1->size == n2->size; } +/* The hash table for remembering what we've seen. */ +static hash_table <ssa_names_hasher> seen_ssa_names; + /* We see the expression EXP in basic block BB. If it's an interesting expression (an MEM_REF through an SSA_NAME) possibly insert the expression into the set NONTRAP or the hash table of seen expressions. @@ -1289,7 +1298,7 @@ add_or_mark_expr (basic_block bb, tree exp, { tree name = TREE_OPERAND (exp, 0); struct name_to_bb map; - void **slot; + name_to_bb **slot; struct name_to_bb *n2bb; basic_block found_bb = 0; @@ -1302,8 +1311,8 @@ add_or_mark_expr (basic_block bb, tree exp, map.offset = tree_low_cst (TREE_OPERAND (exp, 1), 0); map.size = size; - slot = htab_find_slot (seen_ssa_names, &map, INSERT); - n2bb = (struct name_to_bb *) *slot; + slot = seen_ssa_names.find_slot (&map, INSERT); + n2bb = *slot; if (n2bb && n2bb->phase >= nt_call_phase) found_bb = n2bb->bb; @@ -1413,8 +1422,7 @@ get_non_trapping (void) nt_call_phase = 0; nontrap = pointer_set_create (); - seen_ssa_names = htab_create (128, name_to_bb_hash, name_to_bb_eq, - free); + seen_ssa_names.create (128); /* We're going to do a dominator walk, so ensure that we have dominance information. */ calculate_dominance_info (CDI_DOMINATORS); @@ -1431,7 +1439,7 @@ get_non_trapping (void) init_walk_dominator_tree (&walk_data); walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); fini_walk_dominator_tree (&walk_data); - htab_delete (seen_ssa_names); + seen_ssa_names.dispose (); clear_aux_for_blocks (); return nontrap; diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 9c724dc43cb..bea0c28ad45 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "hash-table.h" #include "tree-flow.h" #include "tree-pass.h" #include "domwalk.h" @@ -111,9 +112,33 @@ struct decl_stridxlist_map struct stridxlist list; }; +/* stridxlist hashtable helpers. */ + +struct stridxlist_hasher : typed_noop_remove <decl_stridxlist_map> +{ + typedef decl_stridxlist_map value_type; + typedef decl_stridxlist_map compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); +}; + +/* Hash a from tree in a decl_stridxlist_map. */ + +inline hashval_t +stridxlist_hasher::hash (const value_type *item) +{ + return DECL_UID (item->base.from); +} + +inline bool +stridxlist_hasher::equal (const value_type *v, const compare_type *c) +{ + return tree_map_base_eq (&v->base, &c->base); +} + /* Hash table for mapping decls to a chained list of offset -> idx mappings. */ -static htab_t decl_to_stridxlist_htab; +static hash_table <stridxlist_hasher> decl_to_stridxlist_htab; /* Obstack for struct stridxlist and struct decl_stridxlist_map. */ static struct obstack stridx_obstack; @@ -128,14 +153,6 @@ struct laststmt_struct int stridx; } laststmt; -/* Hash a from tree in a decl_stridxlist_map. */ - -static unsigned int -decl_to_stridxlist_hash (const void *item) -{ - return DECL_UID (((const struct decl_stridxlist_map *) item)->base.from); -} - /* Helper function for get_stridx. */ static int @@ -146,7 +163,7 @@ get_addr_stridx (tree exp) struct stridxlist *list; tree base; - if (decl_to_stridxlist_htab == NULL) + if (!decl_to_stridxlist_htab.is_created ()) return 0; base = get_addr_base_and_unit_offset (exp, &off); @@ -154,8 +171,7 @@ get_addr_stridx (tree exp) return 0; ent.base.from = base; - e = (struct decl_stridxlist_map *) - htab_find_with_hash (decl_to_stridxlist_htab, &ent, DECL_UID (base)); + e = decl_to_stridxlist_htab.find_with_hash (&ent, DECL_UID (base)); if (e == NULL) return 0; @@ -234,7 +250,7 @@ unshare_strinfo_vec (void) static int * addr_stridxptr (tree exp) { - void **slot; + decl_stridxlist_map **slot; struct decl_stridxlist_map ent; struct stridxlist *list; HOST_WIDE_INT off; @@ -243,19 +259,18 @@ addr_stridxptr (tree exp) if (base == NULL_TREE || !DECL_P (base)) return NULL; - if (decl_to_stridxlist_htab == NULL) + if (!decl_to_stridxlist_htab.is_created ()) { - decl_to_stridxlist_htab - = htab_create (64, decl_to_stridxlist_hash, tree_map_base_eq, NULL); + decl_to_stridxlist_htab.create (64); gcc_obstack_init (&stridx_obstack); } ent.base.from = base; - slot = htab_find_slot_with_hash (decl_to_stridxlist_htab, &ent, - DECL_UID (base), INSERT); + slot = decl_to_stridxlist_htab.find_slot_with_hash (&ent, DECL_UID (base), + INSERT); if (*slot) { int i; - list = &((struct decl_stridxlist_map *)*slot)->list; + list = &(*slot)->list; for (i = 0; i < 16; i++) { if (list->offset == off) @@ -273,7 +288,7 @@ addr_stridxptr (tree exp) struct decl_stridxlist_map *e = XOBNEW (&stridx_obstack, struct decl_stridxlist_map); e->base.from = base; - *slot = (void *) e; + *slot = e; list = &e->list; } list->next = NULL; @@ -1985,11 +2000,10 @@ tree_ssa_strlen (void) ssa_ver_to_stridx.release (); free_alloc_pool (strinfo_pool); - if (decl_to_stridxlist_htab) + if (decl_to_stridxlist_htab.is_created ()) { obstack_free (&stridx_obstack, NULL); - htab_delete (decl_to_stridxlist_htab); - decl_to_stridxlist_htab = NULL; + decl_to_stridxlist_htab.dispose (); } laststmt.stmt = NULL; laststmt.len = NULL_TREE; diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index c7eed9e4e0f..1fbc524e57f 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -265,11 +265,6 @@ associate_equivalences_with_edges (void) subtree rooted at the block where we record the equivalency. */ static vec<tree> equiv_stack; -/* Global hash table implementing a mapping from invariant values - to a list of SSA_NAMEs which have the same value. We might be - able to reuse tree-vn for this code. */ -static htab_t equiv; - /* Main structure for recording equivalences into our hash table. */ struct equiv_hash_elt { @@ -280,53 +275,66 @@ struct equiv_hash_elt vec<tree> equivalences; }; -static void uncprop_enter_block (struct dom_walk_data *, basic_block); -static void uncprop_leave_block (struct dom_walk_data *, basic_block); -static void uncprop_into_successor_phis (basic_block); +/* Value to ssa name equivalence hashtable helpers. */ -/* Hashing and equality routines for the hash table. */ +struct val_ssa_equiv_hasher +{ + typedef equiv_hash_elt value_type; + typedef equiv_hash_elt compare_type; + static inline hashval_t hash (const value_type *); + static inline bool equal (const value_type *, const compare_type *); + static inline void remove (value_type *); +}; -static hashval_t -equiv_hash (const void *p) +inline hashval_t +val_ssa_equiv_hasher::hash (const value_type *p) { - tree const value = ((const struct equiv_hash_elt *)p)->value; + tree const value = p->value; return iterative_hash_expr (value, 0); } -static int -equiv_eq (const void *p1, const void *p2) +inline bool +val_ssa_equiv_hasher::equal (const value_type *p1, const compare_type *p2) { - tree value1 = ((const struct equiv_hash_elt *)p1)->value; - tree value2 = ((const struct equiv_hash_elt *)p2)->value; + tree value1 = p1->value; + tree value2 = p2->value; return operand_equal_p (value1, value2, 0); } /* Free an instance of equiv_hash_elt. */ -static void -equiv_free (void *p) +inline void +val_ssa_equiv_hasher::remove (value_type *elt) { - struct equiv_hash_elt *elt = (struct equiv_hash_elt *) p; elt->equivalences.release (); free (elt); } +/* Global hash table implementing a mapping from invariant values + to a list of SSA_NAMEs which have the same value. We might be + able to reuse tree-vn for this code. */ +static hash_table <val_ssa_equiv_hasher> val_ssa_equiv; + +static void uncprop_enter_block (struct dom_walk_data *, basic_block); +static void uncprop_leave_block (struct dom_walk_data *, basic_block); +static void uncprop_into_successor_phis (basic_block); + /* Remove the most recently recorded equivalency for VALUE. */ static void remove_equivalence (tree value) { - struct equiv_hash_elt equiv_hash_elt, *equiv_hash_elt_p; - void **slot; + struct equiv_hash_elt an_equiv_elt, *an_equiv_elt_p; + equiv_hash_elt **slot; - equiv_hash_elt.value = value; - equiv_hash_elt.equivalences.create (0); + an_equiv_elt.value = value; + an_equiv_elt.equivalences.create (0); - slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT); + slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT); - equiv_hash_elt_p = (struct equiv_hash_elt *) *slot; - equiv_hash_elt_p->equivalences.pop (); + an_equiv_elt_p = *slot; + an_equiv_elt_p->equivalences.pop (); } /* Record EQUIVALENCE = VALUE into our hash table. */ @@ -334,23 +342,23 @@ remove_equivalence (tree value) static void record_equiv (tree value, tree equivalence) { - struct equiv_hash_elt *equiv_hash_elt; - void **slot; + equiv_hash_elt *an_equiv_elt_p; + equiv_hash_elt **slot; - equiv_hash_elt = XNEW (struct equiv_hash_elt); - equiv_hash_elt->value = value; - equiv_hash_elt->equivalences.create (0); + an_equiv_elt_p = XNEW (struct equiv_hash_elt); + an_equiv_elt_p->value = value; + an_equiv_elt_p->equivalences.create (0); - slot = htab_find_slot (equiv, equiv_hash_elt, INSERT); + slot = val_ssa_equiv.find_slot (an_equiv_elt_p, INSERT); if (*slot == NULL) - *slot = (void *) equiv_hash_elt; + *slot = an_equiv_elt_p; else - free (equiv_hash_elt); + free (an_equiv_elt_p); - equiv_hash_elt = (struct equiv_hash_elt *) *slot; + an_equiv_elt_p = *slot; - equiv_hash_elt->equivalences.safe_push (equivalence); + an_equiv_elt_p->equivalences.safe_push (equivalence); } /* Main driver for un-cprop. */ @@ -364,7 +372,7 @@ tree_ssa_uncprop (void) associate_equivalences_with_edges (); /* Create our global data structures. */ - equiv = htab_create (1024, equiv_hash, equiv_eq, equiv_free); + val_ssa_equiv.create (1024); equiv_stack.create (2); /* We're going to do a dominator walk, so ensure that we have @@ -392,7 +400,7 @@ tree_ssa_uncprop (void) /* EQUIV_STACK should already be empty at this point, so we just need to empty elements out of the hash table, free EQUIV_STACK, and cleanup the AUX field on the edges. */ - htab_delete (equiv); + val_ssa_equiv.dispose (); equiv_stack.release (); FOR_EACH_BB (bb) { @@ -463,8 +471,8 @@ uncprop_into_successor_phis (basic_block bb) gimple phi = gsi_stmt (gsi); tree arg = PHI_ARG_DEF (phi, e->dest_idx); tree res = PHI_RESULT (phi); - struct equiv_hash_elt equiv_hash_elt; - void **slot; + equiv_hash_elt an_equiv_elt; + equiv_hash_elt **slot; /* If the argument is not an invariant, and refers to the same underlying variable as the PHI result, then there's no @@ -475,13 +483,13 @@ uncprop_into_successor_phis (basic_block bb) continue; /* Lookup this argument's value in the hash table. */ - equiv_hash_elt.value = arg; - equiv_hash_elt.equivalences.create (0); - slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT); + an_equiv_elt.value = arg; + an_equiv_elt.equivalences.create (0); + slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT); if (slot) { - struct equiv_hash_elt *elt = (struct equiv_hash_elt *) *slot; + struct equiv_hash_elt *elt = *slot; int j; /* Walk every equivalence with the same value. If we find diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index b0619faefd5..15a91766892 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1046,42 +1046,6 @@ err: internal_error ("verify_ssa failed"); } -/* Return true if the uid in both int tree maps are equal. */ - -int -int_tree_map_eq (const void *va, const void *vb) -{ - const struct int_tree_map *a = (const struct int_tree_map *) va; - const struct int_tree_map *b = (const struct int_tree_map *) vb; - return (a->uid == b->uid); -} - -/* Hash a UID in a int_tree_map. */ - -unsigned int -int_tree_map_hash (const void *item) -{ - return ((const struct int_tree_map *)item)->uid; -} - -/* Return true if the DECL_UID in both trees are equal. */ - -int -uid_decl_map_eq (const void *va, const void *vb) -{ - const_tree a = (const_tree) va; - const_tree b = (const_tree) vb; - return (a->decl_minimal.uid == b->decl_minimal.uid); -} - -/* Hash a tree in a uid_decl_map. */ - -unsigned int -uid_decl_map_hash (const void *item) -{ - return ((const_tree)item)->decl_minimal.uid; -} - /* Return true if the DECL_UID in both trees are equal. */ static int |