diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index ac1674d5486..75acc342c5a 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -375,13 +375,40 @@ struct component struct component *next; }; -/* Bitmap of ssa names defined by looparound phi nodes covered by chains. */ +typedef hash_map tree_expand_map_t; +static void release_chains (vec chains); -static bitmap looparound_phis; +/* Class for predictive commoning data structure for one LOOP. */ +class loop_pcom_info +{ +public: + loop_pcom_info (loop_p l) + : loop (l), datarefs (vNULL), dependences (vNULL), chains (vNULL), + cache (NULL) + { + dependences.create (10); + datarefs.create (10); + } -/* Cache used by tree_to_aff_combination_expand. */ + ~loop_pcom_info () + { + free_data_refs (datarefs); + free_dependence_relations (dependences); + release_chains (chains); + free_affine_expand_cache (&cache); + } -static hash_map *name_expansions; + /* The pointer to the given loop. */ + loop_p loop; + /* All data references. */ + vec datarefs; + /* All data dependences. */ + vec dependences; + /* All chains. */ + vec chains; + /* Cache used by tree_to_aff_combination_expand. */ + tree_expand_map_t *cache; +}; /* Dumps data reference REF to FILE. */ @@ -673,13 +700,13 @@ suitable_reference_p (struct data_reference *a, enum ref_step_type *ref_step) /* Stores DR_OFFSET (DR) + DR_INIT (DR) to OFFSET. */ static void -aff_combination_dr_offset (struct data_reference *dr, aff_tree *offset) +aff_combination_dr_offset (struct data_reference *dr, aff_tree *offset, + tree_expand_map_t **cache_ptr) { tree type = TREE_TYPE (DR_OFFSET (dr)); aff_tree delta; - tree_to_aff_combination_expand (DR_OFFSET (dr), type, offset, - &name_expansions); + tree_to_aff_combination_expand (DR_OFFSET (dr), type, offset, cache_ptr); aff_combination_const (&delta, type, wi::to_poly_widest (DR_INIT (dr))); aff_combination_add (offset, &delta); } @@ -692,7 +719,7 @@ aff_combination_dr_offset (struct data_reference *dr, aff_tree *offset) static bool determine_offset (struct data_reference *a, struct data_reference *b, - poly_widest_int *off) + poly_widest_int *off, tree_expand_map_t **cache_ptr) { aff_tree diff, baseb, step; tree typea, typeb; @@ -720,13 +747,13 @@ determine_offset (struct data_reference *a, struct data_reference *b, /* Compare the offsets of the addresses, and check whether the difference is a multiple of step. */ - aff_combination_dr_offset (a, &diff); - aff_combination_dr_offset (b, &baseb); + aff_combination_dr_offset (a, &diff, cache_ptr); + aff_combination_dr_offset (b, &baseb, cache_ptr); aff_combination_scale (&baseb, -1); aff_combination_add (&diff, &baseb); - tree_to_aff_combination_expand (DR_STEP (a), TREE_TYPE (DR_STEP (a)), - &step, &name_expansions); + tree_to_aff_combination_expand (DR_STEP (a), TREE_TYPE (DR_STEP (a)), &step, + cache_ptr); return aff_combination_constant_multiple_p (&diff, &step, off); } @@ -750,9 +777,9 @@ last_always_executed_block (class loop *loop) /* Splits dependence graph on DATAREFS described by DEPENDS to components. */ static struct component * -split_data_refs_to_components (class loop *loop, - vec datarefs, - vec depends) +split_data_refs_to_components (class loop *loop, vec datarefs, + vec depends, + tree_expand_map_t **cache_ptr) { unsigned i, n = datarefs.length (); unsigned ca, ia, ib, bad; @@ -827,7 +854,7 @@ split_data_refs_to_components (class loop *loop, if (DR_IS_READ (dra) && DR_IS_READ (drb)) { if (ia == bad || ib == bad - || !determine_offset (dra, drb, &dummy_off)) + || !determine_offset (dra, drb, &dummy_off, cache_ptr)) continue; } /* If A is read and B write or vice versa and there is unsuitable @@ -842,7 +869,7 @@ split_data_refs_to_components (class loop *loop, bitmap_set_bit (no_store_store_comps, ib); continue; } - else if (!determine_offset (dra, drb, &dummy_off)) + else if (!determine_offset (dra, drb, &dummy_off, cache_ptr)) { bitmap_set_bit (no_store_store_comps, ib); merge_comps (comp_father, comp_size, bad, ia); @@ -856,7 +883,7 @@ split_data_refs_to_components (class loop *loop, bitmap_set_bit (no_store_store_comps, ia); continue; } - else if (!determine_offset (dra, drb, &dummy_off)) + else if (!determine_offset (dra, drb, &dummy_off, cache_ptr)) { bitmap_set_bit (no_store_store_comps, ia); merge_comps (comp_father, comp_size, bad, ib); @@ -865,7 +892,7 @@ split_data_refs_to_components (class loop *loop, } else if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb) && ia != bad && ib != bad - && !determine_offset (dra, drb, &dummy_off)) + && !determine_offset (dra, drb, &dummy_off, cache_ptr)) { merge_comps (comp_father, comp_size, bad, ia); merge_comps (comp_father, comp_size, bad, ib); @@ -949,7 +976,7 @@ end: loop. */ static bool -suitable_component_p (class loop *loop, struct component *comp) +suitable_component_p (class loop *loop, struct component *comp, tree_expand_map_t **cache_ptr) { unsigned i; dref a, first; @@ -980,7 +1007,7 @@ suitable_component_p (class loop *loop, struct component *comp) /* Polynomial offsets are no use, since we need to know the gap between iteration numbers at compile time. */ poly_widest_int offset; - if (!determine_offset (first->ref, a->ref, &offset) + if (!determine_offset (first->ref, a->ref, &offset, cache_ptr) || !offset.is_constant (&a->offset)) return false; @@ -1005,14 +1032,15 @@ suitable_component_p (class loop *loop, struct component *comp) the beginning of this file. LOOP is the current loop. */ static struct component * -filter_suitable_components (class loop *loop, struct component *comps) +filter_suitable_components (class loop *loop, struct component *comps, + tree_expand_map_t **cache_ptr) { struct component **comp, *act; for (comp = &comps; *comp; ) { act = *comp; - if (suitable_component_p (loop, act)) + if (suitable_component_p (loop, act, cache_ptr)) comp = &act->next; else { @@ -1206,8 +1234,8 @@ name_for_ref (dref ref) iterations of the innermost enclosing loop). */ static bool -valid_initializer_p (struct data_reference *ref, - unsigned distance, struct data_reference *root) +valid_initializer_p (struct data_reference *ref, unsigned distance, + struct data_reference *root, tree_expand_map_t **cache_ptr) { aff_tree diff, base, step; poly_widest_int off; @@ -1228,13 +1256,13 @@ valid_initializer_p (struct data_reference *ref, /* Verify that this index of REF is equal to the root's index at -DISTANCE-th iteration. */ - aff_combination_dr_offset (root, &diff); - aff_combination_dr_offset (ref, &base); + aff_combination_dr_offset (root, &diff, cache_ptr); + aff_combination_dr_offset (ref, &base, cache_ptr); aff_combination_scale (&base, -1); aff_combination_add (&diff, &base); tree_to_aff_combination_expand (DR_STEP (root), TREE_TYPE (DR_STEP (root)), - &step, &name_expansions); + &step, cache_ptr); if (!aff_combination_constant_multiple_p (&diff, &step, &off)) return false; @@ -1250,7 +1278,8 @@ valid_initializer_p (struct data_reference *ref, is the root of the current chain. */ static gphi * -find_looparound_phi (class loop *loop, dref ref, dref root) +find_looparound_phi (class loop *loop, dref ref, dref root, + tree_expand_map_t **cache_ptr) { tree name, init, init_ref; gphi *phi = NULL; @@ -1303,7 +1332,7 @@ find_looparound_phi (class loop *loop, dref ref, dref root) init_stmt)) return NULL; - if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref)) + if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref, cache_ptr)) return NULL; return phi; @@ -1339,7 +1368,8 @@ insert_looparound_copy (chain_p chain, dref ref, gphi *phi) (also, it may allow us to combine chains together). */ static void -add_looparound_copies (class loop *loop, chain_p chain) +add_looparound_copies (class loop *loop, chain_p chain, bitmap looparound_phis, + tree_expand_map_t **cache_ptr) { unsigned i; dref ref, root = get_chain_root (chain); @@ -1350,7 +1380,7 @@ add_looparound_copies (class loop *loop, chain_p chain) FOR_EACH_VEC_ELT (chain->refs, i, ref) { - phi = find_looparound_phi (loop, ref, root); + phi = find_looparound_phi (loop, ref, root, cache_ptr); if (!phi) continue; @@ -1364,9 +1394,9 @@ add_looparound_copies (class loop *loop, chain_p chain) loop. */ static void -determine_roots_comp (class loop *loop, - struct component *comp, - vec *chains) +determine_roots_comp (class loop *loop, struct component *comp, + vec *chains, bitmap looparound_phis, + tree_expand_map_t **cache_ptr) { unsigned i; dref a; @@ -1422,7 +1452,7 @@ determine_roots_comp (class loop *loop, { if (nontrivial_chain_p (chain)) { - add_looparound_copies (loop, chain); + add_looparound_copies (loop, chain, looparound_phis, cache_ptr); chains->safe_push (chain); } else @@ -1443,7 +1473,7 @@ determine_roots_comp (class loop *loop, if (nontrivial_chain_p (chain)) { - add_looparound_copies (loop, chain); + add_looparound_copies (loop, chain, looparound_phis, cache_ptr); chains->safe_push (chain); } else @@ -1454,13 +1484,14 @@ determine_roots_comp (class loop *loop, separates the references to CHAINS. LOOP is the current loop. */ static void -determine_roots (class loop *loop, - struct component *comps, vec *chains) +determine_roots (class loop *loop, struct component *comps, + vec *chains, bitmap looparound_phis, + tree_expand_map_t **cache_ptr) { struct component *comp; for (comp = comps; comp; comp = comp->next) - determine_roots_comp (loop, comp, chains); + determine_roots_comp (loop, comp, chains, looparound_phis, cache_ptr); } /* Replace the reference in statement STMT with temporary variable @@ -2028,7 +2059,7 @@ execute_load_motion (class loop *loop, chain_p chain, bitmap tmp_vars) such statement, or more statements, NULL is returned. */ static gimple * -single_nonlooparound_use (tree name) +single_nonlooparound_use (tree name, bitmap looparound_phis) { use_operand_p use; imm_use_iterator it; @@ -2063,7 +2094,7 @@ single_nonlooparound_use (tree name) used. */ static void -remove_stmt (gimple *stmt) +remove_stmt (gimple *stmt, bitmap looparound_phis) { tree name; gimple *next; @@ -2072,7 +2103,7 @@ remove_stmt (gimple *stmt) if (gimple_code (stmt) == GIMPLE_PHI) { name = PHI_RESULT (stmt); - next = single_nonlooparound_use (name); + next = single_nonlooparound_use (name, looparound_phis); reset_debug_uses (stmt); psi = gsi_for_stmt (stmt); remove_phi_node (&psi, true); @@ -2094,7 +2125,7 @@ remove_stmt (gimple *stmt) name = gimple_assign_lhs (stmt); if (TREE_CODE (name) == SSA_NAME) { - next = single_nonlooparound_use (name); + next = single_nonlooparound_use (name, looparound_phis); reset_debug_uses (stmt); } else @@ -2122,7 +2153,7 @@ remove_stmt (gimple *stmt) static void execute_pred_commoning_chain (class loop *loop, chain_p chain, - bitmap tmp_vars) + bitmap tmp_vars, bitmap looparound_phis) { unsigned i; dref a; @@ -2172,7 +2203,7 @@ execute_pred_commoning_chain (class loop *loop, chain_p chain, if (last_store_p) last_store_p = false; else - remove_stmt (a->stmt); + remove_stmt (a->stmt, looparound_phis); continue; } @@ -2252,8 +2283,8 @@ determine_unroll_factor (vec chains) Uids of the newly created temporary variables are marked in TMP_VARS. */ static void -execute_pred_commoning (class loop *loop, vec chains, - bitmap tmp_vars) +execute_pred_commoning (class loop *loop, vec chains, bitmap tmp_vars, + bitmap looparound_phis) { chain_p chain; unsigned i; @@ -2263,7 +2294,7 @@ execute_pred_commoning (class loop *loop, vec chains, if (chain->type == CT_INVARIANT) execute_load_motion (loop, chain, tmp_vars); else - execute_pred_commoning_chain (loop, chain, tmp_vars); + execute_pred_commoning_chain (loop, chain, tmp_vars, looparound_phis); } FOR_EACH_VEC_ELT (chains, i, chain) @@ -2277,7 +2308,7 @@ execute_pred_commoning (class loop *loop, vec chains, dref a; unsigned j; for (j = 1; chain->refs.iterate (j, &a); j++) - remove_stmt (a->stmt); + remove_stmt (a->stmt, looparound_phis); } } } @@ -2330,6 +2361,7 @@ struct epcc_data { vec chains; bitmap tmp_vars; + bitmap looparound_phis; }; static void @@ -2341,7 +2373,8 @@ execute_pred_commoning_cbck (class loop *loop, void *data) tree_transform_and_unroll_loop (see detailed description in tree_predictive_commoning_loop). */ replace_names_by_phis (dta->chains); - execute_pred_commoning (loop, dta->chains, dta->tmp_vars); + execute_pred_commoning (loop, dta->chains, dta->tmp_vars, + dta->looparound_phis); } /* Base NAME and all the names in the chain of phi nodes that use it @@ -2434,7 +2467,7 @@ chain_can_be_combined_p (chain_p chain) statement. */ static gimple * -find_use_stmt (tree *name) +find_use_stmt (tree *name, bitmap looparound_phis) { gimple *stmt; tree rhs, lhs; @@ -2442,7 +2475,7 @@ find_use_stmt (tree *name) /* Skip over assignments. */ while (1) { - stmt = single_nonlooparound_use (*name); + stmt = single_nonlooparound_use (*name, looparound_phis); if (!stmt) return NULL; @@ -2487,7 +2520,7 @@ may_reassociate_p (tree type, enum tree_code code) is stored in DISTANCE. */ static gimple * -find_associative_operation_root (gimple *stmt, unsigned *distance) +find_associative_operation_root (gimple *stmt, unsigned *distance, bitmap looparound_phis) { tree lhs; gimple *next; @@ -2503,7 +2536,7 @@ find_associative_operation_root (gimple *stmt, unsigned *distance) lhs = gimple_assign_lhs (stmt); gcc_assert (TREE_CODE (lhs) == SSA_NAME); - next = find_use_stmt (&lhs); + next = find_use_stmt (&lhs, looparound_phis); if (!next || gimple_assign_rhs_code (next) != code) break; @@ -2524,25 +2557,25 @@ find_associative_operation_root (gimple *stmt, unsigned *distance) NAME2. */ static gimple * -find_common_use_stmt (tree *name1, tree *name2) +find_common_use_stmt (tree *name1, tree *name2, bitmap looparound_phis) { gimple *stmt1, *stmt2; - stmt1 = find_use_stmt (name1); + stmt1 = find_use_stmt (name1, looparound_phis); if (!stmt1) return NULL; - stmt2 = find_use_stmt (name2); + stmt2 = find_use_stmt (name2, looparound_phis); if (!stmt2) return NULL; if (stmt1 == stmt2) return stmt1; - stmt1 = find_associative_operation_root (stmt1, NULL); + stmt1 = find_associative_operation_root (stmt1, NULL, looparound_phis); if (!stmt1) return NULL; - stmt2 = find_associative_operation_root (stmt2, NULL); + stmt2 = find_associative_operation_root (stmt2, NULL, looparound_phis); if (!stmt2) return NULL; @@ -2555,7 +2588,7 @@ find_common_use_stmt (tree *name1, tree *name2) static bool combinable_refs_p (dref r1, dref r2, - enum tree_code *code, bool *swap, tree *rslt_type) + enum tree_code *code, bool *swap, tree *rslt_type, bitmap looparound_phis) { enum tree_code acode; bool aswap; @@ -2567,7 +2600,7 @@ combinable_refs_p (dref r1, dref r2, name2 = name_for_ref (r2); gcc_assert (name1 != NULL_TREE && name2 != NULL_TREE); - stmt = find_common_use_stmt (&name1, &name2); + stmt = find_common_use_stmt (&name1, &name2, looparound_phis); if (!stmt /* A simple post-dominance check - make sure the combination @@ -2623,7 +2656,7 @@ remove_name_from_operation (gimple *stmt, tree op) are combined in a single statement, and returns this statement. */ static gimple * -reassociate_to_the_same_stmt (tree name1, tree name2) +reassociate_to_the_same_stmt (tree name1, tree name2, bitmap looparound_phis) { gimple *stmt1, *stmt2, *root1, *root2, *s1, *s2; gassign *new_stmt, *tmp_stmt; @@ -2633,10 +2666,10 @@ reassociate_to_the_same_stmt (tree name1, tree name2) tree type = TREE_TYPE (name1); gimple_stmt_iterator bsi; - stmt1 = find_use_stmt (&name1); - stmt2 = find_use_stmt (&name2); - root1 = find_associative_operation_root (stmt1, &dist1); - root2 = find_associative_operation_root (stmt2, &dist2); + stmt1 = find_use_stmt (&name1, looparound_phis); + stmt2 = find_use_stmt (&name2, looparound_phis); + root1 = find_associative_operation_root (stmt1, &dist1, looparound_phis); + root2 = find_associative_operation_root (stmt2, &dist2, looparound_phis); code = gimple_assign_rhs_code (stmt1); gcc_assert (root1 && root2 && root1 == root2 @@ -2651,22 +2684,22 @@ reassociate_to_the_same_stmt (tree name1, tree name2) while (dist1 > dist2) { - s1 = find_use_stmt (&r1); + s1 = find_use_stmt (&r1, looparound_phis); r1 = gimple_assign_lhs (s1); dist1--; } while (dist2 > dist1) { - s2 = find_use_stmt (&r2); + s2 = find_use_stmt (&r2, looparound_phis); r2 = gimple_assign_lhs (s2); dist2--; } while (s1 != s2) { - s1 = find_use_stmt (&r1); + s1 = find_use_stmt (&r1, looparound_phis); r1 = gimple_assign_lhs (s1); - s2 = find_use_stmt (&r2); + s2 = find_use_stmt (&r2, looparound_phis); r2 = gimple_assign_lhs (s2); } @@ -2708,25 +2741,25 @@ reassociate_to_the_same_stmt (tree name1, tree name2) the expression so that they are used in the same statement. */ static gimple * -stmt_combining_refs (dref r1, dref r2) +stmt_combining_refs (dref r1, dref r2, bitmap looparound_phis) { gimple *stmt1, *stmt2; tree name1 = name_for_ref (r1); tree name2 = name_for_ref (r2); - stmt1 = find_use_stmt (&name1); - stmt2 = find_use_stmt (&name2); + stmt1 = find_use_stmt (&name1, looparound_phis); + stmt2 = find_use_stmt (&name2, looparound_phis); if (stmt1 == stmt2) return stmt1; - return reassociate_to_the_same_stmt (name1, name2); + return reassociate_to_the_same_stmt (name1, name2, looparound_phis); } /* Tries to combine chains CH1 and CH2 together. If this succeeds, the description of the new chain is returned, otherwise we return NULL. */ static chain_p -combine_chains (chain_p ch1, chain_p ch2) +combine_chains (chain_p ch1, chain_p ch2, bitmap looparound_phis) { dref r1, r2, nw; enum tree_code op = ERROR_MARK; @@ -2749,7 +2782,7 @@ combine_chains (chain_p ch1, chain_p ch2) if (r1->distance != r2->distance) return NULL; - if (!combinable_refs_p (r1, r2, &op, &swap, &rslt_type)) + if (!combinable_refs_p (r1, r2, &op, &swap, &rslt_type, looparound_phis)) return NULL; } @@ -2768,7 +2801,7 @@ combine_chains (chain_p ch1, chain_p ch2) && ch2->refs.iterate (i, &r2)); i++) { nw = XCNEW (class dref_d); - nw->stmt = stmt_combining_refs (r1, r2); + nw->stmt = stmt_combining_refs (r1, r2, looparound_phis); nw->distance = r1->distance; new_chain->refs.safe_push (nw); @@ -2817,7 +2850,8 @@ pcom_stmt_dominates_stmt_p (gimple *s1, gimple *s2) /* Try to combine the CHAINS in LOOP. */ static void -try_combine_chains (class loop *loop, vec *chains) +try_combine_chains (class loop *loop, vec *chains, + bitmap looparound_phis) { unsigned i, j; chain_p ch1, ch2, cch; @@ -2839,7 +2873,7 @@ try_combine_chains (class loop *loop, vec *chains) if (!chain_can_be_combined_p (ch2)) continue; - cch = combine_chains (ch1, ch2); + cch = combine_chains (ch1, ch2, looparound_phis); if (cch) { worklist.safe_push (cch); @@ -3172,6 +3206,7 @@ insert_init_seqs (class loop *loop, vec chains) } } + /* Performs predictive commoning for LOOP. Sets bit 1<<1 of return value if LOOP was unrolled; Sets bit 1<<2 of return value if loop closed ssa form was corrupted. Non-zero return value indicates some changes were @@ -3180,10 +3215,7 @@ insert_init_seqs (class loop *loop, vec chains) static unsigned tree_predictive_commoning_loop (class loop *loop, bool allow_unroll_p) { - vec datarefs; - vec dependences; struct component *components; - vec chains = vNULL; unsigned unroll_factor = 0; class tree_niter_desc desc; bool unroll = false, loop_closed_ssa = false; @@ -3202,31 +3234,23 @@ tree_predictive_commoning_loop (class loop *loop, bool allow_unroll_p) /* Find the data references and split them into components according to their dependence relations. */ + loop_pcom_info info (loop); auto_vec loop_nest; - dependences.create (10); - datarefs.create (10); - if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs, - &dependences)) + if (!compute_data_dependences_for_loop (loop, true, &loop_nest, + &info.datarefs, &info.dependences)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Cannot analyze data dependencies\n"); - free_data_refs (datarefs); - free_dependence_relations (dependences); return 0; } if (dump_file && (dump_flags & TDF_DETAILS)) - dump_data_dependence_relations (dump_file, dependences); + dump_data_dependence_relations (dump_file, info.dependences); - components = split_data_refs_to_components (loop, datarefs, dependences); - loop_nest.release (); - free_dependence_relations (dependences); + components = split_data_refs_to_components (loop, info.datarefs, + info.dependences, &info.cache); if (!components) - { - free_data_refs (datarefs); - free_affine_expand_cache (&name_expansions); return 0; - } if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3235,47 +3259,40 @@ tree_predictive_commoning_loop (class loop *loop, bool allow_unroll_p) } /* Find the suitable components and split them into chains. */ - components = filter_suitable_components (loop, components); + components = filter_suitable_components (loop, components, &info.cache); auto_bitmap tmp_vars; - looparound_phis = BITMAP_ALLOC (NULL); - determine_roots (loop, components, &chains); + /* Bitmap of ssa names defined by looparound phi nodes covered by chains. */ + auto_bitmap looparound_phis; + determine_roots (loop, components, &info.chains, looparound_phis, &info.cache); release_components (components); - auto cleanup = [&]() { - release_chains (chains); - free_data_refs (datarefs); - BITMAP_FREE (looparound_phis); - free_affine_expand_cache (&name_expansions); - }; - - if (!chains.exists ()) + if (!info.chains.exists ()) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Predictive commoning failed: no suitable chains\n"); - cleanup (); return 0; } - prepare_initializers (loop, chains); - loop_closed_ssa = prepare_finalizers (loop, chains); + prepare_initializers (loop, info.chains); + loop_closed_ssa = prepare_finalizers (loop, info.chains); /* Try to combine the chains that are always worked with together. */ - try_combine_chains (loop, &chains); + try_combine_chains (loop, &info.chains, looparound_phis); - insert_init_seqs (loop, chains); + insert_init_seqs (loop, info.chains); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Before commoning:\n\n"); - dump_chains (dump_file, chains); + dump_chains (dump_file, info.chains); } if (allow_unroll_p) /* Determine the unroll factor, and if the loop should be unrolled, ensure that its number of iterations is divisible by the factor. */ - unroll_factor = determine_unroll_factor (chains); + unroll_factor = determine_unroll_factor (info.chains); if (unroll_factor > 1) unroll = can_unroll_loop_p (loop, unroll_factor, &desc); @@ -3289,8 +3306,9 @@ tree_predictive_commoning_loop (class loop *loop, bool allow_unroll_p) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Unrolling %u times.\n", unroll_factor); - dta.chains = chains; + dta.chains = info.chains; dta.tmp_vars = tmp_vars; + dta.looparound_phis = looparound_phis; /* Cfg manipulations performed in tree_transform_and_unroll_loop before execute_pred_commoning_cbck is called may cause phi nodes to be @@ -3298,7 +3316,7 @@ tree_predictive_commoning_loop (class loop *loop, bool allow_unroll_p) statements. To fix this, we store the ssa names defined by the phi nodes here instead of the phi nodes themselves, and restore the phi nodes in execute_pred_commoning_cbck. A bit hacky. */ - replace_phis_by_defined_names (chains); + replace_phis_by_defined_names (info.chains); edge exit = single_dom_exit (loop); tree_transform_and_unroll_loop (loop, unroll_factor, exit, &desc, @@ -3310,11 +3328,9 @@ tree_predictive_commoning_loop (class loop *loop, bool allow_unroll_p) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Executing predictive commoning without unrolling.\n"); - execute_pred_commoning (loop, chains, tmp_vars); + execute_pred_commoning (loop, info.chains, tmp_vars, looparound_phis); } - cleanup (); - return (unroll ? 2 : 1) | (loop_closed_ssa ? 4 : 1); }