This patch is the main part of a consolodation of the hash_table patches to the...

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.

From-SVN: r198329
This commit is contained in:
Lawrence Crowl 2013-04-26 00:28:35 +00:00 committed by Lawrence Crowl
parent 11dae3ad79
commit 4a8fb1a1de
55 changed files with 2577 additions and 1848 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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)

View File

@ -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));
}

View File

@ -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",

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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)
{
const struct cu_hash_table_entry *const entry =
(const struct cu_hash_table_entry *) of;
/* Helpers to manipulate hash table of CUs. */
struct cu_hash_table_entry_hasher
{
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>
{
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;
const comdat_type_node *const type_node = (const comdat_type_node *) of;
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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)
{
const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
/* Helper for ptr_hash table. */
struct ptr_hash_hasher : typed_noop_remove <ptr_hash_entry>
{
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++)

View File

@ -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;
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 *);
};
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 when an element is removed from the hash table.
We never remove entries until the entire table is released. */
static void
base_cand_free (void *p ATTRIBUTE_UNUSED)
inline bool
cand_chain_hasher::equal (const value_type *chain1, const compare_type *chain2)
{
}
/* Callback to return true if two candidate chain headers are equal. */
static int
base_cand_eq (const void *p1, const void *p2)
{
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 ();

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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

View File

@ -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;

60
gcc/graphite-htab.h Normal file
View File

@ -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

View File

@ -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 *);

View File

@ -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;

View File

@ -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 ();
}
}

View File

@ -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 ();
}

View File

@ -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)
{
const_cost_classes_t hv = (const_cost_classes_t) v;
/* Helper for cost_classes hashing. */
struct cost_classes_hasher
{
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 ();
}

View File

@ -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

View File

@ -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);
bivs.empty ();
}
/* Returns hash value for biv B. */
static hashval_t
biv_hash (const void *b)
{
return ((const struct biv_entry *) b)->regno;
}
/* 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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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. */

View File

@ -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;

View File

@ -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];

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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;
/* Log entry hashtable helpers. */
/* 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
};
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;
}

View File

@ -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

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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)])

55
gcc/tree-hasher.h Normal file
View File

@ -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 */

View File

@ -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. */
};
/* Reduction info hashtable helpers. */
struct reduction_hasher : typed_free_remove <reduction_info>
{
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. */
static int
reduction_info_eq (const void *aa, const void *bb)
inline bool
reduction_hasher::equal (const value_type *a, const compare_type *b)
{
const struct reduction_info *a = (const struct reduction_info *) aa;
const struct reduction_info *b = (const struct reduction_info *) bb;
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. */
};
/* Name copies hashtable helpers. */
struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt>
{
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. */
static int
name_to_copy_elt_eq (const void *aa, const void *bb)
inline bool
name_to_copy_hasher::equal (const value_type *a, const compare_type *b)
{
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;
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

View File

@ -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;
}

View File

@ -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))

View File

@ -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. */

View File

@ -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 ();
}

View File

@ -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. */

View File

@ -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;

View File

@ -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;

View File

@ -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. */
static hashval_t
equiv_hash (const void *p)
struct val_ssa_equiv_hasher
{
tree const value = ((const struct equiv_hash_elt *)p)->value;
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 *);
};
inline hashval_t
val_ssa_equiv_hasher::hash (const value_type *p)
{
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

View File

@ -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