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:
parent
77fcaf4b70
commit
3ac01fdeef
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue