+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
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)
$(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)
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) \
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)
#\f
# Now figure out from those variables how to compile and link.
# 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) \
$(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 \
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) \
$(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) \
$(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 \
$(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) \
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
$(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) \
$(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) \
$(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) \
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) \
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
$(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)
$(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) \
$(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
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) \
$(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
$(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)
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)
$(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) \
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 \
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) \
$(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)
$(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 \
$(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) \
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)
$(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)
$(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 \
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) \
$(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) \
$(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 \
int elt_size;
};
+/* Hashtable helpers. */
struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor>
{
typedef alloc_pool_descriptor value_type;
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)
{
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)
#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)
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. */
}
}
-/* 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
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. */
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);
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
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));
}
#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. */
/* 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;
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)
if (! GATHER_STATISTICS)
return;
- if (!bitmap_desc_hash)
+ if (!bitmap_desc_hash.is_created ())
return;
fprintf (stderr,
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",
#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"
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);
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. */
/* 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;
}
}
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);
}
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
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;
/* 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))
{
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--;
}
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);
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);
}
{
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;
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;
/* 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;
}
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 ();
}
}
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;
}
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);
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);
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;
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);
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)
#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"
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;
}
\f
-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
/* 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;
}
}
}
trace_info.release ();
- htab_delete (trace_index);
- trace_index = NULL;
+ trace_index.dispose ();
return 0;
}
#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"
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);
struct cu_hash_table_entry *next;
};
-/* Routines to manipulate hash table of CUs. */
-static hashval_t
-htab_cu_hash (const void *of)
+/* Helpers to manipulate hash table of CUs. */
+
+struct cu_hash_table_entry_hasher
{
- const struct cu_hash_table_entry *const entry =
- (const struct cu_hash_table_entry *) of;
+ typedef cu_hash_table_entry value_type;
+ typedef die_struct compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+inline hashval_t
+cu_hash_table_entry_hasher::hash (const value_type *entry)
+{
return htab_hash_string (entry->cu->die_id.die_symbol);
}
-static int
-htab_cu_eq (const void *of1, const void *of2)
+inline bool
+cu_hash_table_entry_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
{
- const struct cu_hash_table_entry *const entry1 =
- (const struct cu_hash_table_entry *) of1;
- const struct die_struct *const entry2 = (const struct die_struct *) of2;
-
return !strcmp (entry1->cu->die_id.die_symbol, entry2->die_id.die_symbol);
}
-static void
-htab_cu_del (void *what)
+inline void
+cu_hash_table_entry_hasher::remove (value_type *entry)
{
- struct cu_hash_table_entry *next,
- *entry = (struct cu_hash_table_entry *) what;
+ struct cu_hash_table_entry *next;
while (entry)
{
}
}
+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)
/* 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;
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 {
#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)
comdat_symbol_number);
}
}
- htab_delete (cu_hash_table);
+ cu_hash_table.dispose ();
}
/* Return non-zero if this DIE is a declaration. */
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
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);
} 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
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;
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
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);
}
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;
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;
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;
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;
}
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;
{
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)
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;
#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);
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;
}
}
-/* 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
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];
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];
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. */
else
{
*slot = inc;
- inc->lineno = htab_elements (*macinfo_htab);
+ inc->lineno = macinfo_htab->elements ();
output_macinfo_op (inc);
}
return count;
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;
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
return 1;
}
-/* Routines to manipulate hash table of comdat type units. */
+/* Helpers to manipulate hash table of comdat type units. */
-static hashval_t
-htab_ct_hash (const void *of)
+struct comdat_type_hasher : typed_noop_remove <comdat_type_node>
{
- hashval_t h;
- const comdat_type_node *const type_node = (const comdat_type_node *) of;
+ typedef comdat_type_node value_type;
+ typedef comdat_type_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+inline hashval_t
+comdat_type_hasher::hash (const value_type *type_node)
+{
+ hashval_t h;
memcpy (&h, type_node->signature, sizeof (h));
return h;
}
-static int
-htab_ct_eq (const void *of1, const void *of2)
+inline bool
+comdat_type_hasher::equal (const value_type *type_node_1,
+ const compare_type *type_node_2)
{
- const comdat_type_node *const type_node_1 = (const comdat_type_node *) of1;
- const comdat_type_node *const type_node_2 = (const comdat_type_node *) of2;
-
return (! memcmp (type_node_1->signature, type_node_2->signature,
DWARF_TYPE_SIGNATURE_SIZE));
}
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)
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)
/* 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));
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 ();
}
\f
/* Output stuff that dwarf requires at the end of every file,
{
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;
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)
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
#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"
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;
\f
static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
eh_landing_pad *);
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);
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;
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)
{
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)
{
assign_filter_values (void)
{
int i;
- htab_t ttypes, ehspec;
+ ttypes_hash_type ttypes;
+ ehspec_hash_type ehspec;
eh_region r;
eh_catch c;
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)
{
}
}
- htab_delete (ttypes);
- htab_delete (ehspec);
+ ttypes.dispose ();
+ ehspec.dispose ();
}
/* Emit SEQ into basic block just before INSN (that is assumed to be
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;
disp_index++;
}
- htab_delete (ar_hash);
+ ar_hash.dispose ();
return disp_index;
}
return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
}
\f
-/* 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)
{
}
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;
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;
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))
call_site_base = saved_call_site_base;
- htab_delete (ar_hash);
+ ar_hash.dispose ();
return 0;
}
#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"
/* 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
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 *);
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. */
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);
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)
{
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;
}
\f
/* Load Motion for loads which only kill themselves. */
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)
{
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;
}
#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"
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,
\f
/* Functions for saving and restoring GCable memory to disk. */
-static htab_t saving_htab;
-
struct ptr_data
{
void *obj;
#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
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
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
/* 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);
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);
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;
}
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");
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++)
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);
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);
XDELETE (state.ptrs);
XDELETE (this_object);
- htab_delete (saving_htab);
+ saving_htab.dispose ();
}
/* Read the state of the compiler back in from F. */
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;
size_t size;
};
-/* Hash table helpers functions. */
-static hashval_t
-hash_ptr (const void *p)
+/* Helper for ptr_hash table. */
+
+struct ptr_hash_hasher : typed_noop_remove <ptr_hash_entry>
{
- const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
+ typedef ptr_hash_entry value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+inline hashval_t
+ptr_hash_hasher::hash (const value_type *d)
+{
return htab_hash_pointer (d->ptr);
}
-static int
-eq_ptr (const void *p1, const void *p2)
+inline bool
+ptr_hash_hasher::equal (const value_type *p, const compare_type *p2)
{
- const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1;
-
return (p->ptr == p2);
}
+/* Hashtable converting address of allocated field to loc descriptor. */
+static hash_table <ptr_hash_hasher> ptr_hash;
+
/* Return descriptor for given call site, create new one if needed. */
static struct loc_descriptor *
-loc_descriptor (const char *name, int line, const char *function)
+make_loc_descriptor (const char *name, int line, const char *function)
{
struct loc_descriptor loc;
struct loc_descriptor **slot;
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);
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;
/* 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;
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
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);
}
/* 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;
}
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++)
#include "pointer-set.h"
#include "expmed.h"
#include "params.h"
+#include "hash-table.h"
\f
/* Information about a strength reduction candidate. Each statement
in the candidate table represents an expression of one of the
/* 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;
return cand_vec[idx - 1];
}
-/* Callback to produce a hash value for a candidate chain header. */
+/* Helper for hashing a candidate chain header. */
-static hashval_t
-base_cand_hash (const void *p)
+struct cand_chain_hasher : typed_noop_remove <cand_chain>
{
- tree base_expr = ((const_cand_chain_t) p)->base_expr;
- return iterative_hash_expr (base_expr, 0);
-}
-
-/* Callback when an element is removed from the hash table.
- We never remove entries until the entire table is released. */
+ typedef cand_chain value_type;
+ typedef cand_chain compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
-static void
-base_cand_free (void *p ATTRIBUTE_UNUSED)
+inline hashval_t
+cand_chain_hasher::hash (const value_type *p)
{
+ tree base_expr = p->base_expr;
+ return iterative_hash_expr (base_expr, 0);
}
-/* Callback to return true if two candidate chain headers are equal. */
-
-static int
-base_cand_eq (const void *p1, const void *p2)
+inline bool
+cand_chain_hasher::equal (const value_type *chain1, const compare_type *chain2)
{
- const_cand_chain_t const chain1 = (const_cand_chain_t) p1;
- const_cand_chain_t const chain2 = (const_cand_chain_t) p2;
return operand_equal_p (chain1->base_expr, chain2->base_expr, 0);
}
+
+/* Hash table embodying a mapping from base exprs to chains of candidates. */
+static hash_table <cand_chain_hasher> base_cand_map;
\f
/* 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
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)
{
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)
{
/* 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);
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);
}
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. */
/* 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 ();
#define GCC_GIMPLE_H
#include "pointer-set.h"
+#include "hash-table.h"
#include "vec.h"
#include "ggc.h"
#include "basic-block.h"
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;
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;
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);
}
}
-/* 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.
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. */
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;
}
}
#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;
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. */
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;
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;
}
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)
{
/* 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)
{
*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;
-}
-
\f
/* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
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;
{
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);
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);
{
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);
/* 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);
/* 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;
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;
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;
}
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.
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);
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,
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);
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;
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;
}
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;
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;
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);
*/
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);
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;
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);
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
#ifdef HAVE_cloog
#include "graphite-poly.h"
+#include "graphite-htab.h"
/* Add the constraints from the set S to the domain of MAP. */
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;
--- /dev/null
+/* 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
}
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 *);
#include "graphite-scop-detection.h"
#include "graphite-clast-to-gimple.h"
#include "graphite-sese-to-poly.h"
+#include "graphite-htab.h"
CloogState *cloog_state;
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
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))
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;
#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
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;
}
/* 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;
}
*pprev = NULL;
if (first == NULL)
- htab_clear_slot (delay_htab, slot);
+ delay_htab.clear_slot (pslot);
else
*pslot = first;
return 1;
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
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;
}
{
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;
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);
{
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))
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)
{
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);
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);
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 ();
}
}
#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"
/* 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
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. */
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
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 ();
}
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "hash-table.h"
#include "hard-reg-set.h"
#include "rtl.h"
#include "expr.h"
/* Info about cost classes for each pseudo. */
static cost_classes_t *regno_cost_classes;
-/* Returns hash value for cost classes info V. */
-static hashval_t
-cost_classes_hash (const void *v)
+/* Helper for cost_classes hashing. */
+
+struct cost_classes_hasher
{
- const_cost_classes_t hv = (const_cost_classes_t) v;
+ typedef cost_classes value_type;
+ typedef cost_classes compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+/* Returns hash value for cost classes info HV. */
+inline hashval_t
+cost_classes_hasher::hash (const value_type *hv)
+{
return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0);
}
-/* Compares cost classes info V1 and V2. */
-static int
-cost_classes_eq (const void *v1, const void *v2)
+/* Compares cost classes info HV1 and HV2. */
+inline bool
+cost_classes_hasher::equal (const value_type *hv1, const compare_type *hv2)
{
- const_cost_classes_t hv1 = (const_cost_classes_t) v1;
- const_cost_classes_t hv2 = (const_cost_classes_t) v2;
-
return hv1->num == hv2->num && memcmp (hv1->classes, hv2->classes,
sizeof (enum reg_class) * hv1->num);
}
/* Delete cost classes info V from the hash table. */
-static void
-cost_classes_del (void *v)
+inline void
+cost_classes_hasher::remove (value_type *v)
{
ira_free (v);
}
/* Hash table of unique cost classes. */
-static htab_t cost_classes_htab;
+static hash_table <cost_classes_hasher> cost_classes_htab;
/* Map allocno class -> cost classes for pseudo of given allocno
class. */
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
cost_classes_t classes_ptr;
enum reg_class cl;
int i;
- PTR *slot;
+ cost_classes **slot;
HARD_REG_SET temp, temp2;
bool exclude_p;
}
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);
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)
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);
finish_regno_cost_classes (void)
{
ira_free (regno_cost_classes);
- htab_delete (cost_classes_htab);
+ cost_classes_htab.dispose ();
}
\f
#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"
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;
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;
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;
{
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
#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. */
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 *);
}
}
- htab_empty (bivs);
-}
-
-/* Returns hash value for biv B. */
-
-static hashval_t
-biv_hash (const void *b)
-{
- return ((const struct biv_entry *) b)->regno;
+ bivs.empty ();
}
-/* Compares biv B and register R. */
-
-static int
-biv_eq (const void *b, const void *r)
-{
- return ((const struct biv_entry *) b)->regno == REGNO ((const_rtx) r);
-}
/* Prepare the data for an induction variable analysis of a LOOP. */
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
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;
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;
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;
}
}
#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"
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
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. */
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;
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;
}
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;
}
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;
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;
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);
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)
{
}
}
/* 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))
/* 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);
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)
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);
}
#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
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;
}
else
{
- struct string_slot *old_slot = (struct string_slot *) *slot;
+ struct string_slot *old_slot = *slot;
return old_slot->s;
}
}
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);
}
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;
{
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);
#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. */
streamer_check_handled_ts_structures ();
#ifdef LTO_STREAMER_DEBUG
- tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
+ tree_htab.create (31);
#endif
}
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;
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);
}
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
#define GCC_LTO_STREAMER_H
#include "plugin-api.h"
+#include "hash-table.h"
#include "tree.h"
#include "gimple.h"
#include "target.h"
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
/* 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. */
#include "coretypes.h"
#include "tm.h"
#include "line-map.h"
+#include "hash-table.h"
#include "input.h"
#include "tree.h"
#include "rtl.h"
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. */
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;
/* 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);
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);
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;
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "diagnostic-core.h"
#include "tree.h"
#include "tree-pass.h"
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. */
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)
{
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];
#include "tm.h"
#include "diagnostic-core.h"
+#include "hash-table.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
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
{
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;
+\f
+
static struct obstack expr_obstack;
/* Occurrence of an expression.
/* 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. */
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. */
{
free (uid_cuid);
- htab_delete (expr_table);
+ expr_table.dispose ();
obstack_free (&expr_obstack, NULL);
obstack_free (&occr_obstack, NULL);
}
\f
-/* 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;
-}
-\f
-
/* 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. */
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. */
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)
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;
{
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");
}
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))
{
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");
}
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 ();
#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"
/* 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;
}
+\f
+
+/* 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;
+\f
/* 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. */
/* 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;
}
/* 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;
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)
{
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)
{
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;
}
} *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 *);
#include "ggc.h"
#include "intl.h"
#include "tree-pass.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "df.h"
#include "dbgcnt.h"
/* 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;
/* 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. */
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);
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)
{
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);
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
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;
}
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree.h"
#include "gimple.h"
#include "tree-flow.h"
tree save_var;
} *tm_log_entry_t;
-/* The actual log. */
-static htab_t tm_log;
-
-/* Addresses to log with a save/restore sequence. These should be in
- dominator order. */
-static vec<tree> tm_log_save_addresses;
-
-/* Map for an SSA_NAME originally pointing to a non aliased new piece
- of memory (malloc, alloc, etc). */
-static htab_t tm_new_mem_hash;
-enum thread_memory_type
- {
- mem_non_local = 0,
- mem_thread_local,
- mem_transaction_local,
- mem_max
- };
+/* Log entry hashtable helpers. */
-typedef struct tm_new_mem_map
+struct log_entry_hasher
{
- /* SSA_NAME being dereferenced. */
- tree val;
- enum thread_memory_type local_new_memory;
-} tm_new_mem_map_t;
+ typedef tm_log_entry value_type;
+ typedef tm_log_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
/* Htab support. Return hash value for a `tm_log_entry'. */
-static hashval_t
-tm_log_hash (const void *p)
+inline hashval_t
+log_entry_hasher::hash (const value_type *log)
{
- const struct tm_log_entry *log = (const struct tm_log_entry *) p;
return iterative_hash_expr (log->addr, 0);
}
/* Htab support. Return true if two log entries are the same. */
-static int
-tm_log_eq (const void *p1, const void *p2)
+inline bool
+log_entry_hasher::equal (const value_type *log1, const compare_type *log2)
{
- const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
- const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
-
/* FIXME:
rth: I suggest that we get rid of the component refs etc.
}
/* 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);
}
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 ();
}
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);
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. */
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;
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. */
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. */
{
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;
/* 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;
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
{
/* 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
#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. */
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);
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);
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)
{
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;
}
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree.h"
#include "tree-pretty-print.h"
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;
/* 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);
}
}
ret:;
- htab_delete (TB_up_ht);
+ TB_up_ht.dispose ();
return;
}
if (node == NULL_TREE)
return NULL_TREE;
- res = (tree) htab_find (TB_up_ht, node);
+ res = TB_up_ht.find (node);
return res;
}
void *data ATTRIBUTE_UNUSED)
{
tree node;
- void **slot;
+ tree_node **slot;
node = *tp;
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;
}
}
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
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "tm_p.h"
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);
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);
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
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
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)
{
#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
/* 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;
{
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;
}
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,
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);
gsi_commit_edge_inserts ();
- htab_delete (complex_variable_components);
+ complex_variable_components.dispose ();
complex_ssa_name_components.release ();
complex_lattice_values.release ();
return 0;
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
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;
}
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;
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));
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;
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)])
--- /dev/null
+/* 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 */
#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
operation. */
};
-/* Equality and hash functions for hashtab code. */
+/* Reduction info hashtable helpers. */
-static int
-reduction_info_eq (const void *aa, const void *bb)
+struct reduction_hasher : typed_free_remove <reduction_info>
{
- const struct reduction_info *a = (const struct reduction_info *) aa;
- const struct reduction_info *b = (const struct reduction_info *) bb;
+ typedef reduction_info value_type;
+ typedef reduction_info compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Equality and hash functions for hashtab code. */
+inline bool
+reduction_hasher::equal (const value_type *a, const compare_type *b)
+{
return (a->reduc_phi == b->reduc_phi);
}
-static hashval_t
-reduction_info_hash (const void *aa)
+inline hashval_t
+reduction_hasher::hash (const value_type *a)
{
- const struct reduction_info *a = (const struct reduction_info *) aa;
-
return a->reduc_version;
}
+typedef hash_table <reduction_hasher> reduction_info_table_type;
+
+
static struct reduction_info *
-reduction_phi (htab_t reduction_list, gimple phi)
+reduction_phi (reduction_info_table_type reduction_list, gimple phi)
{
struct reduction_info tmpred, *red;
- if (htab_elements (reduction_list) == 0 || phi == NULL)
+ if (reduction_list.elements () == 0 || phi == NULL)
return NULL;
tmpred.reduc_phi = phi;
tmpred.reduc_version = gimple_uid (phi);
- red = (struct reduction_info *) htab_find (reduction_list, &tmpred);
+ red = reduction_list.find (&tmpred);
return red;
}
value. */
};
-/* Equality and hash functions for hashtab code. */
+/* Name copies hashtable helpers. */
-static int
-name_to_copy_elt_eq (const void *aa, const void *bb)
+struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt>
{
- const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
- const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb;
+ typedef name_to_copy_elt value_type;
+ typedef name_to_copy_elt compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Equality and hash functions for hashtab code. */
+inline bool
+name_to_copy_hasher::equal (const value_type *a, const compare_type *b)
+{
return a->version == b->version;
}
-static hashval_t
-name_to_copy_elt_hash (const void *aa)
+inline hashval_t
+name_to_copy_hasher::hash (const value_type *a)
{
- const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
-
return (hashval_t) a->version;
}
+typedef hash_table <name_to_copy_hasher> name_to_copy_table_type;
+
/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
matrix. Rather than use floats, we simply keep a single DENOMINATOR that
represents the denominator for every element in the matrix. */
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;
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)
*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;
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. */
{
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;
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);
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;
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 ();
}
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)
{
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));
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;
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;
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);
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))
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);
break;
}
- SET_USE (use, ((struct name_to_copy_elt *) *slot)->new_name);
+ SET_USE (use, (*slot)->new_name);
}
return false;
/* 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));
/* 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),
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;
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;
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));
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;
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);
}
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;
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;
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;
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). */
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);
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;
}
}
- htab_delete (decl_copies);
- htab_delete (name_copies);
+ decl_copies.dispose ();
+ name_copies.dispose ();
}
/* Bitmap containing uids of functions created by parallelization. We cannot
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;
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;
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;
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));
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 ();
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);
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;
}
/* 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;
/* 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. */
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;
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,
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;
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);
}
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
#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"
/* 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);
/* 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;
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. */
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;
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;
}
}
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.
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;
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,
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,
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);
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,
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,
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,
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,
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),
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))
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))
{
fprintf (dump_file, "))\n");
}
- htab_delete (cache);
+ cache.dispose ();
return res;
}
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;
}
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "alloc-pool.h"
#include "tm.h"
#include "tree.h"
/* 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
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);
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);
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))
{
{
tree type = TREE_TYPE (var);
const char *msg;
- void **slot;
+ tree_node **slot;
if (!AGGREGATE_TYPE_P (type))
{
}
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))
{
parm = DECL_CHAIN (parm))
{
tree type = TREE_TYPE (parm);
- void **slot;
+ tree_node **slot;
count++;
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))
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
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
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
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);
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);
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);
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;
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);
}
}
/* 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 ());
}
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))
{
static tree
lookup_avail_expr (gimple stmt, bool insert)
{
- void **slot;
+ expr_hash_elt **slot;
tree lhs;
tree temp;
struct expr_hash_elt element;
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);
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))
{
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. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "gimple-pretty-print.h"
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
{
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. */
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;
map->num_basevars = m - mapstorage;
free (mapstorage);
- htab_delete (tree_to_index);
+ tree_to_index. dispose ();
}
#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"
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. */
/* 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;
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. */
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);
}
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;
decl_rtl_to_reset.truncate (0);
- htab_empty (data->inv_expr_tab);
+ data->inv_expr_tab.empty ();
data->inv_expr_id = 0;
}
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. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
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. */
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.
{
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;
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;
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);
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;
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree-flow.h"
#include "tree-pass.h"
#include "domwalk.h"
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;
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
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);
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;
static int *
addr_stridxptr (tree exp)
{
- void **slot;
+ decl_stridxlist_map **slot;
struct decl_stridxlist_map ent;
struct stridxlist *list;
HOST_WIDE_INT off;
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)
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;
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;
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
{
vec<tree> equivalences;
};
-static void uncprop_enter_block (struct dom_walk_data *, basic_block);
-static void uncprop_leave_block (struct dom_walk_data *, basic_block);
-static void uncprop_into_successor_phis (basic_block);
+/* Value to ssa name equivalence hashtable helpers. */
-/* Hashing and equality routines for the hash table. */
+struct val_ssa_equiv_hasher
+{
+ typedef equiv_hash_elt value_type;
+ typedef equiv_hash_elt compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
-static hashval_t
-equiv_hash (const void *p)
+inline hashval_t
+val_ssa_equiv_hasher::hash (const value_type *p)
{
- tree const value = ((const struct equiv_hash_elt *)p)->value;
+ tree const value = p->value;
return iterative_hash_expr (value, 0);
}
-static int
-equiv_eq (const void *p1, const void *p2)
+inline bool
+val_ssa_equiv_hasher::equal (const value_type *p1, const compare_type *p2)
{
- tree value1 = ((const struct equiv_hash_elt *)p1)->value;
- tree value2 = ((const struct equiv_hash_elt *)p2)->value;
+ tree value1 = p1->value;
+ tree value2 = p2->value;
return operand_equal_p (value1, value2, 0);
}
/* Free an instance of equiv_hash_elt. */
-static void
-equiv_free (void *p)
+inline void
+val_ssa_equiv_hasher::remove (value_type *elt)
{
- struct equiv_hash_elt *elt = (struct equiv_hash_elt *) p;
elt->equivalences.release ();
free (elt);
}
+/* Global hash table implementing a mapping from invariant values
+ to a list of SSA_NAMEs which have the same value. We might be
+ able to reuse tree-vn for this code. */
+static hash_table <val_ssa_equiv_hasher> val_ssa_equiv;
+
+static void uncprop_enter_block (struct dom_walk_data *, basic_block);
+static void uncprop_leave_block (struct dom_walk_data *, basic_block);
+static void uncprop_into_successor_phis (basic_block);
+
/* Remove the most recently recorded equivalency for VALUE. */
static void
remove_equivalence (tree value)
{
- struct equiv_hash_elt equiv_hash_elt, *equiv_hash_elt_p;
- void **slot;
+ struct equiv_hash_elt an_equiv_elt, *an_equiv_elt_p;
+ equiv_hash_elt **slot;
- equiv_hash_elt.value = value;
- equiv_hash_elt.equivalences.create (0);
+ an_equiv_elt.value = value;
+ an_equiv_elt.equivalences.create (0);
- slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
+ slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT);
- equiv_hash_elt_p = (struct equiv_hash_elt *) *slot;
- equiv_hash_elt_p->equivalences.pop ();
+ an_equiv_elt_p = *slot;
+ an_equiv_elt_p->equivalences.pop ();
}
/* Record EQUIVALENCE = VALUE into our hash table. */
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. */
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
/* 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)
{
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
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
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