From: Zdenek Dvorak Date: Wed, 27 Jul 2005 13:26:55 +0000 (+0200) Subject: re PR tree-optimization/22325 (missed optimization in loop) X-Git-Tag: misc/cutover-cvs2svn~1496 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=3ac01fdeef1976c9150d3efa1b5c2915f210a78f;p=gcc.git re PR tree-optimization/22325 (missed optimization in loop) PR tree-optimization/22325 * tree-flow.h (compute_phi_arg_on_exit, force_expr_to_var_cost): Declare. * tree-scalar-evolution.c (scev_const_prop): Add generic final value replacement. * tree-ssa-loop-ivopts.c (force_expr_to_var_cost): Split from ... (force_var_cost): ... this function. (compute_phi_arg_on_exit): Export. From-SVN: r102426 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10f3d12bfdf8..13c7a178992a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2005-07-27 Zdenek Dvorak + + PR tree-optimization/22325 + * tree-flow.h (compute_phi_arg_on_exit, force_expr_to_var_cost): + Declare. + * tree-scalar-evolution.c (scev_const_prop): Add generic final + value replacement. + * tree-ssa-loop-ivopts.c (force_expr_to_var_cost): Split from ... + (force_var_cost): ... this function. + (compute_phi_arg_on_exit): Export. + 2005-07-27 Zdenek Dvorak PR tree-optimization/20773 diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 4a0b48007c59..bfbceba9f27b 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -738,6 +738,8 @@ bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *); void create_iv (tree, tree, tree, struct loop *, block_stmt_iterator *, bool, tree *, tree *); void split_loop_exit_edge (edge); +void compute_phi_arg_on_exit (edge, tree, tree); +unsigned force_expr_to_var_cost (tree); basic_block bsi_insert_on_edge_immediate_loop (edge, tree); void standard_iv_increment_position (struct loop *, block_stmt_iterator *, bool *); diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index f12ec09fc452..52a2d1a612c7 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -2608,8 +2608,8 @@ scev_finalize (void) } /* Replace ssa names for that scev can prove they are constant by the - appropriate constants. Most importantly, this takes care of final - value replacement. + appropriate constants. Also perform final value replacement in loops, + in case the replacement expressions are cheap. We only consider SSA names defined by phi nodes; rest is left to the ordinary constant propagation pass. */ @@ -2618,9 +2618,10 @@ void scev_const_prop (void) { basic_block bb; - tree name, phi, type, ev; - struct loop *loop; + tree name, phi, next_phi, type, ev; + struct loop *loop, *ex_loop; bitmap ssa_names_to_remove = NULL; + unsigned i; if (!current_loops) return; @@ -2675,4 +2676,56 @@ scev_const_prop (void) BITMAP_FREE (ssa_names_to_remove); scev_reset (); } + + /* Now the regular final value replacement. */ + for (i = current_loops->num - 1; i > 0; i--) + { + edge exit; + tree def, stmts; + + loop = current_loops->parray[i]; + if (!loop) + continue; + + /* If we do not know exact number of iterations of the loop, we cannot + replace the final value. */ + exit = loop->single_exit; + if (!exit + || number_of_iterations_in_loop (loop) == chrec_dont_know) + continue; + ex_loop = exit->dest->loop_father; + + for (phi = phi_nodes (exit->dest); phi; phi = next_phi) + { + next_phi = PHI_CHAIN (phi); + def = PHI_ARG_DEF_FROM_EDGE (phi, exit); + if (!is_gimple_reg (def) + || expr_invariant_in_loop_p (loop, def)) + continue; + + if (!POINTER_TYPE_P (TREE_TYPE (def)) + && !INTEGRAL_TYPE_P (TREE_TYPE (def))) + continue; + + def = analyze_scalar_evolution_in_loop (ex_loop, ex_loop, def); + if (!tree_does_not_contain_chrecs (def) + || chrec_contains_symbols_defined_in_loop (def, loop->num)) + continue; + + /* If computing the expression is expensive, let it remain in + loop. TODO -- we should take the cost of computing the expression + in loop into account. */ + if (force_expr_to_var_cost (def) >= target_spill_cost) + continue; + + if (is_gimple_val (def)) + stmts = NULL_TREE; + else + def = force_gimple_operand (def, &stmts, true, + SSA_NAME_VAR (PHI_RESULT (phi))); + SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, exit), def); + if (stmts) + compute_phi_arg_on_exit (exit, stmts, def); + } + } } diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index fda17f9c56d7..e5a8d85504d4 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -3415,12 +3415,11 @@ get_address_cost (bool symbol_present, bool var_present, return cost + acost; } -/* Estimates cost of forcing EXPR into a variable. DEPENDS_ON is a set of the - invariants the computation depends on. */ -static unsigned -force_var_cost (struct ivopts_data *data, - tree expr, bitmap *depends_on) +/* Estimates cost of forcing expression EXPR into a variable. */ + +unsigned +force_expr_to_var_cost (tree expr) { static bool costs_initialized = false; static unsigned integer_cost; @@ -3452,7 +3451,7 @@ force_var_cost (struct ivopts_data *data, build_int_cst_type (type, 2000))) + 1; if (dump_file && (dump_flags & TDF_DETAILS)) { - fprintf (dump_file, "force_var_cost:\n"); + fprintf (dump_file, "force_expr_to_var_cost:\n"); fprintf (dump_file, " integer %d\n", (int) integer_cost); fprintf (dump_file, " symbol %d\n", (int) symbol_cost); fprintf (dump_file, " address %d\n", (int) address_cost); @@ -3465,12 +3464,6 @@ force_var_cost (struct ivopts_data *data, STRIP_NOPS (expr); - if (depends_on) - { - fd_ivopts_data = data; - walk_tree (&expr, find_depends, depends_on, NULL); - } - if (SSA_VAR_P (expr)) return 0; @@ -3505,12 +3498,12 @@ force_var_cost (struct ivopts_data *data, if (is_gimple_val (op0)) cost0 = 0; else - cost0 = force_var_cost (data, op0, NULL); + cost0 = force_expr_to_var_cost (op0); if (is_gimple_val (op1)) cost1 = 0; else - cost1 = force_var_cost (data, op1, NULL); + cost1 = force_expr_to_var_cost (op1); break; @@ -3550,6 +3543,22 @@ force_var_cost (struct ivopts_data *data, return cost < target_spill_cost ? cost : target_spill_cost; } +/* Estimates cost of forcing EXPR into a variable. DEPENDS_ON is a set of the + invariants the computation depends on. */ + +static unsigned +force_var_cost (struct ivopts_data *data, + tree expr, bitmap *depends_on) +{ + if (depends_on) + { + fd_ivopts_data = data; + walk_tree (&expr, find_depends, depends_on, NULL); + } + + return force_expr_to_var_cost (expr); +} + /* Estimates cost of expressing address ADDR as var + symbol + offset. The value of offset is added to OFFSET, SYMBOL_PRESENT and VAR_PRESENT are set to false if the corresponding part is missing. DEPENDS_ON is a set of the @@ -5600,7 +5609,7 @@ protect_loop_closed_ssa_form (edge exit, tree stmt) so that they are emitted on the correct place, and so that the loop closed ssa form is preserved. */ -static void +void compute_phi_arg_on_exit (edge exit, tree stmts, tree op) { tree_stmt_iterator tsi;