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
This commit is contained in:
Zdenek Dvorak 2005-07-27 15:26:55 +02:00 committed by Zdenek Dvorak
parent 77fcaf4b70
commit 3ac01fdeef
4 changed files with 94 additions and 19 deletions

View File

@ -1,3 +1,14 @@
2005-07-27 Zdenek Dvorak <dvorakz@suse.cz>
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 <dvorakz@suse.cz>
PR tree-optimization/20773

View File

@ -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 *);

View File

@ -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);
}
}
}

View File

@ -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;