===================================================================
@@ -178,36 +178,44 @@ struct reduction_info
operation. */
};
-/* Equality and hash functions for hashtab code. */
+/* Reduction info hashtable helpers. */
-static int
-reduction_info_eq (const void *aa, const void *bb)
+struct reduction_hasher : typed_free_remove <reduction_info>
{
- const struct reduction_info *a = (const struct reduction_info *) aa;
- const struct reduction_info *b = (const struct reduction_info *) bb;
+ typedef reduction_info value_type;
+ typedef reduction_info compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Equality and hash functions for hashtab code. */
+inline bool
+reduction_hasher::equal (const value_type *a, const compare_type *b)
+{
return (a->reduc_phi == b->reduc_phi);
}
-static hashval_t
-reduction_info_hash (const void *aa)
+inline hashval_t
+reduction_hasher::hash (const value_type *a)
{
- const struct reduction_info *a = (const struct reduction_info *) aa;
-
return a->reduc_version;
}
+typedef hash_table <reduction_hasher> reduction_info_table_type;
+
+
static struct reduction_info *
-reduction_phi (htab_t reduction_list, gimple phi)
+reduction_phi (reduction_info_table_type reduction_list, gimple phi)
{
struct reduction_info tmpred, *red;
- if (htab_elements (reduction_list) == 0 || phi == NULL)
+ if (reduction_list.elements () == 0 || phi == NULL)
return NULL;
tmpred.reduc_phi = phi;
tmpred.reduc_version = gimple_uid (phi);
- red = (struct reduction_info *) htab_find (reduction_list, &tmpred);
+ red = reduction_list.find (&tmpred);
return red;
}
@@ -222,25 +230,32 @@ struct name_to_copy_elt
value. */
};
-/* Equality and hash functions for hashtab code. */
+/* Name copies hashtable helpers. */
-static int
-name_to_copy_elt_eq (const void *aa, const void *bb)
+struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt>
{
- const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
- const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb;
+ typedef name_to_copy_elt value_type;
+ typedef name_to_copy_elt compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Equality and hash functions for hashtab code. */
+inline bool
+name_to_copy_hasher::equal (const value_type *a, const compare_type *b)
+{
return a->version == b->version;
}
-static hashval_t
-name_to_copy_elt_hash (const void *aa)
+inline hashval_t
+name_to_copy_hasher::hash (const value_type *a)
{
- const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
-
return (hashval_t) a->version;
}
+typedef hash_table <name_to_copy_hasher> name_to_copy_table_type;
+
/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
matrix. Rather than use floats, we simply keep a single DENOMINATOR that
represents the denominator for every element in the matrix. */
@@ -519,15 +534,14 @@ take_address_of (tree obj, tree type, ed
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. */
@@ -775,14 +789,14 @@ expr_invariant_in_region_p (edge entry,
duplicated, storing the copies in DECL_COPIES. */
static tree
-separate_decls_in_region_name (tree name, htab_t name_copies,
+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;
+ name_to_copy_elt **slot;
int_tree_map **dslot;
if (TREE_CODE (name) != SSA_NAME)
@@ -790,10 +804,10 @@ separate_decls_in_region_name (tree 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)
{
@@ -853,7 +867,7 @@ separate_decls_in_region_name (tree name
static void
separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
- htab_t name_copies,
+ name_to_copy_table_type name_copies,
int_tree_htab_type decl_copies)
{
use_operand_p use;
@@ -892,7 +906,8 @@ separate_decls_in_region_stmt (edge entr
replacement decls are stored in DECL_COPIES. */
static bool
-separate_decls_in_region_debug (gimple stmt, htab_t name_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;
@@ -900,7 +915,7 @@ separate_decls_in_region_debug (gimple s
tree var, name;
struct int_tree_map ielt;
struct name_to_copy_elt elt;
- void **slot;
+ name_to_copy_elt **slot;
int_tree_map **dslot;
if (gimple_debug_bind_p (stmt))
@@ -928,7 +943,7 @@ separate_decls_in_region_debug (gimple s
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)
{
Change tree-parloops.c reduction and name_to_copy hash tables from htab_t to hash_table. 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. Update dependent types and calls. Tested on x86_64. Okay for branch? gimple_debug_bind_reset_value (stmt); @@ -936,7 +951,7 @@ separate_decls_in_region_debug (gimple s break; } - SET_USE (use, ((struct name_to_copy_elt *) *slot)->new_name); + SET_USE (use, (*slot)->new_name); } return false; @@ -945,12 +960,11 @@ separate_decls_in_region_debug (gimple s /* 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)); @@ -965,11 +979,10 @@ add_field_for_reduction (void **slot, vo /* 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), @@ -988,11 +1001,10 @@ add_field_for_name (void **slot, void *d 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; @@ -1038,11 +1050,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; @@ -1091,23 +1102,24 @@ create_call_for_reduction_1 (void **slot 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)); @@ -1141,7 +1153,7 @@ create_loads_for_reductions (void **slot 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; @@ -1155,7 +1167,8 @@ create_final_loads_for_reduction (htab_t 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); } @@ -1165,11 +1178,10 @@ create_final_loads_for_reduction (htab_t 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; @@ -1187,11 +1199,11 @@ create_stores_for_reduction (void **slot 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; @@ -1248,15 +1260,16 @@ create_loads_and_stores_for_name (void * 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); + name_to_copy_table_type name_copies; + name_copies.create (10); int_tree_htab_type decl_copies; decl_copies.create (10); unsigned i; @@ -1324,7 +1337,7 @@ separate_decls_in_region (edge entry, ed 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). */ @@ -1340,12 +1353,11 @@ separate_decls_in_region (edge entry, ed 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); @@ -1359,15 +1371,17 @@ separate_decls_in_region (edge entry, ed 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; @@ -1376,7 +1390,7 @@ separate_decls_in_region (edge entry, ed } decl_copies.dispose (); - htab_delete (name_copies); + name_copies.dispose (); } /* Bitmap containing uids of functions created by parallelization. We cannot @@ -1465,7 +1479,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; @@ -1534,7 +1550,7 @@ transform_to_exit_first_loop (struct loo 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; @@ -1712,7 +1728,7 @@ create_parallel_loop (struct loop *loop, 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; @@ -1838,8 +1854,8 @@ gen_parallel_loop (struct loop *loop, ht 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)); @@ -1859,7 +1875,7 @@ gen_parallel_loop (struct loop *loop, ht 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 (); @@ -1906,9 +1922,10 @@ loop_has_vector_phi_nodes (struct loop * 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); @@ -1927,16 +1944,16 @@ build_new_reduction (htab_t reduction_li 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; } @@ -1944,7 +1961,7 @@ set_reduc_phi_uids (void **slot, void *d /* 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; @@ -1976,7 +1993,7 @@ gather_scalar_reductions (loop_p loop, h /* 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. */ @@ -2005,7 +2022,8 @@ try_get_loop_niter (loop_p loop, struct 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; @@ -2036,7 +2054,7 @@ try_create_reduction_list (loop_p loop, 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, @@ -2110,7 +2128,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; @@ -2122,13 +2140,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); @@ -2208,7 +2225,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