This patch is the main part of a consolodation of the hash_table patches to the...
This patch is the main part of a consolodation of the hash_table patches to the cxx-conversion branch for files not under gcc/config. Update various hash tables from htab_t to hash_table. Modify types and calls to match. * tree-parloops.c'reduction * tree-parloops.c'name_to_copy Fold reduction_info_hash and reduction_info_eq into new struct reduction_hasher. Fold name_to_copy_elt_eq and name_to_copy_elt_hash into new struct name_to_copy_hasher. * trans-mem.c'tm_log Fold tm_log_hash, tm_log_eq, tm_log_free into new struct log_entry_hasher. * trans-mem.c'tm_memopt_value_numbers Fold tm_memop_hash, tm_memop_eq into new struct tm_memop_hasher. * tree-ssa-strlen.c'decl_to_stridxlist_htab Fold decl_to_stridxlist_hash into new struct stridxlist_hasher. * tree-ssa-loop-ivopts.c'ivopts_data::inv_expr_tab Fold htab_inv_expr_hash and htab_inv_expr_eq into new struct iv_inv_expr_hasher. * tree-ssa-uncprop.c'equiv Equiv renamed to val_ssa_equiv because of name ambiguity with local variables. Fold equiv_hash, equiv_eq and equiv_free into new struct val_ssa_equiv_hasher. Renamed variables equiv_hash_elt to an_equiv_elt because of name ambiguity with struct type. Changed equiv_hash_elt_p to an_equiv_elt_p to match. * tree-ssa-phiopt.c'seen_ssa_names Fold name_to_bb_hash and name_to_bb_eq into new struct ssa_names_hasher. * tree-ssa-structalias.c'pointer_equiv_class_table * tree-ssa-structalias.c'location_equiv_class_table Fold equiv_class_label_hash and equiv_class_label_eq into new struct equiv_class_hasher. * tree-ssa-structalias.c'shared_bitmap_table Fold shared_bitmap_hash and shared_bitmap_eq into new struct shared_bitmap_hasher. * tree-ssa-live.c'var_map_base_init::tree_to_index New struct tree_int_map_hasher. * tree-sra.c'candidates Fold uid_decl_map_hash and uid_decl_map_eq into new struct uid_decl_hasher. This change moves the definitions from tree-ssa.c into tree-sra.c and removes the declarations from tree-flow.h tree-browser.c Remove stale declaration of removed TB_parent_eq. Fix template parameter for base class to match value_type. gimple.h Use gimplify_hasher::hash rather than gimple_tree_hash in the assertion check. Change return values to match return type. (I.e. no conversions.) * graphite-clast-to-gimple.c'ivs_params::newivs_index * graphite-clast-to-gimple.c'ivs_params::params_index * graphite-clast-to-gimple.c'print_generated_program::params_index * graphite-clast-to-gimple.c'gloog::newivs_index * graphite-clast-to-gimple.c'gloog::params_index * graphite.c graphite_transform_loops::bb_pbb_mapping * sese.c copy_bb_and_scalar_dependences::rename_map Move hash table declarations to a new graphite-htab.h, because they are used in few places. Remove unused: htab_t scop::original_pddrs SCOP_ORIGINAL_PDDRS Remove unused: insert_loop_close_phis insert_guard_phis debug_ivtype_map ivtype_map_elt_info new_ivtype_map_elt * gimplify.c'gimplify_ctx::temp_htab Move struct gimple_temp_hash_elt and struct gimplify_ctx to a new gimplify-ctx.h, because they are used few places. * cselib.c'cselib_hash_table * gcse.c'pre_ldst_table * gimple-ssa-strength-reduction.c'base_cand_map * haifa-sched.c'delay_htab * haifa-sched.c'delay_htab_i2 * ira-color.c'allocno_hard_regs_htab * ira-costs.c'cost_classes_htab * loop-invariant.c'merge_identical_invariants::eq * loop-iv.c'bivs * loop-unroll.c'opt_info::insns_to_split * loop-unroll.c'opt_info::insns_with_var_to_expand * passes.c'name_to_pass_map * plugin.c'event_tab * postreload-gcse.c'expr_table * store-motion.c'store_motion_mems_table * tree-cfg.c'discriminator_per_locus * tree-scalar-evolution.c'resolve_mixers::cache * tree-ssa-dom.c'avail_exprs Remove unused: dse.c bitmap clear_alias_sets dse.c bitmap disqualified_clear_alias_sets dse.c alloc_pool clear_alias_mode_pool dse.c dse_step2_spill dse.c dse_step5_spill graphds.h htab_t graph::indices * attribs.c'scoped_attributes::attribute_hash * bitmap.c'bitmap_desc_hash * dwarf2cfi.c'trace_index * dwarf2out.c'break_out_includes::cu_hash_table * dwarf2out.c'copy_decls_for_unworthy_types::decl_table * dwarf2out.c'optimize_external_refs::map * dwarf2out.c'output_comp_unit::extern_map * dwarf2out.c'output_comdat_type_unit::extern_map * dwarf2out.c'output_macinfo::macinfo_htab * dwarf2out.c'optimize_location_lists::htab * dwarf2out.c'dwarf2out_finish::comdat_type_table * except.c'ehspec_hash_type * except.c'assign_filter_values::ttypes * except.c'assign_filter_values::ehspec * except.c'sjlj_assign_call_site_values::ar_hash * except.c'convert_to_eh_region_ranges::ar_hash * trans-mem.c'tm_new_mem_hash * tree-browser.c'TB_up_ht * tree-eh.c'finally_tree Move the declaration of hash_table <alloc_pool_hasher> alloc_pool_hash in alloc-pool.c to after the method definitions for its parameter class. * ggc-common.c'loc_hash * ggc-common.c'ptr_hash Add a new hash_table method elements_with_deleted to meet the needs of gcc-common.c. Correct many methods with parameter types compare_type to the correct value_type. (Correct code was unlikely to notice the change, but incorrect code will.) * tree-complex.c'complex_variable_components * tree-parloops.c'eliminate_local_variables_stmt::decl_address * tree-parloops.c'separate_decls_in_region::decl_copies Move hash table declarations to a new tree-hasher.h, to resolve compilation dependences and because they are used in few places. * lto-streamer.h'output_block::string_hash_table * lto-streamer-in.c'file_name_hash_table * lto-streamer.c'tree_htab The struct string_slot moves from data-streamer.h to lto-streamer.h to resolve compilation dependences. Tested on x86_64. Index: gcc/ChangeLog 2013-04-25 Lawrence Crowl <crowl@google.com> * Makefile.in: Update as needed below. * alloc-pool.c (static hash_table <alloc_pool_hasher> alloc_pool_hash): Move declaration to after the type's method definitons. * attribs.c (htab_t scoped_attributes::attribute_hash): Change type to hash_table. Update dependent calls and types. * bitmap.c (htab_t bitmap_desc_hash): Change type to hash_table. Update dependent calls and types. * cselib.c (htab_t cselib_hash_table): Change type to hash_table. Update dependent calls and types. * data-streamer.h (struct string_slot): Move to lto-streamer.h. (hash_string_slot_node): Move implementation into lto-streamer.h struct string_slot_hasher. (eq_string_slot_node): Likewise. * data-streamer-out.c: Update output_block::string_hash_table dependent calls and types. * dwarf2cfi.c (htab_t trace_index): Change type to hash_table. Update dependent calls and types. * dwarf2out.c (htab_t break_out_includes::cu_hash_table): Change type to hash_table. Update dependent calls and types. (htab_t copy_decls_for_unworthy_types::decl_table): Likewise. (htab_t optimize_external_refs::map): Likewise. (htab_t output_comp_unit::extern_map): Likewise. (htab_t output_comdat_type_unit::extern_map): Likewise. (htab_t output_macinfo::macinfo_htab): Likewise. (htab_t optimize_location_lists::htab): Likewise. (htab_t dwarf2out_finish::comdat_type_table): Likewise. * except.c (htab_t ehspec_hash_type): Change type to hash_table. Update dependent calls and types. (assign_filter_values::ttypes): Likewise. (assign_filter_values::ehspec): Likewise. (sjlj_assign_call_site_values::ar_hash): Likewise. (convert_to_eh_region_ranges::ar_hash): Likewise. * gcse.c (htab_t pre_ldst_table): Change type to hash_table. Update dependent calls and types. * ggc-common.c (htab_t saving_htab): Change type to hash_table. Update dependent calls and types. (htab_t loc_hash): Likewise. (htab_t ptr_hash): Likewise. (call_count): Rename ggc_call_count. (call_alloc): Rename ggc_call_alloc. (loc_descriptor): Rename make_loc_descriptor. (add_statistics): Rename ggc_add_statistics. * ggc-common.c (saving_htab): Change type to hash_table. Update dependent calls and types. * gimple.h (struct gimplify_ctx): Move to gimplify-ctx.h. (push_gimplify_context): Likewise. (pop_gimplify_context): Likewise. (struct gimple_temp_hash_elt): Added. (struct gimplify_hasher): Likewise. (struct gimplify_ctx.temp_htab): Change type to hash_table. Update dependent calls and types. * gimple-fold.c: Include gimplify-ctx.h. * gimple-ssa-strength-reduction.c (htab_t base_cand_map): Change type to hash_table. Update dependent calls and types. (base_cand_dump_callback): Rename to ssa_base_cand_dump_callback to avoid potential global name collision. * gimplify.c: Include gimplify-ctx.h. (struct gimple_temp_hash_elt): Move to gimplify-ctx.h. (htab_t gimplify_ctx::temp_htab): Update dependent calls and types for new type hash_table. (gimple_tree_hash): Move into gimplify_hasher in gimplify-ctx.h. (gimple_tree_eq): Move into gimplify_hasher in gimplify-ctx.h. * gimplify-ctx.h: New. (struct gimple_temp_hash_elt): Move from gimplify.c. (class gimplify_hasher): New. (struct gimplify_ctx): Move from gimple.h. (htab_t gimplify_ctx::temp_htab): Change type to hash_table. Update dependent calls and types. * graphite-clast-to-gimple.c: Include graphite-htab.h. (htab_t ivs_params::newivs_index): Change type to hash_table. Update dependent calls and types. (htab_t ivs_params::params_index): Likewise. (htab_t print_generated_program::params_index): Likewise. (htab_t gloog::newivs_index): Likewise. (htab_t gloog::params_index): Likewise. * graphite.c: Include graphite-htab.h. 4htab_t graphite_transform_loops::bb_pbb_mapping): Change type to hash_table. Update dependent calls and types. * graphite-clast-to-gimple.h: (extern gloog) Move to graphite-htab.h. (bb_pbb_map_hash): Fold into bb_pbb_htab_type in graphite-htab.h. (eq_bb_pbb_map): Fold into bb_pbb_htab_type in graphite-htab.h. * graphite-dependences.c: Include graphite-htab.h. (loop_is_parallel_p): Change hash table type of parameter. * graphite-htab.h: New. (typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type): New. (extern find_pbb_via_hash): Move from graphite-poly.h. (extern loop_is_parallel_p): Move from graphite-poly.h. (extern get_loop_body_pbbs): Move from graphite-poly.h. * graphite-poly.h (extern find_pbb_via_hash): Move to graphite-htab.h. (extern loop_is_parallel_p): Move to graphite-htab.h. (extern get_loop_body_pbbs): Move to graphite-htab.h. * haifa-sched.c (htab_t delay_htab): Change type to hash_table. Update dependent calls and types. (htab_t delay_htab_i2): Likewise. * ira-color.c (htab_t allocno_hard_regs_htab): Change type to hash_table. Update dependent calls and types. * ira-costs.c (htab_t cost_classes_htab): Change type to hash_table. Update dependent calls and types. * loop-invariant.c (htab_t merge_identical_invariants::eq): Change type to hash_table. Update dependent calls and types. * loop-iv.c (htab_t bivs): Change type to hash_table. Update dependent calls and types. * loop-unroll.c (htab_t opt_info::insns_to_split): Change type to hash_table. Update dependent calls and types. (htab_t opt_info::insns_with_var_to_expand): Likewise. * lto-streamer.h (struct string_slot): Move from data-streamer.h (struct string_slot_hasher): New. (htab_t output_block::string_hash_table): Change type to hash_table. Update dependent calls and types. * lto-streamer-in.c (freeing_string_slot_hasher): New. (htab_t file_name_hash_table): Change type to hash_table. Update dependent calls and types. * lto-streamer-out.c: Update output_block::string_hash_table dependent calls and types. * lto-streamer.c (htab_t tree_htab): Change type to hash_table. Update dependent calls and types. * omp-low.c: Include gimplify-ctx.h. * passes.c (htab_t name_to_pass_map): Change type to hash_table. Update dependent calls and types. (pass_traverse): Rename to passes_pass_traverse. * plugin.c (htab_t event_tab): Change type to hash_table. Update dependent calls and types. * postreload-gcse.c (htab_t expr_table): Change type to hash_table. Update dependent calls and types. (dump_hash_table_entry): Rename dump_expr_hash_table_entry. * sese.c (debug_rename_map_1): Make extern. (htab_t copy_bb_and_scalar_dependences::rename_map): Change type to hash_table. Update dependent calls and types. * sese.h (extern debug_rename_map): Move to .c file. * store-motion.c (htab_t store_motion_mems_table): Change type to hash_table. Update dependent calls and types. * trans-mem.c (htab_t tm_new_mem_hash): Change type to hash_table. Update dependent calls and types. * tree-browser.c (htab_t TB_up_ht): Change type to hash_table. Update dependent calls and types. * tree-cfg.c (htab_t discriminator_per_locus): Change type to hash_table. Update dependent calls and types. * tree-complex.c: Include tree-hasher.h (htab_t complex_variable_components): Change type to hash_table. Update dependent calls and types. * tree-eh.c (htab_t finally_tree): Change type to hash_table. Update dependent calls and types. * tree-flow.h (extern int_tree_map_hash): Moved into tree-hasher struct int_tree_hasher. (extern int_tree_map_eq): Likewise. (uid_decl_map_hash): Removed. (extern decl_tree_map_eq): Likewise. * tree-hasher.h: New. (struct int_tree_hasher): New. (typedef int_tree_htab_type): New. * tree-inline.c: Include gimplify-ctx.h. * tree-mudflap.c: Include gimplify-ctx.h. * tree-parloops.c: Include tree-hasher.h. (htab_t eliminate_local_variables_stmt::decl_address): Change type to hash_table. Update dependent calls and types. (htab_t separate_decls_in_region::decl_copies): Likewise. * tree-scalar-evolution.c (htab_t resolve_mixers::cache): Change type to hash_table. Update dependent calls and types. * tree-sra.c (candidates): Change type to hash_table. Update dependent calls and types. * tree-ssa.c (int_tree_map_eq): Moved into struct int_tree_hasher in tree-flow.h. (int_tree_map_hash): Likewise. * tree-ssa-dom.c (htab_t avail_exprs): Change type to hash_table. Update dependent calls and types. * tree-ssa-live.c (var_map_base_init::tree_to_index): Change type to hash_table. Update dependent calls and types. * tree-ssa-loop-ivopts.c (struct ivopts_data.inv_expr_tab): Change type to hash_table. Update dependent calls and types. * tree-ssa-phiopt.c (seen_ssa_names): Change type to hash_table. Update dependent calls and types. * tree-ssa-strlen.c (decl_to_stridxlist_htab): Change type to hash_table. Update dependent calls and types. * tree-ssa-uncprop.c (equiv): Change type to hash_table. Update dependent calls and types. From-SVN: r198329
This commit is contained in:
parent
11dae3ad79
commit
4a8fb1a1de
237
gcc/ChangeLog
237
gcc/ChangeLog
|
@ -1,3 +1,240 @@
|
|||
2013-04-25 Lawrence Crowl <crowl@google.com>
|
||||
|
||||
* Makefile.in: Update as needed below.
|
||||
|
||||
* alloc-pool.c (static hash_table <alloc_pool_hasher> alloc_pool_hash):
|
||||
Move declaration to after the type's method definitons.
|
||||
|
||||
* attribs.c (htab_t scoped_attributes::attribute_hash):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* bitmap.c (htab_t bitmap_desc_hash):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* cselib.c (htab_t cselib_hash_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* data-streamer.h (struct string_slot): Move to lto-streamer.h.
|
||||
(hash_string_slot_node): Move implementation into lto-streamer.h
|
||||
struct string_slot_hasher.
|
||||
(eq_string_slot_node): Likewise.
|
||||
|
||||
* data-streamer-out.c: Update output_block::string_hash_table
|
||||
dependent calls and types.
|
||||
|
||||
* dwarf2cfi.c (htab_t trace_index):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* dwarf2out.c (htab_t break_out_includes::cu_hash_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(htab_t copy_decls_for_unworthy_types::decl_table): Likewise.
|
||||
(htab_t optimize_external_refs::map): Likewise.
|
||||
(htab_t output_comp_unit::extern_map): Likewise.
|
||||
(htab_t output_comdat_type_unit::extern_map): Likewise.
|
||||
(htab_t output_macinfo::macinfo_htab): Likewise.
|
||||
(htab_t optimize_location_lists::htab): Likewise.
|
||||
(htab_t dwarf2out_finish::comdat_type_table): Likewise.
|
||||
|
||||
* except.c (htab_t ehspec_hash_type):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(assign_filter_values::ttypes): Likewise.
|
||||
(assign_filter_values::ehspec): Likewise.
|
||||
(sjlj_assign_call_site_values::ar_hash): Likewise.
|
||||
(convert_to_eh_region_ranges::ar_hash): Likewise.
|
||||
|
||||
* gcse.c (htab_t pre_ldst_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* ggc-common.c (htab_t saving_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(htab_t loc_hash): Likewise.
|
||||
(htab_t ptr_hash): Likewise.
|
||||
(call_count): Rename ggc_call_count.
|
||||
(call_alloc): Rename ggc_call_alloc.
|
||||
(loc_descriptor): Rename make_loc_descriptor.
|
||||
(add_statistics): Rename ggc_add_statistics.
|
||||
|
||||
* ggc-common.c (saving_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* gimple.h (struct gimplify_ctx): Move to gimplify-ctx.h.
|
||||
(push_gimplify_context): Likewise.
|
||||
(pop_gimplify_context): Likewise.
|
||||
(struct gimple_temp_hash_elt): Added.
|
||||
(struct gimplify_hasher): Likewise.
|
||||
(struct gimplify_ctx.temp_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* gimple-fold.c: Include gimplify-ctx.h.
|
||||
|
||||
* gimple-ssa-strength-reduction.c (htab_t base_cand_map):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(base_cand_dump_callback): Rename to ssa_base_cand_dump_callback to
|
||||
avoid potential global name collision.
|
||||
|
||||
* gimplify.c: Include gimplify-ctx.h.
|
||||
(struct gimple_temp_hash_elt): Move to gimplify-ctx.h.
|
||||
(htab_t gimplify_ctx::temp_htab):
|
||||
Update dependent calls and types for new type hash_table.
|
||||
(gimple_tree_hash): Move into gimplify_hasher in gimplify-ctx.h.
|
||||
(gimple_tree_eq): Move into gimplify_hasher in gimplify-ctx.h.
|
||||
|
||||
* gimplify-ctx.h: New.
|
||||
(struct gimple_temp_hash_elt): Move from gimplify.c.
|
||||
(class gimplify_hasher): New.
|
||||
(struct gimplify_ctx): Move from gimple.h.
|
||||
(htab_t gimplify_ctx::temp_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* graphite-clast-to-gimple.c: Include graphite-htab.h.
|
||||
(htab_t ivs_params::newivs_index):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(htab_t ivs_params::params_index): Likewise.
|
||||
(htab_t print_generated_program::params_index): Likewise.
|
||||
(htab_t gloog::newivs_index): Likewise.
|
||||
(htab_t gloog::params_index): Likewise.
|
||||
|
||||
* graphite.c: Include graphite-htab.h.
|
||||
4htab_t graphite_transform_loops::bb_pbb_mapping):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* graphite-clast-to-gimple.h: (extern gloog) Move to graphite-htab.h.
|
||||
(bb_pbb_map_hash): Fold into bb_pbb_htab_type in graphite-htab.h.
|
||||
(eq_bb_pbb_map): Fold into bb_pbb_htab_type in graphite-htab.h.
|
||||
|
||||
* graphite-dependences.c: Include graphite-htab.h.
|
||||
(loop_is_parallel_p): Change hash table type of parameter.
|
||||
|
||||
* graphite-htab.h: New.
|
||||
(typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type): New.
|
||||
(extern find_pbb_via_hash): Move from graphite-poly.h.
|
||||
(extern loop_is_parallel_p): Move from graphite-poly.h.
|
||||
(extern get_loop_body_pbbs): Move from graphite-poly.h.
|
||||
|
||||
* graphite-poly.h (extern find_pbb_via_hash): Move to graphite-htab.h.
|
||||
(extern loop_is_parallel_p): Move to graphite-htab.h.
|
||||
(extern get_loop_body_pbbs): Move to graphite-htab.h.
|
||||
|
||||
* haifa-sched.c (htab_t delay_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(htab_t delay_htab_i2): Likewise.
|
||||
|
||||
* ira-color.c (htab_t allocno_hard_regs_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* ira-costs.c (htab_t cost_classes_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* loop-invariant.c (htab_t merge_identical_invariants::eq):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* loop-iv.c (htab_t bivs):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* loop-unroll.c (htab_t opt_info::insns_to_split):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(htab_t opt_info::insns_with_var_to_expand): Likewise.
|
||||
|
||||
* lto-streamer.h (struct string_slot): Move from data-streamer.h
|
||||
(struct string_slot_hasher): New.
|
||||
(htab_t output_block::string_hash_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* lto-streamer-in.c (freeing_string_slot_hasher): New.
|
||||
(htab_t file_name_hash_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* lto-streamer-out.c: Update output_block::string_hash_table dependent
|
||||
calls and types.
|
||||
|
||||
* lto-streamer.c (htab_t tree_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* omp-low.c: Include gimplify-ctx.h.
|
||||
|
||||
* passes.c (htab_t name_to_pass_map):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(pass_traverse): Rename to passes_pass_traverse.
|
||||
|
||||
* plugin.c (htab_t event_tab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* postreload-gcse.c (htab_t expr_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(dump_hash_table_entry): Rename dump_expr_hash_table_entry.
|
||||
|
||||
* sese.c (debug_rename_map_1): Make extern.
|
||||
(htab_t copy_bb_and_scalar_dependences::rename_map):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* sese.h (extern debug_rename_map): Move to .c file.
|
||||
|
||||
* store-motion.c (htab_t store_motion_mems_table):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* trans-mem.c (htab_t tm_new_mem_hash):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-browser.c (htab_t TB_up_ht):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-cfg.c (htab_t discriminator_per_locus):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-complex.c: Include tree-hasher.h
|
||||
(htab_t complex_variable_components):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-eh.c (htab_t finally_tree):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-flow.h (extern int_tree_map_hash): Moved into tree-hasher
|
||||
struct int_tree_hasher.
|
||||
(extern int_tree_map_eq): Likewise.
|
||||
(uid_decl_map_hash): Removed.
|
||||
(extern decl_tree_map_eq): Likewise.
|
||||
|
||||
* tree-hasher.h: New.
|
||||
(struct int_tree_hasher): New.
|
||||
(typedef int_tree_htab_type): New.
|
||||
|
||||
* tree-inline.c: Include gimplify-ctx.h.
|
||||
|
||||
* tree-mudflap.c: Include gimplify-ctx.h.
|
||||
|
||||
* tree-parloops.c: Include tree-hasher.h.
|
||||
(htab_t eliminate_local_variables_stmt::decl_address):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
(htab_t separate_decls_in_region::decl_copies): Likewise.
|
||||
|
||||
* tree-scalar-evolution.c (htab_t resolve_mixers::cache):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-sra.c (candidates):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-ssa.c (int_tree_map_eq): Moved into struct int_tree_hasher
|
||||
in tree-flow.h.
|
||||
(int_tree_map_hash): Likewise.
|
||||
|
||||
* tree-ssa-dom.c (htab_t avail_exprs):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-ssa-live.c (var_map_base_init::tree_to_index):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-ssa-loop-ivopts.c (struct ivopts_data.inv_expr_tab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-ssa-phiopt.c (seen_ssa_names):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-ssa-strlen.c (decl_to_stridxlist_htab):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
* tree-ssa-uncprop.c (equiv):
|
||||
Change type to hash_table. Update dependent calls and types.
|
||||
|
||||
2013-04-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/57003
|
||||
|
|
104
gcc/Makefile.in
104
gcc/Makefile.in
|
@ -875,7 +875,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \
|
|||
cfg-flags.def cfghooks.h
|
||||
GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
|
||||
$(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \
|
||||
tree-ssa-alias.h $(INTERNAL_FN_H)
|
||||
tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H)
|
||||
TRANS_MEM_H = trans-mem.h
|
||||
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
|
||||
COVERAGE_H = coverage.h $(GCOV_IO_H)
|
||||
|
@ -938,6 +938,7 @@ TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
|
|||
$(BITMAP_H) sbitmap.h $(BASIC_BLOCK_H) $(GIMPLE_H) \
|
||||
$(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) \
|
||||
tree-ssa-alias.h
|
||||
TREE_HASHER_H = tree-hasher.h $(HASH_TABLE_H) $(TREE_FLOW_H)
|
||||
TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H)
|
||||
SSAEXPAND_H = ssaexpand.h $(TREE_SSA_LIVE_H)
|
||||
PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H)
|
||||
|
@ -958,7 +959,7 @@ LRA_INT_H = lra.h $(BITMAP_H) $(RECOG_H) $(INSN_ATTR_H) insn-codes.h \
|
|||
insn-config.h $(REGS_H) lra-int.h
|
||||
DBGCNT_H = dbgcnt.h dbgcnt.def
|
||||
LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \
|
||||
$(CGRAPH_H) $(VEC_H) $(TREE_H) $(GIMPLE_H) \
|
||||
$(CGRAPH_H) $(VEC_H) $(HASH_TABLE_H) $(TREE_H) $(GIMPLE_H) \
|
||||
$(GCOV_IO_H) $(DIAGNOSTIC_H) alloc-pool.h
|
||||
DATA_STREAMER_H = data-streamer.h $(VEC_H) $(LTO_STREAMER_H)
|
||||
GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \
|
||||
|
@ -977,6 +978,7 @@ GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h plugin.def \
|
|||
PLUGIN_H = plugin.h $(GCC_PLUGIN_H)
|
||||
PLUGIN_VERSION_H = plugin-version.h configargs.h
|
||||
LIBFUNCS_H = libfuncs.h $(HASHTAB_H)
|
||||
GRAPHITE_HTAB_H = graphite-htab.h graphite-clast-to-gimple.h $(HASH_TABLE_H)
|
||||
|
||||
#
|
||||
# Now figure out from those variables how to compile and link.
|
||||
|
@ -2016,7 +2018,7 @@ default-c.o: config/default-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
# Files used by all variants of C and some other languages.
|
||||
|
||||
attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \
|
||||
$(HASH_TABLE_H) $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \
|
||||
$(TARGET_H) langhooks.h $(CPPLIB_H) $(PLUGIN_H)
|
||||
|
||||
incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
|
||||
|
@ -2108,7 +2110,7 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
$(CFGLOOP_H) $(TARGET_H) $(IPA_PROP_H) $(LTO_STREAMER_H) \
|
||||
target-globals.h
|
||||
|
||||
trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \
|
||||
$(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \
|
||||
$(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \
|
||||
$(PARAMS_H) $(TARGET_H) langhooks.h \
|
||||
|
@ -2116,7 +2118,7 @@ trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
gt-trans-mem.h
|
||||
|
||||
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(GGC_H) $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \
|
||||
$(GGC_H) $(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \
|
||||
$(HOSTHOOKS_DEF_H) $(VEC_H) $(PLUGIN_H) $(GGC_INTERNAL_H) $(TIMEVAR_H)
|
||||
|
||||
ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
|
||||
|
@ -2252,8 +2254,8 @@ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
|
|||
$(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \
|
||||
$(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \
|
||||
$(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H)
|
||||
tree-ssa-structalias.o: tree-ssa-structalias.c \
|
||||
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
|
||||
tree-ssa-structalias.o: tree-ssa-structalias.c $(SYSTEM_H) $(CONFIG_H) \
|
||||
coretypes.h $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
|
||||
$(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
|
||||
$(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
|
||||
$(GIMPLE_H) $(HASH_TABLE_H) $(FUNCTION_H) $(CGRAPH_H) \
|
||||
|
@ -2266,7 +2268,7 @@ tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
|||
$(FLAGS_H) $(HASHTAB_H) pointer-set.h \
|
||||
$(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
|
||||
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \
|
||||
$(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \
|
||||
toplev.h $(FUNCTION_H) $(TM_H) coretypes.h \
|
||||
langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
|
||||
$(FLAGS_H) $(GGC_H) $(HASHTAB_H) pointer-set.h \
|
||||
|
@ -2308,7 +2310,7 @@ tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \
|
|||
$(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
|
||||
$(TREE_PRETTY_PRINT_H)
|
||||
tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
|
||||
$(HASH_TABLE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
|
||||
$(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \
|
||||
$(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \
|
||||
$(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \
|
||||
|
@ -2329,13 +2331,13 @@ tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
tree-ssa-propagate.h $(VEC_H) value-prof.h gt-tree-ssa-propagate.h $(FLAGS_H) \
|
||||
$(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H)
|
||||
tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \
|
||||
$(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \
|
||||
$(FUNCTION_H) $(TM_H) coretypes.h \
|
||||
$(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) langhooks.h \
|
||||
tree-ssa-propagate.h $(CFGLOOP_H) $(PARAMS_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H)
|
||||
tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(TREE_H) $(TM_P_H) \
|
||||
$(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) \
|
||||
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h \
|
||||
$(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) \
|
||||
tree-ssa-propagate.h
|
||||
|
@ -2358,7 +2360,7 @@ domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
$(BASIC_BLOCK_H) domwalk.h sbitmap.h
|
||||
tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) $(TIMEVAR_H) \
|
||||
$(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) \
|
||||
$(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) $(HASH_TABLE_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H) $(GIMPLE_H)
|
||||
tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) \
|
||||
|
@ -2380,7 +2382,7 @@ tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
$(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h
|
||||
gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \
|
||||
$(SYSTEM_H) coretypes.h $(TREE_H) $(GIMPLE_H) $(BASIC_BLOCK_H) \
|
||||
$(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \
|
||||
$(HASH_TABLE_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H) alloc-pool.h $(TREE_FLOW_H) domwalk.h \
|
||||
pointer-set.h expmed.h
|
||||
tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
|
@ -2388,7 +2390,7 @@ tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
$(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \
|
||||
$(CFGLOOP_H) $(SCEV_H) intl.h \
|
||||
$(GIMPLE_PRETTY_PRINT_H) gimple-fold.h $(OPTABS_H) $(EXPR_H)
|
||||
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) $(HASH_TABLE_H) \
|
||||
$(TREE_H) $(TM_P_H) $(GGC_H) $(FLAGS_H) $(TARGET_H) \
|
||||
$(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(TM_H) coretypes.h \
|
||||
$(TREE_DUMP_H) $(EXCEPT_H) $(CFGLOOP_H) $(TREE_PASS_H) \
|
||||
|
@ -2433,7 +2435,7 @@ tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
langhooks.h $(IPA_REFERENCE_H) $(GIMPLE_PRETTY_PRINT_H)
|
||||
tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \
|
||||
$(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \
|
||||
$(HASH_TABLE_H) $(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \
|
||||
$(TREE_INLINE_H) tree-iterator.h toplev.h \
|
||||
$(DIAGNOSTIC_CORE_H) $(TARGET_H) $(CFGLOOP_H)
|
||||
tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
|
@ -2479,7 +2481,7 @@ tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \
|
|||
tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \
|
||||
$(DIAGNOSTIC_H) $(TM_H) coretypes.h \
|
||||
$(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
|
||||
$(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASH_TABLE_H) $(SCEV_H) \
|
||||
$(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) \
|
||||
tree-affine.h pointer-set.h $(TARGET_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H) tree-ssa-propagate.h
|
||||
|
@ -2493,7 +2495,7 @@ tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
$(CFGLOOP_H) $(TREE_PASS_H) \
|
||||
$(SCEV_H) $(PARAMS_H) $(TREE_INLINE_H) langhooks.h
|
||||
tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
|
||||
$(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
|
||||
$(PARAMS_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h \
|
||||
$(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \
|
||||
pointer-set.h tree-affine.h tree-ssa-propagate.h $(GIMPLE_PRETTY_PRINT_H)
|
||||
|
@ -2546,15 +2548,15 @@ omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
$(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \
|
||||
$(CFGLOOP_H) tree-iterator.h gt-omp-low.h
|
||||
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(TREE_H) $(TREE_PRETTY_PRINT_H)
|
||||
coretypes.h $(HASH_TABLE_H) $(TREE_H) $(TREE_PRETTY_PRINT_H)
|
||||
omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
|
||||
$(TREE_H) $(DIAGNOSTIC_CORE_H)
|
||||
tree-chrec.o : tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
|
||||
$(TREE_PRETTY_PRINT_H) $(CFGLOOP_H) $(TREE_FLOW_H) $(SCEV_H) \
|
||||
$(PARAMS_H)
|
||||
tree-scalar-evolution.o : tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(DUMPFILE_H) $(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) \
|
||||
$(CFGLOOP_H) $(SCEV_H) $(PARAMS_H) gt-tree-scalar-evolution.h
|
||||
coretypes.h $(DUMPFILE_H) $(HASH_TABLE_H) $(GIMPLE_PRETTY_PRINT_H) \
|
||||
$(TREE_FLOW_H) $(CFGLOOP_H) $(SCEV_H) $(PARAMS_H) gt-tree-scalar-evolution.h
|
||||
tree-data-ref.o : tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(DUMPFILE_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
|
||||
|
@ -2563,18 +2565,18 @@ sese.o : sese.c sese.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_PRETTY_PRINT_H
|
|||
$(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) value-prof.h
|
||||
graphite.o : graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) \
|
||||
$(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \
|
||||
$(DBGCNT_H) graphite-poly.h graphite-scop-detection.h \
|
||||
$(DBGCNT_H) $(GRAPHITE_HTAB_H) graphite-poly.h graphite-scop-detection.h \
|
||||
graphite-clast-to-gimple.h graphite-sese-to-poly.h
|
||||
graphite-blocking.o : graphite-blocking.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
|
||||
sese.h graphite-poly.h
|
||||
graphite-clast-to-gimple.o : graphite-clast-to-gimple.c $(CONFIG_H) \
|
||||
$(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
|
||||
$(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \
|
||||
$(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h $(GRAPHITE_HTAB_H) \
|
||||
graphite-poly.h graphite-clast-to-gimple.h
|
||||
graphite-dependences.o : graphite-dependences.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(TREE_FLOW_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
|
||||
sese.h graphite-poly.h
|
||||
sese.h $(GRAPHITE_HTAB_H) graphite-poly.h
|
||||
graphite-interchange.o : graphite-interchange.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
|
||||
sese.h graphite-poly.h
|
||||
|
@ -2628,7 +2630,8 @@ tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H)
|
||||
tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GIMPLE_PRETTY_PRINT_H) \
|
||||
$(TREE_FLOW_H) $(TREE_HASHER_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H) $(HASH_TABLE_H) \
|
||||
$(TREE_PASS_H) langhooks.h gt-tree-parloops.h $(TREE_VECTORIZER_H)
|
||||
tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(FUNCTION_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
|
||||
|
@ -2647,8 +2650,9 @@ gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
|
|||
$(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) \
|
||||
$(TM_H) $(GIMPLE_H) value-prof.h \
|
||||
$(TRANS_MEM_H) $(GIMPLE_PRETTY_PRINT_H)
|
||||
tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
|
||||
$(GIMPLE_H) $(DIAGNOSTIC_H) $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
|
||||
tree-mudflap.o : tree-mudflap.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
|
||||
$(TREE_INLINE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) \
|
||||
$(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
|
||||
$(TM_H) coretypes.h $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \
|
||||
gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \
|
||||
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h
|
||||
|
@ -2729,7 +2733,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
$(PLUGIN_H) $(IPA_UTILS_H)
|
||||
|
||||
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
|
||||
$(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) \
|
||||
intl.h $(PLUGIN_VERSION_H) $(GGC_H)
|
||||
|
||||
main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H)
|
||||
|
||||
|
@ -2777,7 +2782,8 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) \
|
|||
except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) $(LIBFUNCS_H) \
|
||||
langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
|
||||
dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) intl.h $(GGC_H) \
|
||||
dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) \
|
||||
intl.h $(GGC_H) \
|
||||
gt-except.h $(CGRAPH_H) $(DIAGNOSTIC_H) $(DWARF2_H) \
|
||||
$(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
|
||||
$(TREE_PRETTY_PRINT_H) sbitmap.h $(COMMON_TARGET_H) $(CFGLOOP_H)
|
||||
|
@ -2831,12 +2837,12 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
|
|||
$(TM_H) $(TREE_H) version.h $(RTL_H) $(DWARF2_H) debug.h $(FLAGS_H) \
|
||||
insn-config.h output.h $(DIAGNOSTIC_H) hard-reg-set.h $(REGS_H) $(EXPR_H) \
|
||||
toplev.h $(DIAGNOSTIC_CORE_H) $(DWARF2OUT_H) reload.h \
|
||||
$(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \
|
||||
$(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASH_TABLE_H) \
|
||||
gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \
|
||||
$(GIMPLE_H) ira.h lra.h $(TREE_FLOW_H) \
|
||||
$(TREE_PRETTY_PRINT_H) $(COMMON_TARGET_H) $(OPTS_H)
|
||||
dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \
|
||||
dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \
|
||||
$(TM_H) version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \
|
||||
gt-dwarf2cfi.h debug.h $(DWARF2_H) dwarf2asm.h $(DWARF2OUT_H) $(COMMON_TARGET_H) \
|
||||
$(GGC_H) $(TM_P_H) $(TARGET_H) $(TREE_PASS_H) $(BASIC_BLOCK_H) $(EXCEPT_H)
|
||||
dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
|
@ -2965,7 +2971,7 @@ coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
tree-iterator.h $(CGRAPH_H) gcov-io.c $(TM_P_H) \
|
||||
$(DIAGNOSTIC_CORE_H) intl.h gt-coverage.h $(TARGET_H) $(HASH_TABLE_H)
|
||||
cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
|
||||
$(TM_H) $(RTL_H) \
|
||||
$(HASH_TABLE_H) $(TM_H) $(RTL_H) \
|
||||
$(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) \
|
||||
$(EMIT_RTL_H) $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) \
|
||||
cselib.h gt-cselib.h $(GGC_H) $(TM_P_H) $(PARAMS_H) alloc-pool.h \
|
||||
|
@ -3005,12 +3011,13 @@ cprop.o : cprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
|||
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \
|
||||
$(DF_H) $(CFGLOOP_H)
|
||||
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
|
||||
$(HASH_TABLE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
|
||||
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) toplev.h $(DIAGNOSTIC_CORE_H) \
|
||||
$(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) gt-gcse.h $(TREE_H) \
|
||||
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \
|
||||
$(DF_H) gcse.h
|
||||
store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(HASH_TABLE_H) $(TM_H) $(RTL_H) \
|
||||
$(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
|
||||
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) toplev.h $(DIAGNOSTIC_CORE_H) \
|
||||
$(TM_P_H) $(EXCEPT_H) $(TREE_H) \
|
||||
|
@ -3043,9 +3050,9 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
$(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h
|
||||
tree-ssa-strlen.o : tree-ssa-strlen.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h alloc-pool.h tree-ssa-propagate.h \
|
||||
$(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H)
|
||||
$(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H) $(HASH_TABLE_H)
|
||||
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
|
||||
$(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \
|
||||
$(HASH_TABLE_H) $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \
|
||||
$(IPA_PROP_H) $(DIAGNOSTIC_H) statistics.h \
|
||||
$(PARAMS_H) $(TARGET_H) $(FLAGS_H) \
|
||||
$(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
|
||||
|
@ -3056,7 +3063,7 @@ tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
|
|||
$(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \
|
||||
$(GIMPLE_PRETTY_PRINT_H) langhooks.h
|
||||
tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
|
||||
$(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \
|
||||
$(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(TREE_HASHER_H) $(GIMPLE_H) \
|
||||
tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h
|
||||
tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
|
||||
$(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \
|
||||
|
@ -3114,7 +3121,7 @@ loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
$(DUMPFILE_H) $(TM_H) \
|
||||
$(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
|
||||
$(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) $(PARAMS_H) $(TARGET_H)
|
||||
alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
|
||||
alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASH_TABLE_H)
|
||||
auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \
|
||||
$(REGS_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) \
|
||||
|
@ -3162,12 +3169,12 @@ graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) $(BITMAP_H) $(OBSTACK_H)
|
|||
loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
|
||||
$(RTL_H) $(BASIC_BLOCK_H) \
|
||||
hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(TM_H) $(OBSTACK_H) \
|
||||
intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASHTAB_H)
|
||||
intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASH_TABLE_H)
|
||||
loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(DUMPFILE_H) \
|
||||
$(RTL_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) \
|
||||
$(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(TARGET_H) \
|
||||
$(OBSTACK_H) $(HASHTAB_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h
|
||||
$(OBSTACK_H) $(HASH_TABLE_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h
|
||||
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
|
||||
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \
|
||||
coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_FLOW_H)
|
||||
|
@ -3181,8 +3188,7 @@ loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
$(EXPR_H) $(TM_H) $(OBSTACK_H)
|
||||
loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
|
||||
$(RTL_H) $(TM_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(PARAMS_H) \
|
||||
$(EXPR_H) $(TM_H) $(HASHTAB_H) $(RECOG_H) \
|
||||
$(OBSTACK_H)
|
||||
$(EXPR_H) $(TM_H) $(HASH_TABLE_H) $(RECOG_H) $(OBSTACK_H)
|
||||
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) \
|
||||
$(TIMEVAR_H) graphds.h pointer-set.h $(BITMAP_H)
|
||||
|
@ -3201,7 +3207,7 @@ reginfo.o : reginfo.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
|||
$(FUNCTION_H) output.h $(TM_P_H) $(EXPR_H) $(HASHTAB_H) \
|
||||
$(TARGET_H) $(TREE_PASS_H) $(DF_H) ira.h
|
||||
bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) \
|
||||
$(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASHTAB_H)
|
||||
$(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASH_TABLE_H)
|
||||
vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) $(GGC_H) \
|
||||
$(DIAGNOSTIC_CORE_H) $(HASHTAB_H)
|
||||
hash-table.o : hash-table.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
|
@ -3226,8 +3232,8 @@ postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
|
||||
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) $(DIAGNOSTIC_CORE_H) \
|
||||
$(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \
|
||||
$(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H)
|
||||
$(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TARGET_H) $(HASH_TABLE_H) intl.h \
|
||||
$(OBSTACK_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H)
|
||||
caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(DUMPFILE_H) $(TM_H) $(RTL_H) \
|
||||
$(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
|
||||
|
@ -3261,14 +3267,14 @@ ira-build.o: ira-build.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
$(PARAMS_H) $(DF_H) sparseset.h $(IRA_INT_H) reload.h
|
||||
ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
hard-reg-set.h $(RTL_H) $(EXPR_H) $(TM_P_H) $(FLAGS_H) $(BASIC_BLOCK_H) \
|
||||
$(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) $(TARGET_H) \
|
||||
$(PARAMS_H) $(IRA_INT_H) reload.h
|
||||
$(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) \
|
||||
$(HASH_TABLE_H) $(TARGET_H) $(PARAMS_H) $(IRA_INT_H) reload.h
|
||||
ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(TREE_H) $(FLAGS_H) \
|
||||
insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(PARAMS_H) \
|
||||
$(DF_H) sparseset.h addresses.h $(IRA_INT_H)
|
||||
ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
|
||||
$(HASH_TABLE_H) $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
|
||||
$(EXPR_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) reload.h $(PARAMS_H) \
|
||||
$(DF_H) $(IRA_INT_H)
|
||||
ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
|
@ -3348,7 +3354,7 @@ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
$(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
|
||||
$(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) \
|
||||
$(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) $(COMMON_TARGET_H) \
|
||||
$(HASHTAB_H)
|
||||
$(HASH_TABLE_H)
|
||||
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
|
||||
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
|
||||
|
|
|
@ -82,6 +82,7 @@ struct alloc_pool_descriptor
|
|||
int elt_size;
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor>
|
||||
{
|
||||
typedef alloc_pool_descriptor value_type;
|
||||
|
@ -90,10 +91,6 @@ struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor>
|
|||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hashtable mapping alloc_pool names to descriptors. */
|
||||
static hash_table <alloc_pool_hasher> alloc_pool_hash;
|
||||
|
||||
/* Hashtable helpers. */
|
||||
inline hashval_t
|
||||
alloc_pool_hasher::hash (const value_type *d)
|
||||
{
|
||||
|
@ -107,6 +104,9 @@ alloc_pool_hasher::equal (const value_type *d,
|
|||
return d->name == p2;
|
||||
}
|
||||
|
||||
/* Hashtable mapping alloc_pool names to descriptors. */
|
||||
static hash_table <alloc_pool_hasher> alloc_pool_hash;
|
||||
|
||||
/* For given name, return descriptor, create new if needed. */
|
||||
static struct alloc_pool_descriptor *
|
||||
allocate_pool_descriptor (const char *name)
|
||||
|
|
|
@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cpplib.h"
|
||||
#include "target.h"
|
||||
#include "langhooks.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "plugin.h"
|
||||
|
||||
/* Table of the tables of attributes (common, language, format, machine)
|
||||
|
@ -44,13 +44,45 @@ struct substring
|
|||
int length;
|
||||
};
|
||||
|
||||
/* Simple hash function to avoid need to scan whole string. */
|
||||
|
||||
static inline hashval_t
|
||||
substring_hash (const char *str, int l)
|
||||
{
|
||||
return str[0] + str[l - 1] * 256 + l * 65536;
|
||||
}
|
||||
|
||||
/* Used for attribute_hash. */
|
||||
|
||||
struct attribute_hasher : typed_noop_remove <attribute_spec>
|
||||
{
|
||||
typedef attribute_spec value_type;
|
||||
typedef substring compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
attribute_hasher::hash (const value_type *spec)
|
||||
{
|
||||
const int l = strlen (spec->name);
|
||||
return substring_hash (spec->name, l);
|
||||
}
|
||||
|
||||
inline bool
|
||||
attribute_hasher::equal (const value_type *spec, const compare_type *str)
|
||||
{
|
||||
return (strncmp (spec->name, str->str, str->length) == 0
|
||||
&& !spec->name[str->length]);
|
||||
}
|
||||
|
||||
/* Scoped attribute name representation. */
|
||||
|
||||
struct scoped_attributes
|
||||
{
|
||||
const char *ns;
|
||||
vec<attribute_spec> attributes;
|
||||
htab_t attribute_hash;
|
||||
hash_table <attribute_hasher> attribute_hash;
|
||||
};
|
||||
|
||||
/* The table of scope attributes. */
|
||||
|
@ -83,36 +115,6 @@ extract_attribute_substring (struct substring *str)
|
|||
}
|
||||
}
|
||||
|
||||
/* Simple hash function to avoid need to scan whole string. */
|
||||
|
||||
static inline hashval_t
|
||||
substring_hash (const char *str, int l)
|
||||
{
|
||||
return str[0] + str[l - 1] * 256 + l * 65536;
|
||||
}
|
||||
|
||||
/* Used for attribute_hash. */
|
||||
|
||||
static hashval_t
|
||||
hash_attr (const void *p)
|
||||
{
|
||||
const struct attribute_spec *const spec = (const struct attribute_spec *) p;
|
||||
const int l = strlen (spec->name);
|
||||
|
||||
return substring_hash (spec->name, l);
|
||||
}
|
||||
|
||||
/* Used for attribute_hash. */
|
||||
|
||||
static int
|
||||
eq_attr (const void *p, const void *q)
|
||||
{
|
||||
const struct attribute_spec *const spec = (const struct attribute_spec *) p;
|
||||
const struct substring *const str = (const struct substring *) q;
|
||||
|
||||
return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]);
|
||||
}
|
||||
|
||||
/* Insert an array of attributes ATTRIBUTES into a namespace. This
|
||||
array must be NULL terminated. NS is the name of attribute
|
||||
namespace. The function returns the namespace into which the
|
||||
|
@ -139,7 +141,7 @@ register_scoped_attributes (const struct attribute_spec * attributes,
|
|||
sa.ns = ns;
|
||||
sa.attributes.create (64);
|
||||
result = attributes_table.safe_push (sa);
|
||||
result->attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
|
||||
result->attribute_hash.create (200);
|
||||
}
|
||||
|
||||
/* Really add the attributes to their namespace now. */
|
||||
|
@ -272,11 +274,11 @@ register_scoped_attribute (const struct attribute_spec *attr,
|
|||
scoped_attributes *name_space)
|
||||
{
|
||||
struct substring str;
|
||||
void **slot;
|
||||
attribute_spec **slot;
|
||||
|
||||
gcc_assert (attr != NULL && name_space != NULL);
|
||||
|
||||
gcc_assert (name_space->attribute_hash != NULL);
|
||||
gcc_assert (name_space->attribute_hash.is_created ());
|
||||
|
||||
str.str = attr->name;
|
||||
str.length = strlen (str.str);
|
||||
|
@ -285,11 +287,11 @@ register_scoped_attribute (const struct attribute_spec *attr,
|
|||
in the form '__text__'. */
|
||||
gcc_assert (str.length > 0 && str.str[0] != '_');
|
||||
|
||||
slot = htab_find_slot_with_hash (name_space->attribute_hash, &str,
|
||||
substring_hash (str.str, str.length),
|
||||
INSERT);
|
||||
slot = name_space->attribute_hash
|
||||
.find_slot_with_hash (&str, substring_hash (str.str, str.length),
|
||||
INSERT);
|
||||
gcc_assert (!*slot || attr->name[0] == '*');
|
||||
*slot = (void *) CONST_CAST (struct attribute_spec *, attr);
|
||||
*slot = CONST_CAST (struct attribute_spec *, attr);
|
||||
}
|
||||
|
||||
/* Return the spec for the scoped attribute with namespace NS and
|
||||
|
@ -311,8 +313,7 @@ lookup_scoped_attribute_spec (const_tree ns, const_tree name)
|
|||
attr.str = IDENTIFIER_POINTER (name);
|
||||
attr.length = IDENTIFIER_LENGTH (name);
|
||||
extract_attribute_substring (&attr);
|
||||
return (const struct attribute_spec *)
|
||||
htab_find_with_hash (attrs->attribute_hash, &attr,
|
||||
return attrs->attribute_hash.find_with_hash (&attr,
|
||||
substring_hash (attr.str, attr.length));
|
||||
}
|
||||
|
||||
|
|
64
gcc/bitmap.c
64
gcc/bitmap.c
|
@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "obstack.h"
|
||||
#include "ggc.h"
|
||||
#include "bitmap.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "vec.h"
|
||||
|
||||
/* Store information about each particular bitmap, per allocation site. */
|
||||
|
@ -50,48 +50,55 @@ static int next_bitmap_desc_id = 0;
|
|||
/* Vector mapping descriptor ids to descriptors. */
|
||||
static vec<bitmap_descriptor> bitmap_descriptors;
|
||||
|
||||
/* Hashtable mapping bitmap names to descriptors. */
|
||||
static htab_t bitmap_desc_hash;
|
||||
|
||||
/* Hashtable helpers. */
|
||||
static hashval_t
|
||||
hash_descriptor (const void *p)
|
||||
{
|
||||
const_bitmap_descriptor d = (const_bitmap_descriptor) p;
|
||||
return htab_hash_pointer (d->file) + d->line;
|
||||
}
|
||||
|
||||
struct loc
|
||||
{
|
||||
const char *file;
|
||||
const char *function;
|
||||
int line;
|
||||
};
|
||||
static int
|
||||
eq_descriptor (const void *p1, const void *p2)
|
||||
|
||||
struct bitmap_desc_hasher : typed_noop_remove <bitmap_descriptor_d>
|
||||
{
|
||||
typedef bitmap_descriptor_d value_type;
|
||||
typedef loc compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
bitmap_desc_hasher::hash (const value_type *d)
|
||||
{
|
||||
return htab_hash_pointer (d->file) + d->line;
|
||||
}
|
||||
|
||||
inline bool
|
||||
bitmap_desc_hasher::equal (const value_type *d, const compare_type *l)
|
||||
{
|
||||
const_bitmap_descriptor d = (const_bitmap_descriptor) p1;
|
||||
const struct loc *const l = (const struct loc *) p2;
|
||||
return d->file == l->file && d->function == l->function && d->line == l->line;
|
||||
}
|
||||
|
||||
/* Hashtable mapping bitmap names to descriptors. */
|
||||
static hash_table <bitmap_desc_hasher> bitmap_desc_hash;
|
||||
|
||||
/* For given file and line, return descriptor, create new if needed. */
|
||||
static bitmap_descriptor
|
||||
get_bitmap_descriptor (const char *file, int line, const char *function)
|
||||
{
|
||||
bitmap_descriptor *slot;
|
||||
bitmap_descriptor_d **slot;
|
||||
struct loc loc;
|
||||
|
||||
loc.file = file;
|
||||
loc.function = function;
|
||||
loc.line = line;
|
||||
|
||||
if (!bitmap_desc_hash)
|
||||
bitmap_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
|
||||
if (!bitmap_desc_hash.is_created ())
|
||||
bitmap_desc_hash.create (10);
|
||||
|
||||
slot = (bitmap_descriptor *)
|
||||
htab_find_slot_with_hash (bitmap_desc_hash, &loc,
|
||||
htab_hash_pointer (file) + line,
|
||||
INSERT);
|
||||
slot = bitmap_desc_hash.find_slot_with_hash (&loc,
|
||||
htab_hash_pointer (file) + line,
|
||||
INSERT);
|
||||
if (*slot)
|
||||
return *slot;
|
||||
|
||||
|
@ -2141,13 +2148,12 @@ struct output_info
|
|||
unsigned HOST_WIDEST_INT count;
|
||||
};
|
||||
|
||||
/* Called via htab_traverse. Output bitmap descriptor pointed out by SLOT
|
||||
and update statistics. */
|
||||
static int
|
||||
print_statistics (void **slot, void *b)
|
||||
/* Called via hash_table::traverse. Output bitmap descriptor pointed out by
|
||||
SLOT and update statistics. */
|
||||
int
|
||||
print_statistics (bitmap_descriptor_d **slot, output_info *i)
|
||||
{
|
||||
bitmap_descriptor d = (bitmap_descriptor) *slot;
|
||||
struct output_info *i = (struct output_info *) b;
|
||||
bitmap_descriptor d = *slot;
|
||||
char s[4096];
|
||||
|
||||
if (d->allocated)
|
||||
|
@ -2181,7 +2187,7 @@ dump_bitmap_statistics (void)
|
|||
if (! GATHER_STATISTICS)
|
||||
return;
|
||||
|
||||
if (!bitmap_desc_hash)
|
||||
if (!bitmap_desc_hash.is_created ())
|
||||
return;
|
||||
|
||||
fprintf (stderr,
|
||||
|
@ -2192,7 +2198,7 @@ dump_bitmap_statistics (void)
|
|||
fprintf (stderr, "---------------------------------------------------------------------------------\n");
|
||||
info.count = 0;
|
||||
info.size = 0;
|
||||
htab_traverse (bitmap_desc_hash, print_statistics, &info);
|
||||
bitmap_desc_hash.traverse <output_info *, print_statistics> (&info);
|
||||
fprintf (stderr, "---------------------------------------------------------------------------------\n");
|
||||
fprintf (stderr,
|
||||
"%-41s %9"HOST_WIDEST_INT_PRINT"d %15"HOST_WIDEST_INT_PRINT"d\n",
|
||||
|
|
178
gcc/cselib.c
178
gcc/cselib.c
|
@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "emit-rtl.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "ggc.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "dumpfile.h"
|
||||
#include "cselib.h"
|
||||
#include "valtrack.h"
|
||||
|
@ -49,18 +49,18 @@ struct elt_list {
|
|||
cselib_val *elt;
|
||||
};
|
||||
|
||||
/* See the documentation of cselib_find_slot below. */
|
||||
static enum machine_mode find_slot_memmode;
|
||||
|
||||
static bool cselib_record_memory;
|
||||
static bool cselib_preserve_constants;
|
||||
static bool cselib_any_perm_equivs;
|
||||
static int entry_and_rtx_equal_p (const void *, const void *);
|
||||
static hashval_t get_value_hash (const void *);
|
||||
static inline void promote_debug_loc (struct elt_loc_list *l);
|
||||
static struct elt_list *new_elt_list (struct elt_list *, cselib_val *);
|
||||
static void new_elt_loc_list (cselib_val *, rtx);
|
||||
static void unchain_one_value (cselib_val *);
|
||||
static void unchain_one_elt_list (struct elt_list **);
|
||||
static void unchain_one_elt_loc_list (struct elt_loc_list **);
|
||||
static int discard_useless_locs (void **, void *);
|
||||
static int discard_useless_values (void **, void *);
|
||||
static void remove_useless_values (void);
|
||||
static int rtx_equal_for_cselib_1 (rtx, rtx, enum machine_mode);
|
||||
static unsigned int cselib_hash_rtx (rtx, int, enum machine_mode);
|
||||
|
@ -91,8 +91,61 @@ static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int);
|
|||
this involves walking the table entries for a given value and comparing
|
||||
the locations of the entries with the rtx we are looking up. */
|
||||
|
||||
struct cselib_hasher : typed_noop_remove <cselib_val>
|
||||
{
|
||||
typedef cselib_val value_type;
|
||||
typedef rtx_def compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* The hash function for our hash table. The value is always computed with
|
||||
cselib_hash_rtx when adding an element; this function just extracts the
|
||||
hash value from a cselib_val structure. */
|
||||
|
||||
inline hashval_t
|
||||
cselib_hasher::hash (const value_type *v)
|
||||
{
|
||||
return v->hash;
|
||||
}
|
||||
|
||||
/* The equality test for our hash table. The first argument V is a table
|
||||
element (i.e. a cselib_val), while the second arg X is an rtx. We know
|
||||
that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a
|
||||
CONST of an appropriate mode. */
|
||||
|
||||
inline bool
|
||||
cselib_hasher::equal (const value_type *v, const compare_type *x_arg)
|
||||
{
|
||||
struct elt_loc_list *l;
|
||||
rtx x = CONST_CAST_RTX (x_arg);
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
|
||||
gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED);
|
||||
|
||||
if (mode != GET_MODE (v->val_rtx))
|
||||
return false;
|
||||
|
||||
/* Unwrap X if necessary. */
|
||||
if (GET_CODE (x) == CONST
|
||||
&& (CONST_SCALAR_INT_P (XEXP (x, 0))
|
||||
|| GET_CODE (XEXP (x, 0)) == CONST_FIXED))
|
||||
x = XEXP (x, 0);
|
||||
|
||||
/* We don't guarantee that distinct rtx's have different hash values,
|
||||
so we need to do a comparison. */
|
||||
for (l = v->locs; l; l = l->next)
|
||||
if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode))
|
||||
{
|
||||
promote_debug_loc (l);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A table that enables us to look up elts by their value. */
|
||||
static htab_t cselib_hash_table;
|
||||
static hash_table <cselib_hasher> cselib_hash_table;
|
||||
|
||||
/* This is a global so we don't have to pass this through every function.
|
||||
It is used in new_elt_loc_list to set SETTING_INSN. */
|
||||
|
@ -432,13 +485,13 @@ invariant_or_equiv_p (cselib_val *v)
|
|||
/* Remove from hash table all VALUEs except constants, function
|
||||
invariants and VALUE equivalences. */
|
||||
|
||||
static int
|
||||
preserve_constants_and_equivs (void **x, void *info ATTRIBUTE_UNUSED)
|
||||
int
|
||||
preserve_constants_and_equivs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
|
||||
{
|
||||
cselib_val *v = (cselib_val *)*x;
|
||||
cselib_val *v = *x;
|
||||
|
||||
if (!invariant_or_equiv_p (v))
|
||||
htab_clear_slot (cselib_hash_table, x);
|
||||
cselib_hash_table.clear_slot (x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -478,10 +531,10 @@ cselib_reset_table (unsigned int num)
|
|||
}
|
||||
|
||||
if (cselib_preserve_constants)
|
||||
htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL);
|
||||
cselib_hash_table.traverse <void *, preserve_constants_and_equivs> (NULL);
|
||||
else
|
||||
{
|
||||
htab_empty (cselib_hash_table);
|
||||
cselib_hash_table.empty ();
|
||||
gcc_checking_assert (!cselib_any_perm_equivs);
|
||||
}
|
||||
|
||||
|
@ -502,73 +555,23 @@ cselib_get_next_uid (void)
|
|||
return next_uid;
|
||||
}
|
||||
|
||||
/* See the documentation of cselib_find_slot below. */
|
||||
static enum machine_mode find_slot_memmode;
|
||||
|
||||
/* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE,
|
||||
INSERTing if requested. When X is part of the address of a MEM,
|
||||
MEMMODE should specify the mode of the MEM. While searching the
|
||||
table, MEMMODE is held in FIND_SLOT_MEMMODE, so that autoinc RTXs
|
||||
in X can be resolved. */
|
||||
|
||||
static void **
|
||||
static cselib_val **
|
||||
cselib_find_slot (rtx x, hashval_t hash, enum insert_option insert,
|
||||
enum machine_mode memmode)
|
||||
{
|
||||
void **slot;
|
||||
cselib_val **slot;
|
||||
find_slot_memmode = memmode;
|
||||
slot = htab_find_slot_with_hash (cselib_hash_table, x, hash, insert);
|
||||
slot = cselib_hash_table.find_slot_with_hash (x, hash, insert);
|
||||
find_slot_memmode = VOIDmode;
|
||||
return slot;
|
||||
}
|
||||
|
||||
/* The equality test for our hash table. The first argument ENTRY is a table
|
||||
element (i.e. a cselib_val), while the second arg X is an rtx. We know
|
||||
that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a
|
||||
CONST of an appropriate mode. */
|
||||
|
||||
static int
|
||||
entry_and_rtx_equal_p (const void *entry, const void *x_arg)
|
||||
{
|
||||
struct elt_loc_list *l;
|
||||
const cselib_val *const v = (const cselib_val *) entry;
|
||||
rtx x = CONST_CAST_RTX ((const_rtx)x_arg);
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
|
||||
gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED);
|
||||
|
||||
if (mode != GET_MODE (v->val_rtx))
|
||||
return 0;
|
||||
|
||||
/* Unwrap X if necessary. */
|
||||
if (GET_CODE (x) == CONST
|
||||
&& (CONST_SCALAR_INT_P (XEXP (x, 0))
|
||||
|| GET_CODE (XEXP (x, 0)) == CONST_FIXED))
|
||||
x = XEXP (x, 0);
|
||||
|
||||
/* We don't guarantee that distinct rtx's have different hash values,
|
||||
so we need to do a comparison. */
|
||||
for (l = v->locs; l; l = l->next)
|
||||
if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode))
|
||||
{
|
||||
promote_debug_loc (l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The hash function for our hash table. The value is always computed with
|
||||
cselib_hash_rtx when adding an element; this function just extracts the
|
||||
hash value from a cselib_val structure. */
|
||||
|
||||
static hashval_t
|
||||
get_value_hash (const void *entry)
|
||||
{
|
||||
const cselib_val *const v = (const cselib_val *) entry;
|
||||
return v->hash;
|
||||
}
|
||||
|
||||
/* Return true if X contains a VALUE rtx. If ONLY_USELESS is set, we
|
||||
only return true for values which point to a cselib_val whose value
|
||||
element has been set to zero, which implies the cselib_val will be
|
||||
|
@ -603,10 +606,10 @@ references_value_p (const_rtx x, int only_useless)
|
|||
values (i.e. values without any location). Called through
|
||||
htab_traverse. */
|
||||
|
||||
static int
|
||||
discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED)
|
||||
int
|
||||
discard_useless_locs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
|
||||
{
|
||||
cselib_val *v = (cselib_val *)*x;
|
||||
cselib_val *v = *x;
|
||||
struct elt_loc_list **p = &v->locs;
|
||||
bool had_locs = v->locs != NULL;
|
||||
rtx setting_insn = v->locs ? v->locs->setting_insn : NULL;
|
||||
|
@ -632,10 +635,10 @@ discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED)
|
|||
|
||||
/* If X is a value with no locations, remove it from the hashtable. */
|
||||
|
||||
static int
|
||||
discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED)
|
||||
int
|
||||
discard_useless_values (cselib_val **x, void *info ATTRIBUTE_UNUSED)
|
||||
{
|
||||
cselib_val *v = (cselib_val *)*x;
|
||||
cselib_val *v = *x;
|
||||
|
||||
if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
|
||||
{
|
||||
|
@ -643,7 +646,7 @@ discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED)
|
|||
cselib_discard_hook (v);
|
||||
|
||||
CSELIB_VAL_PTR (v->val_rtx) = NULL;
|
||||
htab_clear_slot (cselib_hash_table, x);
|
||||
cselib_hash_table.clear_slot (x);
|
||||
unchain_one_value (v);
|
||||
n_useless_values--;
|
||||
}
|
||||
|
@ -664,7 +667,7 @@ remove_useless_values (void)
|
|||
do
|
||||
{
|
||||
values_became_useless = 0;
|
||||
htab_traverse (cselib_hash_table, discard_useless_locs, 0);
|
||||
cselib_hash_table.traverse <void *, discard_useless_locs> (NULL);
|
||||
}
|
||||
while (values_became_useless);
|
||||
|
||||
|
@ -683,7 +686,7 @@ remove_useless_values (void)
|
|||
n_debug_values -= n_useless_debug_values;
|
||||
n_useless_debug_values = 0;
|
||||
|
||||
htab_traverse (cselib_hash_table, discard_useless_values, 0);
|
||||
cselib_hash_table.traverse <void *, discard_useless_values> (NULL);
|
||||
|
||||
gcc_assert (!n_useless_values);
|
||||
}
|
||||
|
@ -1352,7 +1355,7 @@ cselib_lookup_mem (rtx x, int create)
|
|||
{
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
enum machine_mode addr_mode;
|
||||
void **slot;
|
||||
cselib_val **slot;
|
||||
cselib_val *addr;
|
||||
cselib_val *mem_elt;
|
||||
struct elt_list *l;
|
||||
|
@ -1958,7 +1961,7 @@ static cselib_val *
|
|||
cselib_lookup_1 (rtx x, enum machine_mode mode,
|
||||
int create, enum machine_mode memmode)
|
||||
{
|
||||
void **slot;
|
||||
cselib_val **slot;
|
||||
cselib_val *e;
|
||||
unsigned int hashval;
|
||||
|
||||
|
@ -2069,7 +2072,7 @@ cselib_lookup_1 (rtx x, enum machine_mode mode,
|
|||
/* We have to fill the slot before calling cselib_subst_to_values:
|
||||
the hash table is inconsistent until we do so, and
|
||||
cselib_subst_to_values will need to do lookups. */
|
||||
*slot = (void *) e;
|
||||
*slot = e;
|
||||
new_elt_loc_list (e, cselib_subst_to_values (x, memmode));
|
||||
return e;
|
||||
}
|
||||
|
@ -2695,9 +2698,7 @@ cselib_process_insn (rtx insn)
|
|||
quadratic behavior for very large hashtables with very few
|
||||
useless elements. */
|
||||
&& ((unsigned int)n_useless_values
|
||||
> (cselib_hash_table->n_elements
|
||||
- cselib_hash_table->n_deleted
|
||||
- n_debug_values) / 4))
|
||||
> (cselib_hash_table.elements () - n_debug_values) / 4))
|
||||
remove_useless_values ();
|
||||
}
|
||||
|
||||
|
@ -2738,8 +2739,7 @@ cselib_init (int record_what)
|
|||
}
|
||||
used_regs = XNEWVEC (unsigned int, cselib_nregs);
|
||||
n_used_regs = 0;
|
||||
cselib_hash_table = htab_create (31, get_value_hash,
|
||||
entry_and_rtx_equal_p, NULL);
|
||||
cselib_hash_table.create (31);
|
||||
next_uid = 1;
|
||||
}
|
||||
|
||||
|
@ -2758,23 +2758,21 @@ cselib_finish (void)
|
|||
free_alloc_pool (cselib_val_pool);
|
||||
free_alloc_pool (value_pool);
|
||||
cselib_clear_table ();
|
||||
htab_delete (cselib_hash_table);
|
||||
cselib_hash_table.dispose ();
|
||||
free (used_regs);
|
||||
used_regs = 0;
|
||||
cselib_hash_table = 0;
|
||||
n_useless_values = 0;
|
||||
n_useless_debug_values = 0;
|
||||
n_debug_values = 0;
|
||||
next_uid = 0;
|
||||
}
|
||||
|
||||
/* Dump the cselib_val *X to FILE *info. */
|
||||
/* Dump the cselib_val *X to FILE *OUT. */
|
||||
|
||||
static int
|
||||
dump_cselib_val (void **x, void *info)
|
||||
int
|
||||
dump_cselib_val (cselib_val **x, FILE *out)
|
||||
{
|
||||
cselib_val *v = (cselib_val *)*x;
|
||||
FILE *out = (FILE *)info;
|
||||
cselib_val *v = *x;
|
||||
bool need_lf = true;
|
||||
|
||||
print_inline_rtx (out, v->val_rtx, 0);
|
||||
|
@ -2849,7 +2847,7 @@ void
|
|||
dump_cselib_table (FILE *out)
|
||||
{
|
||||
fprintf (out, "cselib hash table:\n");
|
||||
htab_traverse (cselib_hash_table, dump_cselib_val, out);
|
||||
cselib_hash_table.traverse <FILE *, dump_cselib_val> (out);
|
||||
if (first_containing_mem != &dummy_val)
|
||||
{
|
||||
fputs ("first mem ", out);
|
||||
|
|
|
@ -42,8 +42,7 @@ streamer_string_index (struct output_block *ob, const char *s, unsigned int len,
|
|||
s_slot.len = len;
|
||||
s_slot.slot_num = 0;
|
||||
|
||||
slot = (struct string_slot **) htab_find_slot (ob->string_hash_table,
|
||||
&s_slot, INSERT);
|
||||
slot = ob->string_hash_table.find_slot (&s_slot, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
struct lto_output_stream *string_stream = ob->string_stream;
|
||||
|
|
|
@ -44,15 +44,6 @@ struct bitpack_d
|
|||
void *stream;
|
||||
};
|
||||
|
||||
|
||||
/* String hashing. */
|
||||
struct string_slot
|
||||
{
|
||||
const char *s;
|
||||
int len;
|
||||
unsigned int slot_num;
|
||||
};
|
||||
|
||||
/* In data-streamer.c */
|
||||
void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT);
|
||||
void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT);
|
||||
|
@ -93,35 +84,6 @@ unsigned HOST_WIDE_INT streamer_read_uhwi (struct lto_input_block *);
|
|||
HOST_WIDE_INT streamer_read_hwi (struct lto_input_block *);
|
||||
gcov_type streamer_read_gcov_count (struct lto_input_block *);
|
||||
|
||||
/* Returns a hash code for P. Adapted from libiberty's htab_hash_string
|
||||
to support strings that may not end in '\0'. */
|
||||
|
||||
static inline hashval_t
|
||||
hash_string_slot_node (const void *p)
|
||||
{
|
||||
const struct string_slot *ds = (const struct string_slot *) p;
|
||||
hashval_t r = ds->len;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ds->len; i++)
|
||||
r = r * 67 + (unsigned)ds->s[i] - 113;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Returns nonzero if P1 and P2 are equal. */
|
||||
|
||||
static inline int
|
||||
eq_string_slot_node (const void *p1, const void *p2)
|
||||
{
|
||||
const struct string_slot *ds1 = (const struct string_slot *) p1;
|
||||
const struct string_slot *ds2 = (const struct string_slot *) p2;
|
||||
|
||||
if (ds1->len == ds2->len)
|
||||
return memcmp (ds1->s, ds2->s, ds1->len) == 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a new bit-packing context for bit-packing into S. */
|
||||
static inline struct bitpack_d
|
||||
bitpack_create (struct lto_output_stream *s)
|
||||
|
|
|
@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "dwarf2out.h"
|
||||
#include "dwarf2asm.h"
|
||||
#include "ggc.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
#include "common/common-target.h"
|
||||
|
@ -153,10 +154,33 @@ typedef struct
|
|||
typedef dw_trace_info *dw_trace_info_ref;
|
||||
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct trace_info_hasher : typed_noop_remove <dw_trace_info>
|
||||
{
|
||||
typedef dw_trace_info value_type;
|
||||
typedef dw_trace_info compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
trace_info_hasher::hash (const value_type *ti)
|
||||
{
|
||||
return INSN_UID (ti->head);
|
||||
}
|
||||
|
||||
inline bool
|
||||
trace_info_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
return a->head == b->head;
|
||||
}
|
||||
|
||||
|
||||
/* The variables making up the pseudo-cfg, as described above. */
|
||||
static vec<dw_trace_info> trace_info;
|
||||
static vec<dw_trace_info_ref> trace_work_list;
|
||||
static htab_t trace_index;
|
||||
static hash_table <trace_info_hasher> trace_index;
|
||||
|
||||
/* A vector of call frame insns for the CIE. */
|
||||
cfi_vec cie_cfi_vec;
|
||||
|
@ -275,28 +299,12 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
|
|||
}
|
||||
|
||||
|
||||
static hashval_t
|
||||
dw_trace_info_hash (const void *ptr)
|
||||
{
|
||||
const dw_trace_info *ti = (const dw_trace_info *) ptr;
|
||||
return INSN_UID (ti->head);
|
||||
}
|
||||
|
||||
static int
|
||||
dw_trace_info_eq (const void *ptr_a, const void *ptr_b)
|
||||
{
|
||||
const dw_trace_info *a = (const dw_trace_info *) ptr_a;
|
||||
const dw_trace_info *b = (const dw_trace_info *) ptr_b;
|
||||
return a->head == b->head;
|
||||
}
|
||||
|
||||
static dw_trace_info *
|
||||
get_trace_info (rtx insn)
|
||||
{
|
||||
dw_trace_info dummy;
|
||||
dummy.head = insn;
|
||||
return (dw_trace_info *)
|
||||
htab_find_with_hash (trace_index, &dummy, INSN_UID (insn));
|
||||
return trace_index.find_with_hash (&dummy, INSN_UID (insn));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -2744,22 +2752,20 @@ create_pseudo_cfg (void)
|
|||
|
||||
/* Create the trace index after we've finished building trace_info,
|
||||
avoiding stale pointer problems due to reallocation. */
|
||||
trace_index = htab_create (trace_info.length (),
|
||||
dw_trace_info_hash, dw_trace_info_eq, NULL);
|
||||
trace_index.create (trace_info.length ());
|
||||
dw_trace_info *tp;
|
||||
FOR_EACH_VEC_ELT (trace_info, i, tp)
|
||||
{
|
||||
void **slot;
|
||||
dw_trace_info **slot;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Creating trace %u : start at %s %d%s\n", i,
|
||||
rtx_name[(int) GET_CODE (tp->head)], INSN_UID (tp->head),
|
||||
tp->switch_sections ? " (section switch)" : "");
|
||||
|
||||
slot = htab_find_slot_with_hash (trace_index, tp,
|
||||
INSN_UID (tp->head), INSERT);
|
||||
slot = trace_index.find_slot_with_hash (tp, INSN_UID (tp->head), INSERT);
|
||||
gcc_assert (*slot == NULL);
|
||||
*slot = (void *) tp;
|
||||
*slot = tp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2908,8 +2914,7 @@ execute_dwarf2_frame (void)
|
|||
}
|
||||
trace_info.release ();
|
||||
|
||||
htab_delete (trace_index);
|
||||
trace_index = NULL;
|
||||
trace_index.dispose ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
450
gcc/dwarf2out.c
450
gcc/dwarf2out.c
|
@ -84,7 +84,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "target.h"
|
||||
#include "common/common-target.h"
|
||||
#include "langhooks.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "cgraph.h"
|
||||
#include "input.h"
|
||||
#include "gimple.h"
|
||||
|
@ -3038,17 +3038,9 @@ static dw_die_ref remove_child_or_replace_with_skeleton (dw_die_ref,
|
|||
dw_die_ref,
|
||||
dw_die_ref);
|
||||
static void break_out_comdat_types (dw_die_ref);
|
||||
static dw_die_ref copy_ancestor_tree (dw_die_ref, dw_die_ref, htab_t);
|
||||
static void copy_decls_walk (dw_die_ref, dw_die_ref, htab_t);
|
||||
static void copy_decls_for_unworthy_types (dw_die_ref);
|
||||
|
||||
static hashval_t htab_cu_hash (const void *);
|
||||
static int htab_cu_eq (const void *, const void *);
|
||||
static void htab_cu_del (void *);
|
||||
static int check_duplicate_cu (dw_die_ref, htab_t, unsigned *);
|
||||
static void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned);
|
||||
static void add_sibling_attributes (dw_die_ref);
|
||||
static void build_abbrev_table (dw_die_ref, htab_t);
|
||||
static void output_location_lists (dw_die_ref);
|
||||
static int constant_size (unsigned HOST_WIDE_INT);
|
||||
static unsigned long size_of_die (dw_die_ref);
|
||||
|
@ -6539,31 +6531,34 @@ struct cu_hash_table_entry
|
|||
struct cu_hash_table_entry *next;
|
||||
};
|
||||
|
||||
/* Routines to manipulate hash table of CUs. */
|
||||
static hashval_t
|
||||
htab_cu_hash (const void *of)
|
||||
{
|
||||
const struct cu_hash_table_entry *const entry =
|
||||
(const struct cu_hash_table_entry *) of;
|
||||
/* Helpers to manipulate hash table of CUs. */
|
||||
|
||||
struct cu_hash_table_entry_hasher
|
||||
{
|
||||
typedef cu_hash_table_entry value_type;
|
||||
typedef die_struct compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
cu_hash_table_entry_hasher::hash (const value_type *entry)
|
||||
{
|
||||
return htab_hash_string (entry->cu->die_id.die_symbol);
|
||||
}
|
||||
|
||||
static int
|
||||
htab_cu_eq (const void *of1, const void *of2)
|
||||
inline bool
|
||||
cu_hash_table_entry_hasher::equal (const value_type *entry1,
|
||||
const compare_type *entry2)
|
||||
{
|
||||
const struct cu_hash_table_entry *const entry1 =
|
||||
(const struct cu_hash_table_entry *) of1;
|
||||
const struct die_struct *const entry2 = (const struct die_struct *) of2;
|
||||
|
||||
return !strcmp (entry1->cu->die_id.die_symbol, entry2->die_id.die_symbol);
|
||||
}
|
||||
|
||||
static void
|
||||
htab_cu_del (void *what)
|
||||
inline void
|
||||
cu_hash_table_entry_hasher::remove (value_type *entry)
|
||||
{
|
||||
struct cu_hash_table_entry *next,
|
||||
*entry = (struct cu_hash_table_entry *) what;
|
||||
struct cu_hash_table_entry *next;
|
||||
|
||||
while (entry)
|
||||
{
|
||||
|
@ -6573,19 +6568,21 @@ htab_cu_del (void *what)
|
|||
}
|
||||
}
|
||||
|
||||
typedef hash_table <cu_hash_table_entry_hasher> cu_hash_type;
|
||||
|
||||
/* Check whether we have already seen this CU and set up SYM_NUM
|
||||
accordingly. */
|
||||
static int
|
||||
check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
|
||||
check_duplicate_cu (dw_die_ref cu, cu_hash_type htable, unsigned int *sym_num)
|
||||
{
|
||||
struct cu_hash_table_entry dummy;
|
||||
struct cu_hash_table_entry **slot, *entry, *last = &dummy;
|
||||
|
||||
dummy.max_comdat_num = 0;
|
||||
|
||||
slot = (struct cu_hash_table_entry **)
|
||||
htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_id.die_symbol),
|
||||
INSERT);
|
||||
slot = htable.find_slot_with_hash (cu,
|
||||
htab_hash_string (cu->die_id.die_symbol),
|
||||
INSERT);
|
||||
entry = *slot;
|
||||
|
||||
for (; entry; last = entry, entry = entry->next)
|
||||
|
@ -6611,13 +6608,14 @@ check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
|
|||
|
||||
/* Record SYM_NUM to record of CU in HTABLE. */
|
||||
static void
|
||||
record_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num)
|
||||
record_comdat_symbol_number (dw_die_ref cu, cu_hash_type htable,
|
||||
unsigned int sym_num)
|
||||
{
|
||||
struct cu_hash_table_entry **slot, *entry;
|
||||
|
||||
slot = (struct cu_hash_table_entry **)
|
||||
htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_id.die_symbol),
|
||||
NO_INSERT);
|
||||
slot = htable.find_slot_with_hash (cu,
|
||||
htab_hash_string (cu->die_id.die_symbol),
|
||||
NO_INSERT);
|
||||
entry = *slot;
|
||||
|
||||
entry->max_comdat_num = sym_num;
|
||||
|
@ -6633,7 +6631,7 @@ break_out_includes (dw_die_ref die)
|
|||
dw_die_ref c;
|
||||
dw_die_ref unit = NULL;
|
||||
limbo_die_node *node, **pnode;
|
||||
htab_t cu_hash_table;
|
||||
cu_hash_type cu_hash_table;
|
||||
|
||||
c = die->die_child;
|
||||
if (c) do {
|
||||
|
@ -6666,7 +6664,7 @@ break_out_includes (dw_die_ref die)
|
|||
#endif
|
||||
|
||||
assign_symbol_names (die);
|
||||
cu_hash_table = htab_create (10, htab_cu_hash, htab_cu_eq, htab_cu_del);
|
||||
cu_hash_table.create (10);
|
||||
for (node = limbo_die_list, pnode = &limbo_die_list;
|
||||
node;
|
||||
node = node->next)
|
||||
|
@ -6686,7 +6684,7 @@ break_out_includes (dw_die_ref die)
|
|||
comdat_symbol_number);
|
||||
}
|
||||
}
|
||||
htab_delete (cu_hash_table);
|
||||
cu_hash_table.dispose ();
|
||||
}
|
||||
|
||||
/* Return non-zero if this DIE is a declaration. */
|
||||
|
@ -6861,6 +6859,94 @@ clone_as_declaration (dw_die_ref die)
|
|||
return clone;
|
||||
}
|
||||
|
||||
|
||||
/* Structure to map a DIE in one CU to its copy in a comdat type unit. */
|
||||
|
||||
struct decl_table_entry
|
||||
{
|
||||
dw_die_ref orig;
|
||||
dw_die_ref copy;
|
||||
};
|
||||
|
||||
/* Helpers to manipulate hash table of copied declarations. */
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct decl_table_entry_hasher : typed_free_remove <decl_table_entry>
|
||||
{
|
||||
typedef decl_table_entry value_type;
|
||||
typedef die_struct compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
decl_table_entry_hasher::hash (const value_type *entry)
|
||||
{
|
||||
return htab_hash_pointer (entry->orig);
|
||||
}
|
||||
|
||||
inline bool
|
||||
decl_table_entry_hasher::equal (const value_type *entry1,
|
||||
const compare_type *entry2)
|
||||
{
|
||||
return entry1->orig == entry2;
|
||||
}
|
||||
|
||||
typedef hash_table <decl_table_entry_hasher> decl_hash_type;
|
||||
|
||||
/* Copy DIE and its ancestors, up to, but not including, the compile unit
|
||||
or type unit entry, to a new tree. Adds the new tree to UNIT and returns
|
||||
a pointer to the copy of DIE. If DECL_TABLE is provided, it is used
|
||||
to check if the ancestor has already been copied into UNIT. */
|
||||
|
||||
static dw_die_ref
|
||||
copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table)
|
||||
{
|
||||
dw_die_ref parent = die->die_parent;
|
||||
dw_die_ref new_parent = unit;
|
||||
dw_die_ref copy;
|
||||
decl_table_entry **slot = NULL;
|
||||
struct decl_table_entry *entry = NULL;
|
||||
|
||||
if (decl_table.is_created ())
|
||||
{
|
||||
/* Check if the entry has already been copied to UNIT. */
|
||||
slot = decl_table.find_slot_with_hash (die, htab_hash_pointer (die),
|
||||
INSERT);
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
{
|
||||
entry = *slot;
|
||||
return entry->copy;
|
||||
}
|
||||
|
||||
/* Record in DECL_TABLE that DIE has been copied to UNIT. */
|
||||
entry = XCNEW (struct decl_table_entry);
|
||||
entry->orig = die;
|
||||
entry->copy = NULL;
|
||||
*slot = entry;
|
||||
}
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
dw_die_ref spec = get_AT_ref (parent, DW_AT_specification);
|
||||
if (spec != NULL)
|
||||
parent = spec;
|
||||
if (!is_unit_die (parent))
|
||||
new_parent = copy_ancestor_tree (unit, parent, decl_table);
|
||||
}
|
||||
|
||||
copy = clone_as_declaration (die);
|
||||
add_child_die (new_parent, copy);
|
||||
|
||||
if (decl_table.is_created ())
|
||||
{
|
||||
/* Record the pointer to the copy. */
|
||||
entry->copy = copy;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
/* Copy the declaration context to the new type unit DIE. This includes
|
||||
any surrounding namespace or type declarations. If the DIE has an
|
||||
AT_specification attribute, it also includes attributes and children
|
||||
|
@ -6908,7 +6994,7 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die)
|
|||
if (decl->die_parent != NULL
|
||||
&& !is_unit_die (decl->die_parent))
|
||||
{
|
||||
new_decl = copy_ancestor_tree (unit, decl, NULL);
|
||||
new_decl = copy_ancestor_tree (unit, decl, decl_hash_type ());
|
||||
if (new_decl != NULL)
|
||||
{
|
||||
remove_AT (new_decl, DW_AT_signature);
|
||||
|
@ -7107,106 +7193,16 @@ break_out_comdat_types (dw_die_ref die)
|
|||
} while (next != NULL);
|
||||
}
|
||||
|
||||
/* Structure to map a DIE in one CU to its copy in a comdat type unit. */
|
||||
|
||||
struct decl_table_entry
|
||||
{
|
||||
dw_die_ref orig;
|
||||
dw_die_ref copy;
|
||||
};
|
||||
|
||||
/* Routines to manipulate hash table of copied declarations. */
|
||||
|
||||
static hashval_t
|
||||
htab_decl_hash (const void *of)
|
||||
{
|
||||
const struct decl_table_entry *const entry =
|
||||
(const struct decl_table_entry *) of;
|
||||
|
||||
return htab_hash_pointer (entry->orig);
|
||||
}
|
||||
|
||||
static int
|
||||
htab_decl_eq (const void *of1, const void *of2)
|
||||
{
|
||||
const struct decl_table_entry *const entry1 =
|
||||
(const struct decl_table_entry *) of1;
|
||||
const struct die_struct *const entry2 = (const struct die_struct *) of2;
|
||||
|
||||
return entry1->orig == entry2;
|
||||
}
|
||||
|
||||
static void
|
||||
htab_decl_del (void *what)
|
||||
{
|
||||
struct decl_table_entry *entry = (struct decl_table_entry *) what;
|
||||
|
||||
free (entry);
|
||||
}
|
||||
|
||||
/* Copy DIE and its ancestors, up to, but not including, the compile unit
|
||||
or type unit entry, to a new tree. Adds the new tree to UNIT and returns
|
||||
a pointer to the copy of DIE. If DECL_TABLE is provided, it is used
|
||||
to check if the ancestor has already been copied into UNIT. */
|
||||
|
||||
static dw_die_ref
|
||||
copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
|
||||
{
|
||||
dw_die_ref parent = die->die_parent;
|
||||
dw_die_ref new_parent = unit;
|
||||
dw_die_ref copy;
|
||||
void **slot = NULL;
|
||||
struct decl_table_entry *entry = NULL;
|
||||
|
||||
if (decl_table)
|
||||
{
|
||||
/* Check if the entry has already been copied to UNIT. */
|
||||
slot = htab_find_slot_with_hash (decl_table, die,
|
||||
htab_hash_pointer (die), INSERT);
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
{
|
||||
entry = (struct decl_table_entry *) *slot;
|
||||
return entry->copy;
|
||||
}
|
||||
|
||||
/* Record in DECL_TABLE that DIE has been copied to UNIT. */
|
||||
entry = XCNEW (struct decl_table_entry);
|
||||
entry->orig = die;
|
||||
entry->copy = NULL;
|
||||
*slot = entry;
|
||||
}
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
dw_die_ref spec = get_AT_ref (parent, DW_AT_specification);
|
||||
if (spec != NULL)
|
||||
parent = spec;
|
||||
if (!is_unit_die (parent))
|
||||
new_parent = copy_ancestor_tree (unit, parent, decl_table);
|
||||
}
|
||||
|
||||
copy = clone_as_declaration (die);
|
||||
add_child_die (new_parent, copy);
|
||||
|
||||
if (decl_table != NULL)
|
||||
{
|
||||
/* Record the pointer to the copy. */
|
||||
entry->copy = copy;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* Like clone_tree, but additionally enter all the children into
|
||||
the hash table decl_table. */
|
||||
|
||||
static dw_die_ref
|
||||
clone_tree_hash (dw_die_ref die, htab_t decl_table)
|
||||
clone_tree_hash (dw_die_ref die, decl_hash_type decl_table)
|
||||
{
|
||||
dw_die_ref c;
|
||||
dw_die_ref clone = clone_die (die);
|
||||
struct decl_table_entry *entry;
|
||||
void **slot = htab_find_slot_with_hash (decl_table, die,
|
||||
decl_table_entry **slot = decl_table.find_slot_with_hash (die,
|
||||
htab_hash_pointer (die), INSERT);
|
||||
/* Assert that DIE isn't in the hash table yet. If it would be there
|
||||
before, the ancestors would be necessarily there as well, therefore
|
||||
|
@ -7228,7 +7224,7 @@ clone_tree_hash (dw_die_ref die, htab_t decl_table)
|
|||
type_unit). */
|
||||
|
||||
static void
|
||||
copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
|
||||
copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table)
|
||||
{
|
||||
dw_die_ref c;
|
||||
dw_attr_ref a;
|
||||
|
@ -7239,20 +7235,20 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
|
|||
if (AT_class (a) == dw_val_class_die_ref)
|
||||
{
|
||||
dw_die_ref targ = AT_ref (a);
|
||||
void **slot;
|
||||
decl_table_entry **slot;
|
||||
struct decl_table_entry *entry;
|
||||
|
||||
if (targ->die_mark != 0 || targ->comdat_type_p)
|
||||
continue;
|
||||
|
||||
slot = htab_find_slot_with_hash (decl_table, targ,
|
||||
htab_hash_pointer (targ), INSERT);
|
||||
slot = decl_table.find_slot_with_hash (targ, htab_hash_pointer (targ),
|
||||
INSERT);
|
||||
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
{
|
||||
/* TARG has already been copied, so we just need to
|
||||
modify the reference to point to the copy. */
|
||||
entry = (struct decl_table_entry *) *slot;
|
||||
entry = *slot;
|
||||
a->dw_attr_val.v.val_die_ref.die = entry->copy;
|
||||
}
|
||||
else
|
||||
|
@ -7319,12 +7315,12 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
|
|||
static void
|
||||
copy_decls_for_unworthy_types (dw_die_ref unit)
|
||||
{
|
||||
htab_t decl_table;
|
||||
decl_hash_type decl_table;
|
||||
|
||||
mark_dies (unit);
|
||||
decl_table = htab_create (10, htab_decl_hash, htab_decl_eq, htab_decl_del);
|
||||
decl_table.create (10);
|
||||
copy_decls_walk (unit, unit, decl_table);
|
||||
htab_delete (decl_table);
|
||||
decl_table.dispose ();
|
||||
unmark_dies (unit);
|
||||
}
|
||||
|
||||
|
@ -7379,37 +7375,42 @@ struct external_ref
|
|||
unsigned n_refs;
|
||||
};
|
||||
|
||||
/* Hash an external_ref. */
|
||||
/* Hashtable helpers. */
|
||||
|
||||
static hashval_t
|
||||
hash_external_ref (const void *p)
|
||||
struct external_ref_hasher : typed_free_remove <external_ref>
|
||||
{
|
||||
typedef external_ref value_type;
|
||||
typedef external_ref compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
external_ref_hasher::hash (const value_type *r)
|
||||
{
|
||||
const struct external_ref *r = (const struct external_ref *)p;
|
||||
return htab_hash_pointer (r->type);
|
||||
}
|
||||
|
||||
/* Compare external_refs. */
|
||||
|
||||
static int
|
||||
external_ref_eq (const void *p1, const void *p2)
|
||||
inline bool
|
||||
external_ref_hasher::equal (const value_type *r1, const compare_type *r2)
|
||||
{
|
||||
const struct external_ref *r1 = (const struct external_ref *)p1;
|
||||
const struct external_ref *r2 = (const struct external_ref *)p2;
|
||||
return r1->type == r2->type;
|
||||
}
|
||||
|
||||
typedef hash_table <external_ref_hasher> external_ref_hash_type;
|
||||
|
||||
/* Return a pointer to the external_ref for references to DIE. */
|
||||
|
||||
static struct external_ref *
|
||||
lookup_external_ref (htab_t map, dw_die_ref die)
|
||||
lookup_external_ref (external_ref_hash_type map, dw_die_ref die)
|
||||
{
|
||||
struct external_ref ref, *ref_p;
|
||||
void ** slot;
|
||||
external_ref **slot;
|
||||
|
||||
ref.type = die;
|
||||
slot = htab_find_slot (map, &ref, INSERT);
|
||||
slot = map.find_slot (&ref, INSERT);
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
return (struct external_ref *) *slot;
|
||||
return *slot;
|
||||
|
||||
ref_p = XCNEW (struct external_ref);
|
||||
ref_p->type = die;
|
||||
|
@ -7423,7 +7424,7 @@ lookup_external_ref (htab_t map, dw_die_ref die)
|
|||
references, remember how many we've seen. */
|
||||
|
||||
static void
|
||||
optimize_external_refs_1 (dw_die_ref die, htab_t map)
|
||||
optimize_external_refs_1 (dw_die_ref die, external_ref_hash_type map)
|
||||
{
|
||||
dw_die_ref c;
|
||||
dw_attr_ref a;
|
||||
|
@ -7456,17 +7457,17 @@ optimize_external_refs_1 (dw_die_ref die, htab_t map)
|
|||
points to an external_ref, DATA is the CU we're processing. If we don't
|
||||
already have a local stub, and we have multiple refs, build a stub. */
|
||||
|
||||
static int
|
||||
build_local_stub (void **slot, void *data)
|
||||
int
|
||||
dwarf2_build_local_stub (external_ref **slot, dw_die_ref data)
|
||||
{
|
||||
struct external_ref *ref_p = (struct external_ref *)*slot;
|
||||
struct external_ref *ref_p = *slot;
|
||||
|
||||
if (ref_p->stub == NULL && ref_p->n_refs > 1 && !dwarf_strict)
|
||||
{
|
||||
/* We have multiple references to this type, so build a small stub.
|
||||
Both of these forms are a bit dodgy from the perspective of the
|
||||
DWARF standard, since technically they should have names. */
|
||||
dw_die_ref cu = (dw_die_ref) data;
|
||||
dw_die_ref cu = data;
|
||||
dw_die_ref type = ref_p->type;
|
||||
dw_die_ref stub = NULL;
|
||||
|
||||
|
@ -7494,12 +7495,13 @@ build_local_stub (void **slot, void *data)
|
|||
them which will be applied in build_abbrev_table. This is useful because
|
||||
references to local DIEs are smaller. */
|
||||
|
||||
static htab_t
|
||||
static external_ref_hash_type
|
||||
optimize_external_refs (dw_die_ref die)
|
||||
{
|
||||
htab_t map = htab_create (10, hash_external_ref, external_ref_eq, free);
|
||||
external_ref_hash_type map;
|
||||
map.create (10);
|
||||
optimize_external_refs_1 (die, map);
|
||||
htab_traverse (map, build_local_stub, die);
|
||||
map.traverse <dw_die_ref, dwarf2_build_local_stub> (die);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -7509,7 +7511,7 @@ optimize_external_refs (dw_die_ref die)
|
|||
die are visited recursively. */
|
||||
|
||||
static void
|
||||
build_abbrev_table (dw_die_ref die, htab_t extern_map)
|
||||
build_abbrev_table (dw_die_ref die, external_ref_hash_type extern_map)
|
||||
{
|
||||
unsigned long abbrev_id;
|
||||
unsigned int n_alloc;
|
||||
|
@ -8640,7 +8642,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
|
|||
{
|
||||
const char *secname, *oldsym;
|
||||
char *tmp;
|
||||
htab_t extern_map;
|
||||
external_ref_hash_type extern_map;
|
||||
|
||||
/* Unless we are outputting main CU, we may throw away empty ones. */
|
||||
if (!output_if_empty && die->die_child == NULL)
|
||||
|
@ -8657,7 +8659,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
|
|||
|
||||
build_abbrev_table (die, extern_map);
|
||||
|
||||
htab_delete (extern_map);
|
||||
extern_map.dispose ();
|
||||
|
||||
/* Initialize the beginning DIE offset - and calculate sizes/offsets. */
|
||||
next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
|
||||
|
@ -8830,7 +8832,7 @@ output_comdat_type_unit (comdat_type_node *node)
|
|||
#if defined (OBJECT_FORMAT_ELF)
|
||||
tree comdat_key;
|
||||
#endif
|
||||
htab_t extern_map;
|
||||
external_ref_hash_type extern_map;
|
||||
|
||||
/* First mark all the DIEs in this CU so we know which get local refs. */
|
||||
mark_dies (node->root_die);
|
||||
|
@ -8839,7 +8841,7 @@ output_comdat_type_unit (comdat_type_node *node)
|
|||
|
||||
build_abbrev_table (node->root_die, extern_map);
|
||||
|
||||
htab_delete (extern_map);
|
||||
extern_map.dispose ();
|
||||
|
||||
/* Initialize the beginning DIE offset - and calculate sizes/offsets. */
|
||||
next_die_offset = DWARF_COMDAT_TYPE_UNIT_HEADER_SIZE;
|
||||
|
@ -21326,26 +21328,31 @@ dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
|
|||
}
|
||||
}
|
||||
|
||||
/* Routines to manipulate hash table of CUs. */
|
||||
/* Helpers to manipulate hash table of CUs. */
|
||||
|
||||
static hashval_t
|
||||
htab_macinfo_hash (const void *of)
|
||||
struct macinfo_entry_hasher : typed_noop_remove <macinfo_entry>
|
||||
{
|
||||
const macinfo_entry *const entry =
|
||||
(const macinfo_entry *) of;
|
||||
typedef macinfo_entry value_type;
|
||||
typedef macinfo_entry compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
macinfo_entry_hasher::hash (const value_type *entry)
|
||||
{
|
||||
return htab_hash_string (entry->info);
|
||||
}
|
||||
|
||||
static int
|
||||
htab_macinfo_eq (const void *of1, const void *of2)
|
||||
inline bool
|
||||
macinfo_entry_hasher::equal (const value_type *entry1,
|
||||
const compare_type *entry2)
|
||||
{
|
||||
const macinfo_entry *const entry1 = (const macinfo_entry *) of1;
|
||||
const macinfo_entry *const entry2 = (const macinfo_entry *) of2;
|
||||
|
||||
return !strcmp (entry1->info, entry2->info);
|
||||
}
|
||||
|
||||
typedef hash_table <macinfo_entry_hasher> macinfo_hash_type;
|
||||
|
||||
/* Output a single .debug_macinfo entry. */
|
||||
|
||||
static void
|
||||
|
@ -21434,7 +21441,7 @@ output_macinfo_op (macinfo_entry *ref)
|
|||
|
||||
static unsigned
|
||||
optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
|
||||
htab_t *macinfo_htab)
|
||||
macinfo_hash_type *macinfo_htab)
|
||||
{
|
||||
macinfo_entry *first, *second, *cur, *inc;
|
||||
char linebuf[sizeof (HOST_WIDE_INT) * 3 + 1];
|
||||
|
@ -21443,7 +21450,7 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
|
|||
char *grp_name, *tail;
|
||||
const char *base;
|
||||
unsigned int i, count, encoded_filename_len, linebuf_len;
|
||||
void **slot;
|
||||
macinfo_entry **slot;
|
||||
|
||||
first = &(*macinfo_table)[idx];
|
||||
second = &(*macinfo_table)[idx + 1];
|
||||
|
@ -21521,17 +21528,17 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
|
|||
inc->code = DW_MACRO_GNU_transparent_include;
|
||||
inc->lineno = 0;
|
||||
inc->info = ggc_strdup (grp_name);
|
||||
if (*macinfo_htab == NULL)
|
||||
*macinfo_htab = htab_create (10, htab_macinfo_hash, htab_macinfo_eq, NULL);
|
||||
if (!macinfo_htab->is_created ())
|
||||
macinfo_htab->create (10);
|
||||
/* Avoid emitting duplicates. */
|
||||
slot = htab_find_slot (*macinfo_htab, inc, INSERT);
|
||||
slot = macinfo_htab->find_slot (inc, INSERT);
|
||||
if (*slot != NULL)
|
||||
{
|
||||
inc->code = 0;
|
||||
inc->info = NULL;
|
||||
/* If such an entry has been used before, just emit
|
||||
a DW_MACRO_GNU_transparent_include op. */
|
||||
inc = (macinfo_entry *) *slot;
|
||||
inc = *slot;
|
||||
output_macinfo_op (inc);
|
||||
/* And clear all macinfo_entry in the range to avoid emitting them
|
||||
in the second pass. */
|
||||
|
@ -21544,7 +21551,7 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
|
|||
else
|
||||
{
|
||||
*slot = inc;
|
||||
inc->lineno = htab_elements (*macinfo_htab);
|
||||
inc->lineno = macinfo_htab->elements ();
|
||||
output_macinfo_op (inc);
|
||||
}
|
||||
return count;
|
||||
|
@ -21595,7 +21602,7 @@ output_macinfo (void)
|
|||
unsigned long length = vec_safe_length (macinfo_table);
|
||||
macinfo_entry *ref;
|
||||
vec<macinfo_entry, va_gc> *files = NULL;
|
||||
htab_t macinfo_htab = NULL;
|
||||
macinfo_hash_type macinfo_htab;
|
||||
|
||||
if (! length)
|
||||
return;
|
||||
|
@ -21668,10 +21675,10 @@ output_macinfo (void)
|
|||
ref->code = 0;
|
||||
}
|
||||
|
||||
if (macinfo_htab == NULL)
|
||||
if (!macinfo_htab.is_created ())
|
||||
return;
|
||||
|
||||
htab_delete (macinfo_htab);
|
||||
macinfo_htab.dispose ();
|
||||
|
||||
/* If any DW_MACRO_GNU_transparent_include were used, on those
|
||||
DW_MACRO_GNU_transparent_include entries terminate the
|
||||
|
@ -22410,24 +22417,28 @@ file_table_relative_p (void ** slot, void *param)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Routines to manipulate hash table of comdat type units. */
|
||||
/* Helpers to manipulate hash table of comdat type units. */
|
||||
|
||||
static hashval_t
|
||||
htab_ct_hash (const void *of)
|
||||
struct comdat_type_hasher : typed_noop_remove <comdat_type_node>
|
||||
{
|
||||
typedef comdat_type_node value_type;
|
||||
typedef comdat_type_node compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
comdat_type_hasher::hash (const value_type *type_node)
|
||||
{
|
||||
hashval_t h;
|
||||
const comdat_type_node *const type_node = (const comdat_type_node *) of;
|
||||
|
||||
memcpy (&h, type_node->signature, sizeof (h));
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
htab_ct_eq (const void *of1, const void *of2)
|
||||
inline bool
|
||||
comdat_type_hasher::equal (const value_type *type_node_1,
|
||||
const compare_type *type_node_2)
|
||||
{
|
||||
const comdat_type_node *const type_node_1 = (const comdat_type_node *) of1;
|
||||
const comdat_type_node *const type_node_2 = (const comdat_type_node *) of2;
|
||||
|
||||
return (! memcmp (type_node_1->signature, type_node_2->signature,
|
||||
DWARF_TYPE_SIGNATURE_SIZE));
|
||||
}
|
||||
|
@ -23491,21 +23502,29 @@ compare_locs (dw_loc_descr_ref x, dw_loc_descr_ref y)
|
|||
return x == NULL && y == NULL;
|
||||
}
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct loc_list_hasher : typed_noop_remove <dw_loc_list_struct>
|
||||
{
|
||||
typedef dw_loc_list_struct value_type;
|
||||
typedef dw_loc_list_struct compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Return precomputed hash of location list X. */
|
||||
|
||||
static hashval_t
|
||||
loc_list_hash (const void *x)
|
||||
inline hashval_t
|
||||
loc_list_hasher::hash (const value_type *x)
|
||||
{
|
||||
return ((const struct dw_loc_list_struct *) x)->hash;
|
||||
return x->hash;
|
||||
}
|
||||
|
||||
/* Return 1 if location lists X and Y are the same. */
|
||||
/* Return true if location lists A and B are the same. */
|
||||
|
||||
static int
|
||||
loc_list_eq (const void *x, const void *y)
|
||||
inline bool
|
||||
loc_list_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
const struct dw_loc_list_struct *a = (const struct dw_loc_list_struct *) x;
|
||||
const struct dw_loc_list_struct *b = (const struct dw_loc_list_struct *) y;
|
||||
if (a == b)
|
||||
return 1;
|
||||
if (a->hash != b->hash)
|
||||
|
@ -23520,16 +23539,19 @@ loc_list_eq (const void *x, const void *y)
|
|||
return a == NULL && b == NULL;
|
||||
}
|
||||
|
||||
typedef hash_table <loc_list_hasher> loc_list_hash_type;
|
||||
|
||||
|
||||
/* Recursively optimize location lists referenced from DIE
|
||||
children and share them whenever possible. */
|
||||
|
||||
static void
|
||||
optimize_location_lists_1 (dw_die_ref die, htab_t htab)
|
||||
optimize_location_lists_1 (dw_die_ref die, loc_list_hash_type htab)
|
||||
{
|
||||
dw_die_ref c;
|
||||
dw_attr_ref a;
|
||||
unsigned ix;
|
||||
void **slot;
|
||||
dw_loc_list_struct **slot;
|
||||
|
||||
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
|
||||
if (AT_class (a) == dw_val_class_loc_list)
|
||||
|
@ -23538,12 +23560,11 @@ optimize_location_lists_1 (dw_die_ref die, htab_t htab)
|
|||
/* TODO: perform some optimizations here, before hashing
|
||||
it and storing into the hash table. */
|
||||
hash_loc_list (list);
|
||||
slot = htab_find_slot_with_hash (htab, list, list->hash,
|
||||
INSERT);
|
||||
slot = htab.find_slot_with_hash (list, list->hash, INSERT);
|
||||
if (*slot == NULL)
|
||||
*slot = (void *) list;
|
||||
*slot = list;
|
||||
else
|
||||
a->dw_attr_val.v.val_loc_list = (dw_loc_list_ref) *slot;
|
||||
a->dw_attr_val.v.val_loc_list = *slot;
|
||||
}
|
||||
|
||||
FOR_EACH_CHILD (die, c, optimize_location_lists_1 (c, htab));
|
||||
|
@ -23588,9 +23609,10 @@ index_location_lists (dw_die_ref die)
|
|||
static void
|
||||
optimize_location_lists (dw_die_ref die)
|
||||
{
|
||||
htab_t htab = htab_create (500, loc_list_hash, loc_list_eq, NULL);
|
||||
loc_list_hash_type htab;
|
||||
htab.create (500);
|
||||
optimize_location_lists_1 (die, htab);
|
||||
htab_delete (htab);
|
||||
htab.dispose ();
|
||||
}
|
||||
|
||||
/* Output stuff that dwarf requires at the end of every file,
|
||||
|
@ -23601,7 +23623,7 @@ dwarf2out_finish (const char *filename)
|
|||
{
|
||||
limbo_die_node *node, *next_node;
|
||||
comdat_type_node *ctnode;
|
||||
htab_t comdat_type_table;
|
||||
hash_table <comdat_type_hasher> comdat_type_table;
|
||||
unsigned int i;
|
||||
dw_die_ref main_comp_unit_die;
|
||||
|
||||
|
@ -23870,10 +23892,10 @@ dwarf2out_finish (const char *filename)
|
|||
for (node = limbo_die_list; node; node = node->next)
|
||||
output_comp_unit (node->die, 0);
|
||||
|
||||
comdat_type_table = htab_create (100, htab_ct_hash, htab_ct_eq, NULL);
|
||||
comdat_type_table.create (100);
|
||||
for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
|
||||
{
|
||||
void **slot = htab_find_slot (comdat_type_table, ctnode, INSERT);
|
||||
comdat_type_node **slot = comdat_type_table.find_slot (ctnode, INSERT);
|
||||
|
||||
/* Don't output duplicate types. */
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
|
@ -23891,7 +23913,7 @@ dwarf2out_finish (const char *filename)
|
|||
output_comdat_type_unit (ctnode);
|
||||
*slot = ctnode;
|
||||
}
|
||||
htab_delete (comdat_type_table);
|
||||
comdat_type_table.dispose ();
|
||||
|
||||
/* The AT_pubnames attribute needs to go in all skeleton dies, including
|
||||
both the main_cu and all skeleton TUs. Making this call unconditional
|
||||
|
|
181
gcc/except.c
181
gcc/except.c
|
@ -128,7 +128,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "dwarf2out.h"
|
||||
#include "dwarf2.h"
|
||||
#include "toplev.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "intl.h"
|
||||
#include "ggc.h"
|
||||
#include "tm_p.h"
|
||||
|
@ -166,6 +166,49 @@ struct GTY(()) call_site_record_d
|
|||
rtx landing_pad;
|
||||
int action;
|
||||
};
|
||||
|
||||
/* In the following structure and associated functions,
|
||||
we represent entries in the action table as 1-based indices.
|
||||
Special cases are:
|
||||
|
||||
0: null action record, non-null landing pad; implies cleanups
|
||||
-1: null action record, null landing pad; implies no action
|
||||
-2: no call-site entry; implies must_not_throw
|
||||
-3: we have yet to process outer regions
|
||||
|
||||
Further, no special cases apply to the "next" field of the record.
|
||||
For next, 0 means end of list. */
|
||||
|
||||
struct action_record
|
||||
{
|
||||
int offset;
|
||||
int filter;
|
||||
int next;
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct action_record_hasher : typed_free_remove <action_record>
|
||||
{
|
||||
typedef action_record value_type;
|
||||
typedef action_record compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
action_record_hasher::hash (const value_type *entry)
|
||||
{
|
||||
return entry->next * 1009 + entry->filter;
|
||||
}
|
||||
|
||||
inline bool
|
||||
action_record_hasher::equal (const value_type *entry, const compare_type *data)
|
||||
{
|
||||
return entry->filter == data->filter && entry->next == data->next;
|
||||
}
|
||||
|
||||
typedef hash_table <action_record_hasher> action_hash_type;
|
||||
|
||||
static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
|
||||
eh_landing_pad *);
|
||||
|
@ -173,18 +216,9 @@ static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
|
|||
static int t2r_eq (const void *, const void *);
|
||||
static hashval_t t2r_hash (const void *);
|
||||
|
||||
static int ttypes_filter_eq (const void *, const void *);
|
||||
static hashval_t ttypes_filter_hash (const void *);
|
||||
static int ehspec_filter_eq (const void *, const void *);
|
||||
static hashval_t ehspec_filter_hash (const void *);
|
||||
static int add_ttypes_entry (htab_t, tree);
|
||||
static int add_ehspec_entry (htab_t, htab_t, tree);
|
||||
static void dw2_build_landing_pads (void);
|
||||
|
||||
static int action_record_eq (const void *, const void *);
|
||||
static hashval_t action_record_hash (const void *);
|
||||
static int add_action_record (htab_t, int, int);
|
||||
static int collect_one_action_chain (htab_t, eh_region);
|
||||
static int collect_one_action_chain (action_hash_type, eh_region);
|
||||
static int add_call_site (rtx, int, int);
|
||||
|
||||
static void push_uleb128 (vec<uchar, va_gc> **, unsigned int);
|
||||
|
@ -687,46 +721,60 @@ struct ttypes_filter {
|
|||
int filter;
|
||||
};
|
||||
|
||||
/* Helper for ttypes_filter hashing. */
|
||||
|
||||
struct ttypes_filter_hasher : typed_free_remove <ttypes_filter>
|
||||
{
|
||||
typedef ttypes_filter value_type;
|
||||
typedef tree_node compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
|
||||
(a tree) for a @TTypes type node we are thinking about adding. */
|
||||
|
||||
static int
|
||||
ttypes_filter_eq (const void *pentry, const void *pdata)
|
||||
inline bool
|
||||
ttypes_filter_hasher::equal (const value_type *entry, const compare_type *data)
|
||||
{
|
||||
const struct ttypes_filter *const entry
|
||||
= (const struct ttypes_filter *) pentry;
|
||||
const_tree const data = (const_tree) pdata;
|
||||
|
||||
return entry->t == data;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
ttypes_filter_hash (const void *pentry)
|
||||
inline hashval_t
|
||||
ttypes_filter_hasher::hash (const value_type *entry)
|
||||
{
|
||||
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
||||
return TREE_HASH (entry->t);
|
||||
}
|
||||
|
||||
typedef hash_table <ttypes_filter_hasher> ttypes_hash_type;
|
||||
|
||||
|
||||
/* Helper for ehspec hashing. */
|
||||
|
||||
struct ehspec_hasher : typed_free_remove <ttypes_filter>
|
||||
{
|
||||
typedef ttypes_filter value_type;
|
||||
typedef ttypes_filter compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
|
||||
exception specification list we are thinking about adding. */
|
||||
/* ??? Currently we use the type lists in the order given. Someone
|
||||
should put these in some canonical order. */
|
||||
|
||||
static int
|
||||
ehspec_filter_eq (const void *pentry, const void *pdata)
|
||||
inline bool
|
||||
ehspec_hasher::equal (const value_type *entry, const compare_type *data)
|
||||
{
|
||||
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
||||
const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
|
||||
|
||||
return type_list_equal (entry->t, data->t);
|
||||
}
|
||||
|
||||
/* Hash function for exception specification lists. */
|
||||
|
||||
static hashval_t
|
||||
ehspec_filter_hash (const void *pentry)
|
||||
inline hashval_t
|
||||
ehspec_hasher::hash (const value_type *entry)
|
||||
{
|
||||
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
|
||||
hashval_t h = 0;
|
||||
tree list;
|
||||
|
||||
|
@ -735,16 +783,19 @@ ehspec_filter_hash (const void *pentry)
|
|||
return h;
|
||||
}
|
||||
|
||||
typedef hash_table <ehspec_hasher> ehspec_hash_type;
|
||||
|
||||
|
||||
/* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
|
||||
to speed up the search. Return the filter value to be used. */
|
||||
|
||||
static int
|
||||
add_ttypes_entry (htab_t ttypes_hash, tree type)
|
||||
add_ttypes_entry (ttypes_hash_type ttypes_hash, tree type)
|
||||
{
|
||||
struct ttypes_filter **slot, *n;
|
||||
|
||||
slot = (struct ttypes_filter **)
|
||||
htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
|
||||
slot = ttypes_hash.find_slot_with_hash (type, (hashval_t) TREE_HASH (type),
|
||||
INSERT);
|
||||
|
||||
if ((n = *slot) == NULL)
|
||||
{
|
||||
|
@ -765,14 +816,14 @@ add_ttypes_entry (htab_t ttypes_hash, tree type)
|
|||
to speed up the search. Return the filter value to be used. */
|
||||
|
||||
static int
|
||||
add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
|
||||
add_ehspec_entry (ehspec_hash_type ehspec_hash, ttypes_hash_type ttypes_hash,
|
||||
tree list)
|
||||
{
|
||||
struct ttypes_filter **slot, *n;
|
||||
struct ttypes_filter dummy;
|
||||
|
||||
dummy.t = list;
|
||||
slot = (struct ttypes_filter **)
|
||||
htab_find_slot (ehspec_hash, &dummy, INSERT);
|
||||
slot = ehspec_hash.find_slot (&dummy, INSERT);
|
||||
|
||||
if ((n = *slot) == NULL)
|
||||
{
|
||||
|
@ -821,7 +872,8 @@ void
|
|||
assign_filter_values (void)
|
||||
{
|
||||
int i;
|
||||
htab_t ttypes, ehspec;
|
||||
ttypes_hash_type ttypes;
|
||||
ehspec_hash_type ehspec;
|
||||
eh_region r;
|
||||
eh_catch c;
|
||||
|
||||
|
@ -831,8 +883,8 @@ assign_filter_values (void)
|
|||
else
|
||||
vec_alloc (cfun->eh->ehspec_data.other, 64);
|
||||
|
||||
ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
|
||||
ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
|
||||
ttypes.create (31);
|
||||
ehspec.create (31);
|
||||
|
||||
for (i = 1; vec_safe_iterate (cfun->eh->region_array, i, &r); ++i)
|
||||
{
|
||||
|
@ -886,8 +938,8 @@ assign_filter_values (void)
|
|||
}
|
||||
}
|
||||
|
||||
htab_delete (ttypes);
|
||||
htab_delete (ehspec);
|
||||
ttypes.dispose ();
|
||||
ehspec.dispose ();
|
||||
}
|
||||
|
||||
/* Emit SEQ into basic block just before INSN (that is assumed to be
|
||||
|
@ -1009,12 +1061,12 @@ static vec<int> sjlj_lp_call_site_index;
|
|||
static int
|
||||
sjlj_assign_call_site_values (void)
|
||||
{
|
||||
htab_t ar_hash;
|
||||
action_hash_type ar_hash;
|
||||
int i, disp_index;
|
||||
eh_landing_pad lp;
|
||||
|
||||
vec_alloc (crtl->eh.action_record_data, 64);
|
||||
ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
|
||||
ar_hash.create (31);
|
||||
|
||||
disp_index = 0;
|
||||
call_site_base = 1;
|
||||
|
@ -1043,7 +1095,7 @@ sjlj_assign_call_site_values (void)
|
|||
disp_index++;
|
||||
}
|
||||
|
||||
htab_delete (ar_hash);
|
||||
ar_hash.dispose ();
|
||||
|
||||
return disp_index;
|
||||
}
|
||||
|
@ -2236,47 +2288,14 @@ expand_builtin_extend_pointer (tree addr_tree)
|
|||
return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
|
||||
}
|
||||
|
||||
/* In the following functions, we represent entries in the action table
|
||||
as 1-based indices. Special cases are:
|
||||
|
||||
0: null action record, non-null landing pad; implies cleanups
|
||||
-1: null action record, null landing pad; implies no action
|
||||
-2: no call-site entry; implies must_not_throw
|
||||
-3: we have yet to process outer regions
|
||||
|
||||
Further, no special cases apply to the "next" field of the record.
|
||||
For next, 0 means end of list. */
|
||||
|
||||
struct action_record
|
||||
{
|
||||
int offset;
|
||||
int filter;
|
||||
int next;
|
||||
};
|
||||
|
||||
static int
|
||||
action_record_eq (const void *pentry, const void *pdata)
|
||||
{
|
||||
const struct action_record *entry = (const struct action_record *) pentry;
|
||||
const struct action_record *data = (const struct action_record *) pdata;
|
||||
return entry->filter == data->filter && entry->next == data->next;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
action_record_hash (const void *pentry)
|
||||
{
|
||||
const struct action_record *entry = (const struct action_record *) pentry;
|
||||
return entry->next * 1009 + entry->filter;
|
||||
}
|
||||
|
||||
static int
|
||||
add_action_record (htab_t ar_hash, int filter, int next)
|
||||
add_action_record (action_hash_type ar_hash, int filter, int next)
|
||||
{
|
||||
struct action_record **slot, *new_ar, tmp;
|
||||
|
||||
tmp.filter = filter;
|
||||
tmp.next = next;
|
||||
slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
|
||||
slot = ar_hash.find_slot (&tmp, INSERT);
|
||||
|
||||
if ((new_ar = *slot) == NULL)
|
||||
{
|
||||
|
@ -2301,7 +2320,7 @@ add_action_record (htab_t ar_hash, int filter, int next)
|
|||
}
|
||||
|
||||
static int
|
||||
collect_one_action_chain (htab_t ar_hash, eh_region region)
|
||||
collect_one_action_chain (action_hash_type ar_hash, eh_region region)
|
||||
{
|
||||
int next;
|
||||
|
||||
|
@ -2430,7 +2449,7 @@ static unsigned int
|
|||
convert_to_eh_region_ranges (void)
|
||||
{
|
||||
rtx insn, iter, note;
|
||||
htab_t ar_hash;
|
||||
action_hash_type ar_hash;
|
||||
int last_action = -3;
|
||||
rtx last_action_insn = NULL_RTX;
|
||||
rtx last_landing_pad = NULL_RTX;
|
||||
|
@ -2444,7 +2463,7 @@ convert_to_eh_region_ranges (void)
|
|||
|
||||
vec_alloc (crtl->eh.action_record_data, 64);
|
||||
|
||||
ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
|
||||
ar_hash.create (31);
|
||||
|
||||
for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
|
||||
if (INSN_P (iter))
|
||||
|
@ -2581,7 +2600,7 @@ convert_to_eh_region_ranges (void)
|
|||
|
||||
call_site_base = saved_call_site_base;
|
||||
|
||||
htab_delete (ar_hash);
|
||||
ar_hash.dispose ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
74
gcc/gcse.c
74
gcc/gcse.c
|
@ -158,7 +158,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "intl.h"
|
||||
#include "obstack.h"
|
||||
#include "tree-pass.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "df.h"
|
||||
#include "dbgcnt.h"
|
||||
#include "target.h"
|
||||
|
@ -359,8 +359,34 @@ struct ls_expr
|
|||
/* Head of the list of load/store memory refs. */
|
||||
static struct ls_expr * pre_ldst_mems = NULL;
|
||||
|
||||
struct pre_ldst_expr_hasher : typed_noop_remove <ls_expr>
|
||||
{
|
||||
typedef ls_expr value_type;
|
||||
typedef value_type compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
inline hashval_t
|
||||
pre_ldst_expr_hasher::hash (const value_type *x)
|
||||
{
|
||||
int do_not_record_p = 0;
|
||||
return
|
||||
hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
|
||||
}
|
||||
|
||||
static int expr_equiv_p (const_rtx, const_rtx);
|
||||
|
||||
inline bool
|
||||
pre_ldst_expr_hasher::equal (const value_type *ptr1,
|
||||
const compare_type *ptr2)
|
||||
{
|
||||
return expr_equiv_p (ptr1->pattern, ptr2->pattern);
|
||||
}
|
||||
|
||||
/* Hashtable for the load/store memory refs. */
|
||||
static htab_t pre_ldst_table = NULL;
|
||||
static hash_table <pre_ldst_expr_hasher> pre_ldst_table;
|
||||
|
||||
/* Bitmap containing one bit for each register in the program.
|
||||
Used when performing GCSE to track which registers have been set since
|
||||
|
@ -447,7 +473,6 @@ static int oprs_available_p (const_rtx, const_rtx);
|
|||
static void insert_expr_in_table (rtx, enum machine_mode, rtx, int, int, int,
|
||||
struct hash_table_d *);
|
||||
static unsigned int hash_expr (const_rtx, enum machine_mode, int *, int);
|
||||
static int expr_equiv_p (const_rtx, const_rtx);
|
||||
static void record_last_reg_set_info (rtx, int);
|
||||
static void record_last_mem_set_info (rtx);
|
||||
static void record_last_set_info (rtx, const_rtx, void *);
|
||||
|
@ -3652,23 +3677,6 @@ one_code_hoisting_pass (void)
|
|||
load towards the exit, and we end up with no loads or stores of 'i'
|
||||
in the loop. */
|
||||
|
||||
static hashval_t
|
||||
pre_ldst_expr_hash (const void *p)
|
||||
{
|
||||
int do_not_record_p = 0;
|
||||
const struct ls_expr *const x = (const struct ls_expr *) p;
|
||||
return
|
||||
hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_ldst_expr_eq (const void *p1, const void *p2)
|
||||
{
|
||||
const struct ls_expr *const ptr1 = (const struct ls_expr *) p1,
|
||||
*const ptr2 = (const struct ls_expr *) p2;
|
||||
return expr_equiv_p (ptr1->pattern, ptr2->pattern);
|
||||
}
|
||||
|
||||
/* This will search the ldst list for a matching expression. If it
|
||||
doesn't find one, we create one and initialize it. */
|
||||
|
||||
|
@ -3678,16 +3686,16 @@ ldst_entry (rtx x)
|
|||
int do_not_record_p = 0;
|
||||
struct ls_expr * ptr;
|
||||
unsigned int hash;
|
||||
void **slot;
|
||||
ls_expr **slot;
|
||||
struct ls_expr e;
|
||||
|
||||
hash = hash_rtx (x, GET_MODE (x), &do_not_record_p,
|
||||
NULL, /*have_reg_qty=*/false);
|
||||
|
||||
e.pattern = x;
|
||||
slot = htab_find_slot_with_hash (pre_ldst_table, &e, hash, INSERT);
|
||||
slot = pre_ldst_table.find_slot_with_hash (&e, hash, INSERT);
|
||||
if (*slot)
|
||||
return (struct ls_expr *)*slot;
|
||||
return *slot;
|
||||
|
||||
ptr = XNEW (struct ls_expr);
|
||||
|
||||
|
@ -3723,9 +3731,8 @@ free_ldst_entry (struct ls_expr * ptr)
|
|||
static void
|
||||
free_ld_motion_mems (void)
|
||||
{
|
||||
if (pre_ldst_table)
|
||||
htab_delete (pre_ldst_table);
|
||||
pre_ldst_table = NULL;
|
||||
if (pre_ldst_table.is_created ())
|
||||
pre_ldst_table.dispose ();
|
||||
|
||||
while (pre_ldst_mems)
|
||||
{
|
||||
|
@ -3780,14 +3787,14 @@ static struct ls_expr *
|
|||
find_rtx_in_ldst (rtx x)
|
||||
{
|
||||
struct ls_expr e;
|
||||
void **slot;
|
||||
if (!pre_ldst_table)
|
||||
ls_expr **slot;
|
||||
if (!pre_ldst_table.is_created ())
|
||||
return NULL;
|
||||
e.pattern = x;
|
||||
slot = htab_find_slot (pre_ldst_table, &e, NO_INSERT);
|
||||
if (!slot || ((struct ls_expr *)*slot)->invalid)
|
||||
slot = pre_ldst_table.find_slot (&e, NO_INSERT);
|
||||
if (!slot || (*slot)->invalid)
|
||||
return NULL;
|
||||
return (struct ls_expr *) *slot;
|
||||
return *slot;
|
||||
}
|
||||
|
||||
/* Load Motion for loads which only kill themselves. */
|
||||
|
@ -3875,8 +3882,7 @@ compute_ld_motion_mems (void)
|
|||
rtx insn;
|
||||
|
||||
pre_ldst_mems = NULL;
|
||||
pre_ldst_table
|
||||
= htab_create (13, pre_ldst_expr_hash, pre_ldst_expr_eq, NULL);
|
||||
pre_ldst_table.create (13);
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
|
@ -3967,7 +3973,7 @@ trim_ld_motion_mems (void)
|
|||
else
|
||||
{
|
||||
*last = ptr->next;
|
||||
htab_remove_elt_with_hash (pre_ldst_table, ptr, ptr->hash_index);
|
||||
pre_ldst_table.remove_elt_with_hash (ptr, ptr->hash_index);
|
||||
free_ldst_entry (ptr);
|
||||
ptr = * last;
|
||||
}
|
||||
|
|
177
gcc/ggc-common.c
177
gcc/ggc-common.c
|
@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "ggc.h"
|
||||
#include "ggc-internal.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
@ -46,10 +46,6 @@ static ggc_statistics *ggc_stats;
|
|||
struct traversal_state;
|
||||
|
||||
static int ggc_htab_delete (void **, void *);
|
||||
static hashval_t saving_htab_hash (const void *);
|
||||
static int saving_htab_eq (const void *, const void *);
|
||||
static int call_count (void **, void *);
|
||||
static int call_alloc (void **, void *);
|
||||
static int compare_ptr_data (const void *, const void *);
|
||||
static void relocate_ptrs (void *, void *);
|
||||
static void write_pch_globals (const struct ggc_root_tab * const *tab,
|
||||
|
@ -289,8 +285,6 @@ ggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED,
|
|||
|
||||
/* Functions for saving and restoring GCable memory to disk. */
|
||||
|
||||
static htab_t saving_htab;
|
||||
|
||||
struct ptr_data
|
||||
{
|
||||
void *obj;
|
||||
|
@ -303,6 +297,30 @@ struct ptr_data
|
|||
|
||||
#define POINTER_HASH(x) (hashval_t)((intptr_t)x >> 3)
|
||||
|
||||
/* Helper for hashing saving_htab. */
|
||||
|
||||
struct saving_hasher : typed_free_remove <ptr_data>
|
||||
{
|
||||
typedef ptr_data value_type;
|
||||
typedef void compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
saving_hasher::hash (const value_type *p)
|
||||
{
|
||||
return POINTER_HASH (p->obj);
|
||||
}
|
||||
|
||||
inline bool
|
||||
saving_hasher::equal (const value_type *p1, const compare_type *p2)
|
||||
{
|
||||
return p1->obj == p2;
|
||||
}
|
||||
|
||||
static hash_table <saving_hasher> saving_htab;
|
||||
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
int
|
||||
|
@ -315,8 +333,7 @@ gt_pch_note_object (void *obj, void *note_ptr_cookie,
|
|||
return 0;
|
||||
|
||||
slot = (struct ptr_data **)
|
||||
htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
|
||||
INSERT);
|
||||
saving_htab.find_slot_with_hash (obj, POINTER_HASH (obj), INSERT);
|
||||
if (*slot != NULL)
|
||||
{
|
||||
gcc_assert ((*slot)->note_ptr_fn == note_ptr_fn
|
||||
|
@ -347,26 +364,12 @@ gt_pch_note_reorder (void *obj, void *note_ptr_cookie,
|
|||
return;
|
||||
|
||||
data = (struct ptr_data *)
|
||||
htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
|
||||
saving_htab.find_with_hash (obj, POINTER_HASH (obj));
|
||||
gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie);
|
||||
|
||||
data->reorder_fn = reorder_fn;
|
||||
}
|
||||
|
||||
/* Hash and equality functions for saving_htab, callbacks for htab_create. */
|
||||
|
||||
static hashval_t
|
||||
saving_htab_hash (const void *p)
|
||||
{
|
||||
return POINTER_HASH (((const struct ptr_data *)p)->obj);
|
||||
}
|
||||
|
||||
static int
|
||||
saving_htab_eq (const void *p1, const void *p2)
|
||||
{
|
||||
return ((const struct ptr_data *)p1)->obj == p2;
|
||||
}
|
||||
|
||||
/* Handy state for the traversal functions. */
|
||||
|
||||
struct traversal_state
|
||||
|
@ -380,11 +383,10 @@ struct traversal_state
|
|||
|
||||
/* Callbacks for htab_traverse. */
|
||||
|
||||
static int
|
||||
call_count (void **slot, void *state_p)
|
||||
int
|
||||
ggc_call_count (ptr_data **slot, traversal_state *state)
|
||||
{
|
||||
struct ptr_data *d = (struct ptr_data *)*slot;
|
||||
struct traversal_state *state = (struct traversal_state *)state_p;
|
||||
struct ptr_data *d = *slot;
|
||||
|
||||
ggc_pch_count_object (state->d, d->obj, d->size,
|
||||
d->note_ptr_fn == gt_pch_p_S);
|
||||
|
@ -392,11 +394,10 @@ call_count (void **slot, void *state_p)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
call_alloc (void **slot, void *state_p)
|
||||
int
|
||||
ggc_call_alloc (ptr_data **slot, traversal_state *state)
|
||||
{
|
||||
struct ptr_data *d = (struct ptr_data *)*slot;
|
||||
struct traversal_state *state = (struct traversal_state *)state_p;
|
||||
struct ptr_data *d = *slot;
|
||||
|
||||
d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size,
|
||||
d->note_ptr_fn == gt_pch_p_S);
|
||||
|
@ -429,7 +430,7 @@ relocate_ptrs (void *ptr_p, void *state_p)
|
|||
return;
|
||||
|
||||
result = (struct ptr_data *)
|
||||
htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
|
||||
saving_htab.find_with_hash (*ptr, POINTER_HASH (*ptr));
|
||||
gcc_assert (result);
|
||||
*ptr = result->new_addr;
|
||||
}
|
||||
|
@ -458,7 +459,7 @@ write_pch_globals (const struct ggc_root_tab * const *tab,
|
|||
else
|
||||
{
|
||||
new_ptr = (struct ptr_data *)
|
||||
htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr));
|
||||
saving_htab.find_with_hash (ptr, POINTER_HASH (ptr));
|
||||
if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
|
||||
!= 1)
|
||||
fatal_error ("can%'t write PCH file: %m");
|
||||
|
@ -492,7 +493,7 @@ gt_pch_save (FILE *f)
|
|||
gt_pch_save_stringpool ();
|
||||
|
||||
timevar_push (TV_PCH_PTR_REALLOC);
|
||||
saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
|
||||
saving_htab.create (50000);
|
||||
|
||||
for (rt = gt_ggc_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
|
@ -508,7 +509,7 @@ gt_pch_save (FILE *f)
|
|||
state.f = f;
|
||||
state.d = init_ggc_pch ();
|
||||
state.count = 0;
|
||||
htab_traverse (saving_htab, call_count, &state);
|
||||
saving_htab.traverse <traversal_state *, ggc_call_count> (&state);
|
||||
|
||||
mmi.size = ggc_pch_total_size (state.d);
|
||||
|
||||
|
@ -524,7 +525,7 @@ gt_pch_save (FILE *f)
|
|||
state.ptrs = XNEWVEC (struct ptr_data *, state.count);
|
||||
state.ptrs_i = 0;
|
||||
|
||||
htab_traverse (saving_htab, call_alloc, &state);
|
||||
saving_htab.traverse <traversal_state *, ggc_call_alloc> (&state);
|
||||
timevar_pop (TV_PCH_PTR_REALLOC);
|
||||
|
||||
timevar_push (TV_PCH_PTR_SORT);
|
||||
|
@ -653,7 +654,7 @@ gt_pch_save (FILE *f)
|
|||
|
||||
XDELETE (state.ptrs);
|
||||
XDELETE (this_object);
|
||||
htab_delete (saving_htab);
|
||||
saving_htab.dispose ();
|
||||
}
|
||||
|
||||
/* Read the state of the compiler back in from F. */
|
||||
|
@ -913,30 +914,32 @@ struct loc_descriptor
|
|||
size_t collected;
|
||||
};
|
||||
|
||||
/* Hashtable used for statistics. */
|
||||
static htab_t loc_hash;
|
||||
/* Hash table helper. */
|
||||
|
||||
/* Hash table helpers functions. */
|
||||
static hashval_t
|
||||
hash_descriptor (const void *p)
|
||||
struct loc_desc_hasher : typed_noop_remove <loc_descriptor>
|
||||
{
|
||||
const struct loc_descriptor *const d = (const struct loc_descriptor *) p;
|
||||
typedef loc_descriptor value_type;
|
||||
typedef loc_descriptor compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
loc_desc_hasher::hash (const value_type *d)
|
||||
{
|
||||
return htab_hash_pointer (d->function) | d->line;
|
||||
}
|
||||
|
||||
static int
|
||||
eq_descriptor (const void *p1, const void *p2)
|
||||
inline bool
|
||||
loc_desc_hasher::equal (const value_type *d, const compare_type *d2)
|
||||
{
|
||||
const struct loc_descriptor *const d = (const struct loc_descriptor *) p1;
|
||||
const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2;
|
||||
|
||||
return (d->file == d2->file && d->line == d2->line
|
||||
&& d->function == d2->function);
|
||||
}
|
||||
|
||||
/* Hashtable converting address of allocated field to loc descriptor. */
|
||||
static htab_t ptr_hash;
|
||||
/* Hashtable used for statistics. */
|
||||
static hash_table <loc_desc_hasher> loc_hash;
|
||||
|
||||
struct ptr_hash_entry
|
||||
{
|
||||
void *ptr;
|
||||
|
@ -944,26 +947,34 @@ struct ptr_hash_entry
|
|||
size_t size;
|
||||
};
|
||||
|
||||
/* Hash table helpers functions. */
|
||||
static hashval_t
|
||||
hash_ptr (const void *p)
|
||||
{
|
||||
const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
|
||||
/* Helper for ptr_hash table. */
|
||||
|
||||
struct ptr_hash_hasher : typed_noop_remove <ptr_hash_entry>
|
||||
{
|
||||
typedef ptr_hash_entry value_type;
|
||||
typedef void compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
ptr_hash_hasher::hash (const value_type *d)
|
||||
{
|
||||
return htab_hash_pointer (d->ptr);
|
||||
}
|
||||
|
||||
static int
|
||||
eq_ptr (const void *p1, const void *p2)
|
||||
inline bool
|
||||
ptr_hash_hasher::equal (const value_type *p, const compare_type *p2)
|
||||
{
|
||||
const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1;
|
||||
|
||||
return (p->ptr == p2);
|
||||
}
|
||||
|
||||
/* Hashtable converting address of allocated field to loc descriptor. */
|
||||
static hash_table <ptr_hash_hasher> ptr_hash;
|
||||
|
||||
/* Return descriptor for given call site, create new one if needed. */
|
||||
static struct loc_descriptor *
|
||||
loc_descriptor (const char *name, int line, const char *function)
|
||||
make_loc_descriptor (const char *name, int line, const char *function)
|
||||
{
|
||||
struct loc_descriptor loc;
|
||||
struct loc_descriptor **slot;
|
||||
|
@ -971,10 +982,10 @@ loc_descriptor (const char *name, int line, const char *function)
|
|||
loc.file = name;
|
||||
loc.line = line;
|
||||
loc.function = function;
|
||||
if (!loc_hash)
|
||||
loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
|
||||
if (!loc_hash.is_created ())
|
||||
loc_hash.create (10);
|
||||
|
||||
slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, INSERT);
|
||||
slot = loc_hash.find_slot (&loc, INSERT);
|
||||
if (*slot)
|
||||
return *slot;
|
||||
*slot = XCNEW (struct loc_descriptor);
|
||||
|
@ -989,16 +1000,16 @@ void
|
|||
ggc_record_overhead (size_t allocated, size_t overhead, void *ptr,
|
||||
const char *name, int line, const char *function)
|
||||
{
|
||||
struct loc_descriptor *loc = loc_descriptor (name, line, function);
|
||||
struct loc_descriptor *loc = make_loc_descriptor (name, line, function);
|
||||
struct ptr_hash_entry *p = XNEW (struct ptr_hash_entry);
|
||||
PTR *slot;
|
||||
ptr_hash_entry **slot;
|
||||
|
||||
p->ptr = ptr;
|
||||
p->loc = loc;
|
||||
p->size = allocated + overhead;
|
||||
if (!ptr_hash)
|
||||
ptr_hash = htab_create (10, hash_ptr, eq_ptr, NULL);
|
||||
slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), INSERT);
|
||||
if (!ptr_hash.is_created ())
|
||||
ptr_hash.create (10);
|
||||
slot = ptr_hash.find_slot_with_hash (ptr, htab_hash_pointer (ptr), INSERT);
|
||||
gcc_assert (!*slot);
|
||||
*slot = p;
|
||||
|
||||
|
@ -1009,14 +1020,14 @@ ggc_record_overhead (size_t allocated, size_t overhead, void *ptr,
|
|||
|
||||
/* Helper function for prune_overhead_list. See if SLOT is still marked and
|
||||
remove it from hashtable if it is not. */
|
||||
static int
|
||||
ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
|
||||
int
|
||||
ggc_prune_ptr (ptr_hash_entry **slot, void *b ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
|
||||
struct ptr_hash_entry *p = *slot;
|
||||
if (!ggc_marked_p (p->ptr))
|
||||
{
|
||||
p->loc->collected += p->size;
|
||||
htab_clear_slot (ptr_hash, slot);
|
||||
ptr_hash.clear_slot (slot);
|
||||
free (p);
|
||||
}
|
||||
return 1;
|
||||
|
@ -1027,15 +1038,15 @@ ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
|
|||
void
|
||||
ggc_prune_overhead_list (void)
|
||||
{
|
||||
htab_traverse (ptr_hash, ggc_prune_ptr, NULL);
|
||||
ptr_hash.traverse <void *, ggc_prune_ptr> (NULL);
|
||||
}
|
||||
|
||||
/* Notice that the pointer has been freed. */
|
||||
void
|
||||
ggc_free_overhead (void *ptr)
|
||||
{
|
||||
PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr),
|
||||
NO_INSERT);
|
||||
ptr_hash_entry **slot;
|
||||
slot = ptr_hash.find_slot_with_hash (ptr, htab_hash_pointer (ptr), NO_INSERT);
|
||||
struct ptr_hash_entry *p;
|
||||
/* The pointer might be not found if a PCH read happened between allocation
|
||||
and ggc_free () call. FIXME: account memory properly in the presence of
|
||||
|
@ -1044,7 +1055,7 @@ ggc_free_overhead (void *ptr)
|
|||
return;
|
||||
p = (struct ptr_hash_entry *) *slot;
|
||||
p->loc->freed += p->size;
|
||||
htab_clear_slot (ptr_hash, slot);
|
||||
ptr_hash.clear_slot (slot);
|
||||
free (p);
|
||||
}
|
||||
|
||||
|
@ -1083,11 +1094,10 @@ cmp_statistic (const void *loc1, const void *loc2)
|
|||
|
||||
/* Collect array of the descriptors from hashtable. */
|
||||
static struct loc_descriptor **loc_array;
|
||||
static int
|
||||
add_statistics (void **slot, void *b)
|
||||
int
|
||||
ggc_add_statistics (loc_descriptor **slot, int *n)
|
||||
{
|
||||
int *n = (int *)b;
|
||||
loc_array[*n] = (struct loc_descriptor *) *slot;
|
||||
loc_array[*n] = *slot;
|
||||
(*n)++;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1108,12 +1118,13 @@ dump_ggc_loc_statistics (bool final)
|
|||
ggc_force_collect = true;
|
||||
ggc_collect ();
|
||||
|
||||
loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements);
|
||||
loc_array = XCNEWVEC (struct loc_descriptor *,
|
||||
loc_hash.elements_with_deleted ());
|
||||
fprintf (stderr, "-------------------------------------------------------\n");
|
||||
fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n",
|
||||
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
|
||||
fprintf (stderr, "-------------------------------------------------------\n");
|
||||
htab_traverse (loc_hash, add_statistics, &nentries);
|
||||
loc_hash.traverse <int *, ggc_add_statistics> (&nentries);
|
||||
qsort (loc_array, nentries, sizeof (*loc_array),
|
||||
final ? final_cmp_statistic : cmp_statistic);
|
||||
for (i = 0; i < nentries; i++)
|
||||
|
|
|
@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "pointer-set.h"
|
||||
#include "expmed.h"
|
||||
#include "params.h"
|
||||
#include "hash-table.h"
|
||||
|
||||
/* Information about a strength reduction candidate. Each statement
|
||||
in the candidate table represents an expression of one of the
|
||||
|
@ -287,9 +288,6 @@ static struct pointer_map_t *stmt_cand_map;
|
|||
/* Obstack for candidates. */
|
||||
static struct obstack cand_obstack;
|
||||
|
||||
/* Hash table embodying a mapping from base exprs to chains of candidates. */
|
||||
static htab_t base_cand_map;
|
||||
|
||||
/* Obstack for candidate chains. */
|
||||
static struct obstack chain_obstack;
|
||||
|
||||
|
@ -311,32 +309,31 @@ lookup_cand (cand_idx idx)
|
|||
return cand_vec[idx - 1];
|
||||
}
|
||||
|
||||
/* Callback to produce a hash value for a candidate chain header. */
|
||||
/* Helper for hashing a candidate chain header. */
|
||||
|
||||
static hashval_t
|
||||
base_cand_hash (const void *p)
|
||||
struct cand_chain_hasher : typed_noop_remove <cand_chain>
|
||||
{
|
||||
tree base_expr = ((const_cand_chain_t) p)->base_expr;
|
||||
typedef cand_chain value_type;
|
||||
typedef cand_chain compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
cand_chain_hasher::hash (const value_type *p)
|
||||
{
|
||||
tree base_expr = p->base_expr;
|
||||
return iterative_hash_expr (base_expr, 0);
|
||||
}
|
||||
|
||||
/* Callback when an element is removed from the hash table.
|
||||
We never remove entries until the entire table is released. */
|
||||
|
||||
static void
|
||||
base_cand_free (void *p ATTRIBUTE_UNUSED)
|
||||
inline bool
|
||||
cand_chain_hasher::equal (const value_type *chain1, const compare_type *chain2)
|
||||
{
|
||||
}
|
||||
|
||||
/* Callback to return true if two candidate chain headers are equal. */
|
||||
|
||||
static int
|
||||
base_cand_eq (const void *p1, const void *p2)
|
||||
{
|
||||
const_cand_chain_t const chain1 = (const_cand_chain_t) p1;
|
||||
const_cand_chain_t const chain2 = (const_cand_chain_t) p2;
|
||||
return operand_equal_p (chain1->base_expr, chain2->base_expr, 0);
|
||||
}
|
||||
|
||||
/* Hash table embodying a mapping from base exprs to chains of candidates. */
|
||||
static hash_table <cand_chain_hasher> base_cand_map;
|
||||
|
||||
/* Use the base expr from candidate C to look for possible candidates
|
||||
that can serve as a basis for C. Each potential basis must also
|
||||
|
@ -357,7 +354,7 @@ find_basis_for_candidate (slsr_cand_t c)
|
|||
int max_iters = PARAM_VALUE (PARAM_MAX_SLSR_CANDIDATE_SCAN);
|
||||
|
||||
mapping_key.base_expr = c->base_expr;
|
||||
chain = (cand_chain_t) htab_find (base_cand_map, &mapping_key);
|
||||
chain = base_cand_map.find (&mapping_key);
|
||||
|
||||
for (; chain && iters < max_iters; chain = chain->next, ++iters)
|
||||
{
|
||||
|
@ -393,13 +390,13 @@ static void
|
|||
record_potential_basis (slsr_cand_t c)
|
||||
{
|
||||
cand_chain_t node;
|
||||
void **slot;
|
||||
cand_chain **slot;
|
||||
|
||||
node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
|
||||
node->base_expr = c->base_expr;
|
||||
node->cand = c;
|
||||
node->next = NULL;
|
||||
slot = htab_find_slot (base_cand_map, node, INSERT);
|
||||
slot = base_cand_map.find_slot (node, INSERT);
|
||||
|
||||
if (*slot)
|
||||
{
|
||||
|
@ -1435,10 +1432,10 @@ dump_cand_vec (void)
|
|||
|
||||
/* Callback used to dump the candidate chains hash table. */
|
||||
|
||||
static int
|
||||
base_cand_dump_callback (void **slot, void *ignored ATTRIBUTE_UNUSED)
|
||||
int
|
||||
ssa_base_cand_dump_callback (cand_chain **slot, void *ignored ATTRIBUTE_UNUSED)
|
||||
{
|
||||
const_cand_chain_t chain = *((const_cand_chain_t *) slot);
|
||||
const_cand_chain_t chain = *slot;
|
||||
cand_chain_t p;
|
||||
|
||||
print_generic_expr (dump_file, chain->base_expr, 0);
|
||||
|
@ -1457,7 +1454,7 @@ static void
|
|||
dump_cand_chains (void)
|
||||
{
|
||||
fprintf (dump_file, "\nStrength reduction candidate chains:\n\n");
|
||||
htab_traverse_noresize (base_cand_map, base_cand_dump_callback, NULL);
|
||||
base_cand_map.traverse_noresize <void *, ssa_base_cand_dump_callback> (NULL);
|
||||
fputs ("\n", dump_file);
|
||||
}
|
||||
|
||||
|
@ -2641,8 +2638,7 @@ execute_strength_reduction (void)
|
|||
gcc_obstack_init (&chain_obstack);
|
||||
|
||||
/* Allocate the mapping from base expressions to candidate chains. */
|
||||
base_cand_map = htab_create (500, base_cand_hash,
|
||||
base_cand_eq, base_cand_free);
|
||||
base_cand_map.create (500);
|
||||
|
||||
/* Initialize the loop optimizer. We need to detect flow across
|
||||
back edges, and this gives us dominator information as well. */
|
||||
|
@ -2673,7 +2669,7 @@ execute_strength_reduction (void)
|
|||
/* Free resources. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
loop_optimizer_finalize ();
|
||||
htab_delete (base_cand_map);
|
||||
base_cand_map.dispose ();
|
||||
obstack_free (&chain_obstack, NULL);
|
||||
pointer_map_destroy (stmt_cand_map);
|
||||
cand_vec.release ();
|
||||
|
|
52
gcc/gimple.h
52
gcc/gimple.h
|
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#define GCC_GIMPLE_H
|
||||
|
||||
#include "pointer-set.h"
|
||||
#include "hash-table.h"
|
||||
#include "vec.h"
|
||||
#include "ggc.h"
|
||||
#include "basic-block.h"
|
||||
|
@ -959,6 +960,55 @@ enum gimplify_status {
|
|||
GS_ALL_DONE = 1 /* The expression is fully gimplified. */
|
||||
};
|
||||
|
||||
/* Formal (expression) temporary table handling: multiple occurrences of
|
||||
the same scalar expression are evaluated into the same temporary. */
|
||||
|
||||
typedef struct gimple_temp_hash_elt
|
||||
{
|
||||
tree val; /* Key */
|
||||
tree temp; /* Value */
|
||||
} elt_t;
|
||||
|
||||
/* Gimplify hashtable helper. */
|
||||
|
||||
struct gimplify_hasher : typed_free_remove <elt_t>
|
||||
{
|
||||
typedef elt_t value_type;
|
||||
typedef elt_t compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
gimplify_hasher::hash (const value_type *p)
|
||||
{
|
||||
tree t = p->val;
|
||||
return iterative_hash_expr (t, 0);
|
||||
}
|
||||
|
||||
inline bool
|
||||
gimplify_hasher::equal (const value_type *p1, const compare_type *p2)
|
||||
{
|
||||
tree t1 = p1->val;
|
||||
tree t2 = p2->val;
|
||||
enum tree_code code = TREE_CODE (t1);
|
||||
|
||||
if (TREE_CODE (t2) != code
|
||||
|| TREE_TYPE (t1) != TREE_TYPE (t2))
|
||||
return false;
|
||||
|
||||
if (!operand_equal_p (t1, t2, 0))
|
||||
return false;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* Only allow them to compare equal if they also hash equal; otherwise
|
||||
results are nondeterminate, and we fail bootstrap comparison. */
|
||||
gcc_assert (hash (p1) == hash (p2));
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct gimplify_ctx
|
||||
{
|
||||
struct gimplify_ctx *prev_context;
|
||||
|
@ -971,7 +1021,7 @@ struct gimplify_ctx
|
|||
|
||||
vec<tree> case_labels;
|
||||
/* The formal temporary table. Should this be persistent? */
|
||||
htab_t temp_htab;
|
||||
hash_table <gimplify_hasher> temp_htab;
|
||||
|
||||
int conditions;
|
||||
bool save_stack;
|
||||
|
|
|
@ -87,15 +87,6 @@ static struct gimplify_ctx *gimplify_ctxp;
|
|||
static struct gimplify_omp_ctx *gimplify_omp_ctxp;
|
||||
|
||||
|
||||
/* Formal (expression) temporary table handling: multiple occurrences of
|
||||
the same scalar expression are evaluated into the same temporary. */
|
||||
|
||||
typedef struct gimple_temp_hash_elt
|
||||
{
|
||||
tree val; /* Key */
|
||||
tree temp; /* Value */
|
||||
} elt_t;
|
||||
|
||||
/* Forward declaration. */
|
||||
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
|
||||
|
||||
|
@ -130,40 +121,6 @@ mark_addressable (tree x)
|
|||
}
|
||||
}
|
||||
|
||||
/* Return a hash value for a formal temporary table entry. */
|
||||
|
||||
static hashval_t
|
||||
gimple_tree_hash (const void *p)
|
||||
{
|
||||
tree t = ((const elt_t *) p)->val;
|
||||
return iterative_hash_expr (t, 0);
|
||||
}
|
||||
|
||||
/* Compare two formal temporary table entries. */
|
||||
|
||||
static int
|
||||
gimple_tree_eq (const void *p1, const void *p2)
|
||||
{
|
||||
tree t1 = ((const elt_t *) p1)->val;
|
||||
tree t2 = ((const elt_t *) p2)->val;
|
||||
enum tree_code code = TREE_CODE (t1);
|
||||
|
||||
if (TREE_CODE (t2) != code
|
||||
|| TREE_TYPE (t1) != TREE_TYPE (t2))
|
||||
return 0;
|
||||
|
||||
if (!operand_equal_p (t1, t2, 0))
|
||||
return 0;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* Only allow them to compare equal if they also hash equal; otherwise
|
||||
results are nondeterminate, and we fail bootstrap comparison. */
|
||||
gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2));
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Link gimple statement GS to the end of the sequence *SEQ_P. If
|
||||
*SEQ_P is NULL, a new sequence is allocated. This function is
|
||||
similar to gimple_seq_add_stmt, but does not scan the operands.
|
||||
|
@ -241,8 +198,8 @@ pop_gimplify_context (gimple body)
|
|||
else
|
||||
record_vars (c->temps);
|
||||
|
||||
if (c->temp_htab)
|
||||
htab_delete (c->temp_htab);
|
||||
if (c->temp_htab.is_created ())
|
||||
c->temp_htab.dispose ();
|
||||
}
|
||||
|
||||
/* Push a GIMPLE_BIND tuple onto the stack of bindings. */
|
||||
|
@ -585,23 +542,22 @@ lookup_tmp_var (tree val, bool is_formal)
|
|||
else
|
||||
{
|
||||
elt_t elt, *elt_p;
|
||||
void **slot;
|
||||
elt_t **slot;
|
||||
|
||||
elt.val = val;
|
||||
if (gimplify_ctxp->temp_htab == NULL)
|
||||
gimplify_ctxp->temp_htab
|
||||
= htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
|
||||
slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
|
||||
if (!gimplify_ctxp->temp_htab.is_created ())
|
||||
gimplify_ctxp->temp_htab.create (1000);
|
||||
slot = gimplify_ctxp->temp_htab.find_slot (&elt, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
elt_p = XNEW (elt_t);
|
||||
elt_p->val = val;
|
||||
elt_p->temp = ret = create_tmp_from_val (val, is_formal);
|
||||
*slot = (void *) elt_p;
|
||||
*slot = elt_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
elt_p = (elt_t *) *slot;
|
||||
elt_p = *slot;
|
||||
ret = elt_p->temp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cloog/cloog.h"
|
||||
#include "graphite-poly.h"
|
||||
#include "graphite-clast-to-gimple.h"
|
||||
#include "graphite-htab.h"
|
||||
|
||||
typedef const struct clast_expr *clast_name_p;
|
||||
|
||||
|
@ -124,6 +125,55 @@ typedef struct clast_name_index {
|
|||
char *free_name;
|
||||
} *clast_name_index_p;
|
||||
|
||||
/* Helper for hashing clast_name_index. */
|
||||
|
||||
struct clast_index_hasher
|
||||
{
|
||||
typedef clast_name_index value_type;
|
||||
typedef clast_name_index compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
/* Computes a hash function for database element E. */
|
||||
|
||||
inline hashval_t
|
||||
clast_index_hasher::hash (const value_type *e)
|
||||
{
|
||||
hashval_t hash = 0;
|
||||
|
||||
int length = strlen (e->name);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
hash = hash | (e->name[i] << (i % 4));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Compares database elements ELT1 and ELT2. */
|
||||
|
||||
inline bool
|
||||
clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
|
||||
{
|
||||
return strcmp (elt1->name, elt2->name) == 0;
|
||||
}
|
||||
|
||||
/* Free the memory taken by a clast_name_index struct. */
|
||||
|
||||
inline void
|
||||
clast_index_hasher::remove (value_type *c)
|
||||
{
|
||||
if (c->free_name)
|
||||
free (c->free_name);
|
||||
mpz_clear (c->bound_one);
|
||||
mpz_clear (c->bound_two);
|
||||
free (c);
|
||||
}
|
||||
|
||||
typedef hash_table <clast_index_hasher> clast_index_htab_type;
|
||||
|
||||
/* Returns a pointer to a new element of type clast_name_index_p built
|
||||
from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
|
||||
|
||||
|
@ -146,35 +196,22 @@ new_clast_name_index (const char *name, int index, int level,
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Free the memory taken by a clast_name_index struct. */
|
||||
|
||||
static void
|
||||
free_clast_name_index (void *ptr)
|
||||
{
|
||||
struct clast_name_index *c = (struct clast_name_index *) ptr;
|
||||
if (c->free_name)
|
||||
free (c->free_name);
|
||||
mpz_clear (c->bound_one);
|
||||
mpz_clear (c->bound_two);
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
/* For a given clast NAME, returns -1 if NAME is not in the
|
||||
INDEX_TABLE, otherwise returns the loop level for the induction
|
||||
variable NAME, or if it is a parameter, the parameter number in the
|
||||
vector of parameters. */
|
||||
|
||||
static inline int
|
||||
clast_name_to_level (clast_name_p name, htab_t index_table)
|
||||
clast_name_to_level (clast_name_p name, clast_index_htab_type index_table)
|
||||
{
|
||||
struct clast_name_index tmp;
|
||||
PTR *slot;
|
||||
clast_name_index **slot;
|
||||
|
||||
gcc_assert (name->type == clast_expr_name);
|
||||
tmp.name = ((const struct clast_name *) name)->name;
|
||||
tmp.free_name = NULL;
|
||||
|
||||
slot = htab_find_slot (index_table, &tmp, NO_INSERT);
|
||||
slot = index_table.find_slot (&tmp, NO_INSERT);
|
||||
|
||||
if (slot && *slot)
|
||||
return ((struct clast_name_index *) *slot)->level;
|
||||
|
@ -187,18 +224,18 @@ clast_name_to_level (clast_name_p name, htab_t index_table)
|
|||
SCATTERING_DIMENSIONS vector. */
|
||||
|
||||
static inline int
|
||||
clast_name_to_index (struct clast_name *name, htab_t index_table)
|
||||
clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table)
|
||||
{
|
||||
struct clast_name_index tmp;
|
||||
PTR *slot;
|
||||
clast_name_index **slot;
|
||||
|
||||
tmp.name = ((const struct clast_name *) name)->name;
|
||||
tmp.free_name = NULL;
|
||||
|
||||
slot = htab_find_slot (index_table, &tmp, NO_INSERT);
|
||||
slot = index_table.find_slot (&tmp, NO_INSERT);
|
||||
|
||||
if (slot && *slot)
|
||||
return ((struct clast_name_index *) *slot)->index;
|
||||
return (*slot)->index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -208,16 +245,16 @@ clast_name_to_index (struct clast_name *name, htab_t index_table)
|
|||
found in the INDEX_TABLE, false otherwise. */
|
||||
|
||||
static inline bool
|
||||
clast_name_to_lb_ub (struct clast_name *name, htab_t index_table,
|
||||
clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table,
|
||||
mpz_t bound_one, mpz_t bound_two)
|
||||
{
|
||||
struct clast_name_index tmp;
|
||||
PTR *slot;
|
||||
clast_name_index **slot;
|
||||
|
||||
tmp.name = name->name;
|
||||
tmp.free_name = NULL;
|
||||
|
||||
slot = htab_find_slot (index_table, &tmp, NO_INSERT);
|
||||
slot = index_table.find_slot (&tmp, NO_INSERT);
|
||||
|
||||
if (slot && *slot)
|
||||
{
|
||||
|
@ -232,15 +269,15 @@ clast_name_to_lb_ub (struct clast_name *name, htab_t index_table,
|
|||
/* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
|
||||
|
||||
static inline void
|
||||
save_clast_name_index (htab_t index_table, const char *name,
|
||||
save_clast_name_index (clast_index_htab_type index_table, const char *name,
|
||||
int index, int level, mpz_t bound_one, mpz_t bound_two)
|
||||
{
|
||||
struct clast_name_index tmp;
|
||||
PTR *slot;
|
||||
clast_name_index **slot;
|
||||
|
||||
tmp.name = name;
|
||||
tmp.free_name = NULL;
|
||||
slot = htab_find_slot (index_table, &tmp, INSERT);
|
||||
slot = index_table.find_slot (&tmp, INSERT);
|
||||
|
||||
if (slot)
|
||||
{
|
||||
|
@ -249,35 +286,6 @@ save_clast_name_index (htab_t index_table, const char *name,
|
|||
*slot = new_clast_name_index (name, index, level, bound_one, bound_two);
|
||||
}
|
||||
}
|
||||
|
||||
/* Computes a hash function for database element ELT. */
|
||||
|
||||
static inline hashval_t
|
||||
clast_name_index_elt_info (const void *elt)
|
||||
{
|
||||
const struct clast_name_index *e = ((const struct clast_name_index *) elt);
|
||||
hashval_t hash = 0;
|
||||
|
||||
int length = strlen (e->name);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
hash = hash | (e->name[i] << (i % 4));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Compares database elements E1 and E2. */
|
||||
|
||||
static inline int
|
||||
eq_clast_name_indexes (const void *e1, const void *e2)
|
||||
{
|
||||
const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
|
||||
const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
|
||||
|
||||
return strcmp (elt1->name, elt2->name) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
|
||||
|
@ -288,7 +296,7 @@ eq_clast_name_indexes (const void *e1, const void *e2)
|
|||
|
||||
typedef struct ivs_params {
|
||||
vec<tree> params, *newivs;
|
||||
htab_t newivs_index, params_index;
|
||||
clast_index_htab_type newivs_index, params_index;
|
||||
sese region;
|
||||
} *ivs_params_p;
|
||||
|
||||
|
@ -300,7 +308,7 @@ clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
|
|||
{
|
||||
int index;
|
||||
|
||||
if (ip->params.exists () && ip->params_index)
|
||||
if (ip->params.exists () && ip->params_index.is_created ())
|
||||
{
|
||||
index = clast_name_to_index (name, ip->params_index);
|
||||
|
||||
|
@ -308,7 +316,7 @@ clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
|
|||
return ip->params[index];
|
||||
}
|
||||
|
||||
gcc_assert (ip->newivs && ip->newivs_index);
|
||||
gcc_assert (ip->newivs && ip->newivs_index.is_created ());
|
||||
index = clast_name_to_index (name, ip->newivs_index);
|
||||
gcc_assert (index >= 0);
|
||||
|
||||
|
@ -699,12 +707,12 @@ type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
|
|||
{
|
||||
bool found = false;
|
||||
|
||||
if (ip->params.exists () && ip->params_index)
|
||||
if (ip->params.exists () && ip->params_index.is_created ())
|
||||
found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
gcc_assert (ip->newivs && ip->newivs_index);
|
||||
gcc_assert (ip->newivs && ip->newivs_index.is_created ());
|
||||
found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
|
||||
bound_two);
|
||||
gcc_assert (found);
|
||||
|
@ -1009,13 +1017,14 @@ new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
|
|||
/* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
|
||||
|
||||
static void
|
||||
mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
|
||||
mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
|
||||
bb_pbb_htab_type bb_pbb_mapping)
|
||||
{
|
||||
bb_pbb_def tmp;
|
||||
PTR *x;
|
||||
bb_pbb_def **x;
|
||||
|
||||
tmp.bb = bb;
|
||||
x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
|
||||
x = bb_pbb_mapping.find_slot (&tmp, INSERT);
|
||||
|
||||
if (x && !*x)
|
||||
*x = new_bb_pbb_def (bb, pbb);
|
||||
|
@ -1024,13 +1033,13 @@ mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
|
|||
/* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
|
||||
|
||||
poly_bb_p
|
||||
find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
|
||||
find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb)
|
||||
{
|
||||
bb_pbb_def tmp;
|
||||
PTR *slot;
|
||||
bb_pbb_def **slot;
|
||||
|
||||
tmp.bb = bb;
|
||||
slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
|
||||
slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT);
|
||||
|
||||
if (slot && *slot)
|
||||
return ((bb_pbb_def *) *slot)->pbb;
|
||||
|
@ -1044,7 +1053,7 @@ find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
|
|||
related poly_bb_p. */
|
||||
|
||||
scop_p
|
||||
get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping,
|
||||
get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping,
|
||||
vec<poly_bb_p> *pbbs)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -1074,7 +1083,7 @@ get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping,
|
|||
|
||||
static edge
|
||||
translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
|
||||
htab_t bb_pbb_mapping, ivs_params_p ip)
|
||||
bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip)
|
||||
{
|
||||
int i, nb_loops;
|
||||
basic_block new_bb;
|
||||
|
@ -1143,7 +1152,8 @@ graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
|
|||
}
|
||||
|
||||
static edge
|
||||
translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p);
|
||||
translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type,
|
||||
int, ivs_params_p);
|
||||
|
||||
/* Create the loop for a clast for statement.
|
||||
|
||||
|
@ -1152,8 +1162,9 @@ translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p);
|
|||
|
||||
static edge
|
||||
translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
|
||||
edge next_e, htab_t bb_pbb_mapping, int level,
|
||||
tree type, tree lb, tree ub, ivs_params_p ip)
|
||||
edge next_e, bb_pbb_htab_type bb_pbb_mapping,
|
||||
int level, tree type, tree lb, tree ub,
|
||||
ivs_params_p ip)
|
||||
{
|
||||
struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
|
||||
type, lb, ub, level, ip);
|
||||
|
@ -1186,7 +1197,8 @@ translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
|
|||
|
||||
static edge
|
||||
translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
|
||||
htab_t bb_pbb_mapping, int level, ivs_params_p ip)
|
||||
bb_pbb_htab_type bb_pbb_mapping, int level,
|
||||
ivs_params_p ip)
|
||||
{
|
||||
tree type, lb, ub;
|
||||
edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
|
||||
|
@ -1244,7 +1256,7 @@ translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
|
|||
|
||||
static edge
|
||||
translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
|
||||
edge next_e, htab_t bb_pbb_mapping, int level,
|
||||
edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level,
|
||||
ivs_params_p ip)
|
||||
{
|
||||
edge last_e = graphite_create_new_guard (next_e, stmt, ip);
|
||||
|
@ -1263,7 +1275,7 @@ translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
|
|||
|
||||
static edge
|
||||
translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
|
||||
htab_t bb_pbb_mapping, int level, ivs_params_p ip)
|
||||
bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip)
|
||||
{
|
||||
if (!stmt)
|
||||
return next_e;
|
||||
|
@ -1304,7 +1316,8 @@ translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
|
|||
|
||||
static CloogUnionDomain *
|
||||
add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
|
||||
int nb_scattering_dims, htab_t params_index)
|
||||
int nb_scattering_dims,
|
||||
clast_index_htab_type params_index)
|
||||
{
|
||||
sese region = SCOP_REGION (scop);
|
||||
int i;
|
||||
|
@ -1547,7 +1560,7 @@ int get_max_scattering_dimensions (scop_p scop)
|
|||
}
|
||||
|
||||
static CloogInput *
|
||||
generate_cloog_input (scop_p scop, htab_t params_index)
|
||||
generate_cloog_input (scop_p scop, clast_index_htab_type params_index)
|
||||
{
|
||||
CloogUnionDomain *union_domain;
|
||||
CloogInput *cloog_input;
|
||||
|
@ -1570,7 +1583,7 @@ generate_cloog_input (scop_p scop, htab_t params_index)
|
|||
without a program. */
|
||||
|
||||
static struct clast_stmt *
|
||||
scop_to_clast (scop_p scop, htab_t params_index)
|
||||
scop_to_clast (scop_p scop, clast_index_htab_type params_index)
|
||||
{
|
||||
CloogInput *cloog_input;
|
||||
struct clast_stmt *clast;
|
||||
|
@ -1599,11 +1612,10 @@ void
|
|||
print_generated_program (FILE *file, scop_p scop)
|
||||
{
|
||||
CloogOptions *options = set_cloog_options ();
|
||||
htab_t params_index;
|
||||
clast_index_htab_type params_index;
|
||||
struct clast_stmt *clast;
|
||||
|
||||
params_index = htab_create (10, clast_name_index_elt_info,
|
||||
eq_clast_name_indexes, free_clast_name_index);
|
||||
params_index.create (10);
|
||||
|
||||
clast = scop_to_clast (scop, params_index);
|
||||
|
||||
|
@ -1629,22 +1641,21 @@ debug_generated_program (scop_p scop)
|
|||
*/
|
||||
|
||||
bool
|
||||
gloog (scop_p scop, htab_t bb_pbb_mapping)
|
||||
gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping)
|
||||
{
|
||||
vec<tree> newivs;
|
||||
newivs.create (10);
|
||||
loop_p context_loop;
|
||||
sese region = SCOP_REGION (scop);
|
||||
ifsese if_region = NULL;
|
||||
htab_t newivs_index, params_index;
|
||||
clast_index_htab_type newivs_index, params_index;
|
||||
struct clast_stmt *clast;
|
||||
struct ivs_params ip;
|
||||
|
||||
timevar_push (TV_GRAPHITE_CODE_GEN);
|
||||
gloog_error = false;
|
||||
|
||||
params_index = htab_create (10, clast_name_index_elt_info,
|
||||
eq_clast_name_indexes, free_clast_name_index);
|
||||
params_index.create (10);
|
||||
|
||||
clast = scop_to_clast (scop, params_index);
|
||||
|
||||
|
@ -1667,8 +1678,7 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
|
|||
graphite_verify ();
|
||||
|
||||
context_loop = SESE_ENTRY (region)->src->loop_father;
|
||||
newivs_index = htab_create (10, clast_name_index_elt_info,
|
||||
eq_clast_name_indexes, free_clast_name_index);
|
||||
newivs_index.create (10);
|
||||
|
||||
ip.newivs = &newivs;
|
||||
ip.newivs_index = newivs_index;
|
||||
|
@ -1690,8 +1700,8 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
|
|||
free (if_region->region);
|
||||
free (if_region);
|
||||
|
||||
htab_delete (newivs_index);
|
||||
htab_delete (params_index);
|
||||
newivs_index.dispose ();
|
||||
params_index.dispose ();
|
||||
newivs.release ();
|
||||
cloog_clast_free (clast);
|
||||
timevar_pop (TV_GRAPHITE_CODE_GEN);
|
||||
|
|
|
@ -38,26 +38,7 @@ typedef struct bb_pbb_def
|
|||
poly_bb_p pbb;
|
||||
} bb_pbb_def;
|
||||
|
||||
extern bool gloog (scop_p, htab_t);
|
||||
extern void debug_clast_stmt (struct clast_stmt *);
|
||||
extern void print_clast_stmt (FILE *, struct clast_stmt *);
|
||||
|
||||
/* Hash function for data base element BB_PBB. */
|
||||
|
||||
static inline hashval_t
|
||||
bb_pbb_map_hash (const void *bb_pbb)
|
||||
{
|
||||
return (hashval_t)(((const bb_pbb_def *)bb_pbb)->bb->index);
|
||||
}
|
||||
|
||||
/* Compare data base element BB_PBB1 and BB_PBB2. */
|
||||
|
||||
static inline int
|
||||
eq_bb_pbb_map (const void *bb_pbb1, const void *bb_pbb2)
|
||||
{
|
||||
const bb_pbb_def *bp1 = (const bb_pbb_def *) bb_pbb1;
|
||||
const bb_pbb_def *bp2 = (const bb_pbb_def *) bb_pbb2;
|
||||
return (bp1->bb->index == bp2->bb->index);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
#ifdef HAVE_cloog
|
||||
#include "graphite-poly.h"
|
||||
#include "graphite-htab.h"
|
||||
|
||||
/* Add the constraints from the set S to the domain of MAP. */
|
||||
|
||||
|
@ -579,7 +580,7 @@ loop_level_carries_dependences (scop_p scop, vec<poly_bb_p> body,
|
|||
poly_bb_p. */
|
||||
|
||||
bool
|
||||
loop_is_parallel_p (loop_p loop, htab_t bb_pbb_mapping, int depth)
|
||||
loop_is_parallel_p (loop_p loop, bb_pbb_htab_type bb_pbb_mapping, int depth)
|
||||
{
|
||||
bool dependences;
|
||||
scop_p scop;
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/* Translation of CLAST (CLooG AST) to Gimple.
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
Contributed by Sebastian Pop <sebastian.pop@amd.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_GRAPHITE_HTAB_H
|
||||
#define GCC_GRAPHITE_HTAB_H
|
||||
|
||||
#include "hash-table.h"
|
||||
#include "graphite-clast-to-gimple.h"
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct bb_pbb_hasher : typed_free_remove <bb_pbb_def>
|
||||
{
|
||||
typedef bb_pbb_def value_type;
|
||||
typedef bb_pbb_def compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hash function for data base element BB_PBB. */
|
||||
|
||||
inline hashval_t
|
||||
bb_pbb_hasher::hash (const value_type *bb_pbb)
|
||||
{
|
||||
return (hashval_t)(bb_pbb->bb->index);
|
||||
}
|
||||
|
||||
/* Compare data base element PB1 and PB2. */
|
||||
|
||||
inline bool
|
||||
bb_pbb_hasher::equal (const value_type *bp1, const compare_type *bp2)
|
||||
{
|
||||
return (bp1->bb->index == bp2->bb->index);
|
||||
}
|
||||
|
||||
typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type;
|
||||
|
||||
extern bool gloog (scop_p, bb_pbb_htab_type);
|
||||
poly_bb_p find_pbb_via_hash (bb_pbb_htab_type, basic_block);
|
||||
bool loop_is_parallel_p (loop_p, bb_pbb_htab_type, int);
|
||||
scop_p get_loop_body_pbbs (loop_p, bb_pbb_htab_type, vec<poly_bb_p> *);
|
||||
|
||||
#endif
|
|
@ -1531,9 +1531,6 @@ restore_scattering (scop_p scop)
|
|||
}
|
||||
|
||||
bool graphite_legal_transform (scop_p);
|
||||
poly_bb_p find_pbb_via_hash (htab_t, basic_block);
|
||||
bool loop_is_parallel_p (loop_p, htab_t, int);
|
||||
scop_p get_loop_body_pbbs (loop_p, htab_t, vec<poly_bb_p> *);
|
||||
isl_map *reverse_loop_at_level (poly_bb_p, int);
|
||||
isl_union_map *reverse_loop_for_pbbs (scop_p, vec<poly_bb_p> , int);
|
||||
__isl_give isl_union_map *extend_schedule (__isl_take isl_union_map *);
|
||||
|
|
|
@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "graphite-scop-detection.h"
|
||||
#include "graphite-clast-to-gimple.h"
|
||||
#include "graphite-sese-to-poly.h"
|
||||
#include "graphite-htab.h"
|
||||
|
||||
CloogState *cloog_state;
|
||||
|
||||
|
@ -255,7 +256,7 @@ graphite_transform_loops (void)
|
|||
scop_p scop;
|
||||
bool need_cfg_cleanup_p = false;
|
||||
vec<scop_p> scops = vNULL;
|
||||
htab_t bb_pbb_mapping;
|
||||
bb_pbb_htab_type bb_pbb_mapping;
|
||||
isl_ctx *ctx;
|
||||
|
||||
/* If a function is parallel it was most probably already run through graphite
|
||||
|
@ -277,7 +278,7 @@ graphite_transform_loops (void)
|
|||
print_global_statistics (dump_file);
|
||||
}
|
||||
|
||||
bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
|
||||
bb_pbb_mapping.create (10);
|
||||
|
||||
FOR_EACH_VEC_ELT (scops, i, scop)
|
||||
if (dbg_cnt (graphite_scop))
|
||||
|
@ -291,7 +292,7 @@ graphite_transform_loops (void)
|
|||
need_cfg_cleanup_p = true;
|
||||
}
|
||||
|
||||
htab_delete (bb_pbb_mapping);
|
||||
bb_pbb_mapping.dispose ();
|
||||
free_scops (scops);
|
||||
graphite_finalize (need_cfg_cleanup_p);
|
||||
the_isl_ctx = NULL;
|
||||
|
|
|
@ -145,7 +145,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cfgloop.h"
|
||||
#include "ira.h"
|
||||
#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "dumpfile.h"
|
||||
|
||||
#ifdef INSN_SCHEDULING
|
||||
|
@ -581,22 +581,72 @@ struct delay_pair
|
|||
int stages;
|
||||
};
|
||||
|
||||
/* Helpers for delay hashing. */
|
||||
|
||||
struct delay_i1_hasher : typed_noop_remove <delay_pair>
|
||||
{
|
||||
typedef delay_pair value_type;
|
||||
typedef void compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Returns a hash value for X, based on hashing just I1. */
|
||||
|
||||
inline hashval_t
|
||||
delay_i1_hasher::hash (const value_type *x)
|
||||
{
|
||||
return htab_hash_pointer (x->i1);
|
||||
}
|
||||
|
||||
/* Return true if I1 of pair X is the same as that of pair Y. */
|
||||
|
||||
inline bool
|
||||
delay_i1_hasher::equal (const value_type *x, const compare_type *y)
|
||||
{
|
||||
return x->i1 == y;
|
||||
}
|
||||
|
||||
struct delay_i2_hasher : typed_free_remove <delay_pair>
|
||||
{
|
||||
typedef delay_pair value_type;
|
||||
typedef void compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Returns a hash value for X, based on hashing just I2. */
|
||||
|
||||
inline hashval_t
|
||||
delay_i2_hasher::hash (const value_type *x)
|
||||
{
|
||||
return htab_hash_pointer (x->i2);
|
||||
}
|
||||
|
||||
/* Return true if I2 of pair X is the same as that of pair Y. */
|
||||
|
||||
inline bool
|
||||
delay_i2_hasher::equal (const value_type *x, const compare_type *y)
|
||||
{
|
||||
return x->i2 == y;
|
||||
}
|
||||
|
||||
/* Two hash tables to record delay_pairs, one indexed by I1 and the other
|
||||
indexed by I2. */
|
||||
static htab_t delay_htab;
|
||||
static htab_t delay_htab_i2;
|
||||
static hash_table <delay_i1_hasher> delay_htab;
|
||||
static hash_table <delay_i2_hasher> delay_htab_i2;
|
||||
|
||||
/* Called through htab_traverse. Walk the hashtable using I2 as
|
||||
index, and delete all elements involving an UID higher than
|
||||
that pointed to by *DATA. */
|
||||
static int
|
||||
htab_i2_traverse (void **slot, void *data)
|
||||
int
|
||||
haifa_htab_i2_traverse (delay_pair **slot, int *data)
|
||||
{
|
||||
int maxuid = *(int *)data;
|
||||
struct delay_pair *p = *(struct delay_pair **)slot;
|
||||
int maxuid = *data;
|
||||
struct delay_pair *p = *slot;
|
||||
if (INSN_UID (p->i2) >= maxuid || INSN_UID (p->i1) >= maxuid)
|
||||
{
|
||||
htab_clear_slot (delay_htab_i2, slot);
|
||||
delay_htab_i2.clear_slot (slot);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -604,16 +654,15 @@ htab_i2_traverse (void **slot, void *data)
|
|||
/* Called through htab_traverse. Walk the hashtable using I2 as
|
||||
index, and delete all elements involving an UID higher than
|
||||
that pointed to by *DATA. */
|
||||
static int
|
||||
htab_i1_traverse (void **slot, void *data)
|
||||
int
|
||||
haifa_htab_i1_traverse (delay_pair **pslot, int *data)
|
||||
{
|
||||
int maxuid = *(int *)data;
|
||||
struct delay_pair **pslot = (struct delay_pair **)slot;
|
||||
int maxuid = *data;
|
||||
struct delay_pair *p, *first, **pprev;
|
||||
|
||||
if (INSN_UID ((*pslot)->i1) >= maxuid)
|
||||
{
|
||||
htab_clear_slot (delay_htab, slot);
|
||||
delay_htab.clear_slot (pslot);
|
||||
return 1;
|
||||
}
|
||||
pprev = &first;
|
||||
|
@ -627,7 +676,7 @@ htab_i1_traverse (void **slot, void *data)
|
|||
}
|
||||
*pprev = NULL;
|
||||
if (first == NULL)
|
||||
htab_clear_slot (delay_htab, slot);
|
||||
delay_htab.clear_slot (pslot);
|
||||
else
|
||||
*pslot = first;
|
||||
return 1;
|
||||
|
@ -638,38 +687,8 @@ htab_i1_traverse (void **slot, void *data)
|
|||
void
|
||||
discard_delay_pairs_above (int max_uid)
|
||||
{
|
||||
htab_traverse (delay_htab, htab_i1_traverse, &max_uid);
|
||||
htab_traverse (delay_htab_i2, htab_i2_traverse, &max_uid);
|
||||
}
|
||||
|
||||
/* Returns a hash value for X (which really is a delay_pair), based on
|
||||
hashing just I1. */
|
||||
static hashval_t
|
||||
delay_hash_i1 (const void *x)
|
||||
{
|
||||
return htab_hash_pointer (((const struct delay_pair *) x)->i1);
|
||||
}
|
||||
|
||||
/* Returns a hash value for X (which really is a delay_pair), based on
|
||||
hashing just I2. */
|
||||
static hashval_t
|
||||
delay_hash_i2 (const void *x)
|
||||
{
|
||||
return htab_hash_pointer (((const struct delay_pair *) x)->i2);
|
||||
}
|
||||
|
||||
/* Return nonzero if I1 of pair X is the same as that of pair Y. */
|
||||
static int
|
||||
delay_i1_eq (const void *x, const void *y)
|
||||
{
|
||||
return ((const struct delay_pair *) x)->i1 == y;
|
||||
}
|
||||
|
||||
/* Return nonzero if I2 of pair X is the same as that of pair Y. */
|
||||
static int
|
||||
delay_i2_eq (const void *x, const void *y)
|
||||
{
|
||||
return ((const struct delay_pair *) x)->i2 == y;
|
||||
delay_htab.traverse <int *, haifa_htab_i1_traverse> (&max_uid);
|
||||
delay_htab_i2.traverse <int *, haifa_htab_i2_traverse> (&max_uid);
|
||||
}
|
||||
|
||||
/* This function can be called by a port just before it starts the final
|
||||
|
@ -699,19 +718,15 @@ record_delay_slot_pair (rtx i1, rtx i2, int cycles, int stages)
|
|||
p->cycles = cycles;
|
||||
p->stages = stages;
|
||||
|
||||
if (!delay_htab)
|
||||
if (!delay_htab.is_created ())
|
||||
{
|
||||
delay_htab = htab_create (10, delay_hash_i1, delay_i1_eq, NULL);
|
||||
delay_htab_i2 = htab_create (10, delay_hash_i2, delay_i2_eq, free);
|
||||
delay_htab.create (10);
|
||||
delay_htab_i2.create (10);
|
||||
}
|
||||
slot = ((struct delay_pair **)
|
||||
htab_find_slot_with_hash (delay_htab, i1, htab_hash_pointer (i1),
|
||||
INSERT));
|
||||
slot = delay_htab.find_slot_with_hash (i1, htab_hash_pointer (i1), INSERT);
|
||||
p->next_same_i1 = *slot;
|
||||
*slot = p;
|
||||
slot = ((struct delay_pair **)
|
||||
htab_find_slot_with_hash (delay_htab_i2, i2, htab_hash_pointer (i2),
|
||||
INSERT));
|
||||
slot = delay_htab_i2.find_slot_with_hash (i2, htab_hash_pointer (i2), INSERT);
|
||||
*slot = p;
|
||||
}
|
||||
|
||||
|
@ -722,12 +737,10 @@ real_insn_for_shadow (rtx insn)
|
|||
{
|
||||
struct delay_pair *pair;
|
||||
|
||||
if (delay_htab == NULL)
|
||||
if (!delay_htab.is_created ())
|
||||
return NULL_RTX;
|
||||
|
||||
pair
|
||||
= (struct delay_pair *)htab_find_with_hash (delay_htab_i2, insn,
|
||||
htab_hash_pointer (insn));
|
||||
pair = delay_htab_i2.find_with_hash (insn, htab_hash_pointer (insn));
|
||||
if (!pair || pair->stages > 0)
|
||||
return NULL_RTX;
|
||||
return pair->i1;
|
||||
|
@ -755,12 +768,10 @@ add_delay_dependencies (rtx insn)
|
|||
sd_iterator_def sd_it;
|
||||
dep_t dep;
|
||||
|
||||
if (!delay_htab)
|
||||
if (!delay_htab.is_created ())
|
||||
return;
|
||||
|
||||
pair
|
||||
= (struct delay_pair *)htab_find_with_hash (delay_htab_i2, insn,
|
||||
htab_hash_pointer (insn));
|
||||
pair = delay_htab_i2.find_with_hash (insn, htab_hash_pointer (insn));
|
||||
if (!pair)
|
||||
return;
|
||||
add_dependence (insn, pair->i1, REG_DEP_ANTI);
|
||||
|
@ -771,8 +782,7 @@ add_delay_dependencies (rtx insn)
|
|||
{
|
||||
rtx pro = DEP_PRO (dep);
|
||||
struct delay_pair *other_pair
|
||||
= (struct delay_pair *)htab_find_with_hash (delay_htab_i2, pro,
|
||||
htab_hash_pointer (pro));
|
||||
= delay_htab_i2.find_with_hash (pro, htab_hash_pointer (pro));
|
||||
if (!other_pair || other_pair->stages)
|
||||
continue;
|
||||
if (pair_delay (other_pair) >= pair_delay (pair))
|
||||
|
@ -1395,12 +1405,11 @@ dep_cost_1 (dep_t link, dw_t dw)
|
|||
if (DEP_COST (link) != UNKNOWN_DEP_COST)
|
||||
return DEP_COST (link);
|
||||
|
||||
if (delay_htab)
|
||||
if (delay_htab.is_created ())
|
||||
{
|
||||
struct delay_pair *delay_entry;
|
||||
delay_entry
|
||||
= (struct delay_pair *)htab_find_with_hash (delay_htab_i2, used,
|
||||
htab_hash_pointer (used));
|
||||
= delay_htab_i2.find_with_hash (used, htab_hash_pointer (used));
|
||||
if (delay_entry)
|
||||
{
|
||||
if (delay_entry->i1 == insn)
|
||||
|
@ -5726,12 +5735,12 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p,
|
|||
{
|
||||
int delay_cost = 0;
|
||||
|
||||
if (delay_htab)
|
||||
if (delay_htab.is_created ())
|
||||
{
|
||||
struct delay_pair *delay_entry;
|
||||
delay_entry
|
||||
= (struct delay_pair *)htab_find_with_hash (delay_htab, insn,
|
||||
htab_hash_pointer (insn));
|
||||
= delay_htab.find_with_hash (insn,
|
||||
htab_hash_pointer (insn));
|
||||
while (delay_entry && delay_cost == 0)
|
||||
{
|
||||
delay_cost = estimate_shadow_tick (delay_entry);
|
||||
|
@ -6189,14 +6198,13 @@ schedule_block (basic_block *target_bb, state_t init_state)
|
|||
goto restart_choose_ready;
|
||||
}
|
||||
|
||||
if (delay_htab)
|
||||
if (delay_htab.is_created ())
|
||||
{
|
||||
/* If this insn is the first part of a delay-slot pair, record a
|
||||
backtrack point. */
|
||||
struct delay_pair *delay_entry;
|
||||
delay_entry
|
||||
= (struct delay_pair *)htab_find_with_hash (delay_htab, insn,
|
||||
htab_hash_pointer (insn));
|
||||
= delay_htab.find_with_hash (insn, htab_hash_pointer (insn));
|
||||
if (delay_entry)
|
||||
{
|
||||
save_backtrack_point (delay_entry, ls);
|
||||
|
@ -6761,10 +6769,10 @@ sched_finish (void)
|
|||
void
|
||||
free_delay_pairs (void)
|
||||
{
|
||||
if (delay_htab)
|
||||
if (delay_htab.is_created ())
|
||||
{
|
||||
htab_empty (delay_htab);
|
||||
htab_empty (delay_htab_i2);
|
||||
delay_htab.empty ();
|
||||
delay_htab_i2.empty ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "flags.h"
|
||||
#include "sbitmap.h"
|
||||
#include "bitmap.h"
|
||||
#include "hash-table.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
#include "expr.h"
|
||||
|
@ -173,33 +174,36 @@ static vec<ira_allocno_t> allocno_stack_vec;
|
|||
/* Vector of unique allocno hard registers. */
|
||||
static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
|
||||
|
||||
/* Returns hash value for allocno hard registers V. */
|
||||
static hashval_t
|
||||
allocno_hard_regs_hash (const void *v)
|
||||
struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
|
||||
{
|
||||
const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v;
|
||||
typedef allocno_hard_regs value_type;
|
||||
typedef allocno_hard_regs compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Returns hash value for allocno hard registers V. */
|
||||
inline hashval_t
|
||||
allocno_hard_regs_hasher::hash (const value_type *hv)
|
||||
{
|
||||
return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
|
||||
}
|
||||
|
||||
/* Compares allocno hard registers V1 and V2. */
|
||||
static int
|
||||
allocno_hard_regs_eq (const void *v1, const void *v2)
|
||||
inline bool
|
||||
allocno_hard_regs_hasher::equal (const value_type *hv1, const compare_type *hv2)
|
||||
{
|
||||
const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1;
|
||||
const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2;
|
||||
|
||||
return hard_reg_set_equal_p (hv1->set, hv2->set);
|
||||
}
|
||||
|
||||
/* Hash table of unique allocno hard registers. */
|
||||
static htab_t allocno_hard_regs_htab;
|
||||
static hash_table <allocno_hard_regs_hasher> allocno_hard_regs_htab;
|
||||
|
||||
/* Return allocno hard registers in the hash table equal to HV. */
|
||||
static allocno_hard_regs_t
|
||||
find_hard_regs (allocno_hard_regs_t hv)
|
||||
{
|
||||
return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv);
|
||||
return allocno_hard_regs_htab.find (hv);
|
||||
}
|
||||
|
||||
/* Insert allocno hard registers HV in the hash table (if it is not
|
||||
|
@ -207,11 +211,11 @@ find_hard_regs (allocno_hard_regs_t hv)
|
|||
static allocno_hard_regs_t
|
||||
insert_hard_regs (allocno_hard_regs_t hv)
|
||||
{
|
||||
PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT);
|
||||
allocno_hard_regs **slot = allocno_hard_regs_htab.find_slot (hv, INSERT);
|
||||
|
||||
if (*slot == NULL)
|
||||
*slot = hv;
|
||||
return (allocno_hard_regs_t) *slot;
|
||||
return *slot;
|
||||
}
|
||||
|
||||
/* Initialize data concerning allocno hard registers. */
|
||||
|
@ -219,8 +223,7 @@ static void
|
|||
init_allocno_hard_regs (void)
|
||||
{
|
||||
allocno_hard_regs_vec.create (200);
|
||||
allocno_hard_regs_htab
|
||||
= htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL);
|
||||
allocno_hard_regs_htab.create (200);
|
||||
}
|
||||
|
||||
/* Add (or update info about) allocno hard registers with SET and
|
||||
|
@ -258,7 +261,7 @@ finish_allocno_hard_regs (void)
|
|||
allocno_hard_regs_vec.iterate (i, &hv);
|
||||
i++)
|
||||
ira_free (hv);
|
||||
htab_delete (allocno_hard_regs_htab);
|
||||
allocno_hard_regs_htab.dispose ();
|
||||
allocno_hard_regs_vec.release ();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "hash-table.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "rtl.h"
|
||||
#include "expr.h"
|
||||
|
@ -131,35 +132,41 @@ typedef const struct cost_classes *const_cost_classes_t;
|
|||
/* Info about cost classes for each pseudo. */
|
||||
static cost_classes_t *regno_cost_classes;
|
||||
|
||||
/* Returns hash value for cost classes info V. */
|
||||
static hashval_t
|
||||
cost_classes_hash (const void *v)
|
||||
{
|
||||
const_cost_classes_t hv = (const_cost_classes_t) v;
|
||||
/* Helper for cost_classes hashing. */
|
||||
|
||||
struct cost_classes_hasher
|
||||
{
|
||||
typedef cost_classes value_type;
|
||||
typedef cost_classes compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
/* Returns hash value for cost classes info HV. */
|
||||
inline hashval_t
|
||||
cost_classes_hasher::hash (const value_type *hv)
|
||||
{
|
||||
return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0);
|
||||
}
|
||||
|
||||
/* Compares cost classes info V1 and V2. */
|
||||
static int
|
||||
cost_classes_eq (const void *v1, const void *v2)
|
||||
/* Compares cost classes info HV1 and HV2. */
|
||||
inline bool
|
||||
cost_classes_hasher::equal (const value_type *hv1, const compare_type *hv2)
|
||||
{
|
||||
const_cost_classes_t hv1 = (const_cost_classes_t) v1;
|
||||
const_cost_classes_t hv2 = (const_cost_classes_t) v2;
|
||||
|
||||
return hv1->num == hv2->num && memcmp (hv1->classes, hv2->classes,
|
||||
sizeof (enum reg_class) * hv1->num);
|
||||
}
|
||||
|
||||
/* Delete cost classes info V from the hash table. */
|
||||
static void
|
||||
cost_classes_del (void *v)
|
||||
inline void
|
||||
cost_classes_hasher::remove (value_type *v)
|
||||
{
|
||||
ira_free (v);
|
||||
}
|
||||
|
||||
/* Hash table of unique cost classes. */
|
||||
static htab_t cost_classes_htab;
|
||||
static hash_table <cost_classes_hasher> cost_classes_htab;
|
||||
|
||||
/* Map allocno class -> cost classes for pseudo of given allocno
|
||||
class. */
|
||||
|
@ -180,8 +187,7 @@ initiate_regno_cost_classes (void)
|
|||
sizeof (cost_classes_t) * N_REG_CLASSES);
|
||||
memset (cost_classes_mode_cache, 0,
|
||||
sizeof (cost_classes_t) * MAX_MACHINE_MODE);
|
||||
cost_classes_htab
|
||||
= htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del);
|
||||
cost_classes_htab.create (200);
|
||||
}
|
||||
|
||||
/* Create new cost classes from cost classes FROM and set up members
|
||||
|
@ -229,7 +235,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
|
|||
cost_classes_t classes_ptr;
|
||||
enum reg_class cl;
|
||||
int i;
|
||||
PTR *slot;
|
||||
cost_classes **slot;
|
||||
HARD_REG_SET temp, temp2;
|
||||
bool exclude_p;
|
||||
|
||||
|
@ -255,7 +261,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
|
|||
}
|
||||
classes.classes[classes.num++] = cl;
|
||||
}
|
||||
slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
|
||||
slot = cost_classes_htab.find_slot (&classes, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
classes_ptr = setup_cost_classes (&classes);
|
||||
|
@ -279,7 +285,7 @@ setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
|
|||
cost_classes_t classes_ptr;
|
||||
enum reg_class cl;
|
||||
int i;
|
||||
PTR *slot;
|
||||
cost_classes **slot;
|
||||
HARD_REG_SET temp;
|
||||
|
||||
if ((classes_ptr = cost_classes_mode_cache[mode]) == NULL)
|
||||
|
@ -294,7 +300,7 @@ setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
|
|||
continue;
|
||||
classes.classes[classes.num++] = cl;
|
||||
}
|
||||
slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
|
||||
slot = cost_classes_htab.find_slot (&classes, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
classes_ptr = setup_cost_classes (&classes);
|
||||
|
@ -312,7 +318,7 @@ static void
|
|||
finish_regno_cost_classes (void)
|
||||
{
|
||||
ira_free (regno_cost_classes);
|
||||
htab_delete (cost_classes_htab);
|
||||
cost_classes_htab.dispose ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "function.h"
|
||||
#include "flags.h"
|
||||
#include "df.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "except.h"
|
||||
#include "params.h"
|
||||
#include "regs.h"
|
||||
|
@ -424,27 +424,28 @@ invariant_expr_equal_p (rtx insn1, rtx e1, rtx insn2, rtx e2)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Returns hash value for invariant expression entry E. */
|
||||
|
||||
static hashval_t
|
||||
hash_invariant_expr (const void *e)
|
||||
struct invariant_expr_hasher : typed_free_remove <invariant_expr_entry>
|
||||
{
|
||||
const struct invariant_expr_entry *const entry =
|
||||
(const struct invariant_expr_entry *) e;
|
||||
typedef invariant_expr_entry value_type;
|
||||
typedef invariant_expr_entry compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Returns hash value for invariant expression entry ENTRY. */
|
||||
|
||||
inline hashval_t
|
||||
invariant_expr_hasher::hash (const value_type *entry)
|
||||
{
|
||||
return entry->hash;
|
||||
}
|
||||
|
||||
/* Compares invariant expression entries E1 and E2. */
|
||||
/* Compares invariant expression entries ENTRY1 and ENTRY2. */
|
||||
|
||||
static int
|
||||
eq_invariant_expr (const void *e1, const void *e2)
|
||||
inline bool
|
||||
invariant_expr_hasher::equal (const value_type *entry1,
|
||||
const compare_type *entry2)
|
||||
{
|
||||
const struct invariant_expr_entry *const entry1 =
|
||||
(const struct invariant_expr_entry *) e1;
|
||||
const struct invariant_expr_entry *const entry2 =
|
||||
(const struct invariant_expr_entry *) e2;
|
||||
|
||||
if (entry1->mode != entry2->mode)
|
||||
return 0;
|
||||
|
||||
|
@ -452,24 +453,26 @@ eq_invariant_expr (const void *e1, const void *e2)
|
|||
entry2->inv->insn, entry2->expr);
|
||||
}
|
||||
|
||||
typedef hash_table <invariant_expr_hasher> invariant_htab_type;
|
||||
|
||||
/* Checks whether invariant with value EXPR in machine mode MODE is
|
||||
recorded in EQ. If this is the case, return the invariant. Otherwise
|
||||
insert INV to the table for this expression and return INV. */
|
||||
|
||||
static struct invariant *
|
||||
find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode,
|
||||
find_or_insert_inv (invariant_htab_type eq, rtx expr, enum machine_mode mode,
|
||||
struct invariant *inv)
|
||||
{
|
||||
hashval_t hash = hash_invariant_expr_1 (inv->insn, expr);
|
||||
struct invariant_expr_entry *entry;
|
||||
struct invariant_expr_entry pentry;
|
||||
PTR *slot;
|
||||
invariant_expr_entry **slot;
|
||||
|
||||
pentry.expr = expr;
|
||||
pentry.inv = inv;
|
||||
pentry.mode = mode;
|
||||
slot = htab_find_slot_with_hash (eq, &pentry, hash, INSERT);
|
||||
entry = (struct invariant_expr_entry *) *slot;
|
||||
slot = eq.find_slot_with_hash (&pentry, hash, INSERT);
|
||||
entry = *slot;
|
||||
|
||||
if (entry)
|
||||
return entry->inv;
|
||||
|
@ -488,7 +491,7 @@ find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode,
|
|||
hash table of the invariants. */
|
||||
|
||||
static void
|
||||
find_identical_invariants (htab_t eq, struct invariant *inv)
|
||||
find_identical_invariants (invariant_htab_type eq, struct invariant *inv)
|
||||
{
|
||||
unsigned depno;
|
||||
bitmap_iterator bi;
|
||||
|
@ -525,13 +528,13 @@ merge_identical_invariants (void)
|
|||
{
|
||||
unsigned i;
|
||||
struct invariant *inv;
|
||||
htab_t eq = htab_create (invariants.length (),
|
||||
hash_invariant_expr, eq_invariant_expr, free);
|
||||
invariant_htab_type eq;
|
||||
eq.create (invariants.length ());
|
||||
|
||||
FOR_EACH_VEC_ELT (invariants, i, inv)
|
||||
find_identical_invariants (eq, inv);
|
||||
|
||||
htab_delete (eq);
|
||||
eq.dispose ();
|
||||
}
|
||||
|
||||
/* Determines the basic blocks inside LOOP that are always executed and
|
||||
|
|
|
@ -60,7 +60,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "intl.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "df.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "dumpfile.h"
|
||||
|
||||
/* Possible return values of iv_get_reaching_def. */
|
||||
|
@ -106,9 +106,35 @@ static struct rtx_iv ** iv_ref_table;
|
|||
|
||||
static struct loop *current_loop;
|
||||
|
||||
/* Hashtable helper. */
|
||||
|
||||
struct biv_entry_hasher : typed_free_remove <biv_entry>
|
||||
{
|
||||
typedef biv_entry value_type;
|
||||
typedef rtx_def compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Returns hash value for biv B. */
|
||||
|
||||
inline hashval_t
|
||||
biv_entry_hasher::hash (const value_type *b)
|
||||
{
|
||||
return b->regno;
|
||||
}
|
||||
|
||||
/* Compares biv B and register R. */
|
||||
|
||||
inline bool
|
||||
biv_entry_hasher::equal (const value_type *b, const compare_type *r)
|
||||
{
|
||||
return b->regno == REGNO (r);
|
||||
}
|
||||
|
||||
/* Bivs of the current loop. */
|
||||
|
||||
static htab_t bivs;
|
||||
static hash_table <biv_entry_hasher> bivs;
|
||||
|
||||
static bool iv_analyze_op (rtx, rtx, struct rtx_iv *);
|
||||
|
||||
|
@ -243,24 +269,9 @@ clear_iv_info (void)
|
|||
}
|
||||
}
|
||||
|
||||
htab_empty (bivs);
|
||||
bivs.empty ();
|
||||
}
|
||||
|
||||
/* Returns hash value for biv B. */
|
||||
|
||||
static hashval_t
|
||||
biv_hash (const void *b)
|
||||
{
|
||||
return ((const struct biv_entry *) b)->regno;
|
||||
}
|
||||
|
||||
/* Compares biv B and register R. */
|
||||
|
||||
static int
|
||||
biv_eq (const void *b, const void *r)
|
||||
{
|
||||
return ((const struct biv_entry *) b)->regno == REGNO ((const_rtx) r);
|
||||
}
|
||||
|
||||
/* Prepare the data for an induction variable analysis of a LOOP. */
|
||||
|
||||
|
@ -277,7 +288,7 @@ iv_analysis_loop_init (struct loop *loop)
|
|||
if (clean_slate)
|
||||
{
|
||||
df_set_flags (DF_EQ_NOTES + DF_DEFER_INSN_RESCAN);
|
||||
bivs = htab_create (10, biv_hash, biv_eq, free);
|
||||
bivs.create (10);
|
||||
clean_slate = false;
|
||||
}
|
||||
else
|
||||
|
@ -837,8 +848,7 @@ record_iv (df_ref def, struct rtx_iv *iv)
|
|||
static bool
|
||||
analyzed_for_bivness_p (rtx def, struct rtx_iv *iv)
|
||||
{
|
||||
struct biv_entry *biv =
|
||||
(struct biv_entry *) htab_find_with_hash (bivs, def, REGNO (def));
|
||||
struct biv_entry *biv = bivs.find_with_hash (def, REGNO (def));
|
||||
|
||||
if (!biv)
|
||||
return false;
|
||||
|
@ -851,7 +861,7 @@ static void
|
|||
record_biv (rtx def, struct rtx_iv *iv)
|
||||
{
|
||||
struct biv_entry *biv = XNEW (struct biv_entry);
|
||||
void **slot = htab_find_slot_with_hash (bivs, def, REGNO (def), INSERT);
|
||||
biv_entry **slot = bivs.find_slot_with_hash (def, REGNO (def), INSERT);
|
||||
|
||||
biv->regno = REGNO (def);
|
||||
biv->iv = *iv;
|
||||
|
@ -1293,11 +1303,10 @@ iv_analysis_done (void)
|
|||
clear_iv_info ();
|
||||
clean_slate = true;
|
||||
df_finish_pass (true);
|
||||
htab_delete (bivs);
|
||||
bivs.dispose ();
|
||||
free (iv_ref_table);
|
||||
iv_ref_table = NULL;
|
||||
iv_ref_table_size = 0;
|
||||
bivs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cfgloop.h"
|
||||
#include "params.h"
|
||||
#include "expr.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "recog.h"
|
||||
#include "target.h"
|
||||
#include "dumpfile.h"
|
||||
|
@ -102,16 +102,70 @@ struct var_to_expand
|
|||
var_expansions[REUSE_EXPANSION - 1]. */
|
||||
};
|
||||
|
||||
/* Hashtable helper for iv_to_split. */
|
||||
|
||||
struct iv_split_hasher : typed_free_remove <iv_to_split>
|
||||
{
|
||||
typedef iv_to_split value_type;
|
||||
typedef iv_to_split compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
|
||||
/* A hash function for information about insns to split. */
|
||||
|
||||
inline hashval_t
|
||||
iv_split_hasher::hash (const value_type *ivts)
|
||||
{
|
||||
return (hashval_t) INSN_UID (ivts->insn);
|
||||
}
|
||||
|
||||
/* An equality functions for information about insns to split. */
|
||||
|
||||
inline bool
|
||||
iv_split_hasher::equal (const value_type *i1, const compare_type *i2)
|
||||
{
|
||||
return i1->insn == i2->insn;
|
||||
}
|
||||
|
||||
/* Hashtable helper for iv_to_split. */
|
||||
|
||||
struct var_expand_hasher : typed_free_remove <var_to_expand>
|
||||
{
|
||||
typedef var_to_expand value_type;
|
||||
typedef var_to_expand compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Return a hash for VES. */
|
||||
|
||||
inline hashval_t
|
||||
var_expand_hasher::hash (const value_type *ves)
|
||||
{
|
||||
return (hashval_t) INSN_UID (ves->insn);
|
||||
}
|
||||
|
||||
/* Return true if I1 and I2 refer to the same instruction. */
|
||||
|
||||
inline bool
|
||||
var_expand_hasher::equal (const value_type *i1, const compare_type *i2)
|
||||
{
|
||||
return i1->insn == i2->insn;
|
||||
}
|
||||
|
||||
/* Information about optimization applied in
|
||||
the unrolled loop. */
|
||||
|
||||
struct opt_info
|
||||
{
|
||||
htab_t insns_to_split; /* A hashtable of insns to split. */
|
||||
hash_table <iv_split_hasher> insns_to_split; /* A hashtable of insns to
|
||||
split. */
|
||||
struct iv_to_split *iv_to_split_head; /* The first iv to split. */
|
||||
struct iv_to_split **iv_to_split_tail; /* Pointer to the tail of the list. */
|
||||
htab_t insns_with_var_to_expand; /* A hashtable of insns with accumulators
|
||||
to expand. */
|
||||
hash_table <var_expand_hasher> insns_with_var_to_expand; /* A hashtable of
|
||||
insns with accumulators to expand. */
|
||||
struct var_to_expand *var_to_expand_head; /* The first var to expand. */
|
||||
struct var_to_expand **var_to_expand_tail; /* Pointer to the tail of the list. */
|
||||
unsigned first_new_block; /* The first basic block that was
|
||||
|
@ -1585,45 +1639,6 @@ unroll_loop_stupid (struct loop *loop)
|
|||
nunroll, num_loop_insns (loop));
|
||||
}
|
||||
|
||||
/* A hash function for information about insns to split. */
|
||||
|
||||
static hashval_t
|
||||
si_info_hash (const void *ivts)
|
||||
{
|
||||
return (hashval_t) INSN_UID (((const struct iv_to_split *) ivts)->insn);
|
||||
}
|
||||
|
||||
/* An equality functions for information about insns to split. */
|
||||
|
||||
static int
|
||||
si_info_eq (const void *ivts1, const void *ivts2)
|
||||
{
|
||||
const struct iv_to_split *const i1 = (const struct iv_to_split *) ivts1;
|
||||
const struct iv_to_split *const i2 = (const struct iv_to_split *) ivts2;
|
||||
|
||||
return i1->insn == i2->insn;
|
||||
}
|
||||
|
||||
/* Return a hash for VES, which is really a "var_to_expand *". */
|
||||
|
||||
static hashval_t
|
||||
ve_info_hash (const void *ves)
|
||||
{
|
||||
return (hashval_t) INSN_UID (((const struct var_to_expand *) ves)->insn);
|
||||
}
|
||||
|
||||
/* Return true if IVTS1 and IVTS2 (which are really both of type
|
||||
"var_to_expand *") refer to the same instruction. */
|
||||
|
||||
static int
|
||||
ve_info_eq (const void *ivts1, const void *ivts2)
|
||||
{
|
||||
const struct var_to_expand *const i1 = (const struct var_to_expand *) ivts1;
|
||||
const struct var_to_expand *const i2 = (const struct var_to_expand *) ivts2;
|
||||
|
||||
return i1->insn == i2->insn;
|
||||
}
|
||||
|
||||
/* Returns true if REG is referenced in one nondebug insn in LOOP.
|
||||
Set *DEBUG_USES to the number of debug insns that reference the
|
||||
variable. */
|
||||
|
@ -1908,8 +1923,8 @@ analyze_insns_in_loop (struct loop *loop)
|
|||
rtx insn;
|
||||
struct iv_to_split *ivts = NULL;
|
||||
struct var_to_expand *ves = NULL;
|
||||
PTR *slot1;
|
||||
PTR *slot2;
|
||||
iv_to_split **slot1;
|
||||
var_to_expand **slot2;
|
||||
vec<edge> edges = get_loop_exit_edges (loop);
|
||||
edge exit;
|
||||
bool can_apply = false;
|
||||
|
@ -1920,8 +1935,7 @@ analyze_insns_in_loop (struct loop *loop)
|
|||
|
||||
if (flag_split_ivs_in_unroller)
|
||||
{
|
||||
opt_info->insns_to_split = htab_create (5 * loop->num_nodes,
|
||||
si_info_hash, si_info_eq, free);
|
||||
opt_info->insns_to_split.create (5 * loop->num_nodes);
|
||||
opt_info->iv_to_split_head = NULL;
|
||||
opt_info->iv_to_split_tail = &opt_info->iv_to_split_head;
|
||||
}
|
||||
|
@ -1942,9 +1956,7 @@ analyze_insns_in_loop (struct loop *loop)
|
|||
if (flag_variable_expansion_in_unroller
|
||||
&& can_apply)
|
||||
{
|
||||
opt_info->insns_with_var_to_expand = htab_create (5 * loop->num_nodes,
|
||||
ve_info_hash,
|
||||
ve_info_eq, free);
|
||||
opt_info->insns_with_var_to_expand.create (5 * loop->num_nodes);
|
||||
opt_info->var_to_expand_head = NULL;
|
||||
opt_info->var_to_expand_tail = &opt_info->var_to_expand_head;
|
||||
}
|
||||
|
@ -1960,12 +1972,12 @@ analyze_insns_in_loop (struct loop *loop)
|
|||
if (!INSN_P (insn))
|
||||
continue;
|
||||
|
||||
if (opt_info->insns_to_split)
|
||||
if (opt_info->insns_to_split.is_created ())
|
||||
ivts = analyze_iv_to_split_insn (insn);
|
||||
|
||||
if (ivts)
|
||||
{
|
||||
slot1 = htab_find_slot (opt_info->insns_to_split, ivts, INSERT);
|
||||
slot1 = opt_info->insns_to_split.find_slot (ivts, INSERT);
|
||||
gcc_assert (*slot1 == NULL);
|
||||
*slot1 = ivts;
|
||||
*opt_info->iv_to_split_tail = ivts;
|
||||
|
@ -1973,12 +1985,12 @@ analyze_insns_in_loop (struct loop *loop)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (opt_info->insns_with_var_to_expand)
|
||||
if (opt_info->insns_with_var_to_expand.is_created ())
|
||||
ves = analyze_insn_to_expand_var (loop, insn);
|
||||
|
||||
if (ves)
|
||||
{
|
||||
slot2 = htab_find_slot (opt_info->insns_with_var_to_expand, ves, INSERT);
|
||||
slot2 = opt_info->insns_with_var_to_expand.find_slot (ves, INSERT);
|
||||
gcc_assert (*slot2 == NULL);
|
||||
*slot2 = ves;
|
||||
*opt_info->var_to_expand_tail = ves;
|
||||
|
@ -2356,7 +2368,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
|
|||
gcc_assert (!unrolling || rewrite_original_loop);
|
||||
|
||||
/* Allocate the basic variables (i0). */
|
||||
if (opt_info->insns_to_split)
|
||||
if (opt_info->insns_to_split.is_created ())
|
||||
for (ivts = opt_info->iv_to_split_head; ivts; ivts = ivts->next)
|
||||
allocate_basic_variable (ivts);
|
||||
|
||||
|
@ -2388,12 +2400,11 @@ apply_opt_in_copies (struct opt_info *opt_info,
|
|||
ve_templ.insn = orig_insn;
|
||||
|
||||
/* Apply splitting iv optimization. */
|
||||
if (opt_info->insns_to_split)
|
||||
if (opt_info->insns_to_split.is_created ())
|
||||
{
|
||||
maybe_strip_eq_note_for_split_iv (opt_info, insn);
|
||||
|
||||
ivts = (struct iv_to_split *)
|
||||
htab_find (opt_info->insns_to_split, &ivts_templ);
|
||||
ivts = opt_info->insns_to_split.find (&ivts_templ);
|
||||
|
||||
if (ivts)
|
||||
{
|
||||
|
@ -2406,10 +2417,10 @@ apply_opt_in_copies (struct opt_info *opt_info,
|
|||
}
|
||||
}
|
||||
/* Apply variable expansion optimization. */
|
||||
if (unrolling && opt_info->insns_with_var_to_expand)
|
||||
if (unrolling && opt_info->insns_with_var_to_expand.is_created ())
|
||||
{
|
||||
ves = (struct var_to_expand *)
|
||||
htab_find (opt_info->insns_with_var_to_expand, &ve_templ);
|
||||
opt_info->insns_with_var_to_expand.find (&ve_templ);
|
||||
if (ves)
|
||||
{
|
||||
gcc_assert (GET_CODE (PATTERN (insn))
|
||||
|
@ -2426,7 +2437,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
|
|||
|
||||
/* Initialize the variable expansions in the loop preheader
|
||||
and take care of combining them at the loop exit. */
|
||||
if (opt_info->insns_with_var_to_expand)
|
||||
if (opt_info->insns_with_var_to_expand.is_created ())
|
||||
{
|
||||
for (ves = opt_info->var_to_expand_head; ves; ves = ves->next)
|
||||
insert_var_expansion_initialization (ves, opt_info->loop_preheader);
|
||||
|
@ -2455,12 +2466,12 @@ apply_opt_in_copies (struct opt_info *opt_info,
|
|||
continue;
|
||||
|
||||
ivts_templ.insn = orig_insn;
|
||||
if (opt_info->insns_to_split)
|
||||
if (opt_info->insns_to_split.is_created ())
|
||||
{
|
||||
maybe_strip_eq_note_for_split_iv (opt_info, orig_insn);
|
||||
|
||||
ivts = (struct iv_to_split *)
|
||||
htab_find (opt_info->insns_to_split, &ivts_templ);
|
||||
opt_info->insns_to_split.find (&ivts_templ);
|
||||
if (ivts)
|
||||
{
|
||||
if (!delta)
|
||||
|
@ -2479,15 +2490,15 @@ apply_opt_in_copies (struct opt_info *opt_info,
|
|||
static void
|
||||
free_opt_info (struct opt_info *opt_info)
|
||||
{
|
||||
if (opt_info->insns_to_split)
|
||||
htab_delete (opt_info->insns_to_split);
|
||||
if (opt_info->insns_with_var_to_expand)
|
||||
if (opt_info->insns_to_split.is_created ())
|
||||
opt_info->insns_to_split.dispose ();
|
||||
if (opt_info->insns_with_var_to_expand.is_created ())
|
||||
{
|
||||
struct var_to_expand *ves;
|
||||
|
||||
for (ves = opt_info->var_to_expand_head; ves; ves = ves->next)
|
||||
ves->var_expansions.release ();
|
||||
htab_delete (opt_info->insns_with_var_to_expand);
|
||||
opt_info->insns_with_var_to_expand.dispose ();
|
||||
}
|
||||
free (opt_info);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,19 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-pass.h"
|
||||
#include "streamer-hooks.h"
|
||||
|
||||
struct freeing_string_slot_hasher : string_slot_hasher
|
||||
{
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
inline void
|
||||
freeing_string_slot_hasher::remove (value_type *v)
|
||||
{
|
||||
free (v);
|
||||
}
|
||||
|
||||
/* The table to hold the file names. */
|
||||
static htab_t file_name_hash_table;
|
||||
static hash_table <freeing_string_slot_hasher> file_name_hash_table;
|
||||
|
||||
|
||||
/* Check that tag ACTUAL has one of the given values. NUM_TAGS is the
|
||||
|
@ -94,14 +105,14 @@ lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length)
|
|||
static const char *
|
||||
canon_file_name (const char *string)
|
||||
{
|
||||
void **slot;
|
||||
string_slot **slot;
|
||||
struct string_slot s_slot;
|
||||
size_t len = strlen (string);
|
||||
|
||||
s_slot.s = string;
|
||||
s_slot.len = len;
|
||||
|
||||
slot = htab_find_slot (file_name_hash_table, &s_slot, INSERT);
|
||||
slot = file_name_hash_table.find_slot (&s_slot, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
char *saved_string;
|
||||
|
@ -117,7 +128,7 @@ canon_file_name (const char *string)
|
|||
}
|
||||
else
|
||||
{
|
||||
struct string_slot *old_slot = (struct string_slot *) *slot;
|
||||
struct string_slot *old_slot = *slot;
|
||||
return old_slot->s;
|
||||
}
|
||||
}
|
||||
|
@ -1137,8 +1148,7 @@ void
|
|||
lto_reader_init (void)
|
||||
{
|
||||
lto_streamer_init ();
|
||||
file_name_hash_table = htab_create (37, hash_string_slot_node,
|
||||
eq_string_slot_node, free);
|
||||
file_name_hash_table.create (37);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -77,8 +77,7 @@ create_output_block (enum lto_section_type section_type)
|
|||
|
||||
clear_line_info (ob);
|
||||
|
||||
ob->string_hash_table = htab_create (37, hash_string_slot_node,
|
||||
eq_string_slot_node, NULL);
|
||||
ob->string_hash_table.create (37);
|
||||
gcc_obstack_init (&ob->obstack);
|
||||
|
||||
return ob;
|
||||
|
@ -92,7 +91,7 @@ destroy_output_block (struct output_block *ob)
|
|||
{
|
||||
enum lto_section_type section_type = ob->section_type;
|
||||
|
||||
htab_delete (ob->string_hash_table);
|
||||
ob->string_hash_table.dispose ();
|
||||
|
||||
free (ob->main_stream);
|
||||
free (ob->string_stream);
|
||||
|
|
|
@ -253,28 +253,33 @@ print_lto_report (const char *s)
|
|||
|
||||
|
||||
#ifdef LTO_STREAMER_DEBUG
|
||||
static htab_t tree_htab;
|
||||
|
||||
struct tree_hash_entry
|
||||
{
|
||||
tree key;
|
||||
intptr_t value;
|
||||
};
|
||||
|
||||
static hashval_t
|
||||
hash_tree (const void *p)
|
||||
struct tree_entry_hasher : typed_noop_remove <tree_hash_entry>
|
||||
{
|
||||
typedef tree_hash_entry value_type;
|
||||
typedef tree_hash_entry compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
tree_entry_hasher::hash (const value_type *e)
|
||||
{
|
||||
const struct tree_hash_entry *e = (const struct tree_hash_entry *) p;
|
||||
return htab_hash_pointer (e->key);
|
||||
}
|
||||
|
||||
static int
|
||||
eq_tree (const void *p1, const void *p2)
|
||||
inline bool
|
||||
tree_entry_hasher::equal (const value_type *e1, const compare_type *e2)
|
||||
{
|
||||
const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1;
|
||||
const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2;
|
||||
return (e1->key == e2->key);
|
||||
}
|
||||
|
||||
static hash_table <tree_hash_entry> tree_htab;
|
||||
#endif
|
||||
|
||||
/* Initialization common to the LTO reader and writer. */
|
||||
|
@ -289,7 +294,7 @@ lto_streamer_init (void)
|
|||
streamer_check_handled_ts_structures ();
|
||||
|
||||
#ifdef LTO_STREAMER_DEBUG
|
||||
tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
|
||||
tree_htab.create (31);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -324,8 +329,7 @@ lto_orig_address_map (tree t, intptr_t orig_t)
|
|||
|
||||
ent.key = t;
|
||||
ent.value = orig_t;
|
||||
slot
|
||||
= (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT);
|
||||
slot = tree_htab.find_slot (&ent, INSERT);
|
||||
gcc_assert (!*slot);
|
||||
*slot = XNEW (struct tree_hash_entry);
|
||||
**slot = ent;
|
||||
|
@ -342,8 +346,7 @@ lto_orig_address_get (tree t)
|
|||
struct tree_hash_entry **slot;
|
||||
|
||||
ent.key = t;
|
||||
slot
|
||||
= (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
|
||||
slot = tree_htab.find_slot (&ent, NO_INSERT);
|
||||
return (slot ? (*slot)->value : 0);
|
||||
}
|
||||
|
||||
|
@ -357,11 +360,10 @@ lto_orig_address_remove (tree t)
|
|||
struct tree_hash_entry **slot;
|
||||
|
||||
ent.key = t;
|
||||
slot
|
||||
= (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
|
||||
slot = tree_htab.find_slot (&ent, NO_INSERT);
|
||||
gcc_assert (slot);
|
||||
free (*slot);
|
||||
htab_clear_slot (tree_htab, (PTR *)slot);
|
||||
tree_htab.clear_slot (slot);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#define GCC_LTO_STREAMER_H
|
||||
|
||||
#include "plugin-api.h"
|
||||
#include "hash-table.h"
|
||||
#include "tree.h"
|
||||
#include "gimple.h"
|
||||
#include "target.h"
|
||||
|
@ -627,6 +628,50 @@ struct lto_simple_output_block
|
|||
struct lto_output_stream *main_stream;
|
||||
};
|
||||
|
||||
/* String hashing. */
|
||||
|
||||
struct string_slot
|
||||
{
|
||||
const char *s;
|
||||
int len;
|
||||
unsigned int slot_num;
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct string_slot_hasher : typed_noop_remove <string_slot>
|
||||
{
|
||||
typedef string_slot value_type;
|
||||
typedef string_slot compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Returns a hash code for DS. Adapted from libiberty's htab_hash_string
|
||||
to support strings that may not end in '\0'. */
|
||||
|
||||
inline hashval_t
|
||||
string_slot_hasher::hash (const value_type *ds)
|
||||
{
|
||||
hashval_t r = ds->len;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ds->len; i++)
|
||||
r = r * 67 + (unsigned)ds->s[i] - 113;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Returns nonzero if DS1 and DS2 are equal. */
|
||||
|
||||
inline bool
|
||||
string_slot_hasher::equal (const value_type *ds1, const compare_type *ds2)
|
||||
{
|
||||
if (ds1->len == ds2->len)
|
||||
return memcmp (ds1->s, ds2->s, ds1->len) == 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Data structure holding all the data and descriptors used when writing
|
||||
an LTO file. */
|
||||
struct output_block
|
||||
|
@ -645,7 +690,7 @@ struct output_block
|
|||
|
||||
/* The hash table that contains the set of strings we have seen so
|
||||
far and the indexes assigned to them. */
|
||||
htab_t string_hash_table;
|
||||
hash_table <string_slot_hasher> string_hash_table;
|
||||
|
||||
/* The current cgraph_node that we are currently serializing. Null
|
||||
if we are serializing something else. */
|
||||
|
|
41
gcc/passes.c
41
gcc/passes.c
|
@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "line-map.h"
|
||||
#include "hash-table.h"
|
||||
#include "input.h"
|
||||
#include "tree.h"
|
||||
#include "rtl.h"
|
||||
|
@ -579,27 +580,33 @@ struct pass_registry
|
|||
struct opt_pass *pass;
|
||||
};
|
||||
|
||||
/* Helper for pass_registry hash table. */
|
||||
|
||||
struct pass_registry_hasher : typed_noop_remove <pass_registry>
|
||||
{
|
||||
typedef pass_registry value_type;
|
||||
typedef pass_registry compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Pass registry hash function. */
|
||||
|
||||
static hashval_t
|
||||
passr_hash (const void *p)
|
||||
inline hashval_t
|
||||
pass_registry_hasher::hash (const value_type *s)
|
||||
{
|
||||
const struct pass_registry *const s = (const struct pass_registry *const) p;
|
||||
return htab_hash_string (s->unique_name);
|
||||
}
|
||||
|
||||
/* Hash equal function */
|
||||
|
||||
static int
|
||||
passr_eq (const void *p1, const void *p2)
|
||||
inline bool
|
||||
pass_registry_hasher::equal (const value_type *s1, const compare_type *s2)
|
||||
{
|
||||
const struct pass_registry *const s1 = (const struct pass_registry *const) p1;
|
||||
const struct pass_registry *const s2 = (const struct pass_registry *const) p2;
|
||||
|
||||
return !strcmp (s1->unique_name, s2->unique_name);
|
||||
}
|
||||
|
||||
static htab_t name_to_pass_map = NULL;
|
||||
static hash_table <pass_registry_hasher> name_to_pass_map;
|
||||
|
||||
/* Register PASS with NAME. */
|
||||
|
||||
|
@ -609,11 +616,11 @@ register_pass_name (struct opt_pass *pass, const char *name)
|
|||
struct pass_registry **slot;
|
||||
struct pass_registry pr;
|
||||
|
||||
if (!name_to_pass_map)
|
||||
name_to_pass_map = htab_create (256, passr_hash, passr_eq, NULL);
|
||||
if (!name_to_pass_map.is_created ())
|
||||
name_to_pass_map.create (256);
|
||||
|
||||
pr.unique_name = name;
|
||||
slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, &pr, INSERT);
|
||||
slot = name_to_pass_map.find_slot (&pr, INSERT);
|
||||
if (!*slot)
|
||||
{
|
||||
struct pass_registry *new_pr;
|
||||
|
@ -634,10 +641,9 @@ static vec<char_ptr> pass_tab = vNULL;
|
|||
|
||||
/* Callback function for traversing NAME_TO_PASS_MAP. */
|
||||
|
||||
static int
|
||||
pass_traverse (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
passes_pass_traverse (pass_registry **p, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct pass_registry **p = (struct pass_registry **)slot;
|
||||
struct opt_pass *pass = (*p)->pass;
|
||||
|
||||
gcc_assert (pass->static_pass_number > 0);
|
||||
|
@ -658,7 +664,7 @@ create_pass_tab (void)
|
|||
return;
|
||||
|
||||
pass_tab.safe_grow_cleared (passes_by_id_size + 1);
|
||||
htab_traverse (name_to_pass_map, pass_traverse, NULL);
|
||||
name_to_pass_map.traverse <void *, passes_pass_traverse> (NULL);
|
||||
}
|
||||
|
||||
static bool override_gate_status (struct opt_pass *, tree, bool);
|
||||
|
@ -743,8 +749,7 @@ get_pass_by_name (const char *name)
|
|||
struct pass_registry **slot, pr;
|
||||
|
||||
pr.unique_name = name;
|
||||
slot = (struct pass_registry **) htab_find_slot (name_to_pass_map,
|
||||
&pr, NO_INSERT);
|
||||
slot = name_to_pass_map.find_slot (&pr, NO_INSERT);
|
||||
|
||||
if (!slot || !*slot)
|
||||
return NULL;
|
||||
|
|
55
gcc/plugin.c
55
gcc/plugin.c
|
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "tree.h"
|
||||
#include "tree-pass.h"
|
||||
|
@ -50,9 +51,36 @@ static const char *plugin_event_name_init[] =
|
|||
|
||||
const char **plugin_event_name = plugin_event_name_init;
|
||||
|
||||
/* Event hashtable helpers. */
|
||||
|
||||
struct event_hasher : typed_noop_remove <const char *>
|
||||
{
|
||||
typedef const char *value_type;
|
||||
typedef const char *compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Helper function for the event hash table that hashes the entry V. */
|
||||
|
||||
inline hashval_t
|
||||
event_hasher::hash (const value_type *v)
|
||||
{
|
||||
return htab_hash_string (*v);
|
||||
}
|
||||
|
||||
/* Helper function for the event hash table that compares the name of an
|
||||
existing entry (S1) with the given string (S2). */
|
||||
|
||||
inline bool
|
||||
event_hasher::equal (const value_type *s1, const compare_type *s2)
|
||||
{
|
||||
return !strcmp (*s1, *s2);
|
||||
}
|
||||
|
||||
/* A hash table to map event names to the position of the names in the
|
||||
plugin_event_name table. */
|
||||
static htab_t event_tab;
|
||||
static hash_table <event_hasher> event_tab;
|
||||
|
||||
/* Keep track of the limit of allocated events and space ready for
|
||||
allocating events. */
|
||||
|
@ -312,41 +340,31 @@ register_plugin_info (const char* name, struct plugin_info *info)
|
|||
plugin->help = info->help;
|
||||
}
|
||||
|
||||
/* Helper function for the event hash table that compares the name of an
|
||||
existing entry (E1) with the given string (S2). */
|
||||
|
||||
static int
|
||||
htab_event_eq (const void *e1, const void *s2)
|
||||
{
|
||||
const char *s1= *(const char * const *) e1;
|
||||
return !strcmp (s1, (const char *) s2);
|
||||
}
|
||||
|
||||
/* Look up the event id for NAME. If the name is not found, return -1
|
||||
if INSERT is NO_INSERT. */
|
||||
|
||||
int
|
||||
get_named_event_id (const char *name, enum insert_option insert)
|
||||
{
|
||||
void **slot;
|
||||
const char ***slot;
|
||||
|
||||
if (!event_tab)
|
||||
if (!event_tab.is_created ())
|
||||
{
|
||||
int i;
|
||||
|
||||
event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL);
|
||||
event_tab.create (150);
|
||||
for (i = 0; i < event_last; i++)
|
||||
{
|
||||
slot = htab_find_slot (event_tab, plugin_event_name[i], INSERT);
|
||||
slot = event_tab.find_slot (&plugin_event_name[i], INSERT);
|
||||
gcc_assert (*slot == HTAB_EMPTY_ENTRY);
|
||||
*slot = &plugin_event_name[i];
|
||||
}
|
||||
}
|
||||
slot = htab_find_slot (event_tab, name, insert);
|
||||
slot = event_tab.find_slot (&name, insert);
|
||||
if (slot == NULL)
|
||||
return -1;
|
||||
if (*slot != HTAB_EMPTY_ENTRY)
|
||||
return (const char **) *slot - &plugin_event_name[0];
|
||||
return *slot - &plugin_event_name[0];
|
||||
|
||||
if (event_last >= event_horizon)
|
||||
{
|
||||
|
@ -368,8 +386,7 @@ get_named_event_id (const char *name, enum insert_option insert)
|
|||
plugin_callbacks, event_horizon);
|
||||
}
|
||||
/* All the pointers in the hash table will need to be updated. */
|
||||
htab_delete (event_tab);
|
||||
event_tab = NULL;
|
||||
event_tab.dispose ();
|
||||
}
|
||||
else
|
||||
*slot = &plugin_event_name[event_last];
|
||||
|
|
|
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tm.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
#include "hash-table.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "tm_p.h"
|
||||
|
@ -87,9 +88,6 @@ static struct
|
|||
type 'struct expr', and for each expression there is a single linked
|
||||
list of occurrences. */
|
||||
|
||||
/* The table itself. */
|
||||
static htab_t expr_table;
|
||||
|
||||
/* Expression elements in the hash table. */
|
||||
struct expr
|
||||
{
|
||||
|
@ -103,6 +101,56 @@ struct expr
|
|||
struct occr *avail_occr;
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct expr_hasher : typed_noop_remove <expr>
|
||||
{
|
||||
typedef expr value_type;
|
||||
typedef expr compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
|
||||
/* Hash expression X.
|
||||
DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found
|
||||
or if the expression contains something we don't want to insert in the
|
||||
table. */
|
||||
|
||||
static hashval_t
|
||||
hash_expr (rtx x, int *do_not_record_p)
|
||||
{
|
||||
*do_not_record_p = 0;
|
||||
return hash_rtx (x, GET_MODE (x), do_not_record_p,
|
||||
NULL, /*have_reg_qty=*/false);
|
||||
}
|
||||
|
||||
/* Callback for hashtab.
|
||||
Return the hash value for expression EXP. We don't actually hash
|
||||
here, we just return the cached hash value. */
|
||||
|
||||
inline hashval_t
|
||||
expr_hasher::hash (const value_type *exp)
|
||||
{
|
||||
return exp->hash;
|
||||
}
|
||||
|
||||
/* Callback for hashtab.
|
||||
Return nonzero if exp1 is equivalent to exp2. */
|
||||
|
||||
inline bool
|
||||
expr_hasher::equal (const value_type *exp1, const compare_type *exp2)
|
||||
{
|
||||
int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
|
||||
|
||||
gcc_assert (!equiv_p || exp1->hash == exp2->hash);
|
||||
return equiv_p;
|
||||
}
|
||||
|
||||
/* The table itself. */
|
||||
static hash_table <expr_hasher> expr_table;
|
||||
|
||||
|
||||
static struct obstack expr_obstack;
|
||||
|
||||
/* Occurrence of an expression.
|
||||
|
@ -183,11 +231,8 @@ static void reset_opr_set_tables (void);
|
|||
|
||||
/* Hash table support. */
|
||||
static hashval_t hash_expr (rtx, int *);
|
||||
static hashval_t hash_expr_for_htab (const void *);
|
||||
static int expr_equiv_p (const void *, const void *);
|
||||
static void insert_expr_in_table (rtx, rtx);
|
||||
static struct expr *lookup_expr_in_table (rtx);
|
||||
static int dump_hash_table_entry (void **, void *);
|
||||
static void dump_hash_table (FILE *);
|
||||
|
||||
/* Helpers for eliminate_partially_redundant_load. */
|
||||
|
@ -234,8 +279,7 @@ alloc_mem (void)
|
|||
make the hash table too small, but unnecessarily making it too large
|
||||
also doesn't help. The i/4 is a gcse.c relic, and seems like a
|
||||
reasonable choice. */
|
||||
expr_table = htab_create (MAX (i / 4, 13),
|
||||
hash_expr_for_htab, expr_equiv_p, NULL);
|
||||
expr_table.create (MAX (i / 4, 13));
|
||||
|
||||
/* We allocate everything on obstacks because we often can roll back
|
||||
the whole obstack to some point. Freeing obstacks is very fast. */
|
||||
|
@ -262,7 +306,7 @@ free_mem (void)
|
|||
{
|
||||
free (uid_cuid);
|
||||
|
||||
htab_delete (expr_table);
|
||||
expr_table.dispose ();
|
||||
|
||||
obstack_free (&expr_obstack, NULL);
|
||||
obstack_free (&occr_obstack, NULL);
|
||||
|
@ -273,45 +317,6 @@ free_mem (void)
|
|||
}
|
||||
|
||||
|
||||
/* Hash expression X.
|
||||
DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found
|
||||
or if the expression contains something we don't want to insert in the
|
||||
table. */
|
||||
|
||||
static hashval_t
|
||||
hash_expr (rtx x, int *do_not_record_p)
|
||||
{
|
||||
*do_not_record_p = 0;
|
||||
return hash_rtx (x, GET_MODE (x), do_not_record_p,
|
||||
NULL, /*have_reg_qty=*/false);
|
||||
}
|
||||
|
||||
/* Callback for hashtab.
|
||||
Return the hash value for expression EXP. We don't actually hash
|
||||
here, we just return the cached hash value. */
|
||||
|
||||
static hashval_t
|
||||
hash_expr_for_htab (const void *expp)
|
||||
{
|
||||
const struct expr *const exp = (const struct expr *) expp;
|
||||
return exp->hash;
|
||||
}
|
||||
|
||||
/* Callback for hashtab.
|
||||
Return nonzero if exp1 is equivalent to exp2. */
|
||||
|
||||
static int
|
||||
expr_equiv_p (const void *exp1p, const void *exp2p)
|
||||
{
|
||||
const struct expr *const exp1 = (const struct expr *) exp1p;
|
||||
const struct expr *const exp2 = (const struct expr *) exp2p;
|
||||
int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
|
||||
|
||||
gcc_assert (!equiv_p || exp1->hash == exp2->hash);
|
||||
return equiv_p;
|
||||
}
|
||||
|
||||
|
||||
/* Insert expression X in INSN in the hash TABLE.
|
||||
If it is already present, record it as the last occurrence in INSN's
|
||||
basic block. */
|
||||
|
@ -343,8 +348,7 @@ insert_expr_in_table (rtx x, rtx insn)
|
|||
cur_expr->hash = hash;
|
||||
cur_expr->avail_occr = NULL;
|
||||
|
||||
slot = (struct expr **) htab_find_slot_with_hash (expr_table, cur_expr,
|
||||
hash, INSERT);
|
||||
slot = expr_table.find_slot_with_hash (cur_expr, hash, INSERT);
|
||||
|
||||
if (! (*slot))
|
||||
/* The expression isn't found, so insert it. */
|
||||
|
@ -412,8 +416,7 @@ lookup_expr_in_table (rtx pat)
|
|||
tmp_expr->hash = hash;
|
||||
tmp_expr->avail_occr = NULL;
|
||||
|
||||
slot = (struct expr **) htab_find_slot_with_hash (expr_table, tmp_expr,
|
||||
hash, INSERT);
|
||||
slot = expr_table.find_slot_with_hash (tmp_expr, hash, INSERT);
|
||||
obstack_free (&expr_obstack, tmp_expr);
|
||||
|
||||
if (!slot)
|
||||
|
@ -427,18 +430,17 @@ lookup_expr_in_table (rtx pat)
|
|||
expression hash table to FILE. */
|
||||
|
||||
/* This helper is called via htab_traverse. */
|
||||
static int
|
||||
dump_hash_table_entry (void **slot, void *filep)
|
||||
int
|
||||
dump_expr_hash_table_entry (expr **slot, FILE *file)
|
||||
{
|
||||
struct expr *expr = (struct expr *) *slot;
|
||||
FILE *file = (FILE *) filep;
|
||||
struct expr *exprs = *slot;
|
||||
struct occr *occr;
|
||||
|
||||
fprintf (file, "expr: ");
|
||||
print_rtl (file, expr->expr);
|
||||
fprintf (file,"\nhashcode: %u\n", expr->hash);
|
||||
print_rtl (file, exprs->expr);
|
||||
fprintf (file,"\nhashcode: %u\n", exprs->hash);
|
||||
fprintf (file,"list of occurrences:\n");
|
||||
occr = expr->avail_occr;
|
||||
occr = exprs->avail_occr;
|
||||
while (occr)
|
||||
{
|
||||
rtx insn = occr->insn;
|
||||
|
@ -455,13 +457,13 @@ dump_hash_table (FILE *file)
|
|||
{
|
||||
fprintf (file, "\n\nexpression hash table\n");
|
||||
fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
|
||||
(long) htab_size (expr_table),
|
||||
(long) htab_elements (expr_table),
|
||||
htab_collisions (expr_table));
|
||||
if (htab_elements (expr_table) > 0)
|
||||
(long) expr_table.size (),
|
||||
(long) expr_table.elements (),
|
||||
expr_table.collisions ());
|
||||
if (expr_table.elements () > 0)
|
||||
{
|
||||
fprintf (file, "\n\ntable entries:\n");
|
||||
htab_traverse (expr_table, dump_hash_table_entry, file);
|
||||
expr_table.traverse <FILE *, dump_expr_hash_table_entry> (file);
|
||||
}
|
||||
fprintf (file, "\n");
|
||||
}
|
||||
|
@ -1223,13 +1225,13 @@ eliminate_partially_redundant_loads (void)
|
|||
marked for later deletion. */
|
||||
|
||||
/* This helper is called via htab_traverse. */
|
||||
static int
|
||||
delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
delete_redundant_insns_1 (expr **slot, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct expr *expr = (struct expr *) *slot;
|
||||
struct expr *exprs = *slot;
|
||||
struct occr *occr;
|
||||
|
||||
for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
|
||||
for (occr = exprs->avail_occr; occr != NULL; occr = occr->next)
|
||||
{
|
||||
if (occr->deleted_p && dbg_cnt (gcse2_delete))
|
||||
{
|
||||
|
@ -1251,7 +1253,7 @@ delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
static void
|
||||
delete_redundant_insns (void)
|
||||
{
|
||||
htab_traverse (expr_table, delete_redundant_insns_1, NULL);
|
||||
expr_table.traverse <void *, delete_redundant_insns_1> (NULL);
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
@ -1277,7 +1279,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
|
|||
if (dump_file)
|
||||
dump_hash_table (dump_file);
|
||||
|
||||
if (htab_elements (expr_table) > 0)
|
||||
if (expr_table.elements () > 0)
|
||||
{
|
||||
eliminate_partially_redundant_loads ();
|
||||
delete_redundant_insns ();
|
||||
|
|
66
gcc/sese.c
66
gcc/sese.c
|
@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "tree-flow.h"
|
||||
#include "cfgloop.h"
|
||||
|
@ -46,20 +47,50 @@ debug_rename_elt (rename_map_elt elt)
|
|||
|
||||
/* Helper function for debug_rename_map. */
|
||||
|
||||
static int
|
||||
debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
|
||||
int
|
||||
debug_rename_map_1 (rename_map_elt_s **slot, void *s ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot;
|
||||
struct rename_map_elt_s *entry = *slot;
|
||||
debug_rename_elt (entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct rename_map_hasher : typed_free_remove <rename_map_elt_s>
|
||||
{
|
||||
typedef rename_map_elt_s value_type;
|
||||
typedef rename_map_elt_s compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Computes a hash function for database element ELT. */
|
||||
|
||||
inline hashval_t
|
||||
rename_map_hasher::hash (const value_type *elt)
|
||||
{
|
||||
return SSA_NAME_VERSION (elt->old_name);
|
||||
}
|
||||
|
||||
/* Compares database elements E1 and E2. */
|
||||
|
||||
inline bool
|
||||
rename_map_hasher::equal (const value_type *elt1, const compare_type *elt2)
|
||||
{
|
||||
return (elt1->old_name == elt2->old_name);
|
||||
}
|
||||
|
||||
typedef hash_table <rename_map_hasher> rename_map_type;
|
||||
|
||||
|
||||
/* Print to stderr all the elements of RENAME_MAP. */
|
||||
|
||||
DEBUG_FUNCTION void
|
||||
debug_rename_map (htab_t rename_map)
|
||||
debug_rename_map (rename_map_type rename_map)
|
||||
{
|
||||
htab_traverse (rename_map, debug_rename_map_1, NULL);
|
||||
rename_map.traverse <void *, debug_rename_map_1> (NULL);
|
||||
}
|
||||
|
||||
/* Computes a hash function for database element ELT. */
|
||||
|
@ -365,17 +396,17 @@ get_false_edge_from_guard_bb (basic_block bb)
|
|||
/* Returns the expression associated to OLD_NAME in RENAME_MAP. */
|
||||
|
||||
static tree
|
||||
get_rename (htab_t rename_map, tree old_name)
|
||||
get_rename (rename_map_type rename_map, tree old_name)
|
||||
{
|
||||
struct rename_map_elt_s tmp;
|
||||
PTR *slot;
|
||||
rename_map_elt_s **slot;
|
||||
|
||||
gcc_assert (TREE_CODE (old_name) == SSA_NAME);
|
||||
tmp.old_name = old_name;
|
||||
slot = htab_find_slot (rename_map, &tmp, NO_INSERT);
|
||||
slot = rename_map.find_slot (&tmp, NO_INSERT);
|
||||
|
||||
if (slot && *slot)
|
||||
return ((rename_map_elt) *slot)->expr;
|
||||
return (*slot)->expr;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
@ -383,16 +414,16 @@ get_rename (htab_t rename_map, tree old_name)
|
|||
/* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR). */
|
||||
|
||||
static void
|
||||
set_rename (htab_t rename_map, tree old_name, tree expr)
|
||||
set_rename (rename_map_type rename_map, tree old_name, tree expr)
|
||||
{
|
||||
struct rename_map_elt_s tmp;
|
||||
PTR *slot;
|
||||
rename_map_elt_s **slot;
|
||||
|
||||
if (old_name == expr)
|
||||
return;
|
||||
|
||||
tmp.old_name = old_name;
|
||||
slot = htab_find_slot (rename_map, &tmp, INSERT);
|
||||
slot = rename_map.find_slot (&tmp, INSERT);
|
||||
|
||||
if (!slot)
|
||||
return;
|
||||
|
@ -410,7 +441,8 @@ set_rename (htab_t rename_map, tree old_name, tree expr)
|
|||
is set when the code generation cannot continue. */
|
||||
|
||||
static bool
|
||||
rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||
rename_uses (gimple copy, rename_map_type rename_map,
|
||||
gimple_stmt_iterator *gsi_tgt,
|
||||
sese region, loop_p loop, vec<tree> iv_map,
|
||||
bool *gloog_error)
|
||||
{
|
||||
|
@ -516,7 +548,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
|||
|
||||
static void
|
||||
graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
|
||||
htab_t rename_map,
|
||||
rename_map_type rename_map,
|
||||
vec<tree> iv_map, sese region,
|
||||
bool *gloog_error)
|
||||
{
|
||||
|
@ -584,14 +616,14 @@ copy_bb_and_scalar_dependences (basic_block bb, sese region,
|
|||
bool *gloog_error)
|
||||
{
|
||||
basic_block new_bb = split_edge (next_e);
|
||||
htab_t rename_map = htab_create (10, rename_map_elt_info,
|
||||
eq_rename_map_elts, free);
|
||||
rename_map_type rename_map;
|
||||
rename_map.create (10);
|
||||
|
||||
next_e = single_succ_edge (new_bb);
|
||||
graphite_copy_stmts_from_block (bb, new_bb, rename_map, iv_map, region,
|
||||
gloog_error);
|
||||
remove_phi_nodes (new_bb);
|
||||
htab_delete (rename_map);
|
||||
rename_map.dispose ();
|
||||
|
||||
return next_e;
|
||||
}
|
||||
|
|
|
@ -257,7 +257,6 @@ typedef struct rename_map_elt_s
|
|||
} *rename_map_elt;
|
||||
|
||||
|
||||
extern void debug_rename_map (htab_t);
|
||||
extern hashval_t rename_map_elt_info (const void *);
|
||||
extern int eq_rename_map_elts (const void *, const void *);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "ggc.h"
|
||||
#include "intl.h"
|
||||
#include "tree-pass.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "df.h"
|
||||
#include "dbgcnt.h"
|
||||
|
||||
|
@ -90,9 +90,6 @@ struct st_expr
|
|||
/* Head of the list of load/store memory refs. */
|
||||
static struct st_expr * store_motion_mems = NULL;
|
||||
|
||||
/* Hashtable for the load/store memory refs. */
|
||||
static htab_t store_motion_mems_table = NULL;
|
||||
|
||||
/* These bitmaps will hold the local dataflow properties per basic block. */
|
||||
static sbitmap *st_kill, *st_avloc, *st_antloc, *st_transp;
|
||||
|
||||
|
@ -108,22 +105,32 @@ static int num_stores;
|
|||
/* Contains the edge_list returned by pre_edge_lcm. */
|
||||
static struct edge_list *edge_list;
|
||||
|
||||
static hashval_t
|
||||
pre_st_expr_hash (const void *p)
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct st_expr_hasher : typed_noop_remove <st_expr>
|
||||
{
|
||||
typedef st_expr value_type;
|
||||
typedef st_expr compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
st_expr_hasher::hash (const value_type *x)
|
||||
{
|
||||
int do_not_record_p = 0;
|
||||
const struct st_expr *const x = (const struct st_expr *) p;
|
||||
return hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
|
||||
}
|
||||
|
||||
static int
|
||||
pre_st_expr_eq (const void *p1, const void *p2)
|
||||
inline bool
|
||||
st_expr_hasher::equal (const value_type *ptr1, const compare_type *ptr2)
|
||||
{
|
||||
const struct st_expr *const ptr1 = (const struct st_expr *) p1,
|
||||
*const ptr2 = (const struct st_expr *) p2;
|
||||
return exp_equiv_p (ptr1->pattern, ptr2->pattern, 0, true);
|
||||
}
|
||||
|
||||
/* Hashtable for the load/store memory refs. */
|
||||
static hash_table <st_expr_hasher> store_motion_mems_table;
|
||||
|
||||
/* This will search the st_expr list for a matching expression. If it
|
||||
doesn't find one, we create one and initialize it. */
|
||||
|
||||
|
@ -133,16 +140,16 @@ st_expr_entry (rtx x)
|
|||
int do_not_record_p = 0;
|
||||
struct st_expr * ptr;
|
||||
unsigned int hash;
|
||||
void **slot;
|
||||
st_expr **slot;
|
||||
struct st_expr e;
|
||||
|
||||
hash = hash_rtx (x, GET_MODE (x), &do_not_record_p,
|
||||
NULL, /*have_reg_qty=*/false);
|
||||
|
||||
e.pattern = x;
|
||||
slot = htab_find_slot_with_hash (store_motion_mems_table, &e, hash, INSERT);
|
||||
slot = store_motion_mems_table.find_slot_with_hash (&e, hash, INSERT);
|
||||
if (*slot)
|
||||
return (struct st_expr *)*slot;
|
||||
return *slot;
|
||||
|
||||
ptr = XNEW (struct st_expr);
|
||||
|
||||
|
@ -176,9 +183,8 @@ free_st_expr_entry (struct st_expr * ptr)
|
|||
static void
|
||||
free_store_motion_mems (void)
|
||||
{
|
||||
if (store_motion_mems_table)
|
||||
htab_delete (store_motion_mems_table);
|
||||
store_motion_mems_table = NULL;
|
||||
if (store_motion_mems_table.is_created ())
|
||||
store_motion_mems_table.dispose ();
|
||||
|
||||
while (store_motion_mems)
|
||||
{
|
||||
|
@ -645,8 +651,7 @@ compute_store_table (void)
|
|||
unsigned int max_gcse_regno = max_reg_num ();
|
||||
|
||||
store_motion_mems = NULL;
|
||||
store_motion_mems_table = htab_create (13, pre_st_expr_hash,
|
||||
pre_st_expr_eq, NULL);
|
||||
store_motion_mems_table.create (13);
|
||||
last_set_in = XCNEWVEC (int, max_gcse_regno);
|
||||
already_set = XNEWVEC (int, max_gcse_regno);
|
||||
|
||||
|
@ -708,8 +713,7 @@ compute_store_table (void)
|
|||
if (! ptr->avail_stores)
|
||||
{
|
||||
*prev_next_ptr_ptr = ptr->next;
|
||||
htab_remove_elt_with_hash (store_motion_mems_table,
|
||||
ptr, ptr->hash_index);
|
||||
store_motion_mems_table.remove_elt_with_hash (ptr, ptr->hash_index);
|
||||
free_st_expr_entry (ptr);
|
||||
}
|
||||
else
|
||||
|
@ -1142,8 +1146,7 @@ one_store_motion_pass (void)
|
|||
num_stores = compute_store_table ();
|
||||
if (num_stores == 0)
|
||||
{
|
||||
htab_delete (store_motion_mems_table);
|
||||
store_motion_mems_table = NULL;
|
||||
store_motion_mems_table.dispose ();
|
||||
end_alias_analysis ();
|
||||
return 0;
|
||||
}
|
||||
|
|
197
gcc/trans-mem.c
197
gcc/trans-mem.c
|
@ -20,6 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tree.h"
|
||||
#include "gimple.h"
|
||||
#include "tree-flow.h"
|
||||
|
@ -879,47 +880,29 @@ typedef struct tm_log_entry
|
|||
tree save_var;
|
||||
} *tm_log_entry_t;
|
||||
|
||||
/* The actual log. */
|
||||
static htab_t tm_log;
|
||||
|
||||
/* Addresses to log with a save/restore sequence. These should be in
|
||||
dominator order. */
|
||||
static vec<tree> tm_log_save_addresses;
|
||||
/* Log entry hashtable helpers. */
|
||||
|
||||
/* Map for an SSA_NAME originally pointing to a non aliased new piece
|
||||
of memory (malloc, alloc, etc). */
|
||||
static htab_t tm_new_mem_hash;
|
||||
|
||||
enum thread_memory_type
|
||||
{
|
||||
mem_non_local = 0,
|
||||
mem_thread_local,
|
||||
mem_transaction_local,
|
||||
mem_max
|
||||
};
|
||||
|
||||
typedef struct tm_new_mem_map
|
||||
struct log_entry_hasher
|
||||
{
|
||||
/* SSA_NAME being dereferenced. */
|
||||
tree val;
|
||||
enum thread_memory_type local_new_memory;
|
||||
} tm_new_mem_map_t;
|
||||
typedef tm_log_entry value_type;
|
||||
typedef tm_log_entry compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
/* Htab support. Return hash value for a `tm_log_entry'. */
|
||||
static hashval_t
|
||||
tm_log_hash (const void *p)
|
||||
inline hashval_t
|
||||
log_entry_hasher::hash (const value_type *log)
|
||||
{
|
||||
const struct tm_log_entry *log = (const struct tm_log_entry *) p;
|
||||
return iterative_hash_expr (log->addr, 0);
|
||||
}
|
||||
|
||||
/* Htab support. Return true if two log entries are the same. */
|
||||
static int
|
||||
tm_log_eq (const void *p1, const void *p2)
|
||||
inline bool
|
||||
log_entry_hasher::equal (const value_type *log1, const compare_type *log2)
|
||||
{
|
||||
const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
|
||||
const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
|
||||
|
||||
/* FIXME:
|
||||
|
||||
rth: I suggest that we get rid of the component refs etc.
|
||||
|
@ -943,20 +926,68 @@ tm_log_eq (const void *p1, const void *p2)
|
|||
}
|
||||
|
||||
/* Htab support. Free one tm_log_entry. */
|
||||
static void
|
||||
tm_log_free (void *p)
|
||||
inline void
|
||||
log_entry_hasher::remove (value_type *lp)
|
||||
{
|
||||
struct tm_log_entry *lp = (struct tm_log_entry *) p;
|
||||
lp->stmts.release ();
|
||||
free (lp);
|
||||
}
|
||||
|
||||
|
||||
/* The actual log. */
|
||||
static hash_table <log_entry_hasher> tm_log;
|
||||
|
||||
/* Addresses to log with a save/restore sequence. These should be in
|
||||
dominator order. */
|
||||
static vec<tree> tm_log_save_addresses;
|
||||
|
||||
enum thread_memory_type
|
||||
{
|
||||
mem_non_local = 0,
|
||||
mem_thread_local,
|
||||
mem_transaction_local,
|
||||
mem_max
|
||||
};
|
||||
|
||||
typedef struct tm_new_mem_map
|
||||
{
|
||||
/* SSA_NAME being dereferenced. */
|
||||
tree val;
|
||||
enum thread_memory_type local_new_memory;
|
||||
} tm_new_mem_map_t;
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct tm_mem_map_hasher : typed_free_remove <tm_new_mem_map_t>
|
||||
{
|
||||
typedef tm_new_mem_map_t value_type;
|
||||
typedef tm_new_mem_map_t compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
tm_mem_map_hasher::hash (const value_type *v)
|
||||
{
|
||||
return (intptr_t)v->val >> 4;
|
||||
}
|
||||
|
||||
inline bool
|
||||
tm_mem_map_hasher::equal (const value_type *v, const compare_type *c)
|
||||
{
|
||||
return v->val == c->val;
|
||||
}
|
||||
|
||||
/* Map for an SSA_NAME originally pointing to a non aliased new piece
|
||||
of memory (malloc, alloc, etc). */
|
||||
static hash_table <tm_mem_map_hasher> tm_new_mem_hash;
|
||||
|
||||
/* Initialize logging data structures. */
|
||||
static void
|
||||
tm_log_init (void)
|
||||
{
|
||||
tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free);
|
||||
tm_new_mem_hash = htab_create (5, struct_ptr_hash, struct_ptr_eq, free);
|
||||
tm_log.create (10);
|
||||
tm_new_mem_hash.create (5);
|
||||
tm_log_save_addresses.create (5);
|
||||
}
|
||||
|
||||
|
@ -964,8 +995,8 @@ tm_log_init (void)
|
|||
static void
|
||||
tm_log_delete (void)
|
||||
{
|
||||
htab_delete (tm_log);
|
||||
htab_delete (tm_new_mem_hash);
|
||||
tm_log.dispose ();
|
||||
tm_new_mem_hash.dispose ();
|
||||
tm_log_save_addresses.release ();
|
||||
}
|
||||
|
||||
|
@ -1006,11 +1037,11 @@ transaction_invariant_address_p (const_tree mem, basic_block region_entry_block)
|
|||
static void
|
||||
tm_log_add (basic_block entry_block, tree addr, gimple stmt)
|
||||
{
|
||||
void **slot;
|
||||
tm_log_entry **slot;
|
||||
struct tm_log_entry l, *lp;
|
||||
|
||||
l.addr = addr;
|
||||
slot = htab_find_slot (tm_log, &l, INSERT);
|
||||
slot = tm_log.find_slot (&l, INSERT);
|
||||
if (!*slot)
|
||||
{
|
||||
tree type = TREE_TYPE (addr);
|
||||
|
@ -1051,7 +1082,7 @@ tm_log_add (basic_block entry_block, tree addr, gimple stmt)
|
|||
size_t i;
|
||||
gimple oldstmt;
|
||||
|
||||
lp = (struct tm_log_entry *) *slot;
|
||||
lp = *slot;
|
||||
|
||||
/* If we're generating a save/restore sequence, we don't care
|
||||
about statements. */
|
||||
|
@ -1153,10 +1184,10 @@ tm_log_emit_stmt (tree addr, gimple stmt)
|
|||
static void
|
||||
tm_log_emit (void)
|
||||
{
|
||||
htab_iterator hi;
|
||||
hash_table <log_entry_hasher>::iterator hi;
|
||||
struct tm_log_entry *lp;
|
||||
|
||||
FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
|
||||
FOR_EACH_HASH_TABLE_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
|
||||
{
|
||||
size_t i;
|
||||
gimple stmt;
|
||||
|
@ -1198,7 +1229,7 @@ tm_log_emit_saves (basic_block entry_block, basic_block bb)
|
|||
for (i = 0; i < tm_log_save_addresses.length (); ++i)
|
||||
{
|
||||
l.addr = tm_log_save_addresses[i];
|
||||
lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
|
||||
lp = *(tm_log.find_slot (&l, NO_INSERT));
|
||||
gcc_assert (lp->save_var != NULL);
|
||||
|
||||
/* We only care about variables in the current transaction. */
|
||||
|
@ -1234,7 +1265,7 @@ tm_log_emit_restores (basic_block entry_block, basic_block bb)
|
|||
for (i = tm_log_save_addresses.length () - 1; i >= 0; i--)
|
||||
{
|
||||
l.addr = tm_log_save_addresses[i];
|
||||
lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
|
||||
lp = *(tm_log.find_slot (&l, NO_INSERT));
|
||||
gcc_assert (lp->save_var != NULL);
|
||||
|
||||
/* We only care about variables in the current transaction. */
|
||||
|
@ -1271,7 +1302,7 @@ thread_private_new_memory (basic_block entry_block, tree x)
|
|||
{
|
||||
gimple stmt = NULL;
|
||||
enum tree_code code;
|
||||
void **slot;
|
||||
tm_new_mem_map_t **slot;
|
||||
tm_new_mem_map_t elt, *elt_p;
|
||||
tree val = x;
|
||||
enum thread_memory_type retval = mem_transaction_local;
|
||||
|
@ -1285,8 +1316,8 @@ thread_private_new_memory (basic_block entry_block, tree x)
|
|||
|
||||
/* Look in cache first. */
|
||||
elt.val = x;
|
||||
slot = htab_find_slot (tm_new_mem_hash, &elt, INSERT);
|
||||
elt_p = (tm_new_mem_map_t *) *slot;
|
||||
slot = tm_new_mem_hash.find_slot (&elt, INSERT);
|
||||
elt_p = *slot;
|
||||
if (elt_p)
|
||||
return elt_p->local_new_memory;
|
||||
|
||||
|
@ -3146,6 +3177,35 @@ typedef struct tm_memop
|
|||
tree addr;
|
||||
} *tm_memop_t;
|
||||
|
||||
/* TM memory operation hashtable helpers. */
|
||||
|
||||
struct tm_memop_hasher : typed_free_remove <tm_memop>
|
||||
{
|
||||
typedef tm_memop value_type;
|
||||
typedef tm_memop compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Htab support. Return a hash value for a `tm_memop'. */
|
||||
inline hashval_t
|
||||
tm_memop_hasher::hash (const value_type *mem)
|
||||
{
|
||||
tree addr = mem->addr;
|
||||
/* We drill down to the SSA_NAME/DECL for the hash, but equality is
|
||||
actually done with operand_equal_p (see tm_memop_eq). */
|
||||
if (TREE_CODE (addr) == ADDR_EXPR)
|
||||
addr = TREE_OPERAND (addr, 0);
|
||||
return iterative_hash_expr (addr, 0);
|
||||
}
|
||||
|
||||
/* Htab support. Return true if two tm_memop's are the same. */
|
||||
inline bool
|
||||
tm_memop_hasher::equal (const value_type *mem1, const compare_type *mem2)
|
||||
{
|
||||
return operand_equal_p (mem1->addr, mem2->addr, 0);
|
||||
}
|
||||
|
||||
/* Sets for solving data flow equations in the memory optimization pass. */
|
||||
struct tm_memopt_bitmaps
|
||||
{
|
||||
|
@ -3178,7 +3238,7 @@ static bitmap_obstack tm_memopt_obstack;
|
|||
/* Unique counter for TM loads and stores. Loads and stores of the
|
||||
same address get the same ID. */
|
||||
static unsigned int tm_memopt_value_id;
|
||||
static htab_t tm_memopt_value_numbers;
|
||||
static hash_table <tm_memop_hasher> tm_memopt_value_numbers;
|
||||
|
||||
#define STORE_AVAIL_IN(BB) \
|
||||
((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
|
||||
|
@ -3201,29 +3261,6 @@ static htab_t tm_memopt_value_numbers;
|
|||
#define BB_VISITED_P(BB) \
|
||||
((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
|
||||
|
||||
/* Htab support. Return a hash value for a `tm_memop'. */
|
||||
static hashval_t
|
||||
tm_memop_hash (const void *p)
|
||||
{
|
||||
const struct tm_memop *mem = (const struct tm_memop *) p;
|
||||
tree addr = mem->addr;
|
||||
/* We drill down to the SSA_NAME/DECL for the hash, but equality is
|
||||
actually done with operand_equal_p (see tm_memop_eq). */
|
||||
if (TREE_CODE (addr) == ADDR_EXPR)
|
||||
addr = TREE_OPERAND (addr, 0);
|
||||
return iterative_hash_expr (addr, 0);
|
||||
}
|
||||
|
||||
/* Htab support. Return true if two tm_memop's are the same. */
|
||||
static int
|
||||
tm_memop_eq (const void *p1, const void *p2)
|
||||
{
|
||||
const struct tm_memop *mem1 = (const struct tm_memop *) p1;
|
||||
const struct tm_memop *mem2 = (const struct tm_memop *) p2;
|
||||
|
||||
return operand_equal_p (mem1->addr, mem2->addr, 0);
|
||||
}
|
||||
|
||||
/* Given a TM load/store in STMT, return the value number for the address
|
||||
it accesses. */
|
||||
|
||||
|
@ -3231,13 +3268,13 @@ static unsigned int
|
|||
tm_memopt_value_number (gimple stmt, enum insert_option op)
|
||||
{
|
||||
struct tm_memop tmpmem, *mem;
|
||||
void **slot;
|
||||
tm_memop **slot;
|
||||
|
||||
gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
|
||||
tmpmem.addr = gimple_call_arg (stmt, 0);
|
||||
slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op);
|
||||
slot = tm_memopt_value_numbers.find_slot (&tmpmem, op);
|
||||
if (*slot)
|
||||
mem = (struct tm_memop *) *slot;
|
||||
mem = *slot;
|
||||
else if (op == INSERT)
|
||||
{
|
||||
mem = XNEW (struct tm_memop);
|
||||
|
@ -3295,11 +3332,11 @@ dump_tm_memopt_set (const char *set_name, bitmap bits)
|
|||
fprintf (dump_file, "TM memopt: %s: [", set_name);
|
||||
EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
|
||||
{
|
||||
htab_iterator hi;
|
||||
struct tm_memop *mem;
|
||||
hash_table <tm_memop_hasher>::iterator hi;
|
||||
struct tm_memop *mem = NULL;
|
||||
|
||||
/* Yeah, yeah, yeah. Whatever. This is just for debugging. */
|
||||
FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
|
||||
FOR_EACH_HASH_TABLE_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
|
||||
if (mem->value_id == i)
|
||||
break;
|
||||
gcc_assert (mem->value_id == i);
|
||||
|
@ -3734,7 +3771,7 @@ execute_tm_memopt (void)
|
|||
vec<basic_block> bbs;
|
||||
|
||||
tm_memopt_value_id = 0;
|
||||
tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free);
|
||||
tm_memopt_value_numbers.create (10);
|
||||
|
||||
for (region = all_tm_regions; region; region = region->next)
|
||||
{
|
||||
|
@ -3768,10 +3805,10 @@ execute_tm_memopt (void)
|
|||
tm_memopt_free_sets (bbs);
|
||||
bbs.release ();
|
||||
bitmap_obstack_release (&tm_memopt_obstack);
|
||||
htab_empty (tm_memopt_value_numbers);
|
||||
tm_memopt_value_numbers.empty ();
|
||||
}
|
||||
|
||||
htab_delete (tm_memopt_value_numbers);
|
||||
tm_memopt_value_numbers.dispose ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tree.h"
|
||||
#include "tree-pretty-print.h"
|
||||
|
||||
|
@ -94,14 +95,45 @@ static tree TB_next_expr (tree);
|
|||
static tree TB_up_expr (tree);
|
||||
static tree TB_first_in_bind (tree);
|
||||
static tree TB_last_in_bind (tree);
|
||||
static int TB_parent_eq (const void *, const void *);
|
||||
static tree TB_history_prev (void);
|
||||
|
||||
/* FIXME: To be declared in a .h file. */
|
||||
void browse_tree (tree);
|
||||
|
||||
/* Hashtable helpers. */
|
||||
struct tree_upper_hasher : typed_noop_remove <tree_node>
|
||||
{
|
||||
typedef tree_node value_type;
|
||||
typedef tree_node compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
tree_upper_hasher::hash (const value_type *v)
|
||||
{
|
||||
return pointer_hash <value_type>::hash (v);
|
||||
}
|
||||
|
||||
inline bool
|
||||
tree_upper_hasher::equal (const value_type *parent, const compare_type *node)
|
||||
{
|
||||
if (parent == NULL || node == NULL)
|
||||
return 0;
|
||||
|
||||
if (EXPR_P (parent))
|
||||
{
|
||||
int n = TREE_OPERAND_LENGTH (parent);
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
if (node == TREE_OPERAND (parent, i))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Static variables. */
|
||||
static htab_t TB_up_ht;
|
||||
static hash_table <tree_upper_hasher> TB_up_ht;
|
||||
static vec<tree, va_gc> *TB_history_stack;
|
||||
static int TB_verbose = 1;
|
||||
|
||||
|
@ -134,7 +166,7 @@ browse_tree (tree begin)
|
|||
|
||||
/* Store in a hashtable information about previous and upper statements. */
|
||||
{
|
||||
TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
|
||||
TB_up_ht.create (1023);
|
||||
TB_update_up (head);
|
||||
}
|
||||
|
||||
|
@ -612,7 +644,7 @@ browse_tree (tree begin)
|
|||
}
|
||||
|
||||
ret:;
|
||||
htab_delete (TB_up_ht);
|
||||
TB_up_ht.dispose ();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -658,7 +690,7 @@ TB_up_expr (tree node)
|
|||
if (node == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
res = (tree) htab_find (TB_up_ht, node);
|
||||
res = TB_up_ht.find (node);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -724,7 +756,7 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree node;
|
||||
void **slot;
|
||||
tree_node **slot;
|
||||
|
||||
node = *tp;
|
||||
|
||||
|
@ -736,8 +768,8 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|||
for (i = 0; i < n; i++)
|
||||
{
|
||||
tree op = TREE_OPERAND (node, i);
|
||||
slot = htab_find_slot (TB_up_ht, op, INSERT);
|
||||
*slot = (void *) node;
|
||||
slot = TB_up_ht.find_slot (op, INSERT);
|
||||
*slot = node;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,28 +777,6 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Function used in TB_up_ht. */
|
||||
|
||||
static int
|
||||
TB_parent_eq (const void *p1, const void *p2)
|
||||
{
|
||||
const_tree const node = (const_tree)p2;
|
||||
const_tree const parent = (const_tree) p1;
|
||||
|
||||
if (p1 == NULL || p2 == NULL)
|
||||
return 0;
|
||||
|
||||
if (EXPR_P (parent))
|
||||
{
|
||||
int n = TREE_OPERAND_LENGTH (parent);
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
if (node == TREE_OPERAND (parent, i))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update information about upper expressions in the hash table. */
|
||||
|
||||
static void
|
||||
|
|
|
@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "tm_p.h"
|
||||
|
@ -87,7 +88,36 @@ struct locus_discrim_map
|
|||
location_t locus;
|
||||
int discriminator;
|
||||
};
|
||||
static htab_t discriminator_per_locus;
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct locus_descrim_hasher : typed_free_remove <locus_discrim_map>
|
||||
{
|
||||
typedef locus_discrim_map value_type;
|
||||
typedef locus_discrim_map compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Trivial hash function for a location_t. ITEM is a pointer to
|
||||
a hash table entry that maps a location_t to a discriminator. */
|
||||
|
||||
inline hashval_t
|
||||
locus_descrim_hasher::hash (const value_type *item)
|
||||
{
|
||||
return item->locus;
|
||||
}
|
||||
|
||||
/* Equality function for the locus-to-discriminator map. A and B
|
||||
point to the two hash table entries to compare. */
|
||||
|
||||
inline bool
|
||||
locus_descrim_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
return a->locus == b->locus;
|
||||
}
|
||||
|
||||
static hash_table <locus_descrim_hasher> discriminator_per_locus;
|
||||
|
||||
/* Basic blocks and flowgraphs. */
|
||||
static void make_blocks (gimple_seq);
|
||||
|
@ -99,8 +129,6 @@ static void make_cond_expr_edges (basic_block);
|
|||
static void make_gimple_switch_edges (basic_block);
|
||||
static void make_goto_expr_edges (basic_block);
|
||||
static void make_gimple_asm_edges (basic_block);
|
||||
static unsigned int locus_map_hash (const void *);
|
||||
static int locus_map_eq (const void *, const void *);
|
||||
static void assign_discriminator (location_t, basic_block);
|
||||
static edge gimple_redirect_edge_and_branch (edge, basic_block);
|
||||
static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
|
||||
|
@ -201,11 +229,10 @@ build_gimple_cfg (gimple_seq seq)
|
|||
group_case_labels ();
|
||||
|
||||
/* Create the edges of the flowgraph. */
|
||||
discriminator_per_locus = htab_create (13, locus_map_hash, locus_map_eq,
|
||||
free);
|
||||
discriminator_per_locus.create (13);
|
||||
make_edges ();
|
||||
cleanup_dead_labels ();
|
||||
htab_delete (discriminator_per_locus);
|
||||
discriminator_per_locus.dispose ();
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
|
@ -675,26 +702,6 @@ make_edges (void)
|
|||
fold_cond_expr_cond ();
|
||||
}
|
||||
|
||||
/* Trivial hash function for a location_t. ITEM is a pointer to
|
||||
a hash table entry that maps a location_t to a discriminator. */
|
||||
|
||||
static unsigned int
|
||||
locus_map_hash (const void *item)
|
||||
{
|
||||
return ((const struct locus_discrim_map *) item)->locus;
|
||||
}
|
||||
|
||||
/* Equality function for the locus-to-discriminator map. VA and VB
|
||||
point to the two hash table entries to compare. */
|
||||
|
||||
static int
|
||||
locus_map_eq (const void *va, const void *vb)
|
||||
{
|
||||
const struct locus_discrim_map *a = (const struct locus_discrim_map *) va;
|
||||
const struct locus_discrim_map *b = (const struct locus_discrim_map *) vb;
|
||||
return a->locus == b->locus;
|
||||
}
|
||||
|
||||
/* Find the next available discriminator value for LOCUS. The
|
||||
discriminator distinguishes among several basic blocks that
|
||||
share a common locus, allowing for more accurate sample-based
|
||||
|
@ -708,9 +715,7 @@ next_discriminator_for_locus (location_t locus)
|
|||
|
||||
item.locus = locus;
|
||||
item.discriminator = 0;
|
||||
slot = (struct locus_discrim_map **)
|
||||
htab_find_slot_with_hash (discriminator_per_locus, (void *) &item,
|
||||
(hashval_t) locus, INSERT);
|
||||
slot = discriminator_per_locus.find_slot_with_hash (&item, locus, INSERT);
|
||||
gcc_assert (slot);
|
||||
if (*slot == HTAB_EMPTY_ENTRY)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-iterator.h"
|
||||
#include "tree-pass.h"
|
||||
#include "tree-ssa-propagate.h"
|
||||
#include "tree-hasher.h"
|
||||
|
||||
|
||||
/* For each complex ssa name, a lattice value. We're interested in finding
|
||||
|
@ -53,7 +54,7 @@ static vec<complex_lattice_t> complex_lattice_values;
|
|||
|
||||
/* For each complex variable, a pair of variables for the components exists in
|
||||
the hashtable. */
|
||||
static htab_t complex_variable_components;
|
||||
static int_tree_htab_type complex_variable_components;
|
||||
|
||||
/* For each complex SSA_NAME, a pair of ssa names for the components. */
|
||||
static vec<tree> complex_ssa_name_components;
|
||||
|
@ -65,7 +66,7 @@ cvc_lookup (unsigned int uid)
|
|||
{
|
||||
struct int_tree_map *h, in;
|
||||
in.uid = uid;
|
||||
h = (struct int_tree_map *) htab_find_with_hash (complex_variable_components, &in, uid);
|
||||
h = complex_variable_components.find_with_hash (&in, uid);
|
||||
return h ? h->to : NULL;
|
||||
}
|
||||
|
||||
|
@ -75,14 +76,13 @@ static void
|
|||
cvc_insert (unsigned int uid, tree to)
|
||||
{
|
||||
struct int_tree_map *h;
|
||||
void **loc;
|
||||
int_tree_map **loc;
|
||||
|
||||
h = XNEW (struct int_tree_map);
|
||||
h->uid = uid;
|
||||
h->to = to;
|
||||
loc = htab_find_slot_with_hash (complex_variable_components, h,
|
||||
uid, INSERT);
|
||||
*(struct int_tree_map **) loc = h;
|
||||
loc = complex_variable_components.find_slot_with_hash (h, uid, INSERT);
|
||||
*loc = h;
|
||||
}
|
||||
|
||||
/* Return true if T is not a zero constant. In the case of real values,
|
||||
|
@ -1604,8 +1604,7 @@ tree_lower_complex (void)
|
|||
init_parameter_lattice_values ();
|
||||
ssa_propagate (complex_visit_stmt, complex_visit_phi);
|
||||
|
||||
complex_variable_components = htab_create (10, int_tree_map_hash,
|
||||
int_tree_map_eq, free);
|
||||
complex_variable_components.create (10);
|
||||
|
||||
complex_ssa_name_components.create (2 * num_ssa_names);
|
||||
complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names);
|
||||
|
@ -1626,7 +1625,7 @@ tree_lower_complex (void)
|
|||
|
||||
gsi_commit_edge_inserts ();
|
||||
|
||||
htab_delete (complex_variable_components);
|
||||
complex_variable_components.dispose ();
|
||||
complex_ssa_name_components.release ();
|
||||
complex_lattice_values.release ();
|
||||
return 0;
|
||||
|
|
|
@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "flags.h"
|
||||
|
@ -193,20 +194,42 @@ struct finally_tree_node
|
|||
gimple parent;
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct finally_tree_hasher : typed_free_remove <finally_tree_node>
|
||||
{
|
||||
typedef finally_tree_node value_type;
|
||||
typedef finally_tree_node compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
finally_tree_hasher::hash (const value_type *v)
|
||||
{
|
||||
return (intptr_t)v->child.t >> 4;
|
||||
}
|
||||
|
||||
inline bool
|
||||
finally_tree_hasher::equal (const value_type *v, const compare_type *c)
|
||||
{
|
||||
return v->child.t == c->child.t;
|
||||
}
|
||||
|
||||
/* Note that this table is *not* marked GTY. It is short-lived. */
|
||||
static htab_t finally_tree;
|
||||
static hash_table <finally_tree_hasher> finally_tree;
|
||||
|
||||
static void
|
||||
record_in_finally_tree (treemple child, gimple parent)
|
||||
{
|
||||
struct finally_tree_node *n;
|
||||
void **slot;
|
||||
finally_tree_node **slot;
|
||||
|
||||
n = XNEW (struct finally_tree_node);
|
||||
n->child = child;
|
||||
n->parent = parent;
|
||||
|
||||
slot = htab_find_slot (finally_tree, n, INSERT);
|
||||
slot = finally_tree.find_slot (n, INSERT);
|
||||
gcc_assert (!*slot);
|
||||
*slot = n;
|
||||
}
|
||||
|
@ -285,7 +308,7 @@ outside_finally_tree (treemple start, gimple target)
|
|||
do
|
||||
{
|
||||
n.child = start;
|
||||
p = (struct finally_tree_node *) htab_find (finally_tree, &n);
|
||||
p = finally_tree.find (&n);
|
||||
if (!p)
|
||||
return true;
|
||||
start.g = p->parent;
|
||||
|
@ -2102,7 +2125,7 @@ lower_eh_constructs (void)
|
|||
if (bodyp == NULL)
|
||||
return 0;
|
||||
|
||||
finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);
|
||||
finally_tree.create (31);
|
||||
eh_region_may_contain_throw_map = BITMAP_ALLOC (NULL);
|
||||
memset (&null_state, 0, sizeof (null_state));
|
||||
|
||||
|
@ -2120,7 +2143,7 @@ lower_eh_constructs (void)
|
|||
didn't change its value, and we don't have to re-set the function. */
|
||||
gcc_assert (bodyp == gimple_body (current_function_decl));
|
||||
|
||||
htab_delete (finally_tree);
|
||||
finally_tree.dispose ();
|
||||
BITMAP_FREE (eh_region_may_contain_throw_map);
|
||||
eh_seq = NULL;
|
||||
|
||||
|
|
|
@ -282,12 +282,6 @@ struct int_tree_map {
|
|||
tree to;
|
||||
};
|
||||
|
||||
extern unsigned int int_tree_map_hash (const void *);
|
||||
extern int int_tree_map_eq (const void *, const void *);
|
||||
|
||||
extern unsigned int uid_decl_map_hash (const void *);
|
||||
extern int uid_decl_map_eq (const void *, const void *);
|
||||
|
||||
#define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names))
|
||||
#define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* Hash Table Helper for Trees
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
Contributed by Lawrence Crowl <crowl@google.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_TREE_HASHER_H
|
||||
#define GCC_TREE_HASHER_H 1
|
||||
|
||||
#include "hash-table.h"
|
||||
#include "tree-flow.h"
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct int_tree_hasher : typed_free_remove <int_tree_map>
|
||||
{
|
||||
typedef int_tree_map value_type;
|
||||
typedef int_tree_map compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hash a UID in a int_tree_map. */
|
||||
|
||||
inline hashval_t
|
||||
int_tree_hasher::hash (const value_type *item)
|
||||
{
|
||||
return item->uid;
|
||||
}
|
||||
|
||||
/* Return true if the uid in both int tree maps are equal. */
|
||||
|
||||
inline bool
|
||||
int_tree_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
return (a->uid == b->uid);
|
||||
}
|
||||
|
||||
typedef hash_table <int_tree_hasher> int_tree_htab_type;
|
||||
|
||||
#endif /* GCC_TREE_HASHER_H */
|
|
@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-pass.h"
|
||||
#include "langhooks.h"
|
||||
#include "tree-vectorizer.h"
|
||||
#include "tree-hasher.h"
|
||||
|
||||
/* This pass tries to distribute iterations of loops into several threads.
|
||||
The implementation is straightforward -- for each loop we test whether its
|
||||
|
@ -176,36 +177,44 @@ struct reduction_info
|
|||
operation. */
|
||||
};
|
||||
|
||||
/* Reduction info hashtable helpers. */
|
||||
|
||||
struct reduction_hasher : typed_free_remove <reduction_info>
|
||||
{
|
||||
typedef reduction_info value_type;
|
||||
typedef reduction_info compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Equality and hash functions for hashtab code. */
|
||||
|
||||
static int
|
||||
reduction_info_eq (const void *aa, const void *bb)
|
||||
inline bool
|
||||
reduction_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
const struct reduction_info *a = (const struct reduction_info *) aa;
|
||||
const struct reduction_info *b = (const struct reduction_info *) bb;
|
||||
|
||||
return (a->reduc_phi == b->reduc_phi);
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
reduction_info_hash (const void *aa)
|
||||
inline hashval_t
|
||||
reduction_hasher::hash (const value_type *a)
|
||||
{
|
||||
const struct reduction_info *a = (const struct reduction_info *) aa;
|
||||
|
||||
return a->reduc_version;
|
||||
}
|
||||
|
||||
typedef hash_table <reduction_hasher> reduction_info_table_type;
|
||||
|
||||
|
||||
static struct reduction_info *
|
||||
reduction_phi (htab_t reduction_list, gimple phi)
|
||||
reduction_phi (reduction_info_table_type reduction_list, gimple phi)
|
||||
{
|
||||
struct reduction_info tmpred, *red;
|
||||
|
||||
if (htab_elements (reduction_list) == 0 || phi == NULL)
|
||||
if (reduction_list.elements () == 0 || phi == NULL)
|
||||
return NULL;
|
||||
|
||||
tmpred.reduc_phi = phi;
|
||||
tmpred.reduc_version = gimple_uid (phi);
|
||||
red = (struct reduction_info *) htab_find (reduction_list, &tmpred);
|
||||
red = reduction_list.find (&tmpred);
|
||||
|
||||
return red;
|
||||
}
|
||||
|
@ -220,25 +229,32 @@ struct name_to_copy_elt
|
|||
value. */
|
||||
};
|
||||
|
||||
/* Name copies hashtable helpers. */
|
||||
|
||||
struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt>
|
||||
{
|
||||
typedef name_to_copy_elt value_type;
|
||||
typedef name_to_copy_elt compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Equality and hash functions for hashtab code. */
|
||||
|
||||
static int
|
||||
name_to_copy_elt_eq (const void *aa, const void *bb)
|
||||
inline bool
|
||||
name_to_copy_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
|
||||
const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb;
|
||||
|
||||
return a->version == b->version;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
name_to_copy_elt_hash (const void *aa)
|
||||
inline hashval_t
|
||||
name_to_copy_hasher::hash (const value_type *a)
|
||||
{
|
||||
const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
|
||||
|
||||
return (hashval_t) a->version;
|
||||
}
|
||||
|
||||
typedef hash_table <name_to_copy_hasher> name_to_copy_table_type;
|
||||
|
||||
/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
|
||||
matrix. Rather than use floats, we simply keep a single DENOMINATOR that
|
||||
represents the denominator for every element in the matrix. */
|
||||
|
@ -445,11 +461,11 @@ loop_has_blocks_with_irreducible_flag (struct loop *loop)
|
|||
right before GSI. */
|
||||
|
||||
static tree
|
||||
take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
|
||||
gimple_stmt_iterator *gsi)
|
||||
take_address_of (tree obj, tree type, edge entry,
|
||||
int_tree_htab_type decl_address, gimple_stmt_iterator *gsi)
|
||||
{
|
||||
int uid;
|
||||
void **dslot;
|
||||
int_tree_map **dslot;
|
||||
struct int_tree_map ielt, *nielt;
|
||||
tree *var_p, name, addr;
|
||||
gimple stmt;
|
||||
|
@ -472,7 +488,7 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
|
|||
on it. */
|
||||
uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
|
||||
ielt.uid = uid;
|
||||
dslot = htab_find_slot_with_hash (decl_address, &ielt, uid, INSERT);
|
||||
dslot = decl_address.find_slot_with_hash (&ielt, uid, INSERT);
|
||||
if (!*dslot)
|
||||
{
|
||||
if (gsi == NULL)
|
||||
|
@ -490,7 +506,7 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
|
|||
*dslot = nielt;
|
||||
}
|
||||
else
|
||||
name = ((struct int_tree_map *) *dslot)->to;
|
||||
name = (*dslot)->to;
|
||||
|
||||
/* Express the address in terms of the canonical SSA name. */
|
||||
TREE_OPERAND (*var_p, 0) = name;
|
||||
|
@ -517,15 +533,14 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
|
|||
for reduction described in SLOT, and place it at the preheader of
|
||||
the loop described in DATA. */
|
||||
|
||||
static int
|
||||
initialize_reductions (void **slot, void *data)
|
||||
int
|
||||
initialize_reductions (reduction_info **slot, struct loop *loop)
|
||||
{
|
||||
tree init, c;
|
||||
tree bvar, type, arg;
|
||||
edge e;
|
||||
|
||||
struct reduction_info *const reduc = (struct reduction_info *) *slot;
|
||||
struct loop *loop = (struct loop *) data;
|
||||
struct reduction_info *const reduc = *slot;
|
||||
|
||||
/* Create initialization in preheader:
|
||||
reduction_variable = initialization value of reduction. */
|
||||
|
@ -567,7 +582,7 @@ struct elv_data
|
|||
{
|
||||
struct walk_stmt_info info;
|
||||
edge entry;
|
||||
htab_t decl_address;
|
||||
int_tree_htab_type decl_address;
|
||||
gimple_stmt_iterator *gsi;
|
||||
bool changed;
|
||||
bool reset;
|
||||
|
@ -657,7 +672,7 @@ eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
|
||||
static void
|
||||
eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi,
|
||||
htab_t decl_address)
|
||||
int_tree_htab_type decl_address)
|
||||
{
|
||||
struct elv_data dta;
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
|
@ -709,8 +724,8 @@ eliminate_local_variables (edge entry, edge exit)
|
|||
unsigned i;
|
||||
gimple_stmt_iterator gsi;
|
||||
bool has_debug_stmt = false;
|
||||
htab_t decl_address = htab_create (10, int_tree_map_hash, int_tree_map_eq,
|
||||
free);
|
||||
int_tree_htab_type decl_address;
|
||||
decl_address.create (10);
|
||||
basic_block entry_bb = entry->src;
|
||||
basic_block exit_bb = exit->dest;
|
||||
|
||||
|
@ -734,7 +749,7 @@ eliminate_local_variables (edge entry, edge exit)
|
|||
if (gimple_debug_bind_p (gsi_stmt (gsi)))
|
||||
eliminate_local_variables_stmt (entry, &gsi, decl_address);
|
||||
|
||||
htab_delete (decl_address);
|
||||
decl_address.dispose ();
|
||||
body.release ();
|
||||
}
|
||||
|
||||
|
@ -773,25 +788,25 @@ expr_invariant_in_region_p (edge entry, edge exit, tree expr)
|
|||
duplicated, storing the copies in DECL_COPIES. */
|
||||
|
||||
static tree
|
||||
separate_decls_in_region_name (tree name,
|
||||
htab_t name_copies, htab_t decl_copies,
|
||||
bool copy_name_p)
|
||||
separate_decls_in_region_name (tree name, name_to_copy_table_type name_copies,
|
||||
int_tree_htab_type decl_copies, bool copy_name_p)
|
||||
{
|
||||
tree copy, var, var_copy;
|
||||
unsigned idx, uid, nuid;
|
||||
struct int_tree_map ielt, *nielt;
|
||||
struct name_to_copy_elt elt, *nelt;
|
||||
void **slot, **dslot;
|
||||
name_to_copy_elt **slot;
|
||||
int_tree_map **dslot;
|
||||
|
||||
if (TREE_CODE (name) != SSA_NAME)
|
||||
return name;
|
||||
|
||||
idx = SSA_NAME_VERSION (name);
|
||||
elt.version = idx;
|
||||
slot = htab_find_slot_with_hash (name_copies, &elt, idx,
|
||||
copy_name_p ? INSERT : NO_INSERT);
|
||||
slot = name_copies.find_slot_with_hash (&elt, idx,
|
||||
copy_name_p ? INSERT : NO_INSERT);
|
||||
if (slot && *slot)
|
||||
return ((struct name_to_copy_elt *) *slot)->new_name;
|
||||
return (*slot)->new_name;
|
||||
|
||||
if (copy_name_p)
|
||||
{
|
||||
|
@ -814,7 +829,7 @@ separate_decls_in_region_name (tree name,
|
|||
|
||||
uid = DECL_UID (var);
|
||||
ielt.uid = uid;
|
||||
dslot = htab_find_slot_with_hash (decl_copies, &ielt, uid, INSERT);
|
||||
dslot = decl_copies.find_slot_with_hash (&ielt, uid, INSERT);
|
||||
if (!*dslot)
|
||||
{
|
||||
var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
|
||||
|
@ -828,7 +843,7 @@ separate_decls_in_region_name (tree name,
|
|||
it again. */
|
||||
nuid = DECL_UID (var_copy);
|
||||
ielt.uid = nuid;
|
||||
dslot = htab_find_slot_with_hash (decl_copies, &ielt, nuid, INSERT);
|
||||
dslot = decl_copies.find_slot_with_hash (&ielt, nuid, INSERT);
|
||||
gcc_assert (!*dslot);
|
||||
nielt = XNEW (struct int_tree_map);
|
||||
nielt->uid = nuid;
|
||||
|
@ -851,7 +866,8 @@ separate_decls_in_region_name (tree name,
|
|||
|
||||
static void
|
||||
separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
|
||||
htab_t name_copies, htab_t decl_copies)
|
||||
name_to_copy_table_type name_copies,
|
||||
int_tree_htab_type decl_copies)
|
||||
{
|
||||
use_operand_p use;
|
||||
def_operand_p def;
|
||||
|
@ -889,15 +905,17 @@ separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
|
|||
replacement decls are stored in DECL_COPIES. */
|
||||
|
||||
static bool
|
||||
separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
|
||||
htab_t decl_copies)
|
||||
separate_decls_in_region_debug (gimple stmt,
|
||||
name_to_copy_table_type name_copies,
|
||||
int_tree_htab_type decl_copies)
|
||||
{
|
||||
use_operand_p use;
|
||||
ssa_op_iter oi;
|
||||
tree var, name;
|
||||
struct int_tree_map ielt;
|
||||
struct name_to_copy_elt elt;
|
||||
void **slot, **dslot;
|
||||
name_to_copy_elt **slot;
|
||||
int_tree_map **dslot;
|
||||
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
var = gimple_debug_bind_get_var (stmt);
|
||||
|
@ -909,7 +927,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
|
|||
return true;
|
||||
gcc_assert (DECL_P (var) && SSA_VAR_P (var));
|
||||
ielt.uid = DECL_UID (var);
|
||||
dslot = htab_find_slot_with_hash (decl_copies, &ielt, ielt.uid, NO_INSERT);
|
||||
dslot = decl_copies.find_slot_with_hash (&ielt, ielt.uid, NO_INSERT);
|
||||
if (!dslot)
|
||||
return true;
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
|
@ -924,7 +942,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
|
|||
continue;
|
||||
|
||||
elt.version = SSA_NAME_VERSION (name);
|
||||
slot = htab_find_slot_with_hash (name_copies, &elt, elt.version, NO_INSERT);
|
||||
slot = name_copies.find_slot_with_hash (&elt, elt.version, NO_INSERT);
|
||||
if (!slot)
|
||||
{
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
|
@ -932,7 +950,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
|
|||
break;
|
||||
}
|
||||
|
||||
SET_USE (use, ((struct name_to_copy_elt *) *slot)->new_name);
|
||||
SET_USE (use, (*slot)->new_name);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -941,12 +959,11 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
|
|||
/* Callback for htab_traverse. Adds a field corresponding to the reduction
|
||||
specified in SLOT. The type is passed in DATA. */
|
||||
|
||||
static int
|
||||
add_field_for_reduction (void **slot, void *data)
|
||||
int
|
||||
add_field_for_reduction (reduction_info **slot, tree type)
|
||||
{
|
||||
|
||||
struct reduction_info *const red = (struct reduction_info *) *slot;
|
||||
tree const type = (tree) data;
|
||||
struct reduction_info *const red = *slot;
|
||||
tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt));
|
||||
tree field = build_decl (gimple_location (red->reduc_stmt),
|
||||
FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
|
||||
|
@ -961,11 +978,10 @@ add_field_for_reduction (void **slot, void *data)
|
|||
/* Callback for htab_traverse. Adds a field corresponding to a ssa name
|
||||
described in SLOT. The type is passed in DATA. */
|
||||
|
||||
static int
|
||||
add_field_for_name (void **slot, void *data)
|
||||
int
|
||||
add_field_for_name (name_to_copy_elt **slot, tree type)
|
||||
{
|
||||
struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
|
||||
tree type = (tree) data;
|
||||
struct name_to_copy_elt *const elt = *slot;
|
||||
tree name = ssa_name (elt->version);
|
||||
tree field = build_decl (UNKNOWN_LOCATION,
|
||||
FIELD_DECL, SSA_NAME_IDENTIFIER (name),
|
||||
|
@ -984,11 +1000,10 @@ add_field_for_name (void **slot, void *data)
|
|||
The phi's result will be stored in NEW_PHI field of the
|
||||
reduction's data structure. */
|
||||
|
||||
static int
|
||||
create_phi_for_local_result (void **slot, void *data)
|
||||
int
|
||||
create_phi_for_local_result (reduction_info **slot, struct loop *loop)
|
||||
{
|
||||
struct reduction_info *const reduc = (struct reduction_info *) *slot;
|
||||
const struct loop *const loop = (const struct loop *) data;
|
||||
struct reduction_info *const reduc = *slot;
|
||||
edge e;
|
||||
gimple new_phi;
|
||||
basic_block store_bb;
|
||||
|
@ -1034,11 +1049,10 @@ struct clsn_data
|
|||
DATA annotates the place in memory the atomic operation relates to,
|
||||
and the basic block it needs to be generated in. */
|
||||
|
||||
static int
|
||||
create_call_for_reduction_1 (void **slot, void *data)
|
||||
int
|
||||
create_call_for_reduction_1 (reduction_info **slot, struct clsn_data *clsn_data)
|
||||
{
|
||||
struct reduction_info *const reduc = (struct reduction_info *) *slot;
|
||||
struct clsn_data *const clsn_data = (struct clsn_data *) data;
|
||||
struct reduction_info *const reduc = *slot;
|
||||
gimple_stmt_iterator gsi;
|
||||
tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
|
||||
tree load_struct;
|
||||
|
@ -1087,23 +1101,24 @@ create_call_for_reduction_1 (void **slot, void *data)
|
|||
LD_ST_DATA describes the shared data structure where
|
||||
shared data is stored in and loaded from. */
|
||||
static void
|
||||
create_call_for_reduction (struct loop *loop, htab_t reduction_list,
|
||||
create_call_for_reduction (struct loop *loop,
|
||||
reduction_info_table_type reduction_list,
|
||||
struct clsn_data *ld_st_data)
|
||||
{
|
||||
htab_traverse (reduction_list, create_phi_for_local_result, loop);
|
||||
reduction_list.traverse <struct loop *, create_phi_for_local_result> (loop);
|
||||
/* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
|
||||
ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest;
|
||||
htab_traverse (reduction_list, create_call_for_reduction_1, ld_st_data);
|
||||
reduction_list
|
||||
.traverse <struct clsn_data *, create_call_for_reduction_1> (ld_st_data);
|
||||
}
|
||||
|
||||
/* Callback for htab_traverse. Loads the final reduction value at the
|
||||
join point of all threads, and inserts it in the right place. */
|
||||
|
||||
static int
|
||||
create_loads_for_reductions (void **slot, void *data)
|
||||
int
|
||||
create_loads_for_reductions (reduction_info **slot, struct clsn_data *clsn_data)
|
||||
{
|
||||
struct reduction_info *const red = (struct reduction_info *) *slot;
|
||||
struct clsn_data *const clsn_data = (struct clsn_data *) data;
|
||||
struct reduction_info *const red = *slot;
|
||||
gimple stmt;
|
||||
gimple_stmt_iterator gsi;
|
||||
tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
|
||||
|
@ -1137,7 +1152,7 @@ create_loads_for_reductions (void **slot, void *data)
|
|||
REDUCTION_LIST describes the list of reductions that the
|
||||
loads should be generated for. */
|
||||
static void
|
||||
create_final_loads_for_reduction (htab_t reduction_list,
|
||||
create_final_loads_for_reduction (reduction_info_table_type reduction_list,
|
||||
struct clsn_data *ld_st_data)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
|
@ -1151,7 +1166,8 @@ create_final_loads_for_reduction (htab_t reduction_list,
|
|||
gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
|
||||
SSA_NAME_DEF_STMT (ld_st_data->load) = stmt;
|
||||
|
||||
htab_traverse (reduction_list, create_loads_for_reductions, ld_st_data);
|
||||
reduction_list
|
||||
.traverse <struct clsn_data *, create_loads_for_reductions> (ld_st_data);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1161,11 +1177,10 @@ create_final_loads_for_reduction (htab_t reduction_list,
|
|||
The reduction is specified in SLOT. The store information is
|
||||
passed in DATA. */
|
||||
|
||||
static int
|
||||
create_stores_for_reduction (void **slot, void *data)
|
||||
int
|
||||
create_stores_for_reduction (reduction_info **slot, struct clsn_data *clsn_data)
|
||||
{
|
||||
struct reduction_info *const red = (struct reduction_info *) *slot;
|
||||
struct clsn_data *const clsn_data = (struct clsn_data *) data;
|
||||
struct reduction_info *const red = *slot;
|
||||
tree t;
|
||||
gimple stmt;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
@ -1183,11 +1198,11 @@ create_stores_for_reduction (void **slot, void *data)
|
|||
store to a field of STORE in STORE_BB for the ssa name and its duplicate
|
||||
specified in SLOT. */
|
||||
|
||||
static int
|
||||
create_loads_and_stores_for_name (void **slot, void *data)
|
||||
int
|
||||
create_loads_and_stores_for_name (name_to_copy_elt **slot,
|
||||
struct clsn_data *clsn_data)
|
||||
{
|
||||
struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
|
||||
struct clsn_data *const clsn_data = (struct clsn_data *) data;
|
||||
struct name_to_copy_elt *const elt = *slot;
|
||||
tree t;
|
||||
gimple stmt;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
@ -1244,17 +1259,18 @@ create_loads_and_stores_for_name (void **slot, void *data)
|
|||
in LOOP. */
|
||||
|
||||
static void
|
||||
separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
|
||||
separate_decls_in_region (edge entry, edge exit,
|
||||
reduction_info_table_type reduction_list,
|
||||
tree *arg_struct, tree *new_arg_struct,
|
||||
struct clsn_data *ld_st_data)
|
||||
|
||||
{
|
||||
basic_block bb1 = split_edge (entry);
|
||||
basic_block bb0 = single_pred (bb1);
|
||||
htab_t name_copies = htab_create (10, name_to_copy_elt_hash,
|
||||
name_to_copy_elt_eq, free);
|
||||
htab_t decl_copies = htab_create (10, int_tree_map_hash, int_tree_map_eq,
|
||||
free);
|
||||
name_to_copy_table_type name_copies;
|
||||
name_copies.create (10);
|
||||
int_tree_htab_type decl_copies;
|
||||
decl_copies.create (10);
|
||||
unsigned i;
|
||||
tree type, type_name, nvar;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
@ -1320,7 +1336,7 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
|
|||
|
||||
body.release ();
|
||||
|
||||
if (htab_elements (name_copies) == 0 && htab_elements (reduction_list) == 0)
|
||||
if (name_copies.elements () == 0 && reduction_list.elements () == 0)
|
||||
{
|
||||
/* It may happen that there is nothing to copy (if there are only
|
||||
loop carried and external variables in the loop). */
|
||||
|
@ -1336,12 +1352,11 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
|
|||
type);
|
||||
TYPE_NAME (type) = type_name;
|
||||
|
||||
htab_traverse (name_copies, add_field_for_name, type);
|
||||
if (reduction_list && htab_elements (reduction_list) > 0)
|
||||
name_copies.traverse <tree, add_field_for_name> (type);
|
||||
if (reduction_list.is_created () && reduction_list.elements () > 0)
|
||||
{
|
||||
/* Create the fields for reductions. */
|
||||
htab_traverse (reduction_list, add_field_for_reduction,
|
||||
type);
|
||||
reduction_list.traverse <tree, add_field_for_reduction> (type);
|
||||
}
|
||||
layout_type (type);
|
||||
|
||||
|
@ -1355,15 +1370,17 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
|
|||
ld_st_data->store_bb = bb0;
|
||||
ld_st_data->load_bb = bb1;
|
||||
|
||||
htab_traverse (name_copies, create_loads_and_stores_for_name,
|
||||
ld_st_data);
|
||||
name_copies
|
||||
.traverse <struct clsn_data *, create_loads_and_stores_for_name>
|
||||
(ld_st_data);
|
||||
|
||||
/* Load the calculation from memory (after the join of the threads). */
|
||||
|
||||
if (reduction_list && htab_elements (reduction_list) > 0)
|
||||
if (reduction_list.is_created () && reduction_list.elements () > 0)
|
||||
{
|
||||
htab_traverse (reduction_list, create_stores_for_reduction,
|
||||
ld_st_data);
|
||||
reduction_list
|
||||
.traverse <struct clsn_data *, create_stores_for_reduction>
|
||||
(ld_st_data);
|
||||
clsn_data.load = make_ssa_name (nvar, NULL);
|
||||
clsn_data.load_bb = exit->dest;
|
||||
clsn_data.store = ld_st_data->store;
|
||||
|
@ -1371,8 +1388,8 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
|
|||
}
|
||||
}
|
||||
|
||||
htab_delete (decl_copies);
|
||||
htab_delete (name_copies);
|
||||
decl_copies.dispose ();
|
||||
name_copies.dispose ();
|
||||
}
|
||||
|
||||
/* Bitmap containing uids of functions created by parallelization. We cannot
|
||||
|
@ -1461,7 +1478,9 @@ create_loop_fn (location_t loc)
|
|||
REDUCTION_LIST describes the reductions in LOOP. */
|
||||
|
||||
static void
|
||||
transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit)
|
||||
transform_to_exit_first_loop (struct loop *loop,
|
||||
reduction_info_table_type reduction_list,
|
||||
tree nit)
|
||||
{
|
||||
basic_block *bbs, *nbbs, ex_bb, orig_header;
|
||||
unsigned n;
|
||||
|
@ -1530,7 +1549,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
|
|||
PHI_RESULT of this phi is the resulting value of the reduction
|
||||
variable when exiting the loop. */
|
||||
|
||||
if (htab_elements (reduction_list) > 0)
|
||||
if (reduction_list.elements () > 0)
|
||||
{
|
||||
struct reduction_info *red;
|
||||
|
||||
|
@ -1708,7 +1727,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
|
|||
REDUCTION_LIST describes the reductions existent in the LOOP. */
|
||||
|
||||
static void
|
||||
gen_parallel_loop (struct loop *loop, htab_t reduction_list,
|
||||
gen_parallel_loop (struct loop *loop, reduction_info_table_type reduction_list,
|
||||
unsigned n_threads, struct tree_niter_desc *niter)
|
||||
{
|
||||
loop_iterator li;
|
||||
|
@ -1834,8 +1853,8 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
|
|||
transform_to_exit_first_loop (loop, reduction_list, nit);
|
||||
|
||||
/* Generate initializations for reductions. */
|
||||
if (htab_elements (reduction_list) > 0)
|
||||
htab_traverse (reduction_list, initialize_reductions, loop);
|
||||
if (reduction_list.elements () > 0)
|
||||
reduction_list.traverse <struct loop *, initialize_reductions> (loop);
|
||||
|
||||
/* Eliminate the references to local variables from the loop. */
|
||||
gcc_assert (single_exit (loop));
|
||||
|
@ -1855,7 +1874,7 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
|
|||
loc = gimple_location (cond_stmt);
|
||||
parallel_head = create_parallel_loop (loop, create_loop_fn (loc), arg_struct,
|
||||
new_arg_struct, n_threads, loc);
|
||||
if (htab_elements (reduction_list) > 0)
|
||||
if (reduction_list.elements () > 0)
|
||||
create_call_for_reduction (loop, reduction_list, &clsn_data);
|
||||
|
||||
scev_reset ();
|
||||
|
@ -1902,9 +1921,10 @@ loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
|
|||
and PHI, insert it to the REDUCTION_LIST. */
|
||||
|
||||
static void
|
||||
build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi)
|
||||
build_new_reduction (reduction_info_table_type reduction_list,
|
||||
gimple reduc_stmt, gimple phi)
|
||||
{
|
||||
PTR *slot;
|
||||
reduction_info **slot;
|
||||
struct reduction_info *new_reduction;
|
||||
|
||||
gcc_assert (reduc_stmt);
|
||||
|
@ -1923,16 +1943,16 @@ build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi)
|
|||
new_reduction->reduc_phi = phi;
|
||||
new_reduction->reduc_version = SSA_NAME_VERSION (gimple_phi_result (phi));
|
||||
new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt);
|
||||
slot = htab_find_slot (reduction_list, new_reduction, INSERT);
|
||||
slot = reduction_list.find_slot (new_reduction, INSERT);
|
||||
*slot = new_reduction;
|
||||
}
|
||||
|
||||
/* Callback for htab_traverse. Sets gimple_uid of reduc_phi stmts. */
|
||||
|
||||
static int
|
||||
set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
int
|
||||
set_reduc_phi_uids (reduction_info **slot, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct reduction_info *const red = (struct reduction_info *) *slot;
|
||||
struct reduction_info *const red = *slot;
|
||||
gimple_set_uid (red->reduc_phi, red->reduc_version);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1940,7 +1960,7 @@ set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
/* Detect all reductions in the LOOP, insert them into REDUCTION_LIST. */
|
||||
|
||||
static void
|
||||
gather_scalar_reductions (loop_p loop, htab_t reduction_list)
|
||||
gather_scalar_reductions (loop_p loop, reduction_info_table_type reduction_list)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
loop_vec_info simple_loop_info;
|
||||
|
@ -1972,7 +1992,7 @@ gather_scalar_reductions (loop_p loop, htab_t reduction_list)
|
|||
/* As gimple_uid is used by the vectorizer in between vect_analyze_loop_form
|
||||
and destroy_loop_vec_info, we can set gimple_uid of reduc_phi stmts
|
||||
only now. */
|
||||
htab_traverse (reduction_list, set_reduc_phi_uids, NULL);
|
||||
reduction_list.traverse <void *, set_reduc_phi_uids> (NULL);
|
||||
}
|
||||
|
||||
/* Try to initialize NITER for code generation part. */
|
||||
|
@ -2001,7 +2021,8 @@ try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter)
|
|||
REDUCTION_LIST describes the reductions. */
|
||||
|
||||
static bool
|
||||
try_create_reduction_list (loop_p loop, htab_t reduction_list)
|
||||
try_create_reduction_list (loop_p loop,
|
||||
reduction_info_table_type reduction_list)
|
||||
{
|
||||
edge exit = single_dom_exit (loop);
|
||||
gimple_stmt_iterator gsi;
|
||||
|
@ -2032,7 +2053,7 @@ try_create_reduction_list (loop_p loop, htab_t reduction_list)
|
|||
fprintf (dump_file,
|
||||
" checking if it a part of reduction pattern: \n");
|
||||
}
|
||||
if (htab_elements (reduction_list) == 0)
|
||||
if (reduction_list.elements () == 0)
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file,
|
||||
|
@ -2106,7 +2127,7 @@ parallelize_loops (void)
|
|||
struct loop *loop;
|
||||
struct tree_niter_desc niter_desc;
|
||||
loop_iterator li;
|
||||
htab_t reduction_list;
|
||||
reduction_info_table_type reduction_list;
|
||||
struct obstack parloop_obstack;
|
||||
HOST_WIDE_INT estimated;
|
||||
LOC loop_loc;
|
||||
|
@ -2118,13 +2139,12 @@ parallelize_loops (void)
|
|||
return false;
|
||||
|
||||
gcc_obstack_init (&parloop_obstack);
|
||||
reduction_list = htab_create (10, reduction_info_hash,
|
||||
reduction_info_eq, free);
|
||||
reduction_list.create (10);
|
||||
init_stmt_vec_info_vec ();
|
||||
|
||||
FOR_EACH_LOOP (li, loop, 0)
|
||||
{
|
||||
htab_empty (reduction_list);
|
||||
reduction_list.empty ();
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Trying loop %d as candidate\n",loop->num);
|
||||
|
@ -2204,7 +2224,7 @@ parallelize_loops (void)
|
|||
}
|
||||
|
||||
free_stmt_vec_info_vec ();
|
||||
htab_delete (reduction_list);
|
||||
reduction_list.dispose ();
|
||||
obstack_free (&parloop_obstack, NULL);
|
||||
|
||||
/* Parallelization will cause new function calls to be inserted through
|
||||
|
|
|
@ -256,6 +256,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "gimple-pretty-print.h"
|
||||
#include "tree-flow.h"
|
||||
#include "cfgloop.h"
|
||||
|
@ -317,7 +318,7 @@ new_scev_info_str (basic_block instantiated_below, tree var)
|
|||
|
||||
/* Computes a hash function for database element ELT. */
|
||||
|
||||
static hashval_t
|
||||
static inline hashval_t
|
||||
hash_scev_info (const void *elt)
|
||||
{
|
||||
return SSA_NAME_VERSION (((const struct scev_info_str *) elt)->var);
|
||||
|
@ -325,7 +326,7 @@ hash_scev_info (const void *elt)
|
|||
|
||||
/* Compares database elements E1 and E2. */
|
||||
|
||||
static int
|
||||
static inline int
|
||||
eq_scev_info (const void *e1, const void *e2)
|
||||
{
|
||||
const struct scev_info_str *elt1 = (const struct scev_info_str *) e1;
|
||||
|
@ -343,6 +344,39 @@ del_scev_info (void *e)
|
|||
ggc_free (e);
|
||||
}
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct scev_info_hasher
|
||||
{
|
||||
typedef scev_info_str value_type;
|
||||
typedef scev_info_str compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
scev_info_hasher::hash (const value_type *elt)
|
||||
{
|
||||
return hash_scev_info (elt);
|
||||
}
|
||||
|
||||
inline bool
|
||||
scev_info_hasher::equal (const value_type *elt1, const compare_type *elt2)
|
||||
{
|
||||
return eq_scev_info (elt1, elt2);
|
||||
}
|
||||
|
||||
/* Deletes database element E. */
|
||||
|
||||
inline void
|
||||
scev_info_hasher::remove (value_type *e)
|
||||
{
|
||||
del_scev_info (e);
|
||||
}
|
||||
|
||||
typedef hash_table <scev_info_hasher> scev_info_hash_table_type;
|
||||
|
||||
/* Get the scalar evolution of VAR for INSTANTIATED_BELOW basic block.
|
||||
A first query on VAR returns chrec_not_analyzed_yet. */
|
||||
|
||||
|
@ -2048,14 +2082,14 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop,
|
|||
INSTANTIATED_BELOW block. */
|
||||
|
||||
static tree
|
||||
get_instantiated_value (htab_t cache, basic_block instantiated_below,
|
||||
tree version)
|
||||
get_instantiated_value (scev_info_hash_table_type cache,
|
||||
basic_block instantiated_below, tree version)
|
||||
{
|
||||
struct scev_info_str *info, pattern;
|
||||
|
||||
pattern.var = version;
|
||||
pattern.instantiated_below = instantiated_below;
|
||||
info = (struct scev_info_str *) htab_find (cache, &pattern);
|
||||
info = cache.find (&pattern);
|
||||
|
||||
if (info)
|
||||
return info->chrec;
|
||||
|
@ -2067,19 +2101,19 @@ get_instantiated_value (htab_t cache, basic_block instantiated_below,
|
|||
INSTANTIATED_BELOW to VAL. */
|
||||
|
||||
static void
|
||||
set_instantiated_value (htab_t cache, basic_block instantiated_below,
|
||||
tree version, tree val)
|
||||
set_instantiated_value (scev_info_hash_table_type cache,
|
||||
basic_block instantiated_below, tree version, tree val)
|
||||
{
|
||||
struct scev_info_str *info, pattern;
|
||||
PTR *slot;
|
||||
scev_info_str **slot;
|
||||
|
||||
pattern.var = version;
|
||||
pattern.instantiated_below = instantiated_below;
|
||||
slot = htab_find_slot (cache, &pattern, INSERT);
|
||||
slot = cache.find_slot (&pattern, INSERT);
|
||||
|
||||
if (!*slot)
|
||||
*slot = new_scev_info_str (instantiated_below, version);
|
||||
info = (struct scev_info_str *) *slot;
|
||||
info = *slot;
|
||||
info->chrec = val;
|
||||
}
|
||||
|
||||
|
@ -2114,7 +2148,7 @@ loop_closed_phi_def (tree var)
|
|||
}
|
||||
|
||||
static tree instantiate_scev_r (basic_block, struct loop *, struct loop *,
|
||||
tree, bool, htab_t, int);
|
||||
tree, bool, scev_info_hash_table_type, int);
|
||||
|
||||
/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
|
||||
and EVOLUTION_LOOP, that were left under a symbolic form.
|
||||
|
@ -2134,7 +2168,8 @@ static tree
|
|||
instantiate_scev_name (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree res;
|
||||
struct loop *def_loop;
|
||||
|
@ -2236,7 +2271,8 @@ static tree
|
|||
instantiate_scev_poly (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree op1;
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
|
||||
|
@ -2282,7 +2318,8 @@ instantiate_scev_binary (basic_block instantiate_below,
|
|||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec, enum tree_code code,
|
||||
tree type, tree c0, tree c1,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree op1;
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop,
|
||||
|
@ -2341,7 +2378,8 @@ static tree
|
|||
instantiate_array_ref (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree res;
|
||||
tree index = TREE_OPERAND (chrec, 1);
|
||||
|
@ -2380,7 +2418,8 @@ instantiate_scev_convert (basic_block instantiate_below,
|
|||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
tree type, tree op,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions,
|
||||
scev_info_hash_table_type cache, int size_expr)
|
||||
{
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
|
||||
inner_loop, op,
|
||||
|
@ -2429,7 +2468,8 @@ instantiate_scev_not (basic_block instantiate_below,
|
|||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
enum tree_code code, tree type, tree op,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
|
||||
inner_loop, op,
|
||||
|
@ -2478,7 +2518,8 @@ static tree
|
|||
instantiate_scev_3 (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree op1, op2;
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
|
||||
|
@ -2526,7 +2567,8 @@ static tree
|
|||
instantiate_scev_2 (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree op1;
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
|
||||
|
@ -2566,7 +2608,8 @@ static tree
|
|||
instantiate_scev_1 (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
|
||||
inner_loop, TREE_OPERAND (chrec, 0),
|
||||
|
@ -2599,7 +2642,8 @@ static tree
|
|||
instantiate_scev_r (basic_block instantiate_below,
|
||||
struct loop *evolution_loop, struct loop *inner_loop,
|
||||
tree chrec,
|
||||
bool fold_conversions, htab_t cache, int size_expr)
|
||||
bool fold_conversions, scev_info_hash_table_type cache,
|
||||
int size_expr)
|
||||
{
|
||||
/* Give up if the expression is larger than the MAX that we allow. */
|
||||
if (size_expr++ > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
|
||||
|
@ -2705,7 +2749,8 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
|
|||
tree chrec)
|
||||
{
|
||||
tree res;
|
||||
htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
|
||||
scev_info_hash_table_type cache;
|
||||
cache.create (10);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_SCEV))
|
||||
{
|
||||
|
@ -2727,7 +2772,7 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
|
|||
fprintf (dump_file, "))\n");
|
||||
}
|
||||
|
||||
htab_delete (cache);
|
||||
cache.dispose ();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -2740,10 +2785,11 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
|
|||
tree
|
||||
resolve_mixers (struct loop *loop, tree chrec)
|
||||
{
|
||||
htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
|
||||
scev_info_hash_table_type cache;
|
||||
cache.create (10);
|
||||
tree ret = instantiate_scev_r (block_before_loop (loop), loop, NULL,
|
||||
chrec, true, cache, 0);
|
||||
htab_delete (cache);
|
||||
cache.dispose ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "alloc-pool.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
|
@ -269,18 +270,44 @@ static alloc_pool link_pool;
|
|||
/* Base (tree) -> Vector (vec<access_p> *) map. */
|
||||
static struct pointer_map_t *base_access_vec;
|
||||
|
||||
/* Candidate hash table helpers. */
|
||||
|
||||
struct uid_decl_hasher : typed_noop_remove <tree_node>
|
||||
{
|
||||
typedef tree_node value_type;
|
||||
typedef tree_node compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hash a tree in a uid_decl_map. */
|
||||
|
||||
inline hashval_t
|
||||
uid_decl_hasher::hash (const value_type *item)
|
||||
{
|
||||
return item->decl_minimal.uid;
|
||||
}
|
||||
|
||||
/* Return true if the DECL_UID in both trees are equal. */
|
||||
|
||||
inline bool
|
||||
uid_decl_hasher::equal (const value_type *a, const compare_type *b)
|
||||
{
|
||||
return (a->decl_minimal.uid == b->decl_minimal.uid);
|
||||
}
|
||||
|
||||
/* Set of candidates. */
|
||||
static bitmap candidate_bitmap;
|
||||
static htab_t candidates;
|
||||
static hash_table <uid_decl_hasher> candidates;
|
||||
|
||||
/* For a candidate UID return the candidates decl. */
|
||||
|
||||
static inline tree
|
||||
candidate (unsigned uid)
|
||||
{
|
||||
struct tree_decl_minimal t;
|
||||
t.uid = uid;
|
||||
return (tree) htab_find_with_hash (candidates, &t, uid);
|
||||
tree_node t;
|
||||
t.decl_minimal.uid = uid;
|
||||
return candidates.find_with_hash (&t, static_cast <hashval_t> (uid));
|
||||
}
|
||||
|
||||
/* Bitmap of candidates which we should try to entirely scalarize away and
|
||||
|
@ -611,8 +638,7 @@ static void
|
|||
sra_initialize (void)
|
||||
{
|
||||
candidate_bitmap = BITMAP_ALLOC (NULL);
|
||||
candidates = htab_create (vec_safe_length (cfun->local_decls) / 2,
|
||||
uid_decl_map_hash, uid_decl_map_eq, NULL);
|
||||
candidates.create (vec_safe_length (cfun->local_decls) / 2);
|
||||
should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
|
||||
cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
|
||||
gcc_obstack_init (&name_obstack);
|
||||
|
@ -642,7 +668,7 @@ static void
|
|||
sra_deinitialize (void)
|
||||
{
|
||||
BITMAP_FREE (candidate_bitmap);
|
||||
htab_delete (candidates);
|
||||
candidates.dispose ();
|
||||
BITMAP_FREE (should_scalarize_away_bitmap);
|
||||
BITMAP_FREE (cannot_scalarize_away_bitmap);
|
||||
free_alloc_pool (access_pool);
|
||||
|
@ -659,9 +685,9 @@ static void
|
|||
disqualify_candidate (tree decl, const char *reason)
|
||||
{
|
||||
if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
|
||||
htab_clear_slot (candidates,
|
||||
htab_find_slot_with_hash (candidates, decl,
|
||||
DECL_UID (decl), NO_INSERT));
|
||||
candidates.clear_slot (candidates.find_slot_with_hash (decl,
|
||||
DECL_UID (decl),
|
||||
NO_INSERT));
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
|
@ -1680,7 +1706,7 @@ maybe_add_sra_candidate (tree var)
|
|||
{
|
||||
tree type = TREE_TYPE (var);
|
||||
const char *msg;
|
||||
void **slot;
|
||||
tree_node **slot;
|
||||
|
||||
if (!AGGREGATE_TYPE_P (type))
|
||||
{
|
||||
|
@ -1728,8 +1754,8 @@ maybe_add_sra_candidate (tree var)
|
|||
}
|
||||
|
||||
bitmap_set_bit (candidate_bitmap, DECL_UID (var));
|
||||
slot = htab_find_slot_with_hash (candidates, var, DECL_UID (var), INSERT);
|
||||
*slot = (void *) var;
|
||||
slot = candidates.find_slot_with_hash (var, DECL_UID (var), INSERT);
|
||||
*slot = var;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
|
@ -3587,7 +3613,7 @@ find_param_candidates (void)
|
|||
parm = DECL_CHAIN (parm))
|
||||
{
|
||||
tree type = TREE_TYPE (parm);
|
||||
void **slot;
|
||||
tree_node **slot;
|
||||
|
||||
count++;
|
||||
|
||||
|
@ -3626,9 +3652,8 @@ find_param_candidates (void)
|
|||
continue;
|
||||
|
||||
bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
|
||||
slot = htab_find_slot_with_hash (candidates, parm,
|
||||
DECL_UID (parm), INSERT);
|
||||
*slot = (void *) parm;
|
||||
slot = candidates.find_slot_with_hash (parm, DECL_UID (parm), INSERT);
|
||||
*slot = parm;
|
||||
|
||||
ret = true;
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
|
|
|
@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "flags.h"
|
||||
|
@ -101,15 +102,6 @@ struct edge_info
|
|||
vec<cond_equivalence> cond_equivalences;
|
||||
};
|
||||
|
||||
/* Hash table with expressions made available during the renaming process.
|
||||
When an assignment of the form X_i = EXPR is found, the statement is
|
||||
stored in this table. If the same expression EXPR is later found on the
|
||||
RHS of another statement, it is replaced with X_i (thus performing
|
||||
global redundancy elimination). Similarly as we pass through conditionals
|
||||
we record the conditional itself as having either a true or false value
|
||||
in this table. */
|
||||
static htab_t avail_exprs;
|
||||
|
||||
/* Stack of available expressions in AVAIL_EXPRs. Each block pushes any
|
||||
expressions it enters into the hash table along with a marker entry
|
||||
(null). When we finish processing the block, we pop off entries and
|
||||
|
@ -140,6 +132,81 @@ struct expr_hash_elt
|
|||
struct expr_hash_elt *stamp;
|
||||
};
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
static bool hashable_expr_equal_p (const struct hashable_expr *,
|
||||
const struct hashable_expr *);
|
||||
static void free_expr_hash_elt (void *);
|
||||
|
||||
struct expr_elt_hasher
|
||||
{
|
||||
typedef expr_hash_elt value_type;
|
||||
typedef expr_hash_elt compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
expr_elt_hasher::hash (const value_type *p)
|
||||
{
|
||||
return p->hash;
|
||||
}
|
||||
|
||||
inline bool
|
||||
expr_elt_hasher::equal (const value_type *p1, const compare_type *p2)
|
||||
{
|
||||
gimple stmt1 = p1->stmt;
|
||||
const struct hashable_expr *expr1 = &p1->expr;
|
||||
const struct expr_hash_elt *stamp1 = p1->stamp;
|
||||
gimple stmt2 = p2->stmt;
|
||||
const struct hashable_expr *expr2 = &p2->expr;
|
||||
const struct expr_hash_elt *stamp2 = p2->stamp;
|
||||
|
||||
/* This case should apply only when removing entries from the table. */
|
||||
if (stamp1 == stamp2)
|
||||
return true;
|
||||
|
||||
/* FIXME tuples:
|
||||
We add stmts to a hash table and them modify them. To detect the case
|
||||
that we modify a stmt and then search for it, we assume that the hash
|
||||
is always modified by that change.
|
||||
We have to fully check why this doesn't happen on trunk or rewrite
|
||||
this in a more reliable (and easier to understand) way. */
|
||||
if (((const struct expr_hash_elt *)p1)->hash
|
||||
!= ((const struct expr_hash_elt *)p2)->hash)
|
||||
return false;
|
||||
|
||||
/* In case of a collision, both RHS have to be identical and have the
|
||||
same VUSE operands. */
|
||||
if (hashable_expr_equal_p (expr1, expr2)
|
||||
&& types_compatible_p (expr1->type, expr2->type))
|
||||
{
|
||||
/* Note that STMT1 and/or STMT2 may be NULL. */
|
||||
return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE)
|
||||
== (stmt2 ? gimple_vuse (stmt2) : NULL_TREE));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Delete an expr_hash_elt and reclaim its storage. */
|
||||
|
||||
inline void
|
||||
expr_elt_hasher::remove (value_type *element)
|
||||
{
|
||||
free_expr_hash_elt (element);
|
||||
}
|
||||
|
||||
/* Hash table with expressions made available during the renaming process.
|
||||
When an assignment of the form X_i = EXPR is found, the statement is
|
||||
stored in this table. If the same expression EXPR is later found on the
|
||||
RHS of another statement, it is replaced with X_i (thus performing
|
||||
global redundancy elimination). Similarly as we pass through conditionals
|
||||
we record the conditional itself as having either a true or false value
|
||||
in this table. */
|
||||
static hash_table <expr_elt_hasher> avail_exprs;
|
||||
|
||||
/* Stack of dest,src pairs that need to be restored during finalization.
|
||||
|
||||
A NULL entry is used to mark the end of pairs which need to be
|
||||
|
@ -169,9 +236,7 @@ static struct opt_stats_d opt_stats;
|
|||
static void optimize_stmt (basic_block, gimple_stmt_iterator);
|
||||
static tree lookup_avail_expr (gimple, bool);
|
||||
static hashval_t avail_expr_hash (const void *);
|
||||
static hashval_t real_avail_expr_hash (const void *);
|
||||
static int avail_expr_eq (const void *, const void *);
|
||||
static void htab_statistics (FILE *, htab_t);
|
||||
static void htab_statistics (FILE *, hash_table <expr_elt_hasher>);
|
||||
static void record_cond (cond_equivalence *);
|
||||
static void record_const_or_copy (tree, tree);
|
||||
static void record_equality (tree, tree);
|
||||
|
@ -722,7 +787,7 @@ tree_ssa_dominator_optimize (void)
|
|||
memset (&opt_stats, 0, sizeof (opt_stats));
|
||||
|
||||
/* Create our hash tables. */
|
||||
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free_expr_hash_elt);
|
||||
avail_exprs.create (1024);
|
||||
avail_exprs_stack.create (20);
|
||||
const_and_copies_stack.create (20);
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
|
@ -830,7 +895,7 @@ tree_ssa_dominator_optimize (void)
|
|||
loop_optimizer_finalize ();
|
||||
|
||||
/* Delete our main hashtable. */
|
||||
htab_delete (avail_exprs);
|
||||
avail_exprs.dispose ();
|
||||
|
||||
/* And finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
|
@ -935,7 +1000,7 @@ remove_local_expressions_from_table (void)
|
|||
while (avail_exprs_stack.length () > 0)
|
||||
{
|
||||
expr_hash_elt_t victim = avail_exprs_stack.pop ();
|
||||
void **slot;
|
||||
expr_hash_elt **slot;
|
||||
|
||||
if (victim == NULL)
|
||||
break;
|
||||
|
@ -949,10 +1014,9 @@ remove_local_expressions_from_table (void)
|
|||
print_expr_hash_elt (dump_file, victim);
|
||||
}
|
||||
|
||||
slot = htab_find_slot_with_hash (avail_exprs,
|
||||
victim, victim->hash, NO_INSERT);
|
||||
gcc_assert (slot && *slot == (void *) victim);
|
||||
htab_clear_slot (avail_exprs, slot);
|
||||
slot = avail_exprs.find_slot_with_hash (victim, victim->hash, NO_INSERT);
|
||||
gcc_assert (slot && *slot == victim);
|
||||
avail_exprs.clear_slot (slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1203,12 +1267,12 @@ debug_dominator_optimization_stats (void)
|
|||
/* Dump statistics for the hash table HTAB. */
|
||||
|
||||
static void
|
||||
htab_statistics (FILE *file, htab_t htab)
|
||||
htab_statistics (FILE *file, hash_table <expr_elt_hasher> htab)
|
||||
{
|
||||
fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
|
||||
(long) htab_size (htab),
|
||||
(long) htab_elements (htab),
|
||||
htab_collisions (htab));
|
||||
(long) htab.size (),
|
||||
(long) htab.elements (),
|
||||
htab.collisions ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1220,15 +1284,14 @@ static void
|
|||
record_cond (cond_equivalence *p)
|
||||
{
|
||||
struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
|
||||
void **slot;
|
||||
expr_hash_elt **slot;
|
||||
|
||||
initialize_hash_element_from_expr (&p->cond, p->value, element);
|
||||
|
||||
slot = htab_find_slot_with_hash (avail_exprs, (void *)element,
|
||||
element->hash, INSERT);
|
||||
slot = avail_exprs.find_slot_with_hash (element, element->hash, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
*slot = (void *) element;
|
||||
*slot = element;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
|
@ -2404,7 +2467,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si)
|
|||
static tree
|
||||
lookup_avail_expr (gimple stmt, bool insert)
|
||||
{
|
||||
void **slot;
|
||||
expr_hash_elt **slot;
|
||||
tree lhs;
|
||||
tree temp;
|
||||
struct expr_hash_elt element;
|
||||
|
@ -2432,8 +2495,8 @@ lookup_avail_expr (gimple stmt, bool insert)
|
|||
return NULL_TREE;
|
||||
|
||||
/* Finally try to find the expression in the main expression hash table. */
|
||||
slot = htab_find_slot_with_hash (avail_exprs, &element, element.hash,
|
||||
(insert ? INSERT : NO_INSERT));
|
||||
slot = avail_exprs.find_slot_with_hash (&element, element.hash,
|
||||
(insert ? INSERT : NO_INSERT));
|
||||
if (slot == NULL)
|
||||
{
|
||||
free_expr_hash_elt_contents (&element);
|
||||
|
@ -2444,7 +2507,7 @@ lookup_avail_expr (gimple stmt, bool insert)
|
|||
struct expr_hash_elt *element2 = XNEW (struct expr_hash_elt);
|
||||
*element2 = element;
|
||||
element2->stamp = element2;
|
||||
*slot = (void *) element2;
|
||||
*slot = element2;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
|
@ -2511,49 +2574,6 @@ avail_expr_hash (const void *p)
|
|||
return val;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
real_avail_expr_hash (const void *p)
|
||||
{
|
||||
return ((const struct expr_hash_elt *)p)->hash;
|
||||
}
|
||||
|
||||
static int
|
||||
avail_expr_eq (const void *p1, const void *p2)
|
||||
{
|
||||
gimple stmt1 = ((const struct expr_hash_elt *)p1)->stmt;
|
||||
const struct hashable_expr *expr1 = &((const struct expr_hash_elt *)p1)->expr;
|
||||
const struct expr_hash_elt *stamp1 = ((const struct expr_hash_elt *)p1)->stamp;
|
||||
gimple stmt2 = ((const struct expr_hash_elt *)p2)->stmt;
|
||||
const struct hashable_expr *expr2 = &((const struct expr_hash_elt *)p2)->expr;
|
||||
const struct expr_hash_elt *stamp2 = ((const struct expr_hash_elt *)p2)->stamp;
|
||||
|
||||
/* This case should apply only when removing entries from the table. */
|
||||
if (stamp1 == stamp2)
|
||||
return true;
|
||||
|
||||
/* FIXME tuples:
|
||||
We add stmts to a hash table and them modify them. To detect the case
|
||||
that we modify a stmt and then search for it, we assume that the hash
|
||||
is always modified by that change.
|
||||
We have to fully check why this doesn't happen on trunk or rewrite
|
||||
this in a more reliable (and easier to understand) way. */
|
||||
if (((const struct expr_hash_elt *)p1)->hash
|
||||
!= ((const struct expr_hash_elt *)p2)->hash)
|
||||
return false;
|
||||
|
||||
/* In case of a collision, both RHS have to be identical and have the
|
||||
same VUSE operands. */
|
||||
if (hashable_expr_equal_p (expr1, expr2)
|
||||
&& types_compatible_p (expr1->type, expr2->type))
|
||||
{
|
||||
/* Note that STMT1 and/or STMT2 may be NULL. */
|
||||
return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE)
|
||||
== (stmt2 ? gimple_vuse (stmt2) : NULL_TREE));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* PHI-ONLY copy and constant propagation. This pass is meant to clean
|
||||
up degenerate PHIs created by or exposed by jump threading. */
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "gimple-pretty-print.h"
|
||||
|
@ -53,6 +54,29 @@ static void verify_live_on_entry (tree_live_info_p);
|
|||
ssa_name or variable, and vice versa. */
|
||||
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct tree_int_map_hasher : typed_noop_remove <tree_int_map>
|
||||
{
|
||||
typedef tree_int_map value_type;
|
||||
typedef tree_int_map compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
tree_int_map_hasher::hash (const value_type *v)
|
||||
{
|
||||
return tree_map_base_hash (v);
|
||||
}
|
||||
|
||||
inline bool
|
||||
tree_int_map_hasher::equal (const value_type *v, const compare_type *c)
|
||||
{
|
||||
return tree_int_map_eq (v, c);
|
||||
}
|
||||
|
||||
|
||||
/* This routine will initialize the basevar fields of MAP. */
|
||||
|
||||
static void
|
||||
|
@ -60,12 +84,11 @@ var_map_base_init (var_map map)
|
|||
{
|
||||
int x, num_part;
|
||||
tree var;
|
||||
htab_t tree_to_index;
|
||||
hash_table <tree_int_map_hasher> tree_to_index;
|
||||
struct tree_int_map *m, *mapstorage;
|
||||
|
||||
num_part = num_var_partitions (map);
|
||||
tree_to_index = htab_create (num_part, tree_map_base_hash,
|
||||
tree_int_map_eq, NULL);
|
||||
tree_to_index.create (num_part);
|
||||
/* We can have at most num_part entries in the hash tables, so it's
|
||||
enough to allocate so many map elements once, saving some malloc
|
||||
calls. */
|
||||
|
@ -91,8 +114,7 @@ var_map_base_init (var_map map)
|
|||
underlying decl. */
|
||||
m->base.from = TREE_TYPE (var);
|
||||
/* If base variable hasn't been seen, set it up. */
|
||||
slot = (struct tree_int_map **) htab_find_slot (tree_to_index,
|
||||
m, INSERT);
|
||||
slot = tree_to_index.find_slot (m, INSERT);
|
||||
if (!*slot)
|
||||
{
|
||||
baseindex = m - mapstorage;
|
||||
|
@ -108,7 +130,7 @@ var_map_base_init (var_map map)
|
|||
map->num_basevars = m - mapstorage;
|
||||
|
||||
free (mapstorage);
|
||||
htab_delete (tree_to_index);
|
||||
tree_to_index. dispose ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "ggc.h"
|
||||
#include "insn-config.h"
|
||||
#include "pointer-set.h"
|
||||
#include "hashtab.h"
|
||||
#include "hash-table.h"
|
||||
#include "tree-chrec.h"
|
||||
#include "tree-scalar-evolution.h"
|
||||
#include "cfgloop.h"
|
||||
|
@ -236,6 +236,33 @@ typedef struct iv_use *iv_use_p;
|
|||
|
||||
typedef struct iv_cand *iv_cand_p;
|
||||
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct iv_inv_expr_hasher : typed_free_remove <iv_inv_expr_ent>
|
||||
{
|
||||
typedef iv_inv_expr_ent value_type;
|
||||
typedef iv_inv_expr_ent compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hash function for loop invariant expressions. */
|
||||
|
||||
inline hashval_t
|
||||
iv_inv_expr_hasher::hash (const value_type *expr)
|
||||
{
|
||||
return expr->hash;
|
||||
}
|
||||
|
||||
/* Hash table equality function for expressions. */
|
||||
|
||||
inline bool
|
||||
iv_inv_expr_hasher::equal (const value_type *expr1, const compare_type *expr2)
|
||||
{
|
||||
return expr1->hash == expr2->hash
|
||||
&& operand_equal_p (expr1->expr, expr2->expr, 0);
|
||||
}
|
||||
|
||||
struct ivopts_data
|
||||
{
|
||||
/* The currently optimized loop. */
|
||||
|
@ -255,7 +282,7 @@ struct ivopts_data
|
|||
|
||||
/* The hashtable of loop invariant expressions created
|
||||
by ivopt. */
|
||||
htab_t inv_expr_tab;
|
||||
hash_table <iv_inv_expr_hasher> inv_expr_tab;
|
||||
|
||||
/* Loop invariant expression id. */
|
||||
int inv_expr_id;
|
||||
|
@ -814,30 +841,6 @@ niter_for_single_dom_exit (struct ivopts_data *data)
|
|||
return niter_for_exit (data, exit);
|
||||
}
|
||||
|
||||
/* Hash table equality function for expressions. */
|
||||
|
||||
static int
|
||||
htab_inv_expr_eq (const void *ent1, const void *ent2)
|
||||
{
|
||||
const struct iv_inv_expr_ent *expr1 =
|
||||
(const struct iv_inv_expr_ent *)ent1;
|
||||
const struct iv_inv_expr_ent *expr2 =
|
||||
(const struct iv_inv_expr_ent *)ent2;
|
||||
|
||||
return expr1->hash == expr2->hash
|
||||
&& operand_equal_p (expr1->expr, expr2->expr, 0);
|
||||
}
|
||||
|
||||
/* Hash function for loop invariant expressions. */
|
||||
|
||||
static hashval_t
|
||||
htab_inv_expr_hash (const void *ent)
|
||||
{
|
||||
const struct iv_inv_expr_ent *expr =
|
||||
(const struct iv_inv_expr_ent *)ent;
|
||||
return expr->hash;
|
||||
}
|
||||
|
||||
/* Initializes data structures used by the iv optimization pass, stored
|
||||
in DATA. */
|
||||
|
||||
|
@ -852,8 +855,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
|
|||
data->niters = NULL;
|
||||
data->iv_uses.create (20);
|
||||
data->iv_candidates.create (20);
|
||||
data->inv_expr_tab = htab_create (10, htab_inv_expr_hash,
|
||||
htab_inv_expr_eq, free);
|
||||
data->inv_expr_tab.create (10);
|
||||
data->inv_expr_id = 0;
|
||||
decl_rtl_to_reset.create (20);
|
||||
}
|
||||
|
@ -3850,8 +3852,7 @@ get_expr_id (struct ivopts_data *data, tree expr)
|
|||
|
||||
ent.expr = expr;
|
||||
ent.hash = iterative_hash_expr (expr, 0);
|
||||
slot = (struct iv_inv_expr_ent **) htab_find_slot (data->inv_expr_tab,
|
||||
&ent, INSERT);
|
||||
slot = data->inv_expr_tab.find_slot (&ent, INSERT);
|
||||
if (*slot)
|
||||
return (*slot)->id;
|
||||
|
||||
|
@ -6653,7 +6654,7 @@ free_loop_data (struct ivopts_data *data)
|
|||
|
||||
decl_rtl_to_reset.truncate (0);
|
||||
|
||||
htab_empty (data->inv_expr_tab);
|
||||
data->inv_expr_tab.empty ();
|
||||
data->inv_expr_id = 0;
|
||||
}
|
||||
|
||||
|
@ -6671,7 +6672,7 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data)
|
|||
decl_rtl_to_reset.release ();
|
||||
data->iv_uses.release ();
|
||||
data->iv_candidates.release ();
|
||||
htab_delete (data->inv_expr_tab);
|
||||
data->inv_expr_tab.dispose ();
|
||||
}
|
||||
|
||||
/* Returns true if the loop body BODY includes any function calls. */
|
||||
|
|
|
@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tm.h"
|
||||
#include "ggc.h"
|
||||
#include "tree.h"
|
||||
|
@ -1239,8 +1240,15 @@ struct name_to_bb
|
|||
basic_block bb;
|
||||
};
|
||||
|
||||
/* The hash table for remembering what we've seen. */
|
||||
static htab_t seen_ssa_names;
|
||||
/* Hashtable helpers. */
|
||||
|
||||
struct ssa_names_hasher : typed_free_remove <name_to_bb>
|
||||
{
|
||||
typedef name_to_bb value_type;
|
||||
typedef name_to_bb compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Used for quick clearing of the hash-table when we see calls.
|
||||
Hash entries with phase < nt_call_phase are invalid. */
|
||||
|
@ -1250,27 +1258,28 @@ static unsigned int nt_call_phase;
|
|||
static struct pointer_set_t *nontrap_set;
|
||||
|
||||
/* The hash function. */
|
||||
static hashval_t
|
||||
name_to_bb_hash (const void *p)
|
||||
|
||||
inline hashval_t
|
||||
ssa_names_hasher::hash (const value_type *n)
|
||||
{
|
||||
const struct name_to_bb *n = (const struct name_to_bb *) p;
|
||||
return n->ssa_name_ver ^ (((hashval_t) n->store) << 31)
|
||||
^ (n->offset << 6) ^ (n->size << 3);
|
||||
}
|
||||
|
||||
/* The equality function of *P1 and *P2. */
|
||||
static int
|
||||
name_to_bb_eq (const void *p1, const void *p2)
|
||||
{
|
||||
const struct name_to_bb *n1 = (const struct name_to_bb *)p1;
|
||||
const struct name_to_bb *n2 = (const struct name_to_bb *)p2;
|
||||
|
||||
inline bool
|
||||
ssa_names_hasher::equal (const value_type *n1, const compare_type *n2)
|
||||
{
|
||||
return n1->ssa_name_ver == n2->ssa_name_ver
|
||||
&& n1->store == n2->store
|
||||
&& n1->offset == n2->offset
|
||||
&& n1->size == n2->size;
|
||||
}
|
||||
|
||||
/* The hash table for remembering what we've seen. */
|
||||
static hash_table <ssa_names_hasher> seen_ssa_names;
|
||||
|
||||
/* We see the expression EXP in basic block BB. If it's an interesting
|
||||
expression (an MEM_REF through an SSA_NAME) possibly insert the
|
||||
expression into the set NONTRAP or the hash table of seen expressions.
|
||||
|
@ -1289,7 +1298,7 @@ add_or_mark_expr (basic_block bb, tree exp,
|
|||
{
|
||||
tree name = TREE_OPERAND (exp, 0);
|
||||
struct name_to_bb map;
|
||||
void **slot;
|
||||
name_to_bb **slot;
|
||||
struct name_to_bb *n2bb;
|
||||
basic_block found_bb = 0;
|
||||
|
||||
|
@ -1302,8 +1311,8 @@ add_or_mark_expr (basic_block bb, tree exp,
|
|||
map.offset = tree_low_cst (TREE_OPERAND (exp, 1), 0);
|
||||
map.size = size;
|
||||
|
||||
slot = htab_find_slot (seen_ssa_names, &map, INSERT);
|
||||
n2bb = (struct name_to_bb *) *slot;
|
||||
slot = seen_ssa_names.find_slot (&map, INSERT);
|
||||
n2bb = *slot;
|
||||
if (n2bb && n2bb->phase >= nt_call_phase)
|
||||
found_bb = n2bb->bb;
|
||||
|
||||
|
@ -1413,8 +1422,7 @@ get_non_trapping (void)
|
|||
|
||||
nt_call_phase = 0;
|
||||
nontrap = pointer_set_create ();
|
||||
seen_ssa_names = htab_create (128, name_to_bb_hash, name_to_bb_eq,
|
||||
free);
|
||||
seen_ssa_names.create (128);
|
||||
/* We're going to do a dominator walk, so ensure that we have
|
||||
dominance information. */
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
@ -1431,7 +1439,7 @@ get_non_trapping (void)
|
|||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
htab_delete (seen_ssa_names);
|
||||
seen_ssa_names.dispose ();
|
||||
|
||||
clear_aux_for_blocks ();
|
||||
return nontrap;
|
||||
|
|
|
@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "hash-table.h"
|
||||
#include "tree-flow.h"
|
||||
#include "tree-pass.h"
|
||||
#include "domwalk.h"
|
||||
|
@ -111,9 +112,33 @@ struct decl_stridxlist_map
|
|||
struct stridxlist list;
|
||||
};
|
||||
|
||||
/* stridxlist hashtable helpers. */
|
||||
|
||||
struct stridxlist_hasher : typed_noop_remove <decl_stridxlist_map>
|
||||
{
|
||||
typedef decl_stridxlist_map value_type;
|
||||
typedef decl_stridxlist_map compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
};
|
||||
|
||||
/* Hash a from tree in a decl_stridxlist_map. */
|
||||
|
||||
inline hashval_t
|
||||
stridxlist_hasher::hash (const value_type *item)
|
||||
{
|
||||
return DECL_UID (item->base.from);
|
||||
}
|
||||
|
||||
inline bool
|
||||
stridxlist_hasher::equal (const value_type *v, const compare_type *c)
|
||||
{
|
||||
return tree_map_base_eq (&v->base, &c->base);
|
||||
}
|
||||
|
||||
/* Hash table for mapping decls to a chained list of offset -> idx
|
||||
mappings. */
|
||||
static htab_t decl_to_stridxlist_htab;
|
||||
static hash_table <stridxlist_hasher> decl_to_stridxlist_htab;
|
||||
|
||||
/* Obstack for struct stridxlist and struct decl_stridxlist_map. */
|
||||
static struct obstack stridx_obstack;
|
||||
|
@ -128,14 +153,6 @@ struct laststmt_struct
|
|||
int stridx;
|
||||
} laststmt;
|
||||
|
||||
/* Hash a from tree in a decl_stridxlist_map. */
|
||||
|
||||
static unsigned int
|
||||
decl_to_stridxlist_hash (const void *item)
|
||||
{
|
||||
return DECL_UID (((const struct decl_stridxlist_map *) item)->base.from);
|
||||
}
|
||||
|
||||
/* Helper function for get_stridx. */
|
||||
|
||||
static int
|
||||
|
@ -146,7 +163,7 @@ get_addr_stridx (tree exp)
|
|||
struct stridxlist *list;
|
||||
tree base;
|
||||
|
||||
if (decl_to_stridxlist_htab == NULL)
|
||||
if (!decl_to_stridxlist_htab.is_created ())
|
||||
return 0;
|
||||
|
||||
base = get_addr_base_and_unit_offset (exp, &off);
|
||||
|
@ -154,8 +171,7 @@ get_addr_stridx (tree exp)
|
|||
return 0;
|
||||
|
||||
ent.base.from = base;
|
||||
e = (struct decl_stridxlist_map *)
|
||||
htab_find_with_hash (decl_to_stridxlist_htab, &ent, DECL_UID (base));
|
||||
e = decl_to_stridxlist_htab.find_with_hash (&ent, DECL_UID (base));
|
||||
if (e == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -234,7 +250,7 @@ unshare_strinfo_vec (void)
|
|||
static int *
|
||||
addr_stridxptr (tree exp)
|
||||
{
|
||||
void **slot;
|
||||
decl_stridxlist_map **slot;
|
||||
struct decl_stridxlist_map ent;
|
||||
struct stridxlist *list;
|
||||
HOST_WIDE_INT off;
|
||||
|
@ -243,19 +259,18 @@ addr_stridxptr (tree exp)
|
|||
if (base == NULL_TREE || !DECL_P (base))
|
||||
return NULL;
|
||||
|
||||
if (decl_to_stridxlist_htab == NULL)
|
||||
if (!decl_to_stridxlist_htab.is_created ())
|
||||
{
|
||||
decl_to_stridxlist_htab
|
||||
= htab_create (64, decl_to_stridxlist_hash, tree_map_base_eq, NULL);
|
||||
decl_to_stridxlist_htab.create (64);
|
||||
gcc_obstack_init (&stridx_obstack);
|
||||
}
|
||||
ent.base.from = base;
|
||||
slot = htab_find_slot_with_hash (decl_to_stridxlist_htab, &ent,
|
||||
DECL_UID (base), INSERT);
|
||||
slot = decl_to_stridxlist_htab.find_slot_with_hash (&ent, DECL_UID (base),
|
||||
INSERT);
|
||||
if (*slot)
|
||||
{
|
||||
int i;
|
||||
list = &((struct decl_stridxlist_map *)*slot)->list;
|
||||
list = &(*slot)->list;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (list->offset == off)
|
||||
|
@ -273,7 +288,7 @@ addr_stridxptr (tree exp)
|
|||
struct decl_stridxlist_map *e
|
||||
= XOBNEW (&stridx_obstack, struct decl_stridxlist_map);
|
||||
e->base.from = base;
|
||||
*slot = (void *) e;
|
||||
*slot = e;
|
||||
list = &e->list;
|
||||
}
|
||||
list->next = NULL;
|
||||
|
@ -1985,11 +2000,10 @@ tree_ssa_strlen (void)
|
|||
|
||||
ssa_ver_to_stridx.release ();
|
||||
free_alloc_pool (strinfo_pool);
|
||||
if (decl_to_stridxlist_htab)
|
||||
if (decl_to_stridxlist_htab.is_created ())
|
||||
{
|
||||
obstack_free (&stridx_obstack, NULL);
|
||||
htab_delete (decl_to_stridxlist_htab);
|
||||
decl_to_stridxlist_htab = NULL;
|
||||
decl_to_stridxlist_htab.dispose ();
|
||||
}
|
||||
laststmt.stmt = NULL;
|
||||
laststmt.len = NULL_TREE;
|
||||
|
|
|
@ -265,11 +265,6 @@ associate_equivalences_with_edges (void)
|
|||
subtree rooted at the block where we record the equivalency. */
|
||||
static vec<tree> equiv_stack;
|
||||
|
||||
/* Global hash table implementing a mapping from invariant values
|
||||
to a list of SSA_NAMEs which have the same value. We might be
|
||||
able to reuse tree-vn for this code. */
|
||||
static htab_t equiv;
|
||||
|
||||
/* Main structure for recording equivalences into our hash table. */
|
||||
struct equiv_hash_elt
|
||||
{
|
||||
|
@ -280,53 +275,66 @@ struct equiv_hash_elt
|
|||
vec<tree> equivalences;
|
||||
};
|
||||
|
||||
static void uncprop_enter_block (struct dom_walk_data *, basic_block);
|
||||
static void uncprop_leave_block (struct dom_walk_data *, basic_block);
|
||||
static void uncprop_into_successor_phis (basic_block);
|
||||
/* Value to ssa name equivalence hashtable helpers. */
|
||||
|
||||
/* Hashing and equality routines for the hash table. */
|
||||
|
||||
static hashval_t
|
||||
equiv_hash (const void *p)
|
||||
struct val_ssa_equiv_hasher
|
||||
{
|
||||
tree const value = ((const struct equiv_hash_elt *)p)->value;
|
||||
typedef equiv_hash_elt value_type;
|
||||
typedef equiv_hash_elt compare_type;
|
||||
static inline hashval_t hash (const value_type *);
|
||||
static inline bool equal (const value_type *, const compare_type *);
|
||||
static inline void remove (value_type *);
|
||||
};
|
||||
|
||||
inline hashval_t
|
||||
val_ssa_equiv_hasher::hash (const value_type *p)
|
||||
{
|
||||
tree const value = p->value;
|
||||
return iterative_hash_expr (value, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
equiv_eq (const void *p1, const void *p2)
|
||||
inline bool
|
||||
val_ssa_equiv_hasher::equal (const value_type *p1, const compare_type *p2)
|
||||
{
|
||||
tree value1 = ((const struct equiv_hash_elt *)p1)->value;
|
||||
tree value2 = ((const struct equiv_hash_elt *)p2)->value;
|
||||
tree value1 = p1->value;
|
||||
tree value2 = p2->value;
|
||||
|
||||
return operand_equal_p (value1, value2, 0);
|
||||
}
|
||||
|
||||
/* Free an instance of equiv_hash_elt. */
|
||||
|
||||
static void
|
||||
equiv_free (void *p)
|
||||
inline void
|
||||
val_ssa_equiv_hasher::remove (value_type *elt)
|
||||
{
|
||||
struct equiv_hash_elt *elt = (struct equiv_hash_elt *) p;
|
||||
elt->equivalences.release ();
|
||||
free (elt);
|
||||
}
|
||||
|
||||
/* Global hash table implementing a mapping from invariant values
|
||||
to a list of SSA_NAMEs which have the same value. We might be
|
||||
able to reuse tree-vn for this code. */
|
||||
static hash_table <val_ssa_equiv_hasher> val_ssa_equiv;
|
||||
|
||||
static void uncprop_enter_block (struct dom_walk_data *, basic_block);
|
||||
static void uncprop_leave_block (struct dom_walk_data *, basic_block);
|
||||
static void uncprop_into_successor_phis (basic_block);
|
||||
|
||||
/* Remove the most recently recorded equivalency for VALUE. */
|
||||
|
||||
static void
|
||||
remove_equivalence (tree value)
|
||||
{
|
||||
struct equiv_hash_elt equiv_hash_elt, *equiv_hash_elt_p;
|
||||
void **slot;
|
||||
struct equiv_hash_elt an_equiv_elt, *an_equiv_elt_p;
|
||||
equiv_hash_elt **slot;
|
||||
|
||||
equiv_hash_elt.value = value;
|
||||
equiv_hash_elt.equivalences.create (0);
|
||||
an_equiv_elt.value = value;
|
||||
an_equiv_elt.equivalences.create (0);
|
||||
|
||||
slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
|
||||
slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT);
|
||||
|
||||
equiv_hash_elt_p = (struct equiv_hash_elt *) *slot;
|
||||
equiv_hash_elt_p->equivalences.pop ();
|
||||
an_equiv_elt_p = *slot;
|
||||
an_equiv_elt_p->equivalences.pop ();
|
||||
}
|
||||
|
||||
/* Record EQUIVALENCE = VALUE into our hash table. */
|
||||
|
@ -334,23 +342,23 @@ remove_equivalence (tree value)
|
|||
static void
|
||||
record_equiv (tree value, tree equivalence)
|
||||
{
|
||||
struct equiv_hash_elt *equiv_hash_elt;
|
||||
void **slot;
|
||||
equiv_hash_elt *an_equiv_elt_p;
|
||||
equiv_hash_elt **slot;
|
||||
|
||||
equiv_hash_elt = XNEW (struct equiv_hash_elt);
|
||||
equiv_hash_elt->value = value;
|
||||
equiv_hash_elt->equivalences.create (0);
|
||||
an_equiv_elt_p = XNEW (struct equiv_hash_elt);
|
||||
an_equiv_elt_p->value = value;
|
||||
an_equiv_elt_p->equivalences.create (0);
|
||||
|
||||
slot = htab_find_slot (equiv, equiv_hash_elt, INSERT);
|
||||
slot = val_ssa_equiv.find_slot (an_equiv_elt_p, INSERT);
|
||||
|
||||
if (*slot == NULL)
|
||||
*slot = (void *) equiv_hash_elt;
|
||||
*slot = an_equiv_elt_p;
|
||||
else
|
||||
free (equiv_hash_elt);
|
||||
free (an_equiv_elt_p);
|
||||
|
||||
equiv_hash_elt = (struct equiv_hash_elt *) *slot;
|
||||
an_equiv_elt_p = *slot;
|
||||
|
||||
equiv_hash_elt->equivalences.safe_push (equivalence);
|
||||
an_equiv_elt_p->equivalences.safe_push (equivalence);
|
||||
}
|
||||
|
||||
/* Main driver for un-cprop. */
|
||||
|
@ -364,7 +372,7 @@ tree_ssa_uncprop (void)
|
|||
associate_equivalences_with_edges ();
|
||||
|
||||
/* Create our global data structures. */
|
||||
equiv = htab_create (1024, equiv_hash, equiv_eq, equiv_free);
|
||||
val_ssa_equiv.create (1024);
|
||||
equiv_stack.create (2);
|
||||
|
||||
/* We're going to do a dominator walk, so ensure that we have
|
||||
|
@ -392,7 +400,7 @@ tree_ssa_uncprop (void)
|
|||
/* EQUIV_STACK should already be empty at this point, so we just
|
||||
need to empty elements out of the hash table, free EQUIV_STACK,
|
||||
and cleanup the AUX field on the edges. */
|
||||
htab_delete (equiv);
|
||||
val_ssa_equiv.dispose ();
|
||||
equiv_stack.release ();
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
|
@ -463,8 +471,8 @@ uncprop_into_successor_phis (basic_block bb)
|
|||
gimple phi = gsi_stmt (gsi);
|
||||
tree arg = PHI_ARG_DEF (phi, e->dest_idx);
|
||||
tree res = PHI_RESULT (phi);
|
||||
struct equiv_hash_elt equiv_hash_elt;
|
||||
void **slot;
|
||||
equiv_hash_elt an_equiv_elt;
|
||||
equiv_hash_elt **slot;
|
||||
|
||||
/* If the argument is not an invariant, and refers to the same
|
||||
underlying variable as the PHI result, then there's no
|
||||
|
@ -475,13 +483,13 @@ uncprop_into_successor_phis (basic_block bb)
|
|||
continue;
|
||||
|
||||
/* Lookup this argument's value in the hash table. */
|
||||
equiv_hash_elt.value = arg;
|
||||
equiv_hash_elt.equivalences.create (0);
|
||||
slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
|
||||
an_equiv_elt.value = arg;
|
||||
an_equiv_elt.equivalences.create (0);
|
||||
slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT);
|
||||
|
||||
if (slot)
|
||||
{
|
||||
struct equiv_hash_elt *elt = (struct equiv_hash_elt *) *slot;
|
||||
struct equiv_hash_elt *elt = *slot;
|
||||
int j;
|
||||
|
||||
/* Walk every equivalence with the same value. If we find
|
||||
|
|
|
@ -1046,42 +1046,6 @@ err:
|
|||
internal_error ("verify_ssa failed");
|
||||
}
|
||||
|
||||
/* Return true if the uid in both int tree maps are equal. */
|
||||
|
||||
int
|
||||
int_tree_map_eq (const void *va, const void *vb)
|
||||
{
|
||||
const struct int_tree_map *a = (const struct int_tree_map *) va;
|
||||
const struct int_tree_map *b = (const struct int_tree_map *) vb;
|
||||
return (a->uid == b->uid);
|
||||
}
|
||||
|
||||
/* Hash a UID in a int_tree_map. */
|
||||
|
||||
unsigned int
|
||||
int_tree_map_hash (const void *item)
|
||||
{
|
||||
return ((const struct int_tree_map *)item)->uid;
|
||||
}
|
||||
|
||||
/* Return true if the DECL_UID in both trees are equal. */
|
||||
|
||||
int
|
||||
uid_decl_map_eq (const void *va, const void *vb)
|
||||
{
|
||||
const_tree a = (const_tree) va;
|
||||
const_tree b = (const_tree) vb;
|
||||
return (a->decl_minimal.uid == b->decl_minimal.uid);
|
||||
}
|
||||
|
||||
/* Hash a tree in a uid_decl_map. */
|
||||
|
||||
unsigned int
|
||||
uid_decl_map_hash (const void *item)
|
||||
{
|
||||
return ((const_tree)item)->decl_minimal.uid;
|
||||
}
|
||||
|
||||
/* Return true if the DECL_UID in both trees are equal. */
|
||||
|
||||
static int
|
||||
|
|
Loading…
Reference in New Issue