Commit f5f12961 by Zdenek Dvorak Committed by Zdenek Dvorak

tree-ssa-loop-ivopts.c (struct cost_pair): Add value field.

	* tree-ssa-loop-ivopts.c (struct cost_pair): Add value field.
	(find_interesting_uses_cond): Do not use integer_zerop and
	integer_nonzerop to check for integer constants.
	(set_use_iv_cost): Record the value field.
	(determine_use_iv_cost_generic, determine_use_iv_cost_address,
	determine_use_iv_cost_outer): Set the value field of the cost pair.
	(may_eliminate_iv): Do not return the comparison code.
	(iv_elimination_compare): New function.
	(determine_use_iv_cost_condition): Set the value field.  Record
	noneliminable invariants correctly.
	(rewrite_use_compare, rewrite_use_outer): Use the value field.

From-SVN: r98634
parent d4ee4d25
2005-04-23 Zdenek Dvorak <dvorakz@suse.cz>
* tree-ssa-loop-ivopts.c (struct cost_pair): Add value field.
(find_interesting_uses_cond): Do not use integer_zerop and
integer_nonzerop to check for integer constants.
(set_use_iv_cost): Record the value field.
(determine_use_iv_cost_generic, determine_use_iv_cost_address,
determine_use_iv_cost_outer): Set the value field of the cost pair.
(may_eliminate_iv): Do not return the comparison code.
(iv_elimination_compare): New function.
(determine_use_iv_cost_condition): Set the value field. Record
noneliminable invariants correctly.
(rewrite_use_compare, rewrite_use_outer): Use the value field.
2005-04-23 DJ Delorie <dj@redhat.com> 2005-04-23 DJ Delorie <dj@redhat.com>
* diagnostic.c (warning): Accept parameter to classify warning option. * diagnostic.c (warning): Accept parameter to classify warning option.
......
...@@ -143,6 +143,9 @@ struct cost_pair ...@@ -143,6 +143,9 @@ struct cost_pair
unsigned cost; /* The cost. */ unsigned cost; /* The cost. */
bitmap depends_on; /* The list of invariants that have to be bitmap depends_on; /* The list of invariants that have to be
preserved. */ preserved. */
tree value; /* For final value elimination, the expression for
the final value of the iv. For iv elimination,
the new bound to compare with. */
}; };
/* Use. */ /* Use. */
...@@ -1276,8 +1279,8 @@ find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p) ...@@ -1276,8 +1279,8 @@ find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p)
const_iv.step = NULL_TREE; const_iv.step = NULL_TREE;
if (integer_zerop (*cond_p) if (TREE_CODE (*cond_p) != SSA_NAME
|| integer_nonzerop (*cond_p)) && !COMPARISON_CLASS_P (*cond_p))
return; return;
if (TREE_CODE (*cond_p) == SSA_NAME) if (TREE_CODE (*cond_p) == SSA_NAME)
...@@ -2270,12 +2273,13 @@ alloc_use_cost_map (struct ivopts_data *data) ...@@ -2270,12 +2273,13 @@ alloc_use_cost_map (struct ivopts_data *data)
} }
/* Sets cost of (USE, CANDIDATE) pair to COST and record that it depends /* Sets cost of (USE, CANDIDATE) pair to COST and record that it depends
on invariants DEPENDS_ON. */ on invariants DEPENDS_ON and that the value used in expressing it
is VALUE.*/
static void static void
set_use_iv_cost (struct ivopts_data *data, set_use_iv_cost (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand, unsigned cost, struct iv_use *use, struct iv_cand *cand, unsigned cost,
bitmap depends_on) bitmap depends_on, tree value)
{ {
unsigned i, s; unsigned i, s;
...@@ -2290,6 +2294,7 @@ set_use_iv_cost (struct ivopts_data *data, ...@@ -2290,6 +2294,7 @@ set_use_iv_cost (struct ivopts_data *data,
use->cost_map[cand->id].cand = cand; use->cost_map[cand->id].cand = cand;
use->cost_map[cand->id].cost = cost; use->cost_map[cand->id].cost = cost;
use->cost_map[cand->id].depends_on = depends_on; use->cost_map[cand->id].depends_on = depends_on;
use->cost_map[cand->id].value = value;
return; return;
} }
...@@ -2308,6 +2313,7 @@ found: ...@@ -2308,6 +2313,7 @@ found:
use->cost_map[i].cand = cand; use->cost_map[i].cand = cand;
use->cost_map[i].cost = cost; use->cost_map[i].cost = cost;
use->cost_map[i].depends_on = depends_on; use->cost_map[i].depends_on = depends_on;
use->cost_map[i].value = value;
} }
/* Gets cost of (USE, CANDIDATE) pair. */ /* Gets cost of (USE, CANDIDATE) pair. */
...@@ -3307,12 +3313,12 @@ determine_use_iv_cost_generic (struct ivopts_data *data, ...@@ -3307,12 +3313,12 @@ determine_use_iv_cost_generic (struct ivopts_data *data,
if (cand->pos == IP_ORIGINAL if (cand->pos == IP_ORIGINAL
&& cand->incremented_at == use->stmt) && cand->incremented_at == use->stmt)
{ {
set_use_iv_cost (data, use, cand, 0, NULL); set_use_iv_cost (data, use, cand, 0, NULL, NULL_TREE);
return true; return true;
} }
cost = get_computation_cost (data, use, cand, false, &depends_on); cost = get_computation_cost (data, use, cand, false, &depends_on);
set_use_iv_cost (data, use, cand, cost, depends_on); set_use_iv_cost (data, use, cand, cost, depends_on, NULL_TREE);
return cost != INFTY; return cost != INFTY;
} }
...@@ -3326,7 +3332,7 @@ determine_use_iv_cost_address (struct ivopts_data *data, ...@@ -3326,7 +3332,7 @@ determine_use_iv_cost_address (struct ivopts_data *data,
bitmap depends_on; bitmap depends_on;
unsigned cost = get_computation_cost (data, use, cand, true, &depends_on); unsigned cost = get_computation_cost (data, use, cand, true, &depends_on);
set_use_iv_cost (data, use, cand, cost, depends_on); set_use_iv_cost (data, use, cand, cost, depends_on, NULL_TREE);
return cost != INFTY; return cost != INFTY;
} }
...@@ -3382,14 +3388,29 @@ iv_period (struct iv *iv) ...@@ -3382,14 +3388,29 @@ iv_period (struct iv *iv)
return period; return period;
} }
/* Returns the comparison operator used when eliminating the iv USE. */
static enum tree_code
iv_elimination_compare (struct ivopts_data *data, struct iv_use *use)
{
struct loop *loop = data->current_loop;
basic_block ex_bb;
edge exit;
ex_bb = bb_for_stmt (use->stmt);
exit = EDGE_SUCC (ex_bb, 0);
if (flow_bb_inside_loop_p (loop, exit->dest))
exit = EDGE_SUCC (ex_bb, 1);
return (exit->flags & EDGE_TRUE_VALUE ? EQ_EXPR : NE_EXPR);
}
/* Check whether it is possible to express the condition in USE by comparison /* Check whether it is possible to express the condition in USE by comparison
of candidate CAND. If so, store the comparison code to COMPARE and the of candidate CAND. If so, store the value compared with to BOUND. */
value compared with to BOUND. */
static bool static bool
may_eliminate_iv (struct ivopts_data *data, may_eliminate_iv (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand, struct iv_use *use, struct iv_cand *cand, tree *bound)
enum tree_code *compare, tree *bound)
{ {
basic_block ex_bb; basic_block ex_bb;
edge exit; edge exit;
...@@ -3440,11 +3461,6 @@ may_eliminate_iv (struct ivopts_data *data, ...@@ -3440,11 +3461,6 @@ may_eliminate_iv (struct ivopts_data *data,
fold_convert (wider_type, nit))))) fold_convert (wider_type, nit)))))
return false; return false;
if (exit->flags & EDGE_TRUE_VALUE)
*compare = EQ_EXPR;
else
*compare = NE_EXPR;
*bound = cand_value_at (loop, cand, use->stmt, nit); *bound = cand_value_at (loop, cand, use->stmt, nit);
return true; return true;
} }
...@@ -3455,37 +3471,46 @@ static bool ...@@ -3455,37 +3471,46 @@ static bool
determine_use_iv_cost_condition (struct ivopts_data *data, determine_use_iv_cost_condition (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand) struct iv_use *use, struct iv_cand *cand)
{ {
tree bound; tree bound = NULL_TREE, op, cond;
enum tree_code compare; bitmap depends_on = NULL;
unsigned cost;
/* Only consider real candidates. */ /* Only consider real candidates. */
if (!cand->iv) if (!cand->iv)
{ {
set_use_iv_cost (data, use, cand, INFTY, NULL); set_use_iv_cost (data, use, cand, INFTY, NULL, NULL_TREE);
return false; return false;
} }
if (may_eliminate_iv (data, use, cand, &compare, &bound)) if (may_eliminate_iv (data, use, cand, &bound))
{ {
bitmap depends_on = NULL; cost = force_var_cost (data, bound, &depends_on);
unsigned cost = force_var_cost (data, bound, &depends_on);
set_use_iv_cost (data, use, cand, cost, depends_on); set_use_iv_cost (data, use, cand, cost, depends_on, bound);
return cost != INFTY; return cost != INFTY;
} }
/* The induction variable elimination failed; just express the original /* The induction variable elimination failed; just express the original
giv. If it is compared with an invariant, note that we cannot get giv. If it is compared with an invariant, note that we cannot get
rid of it. */ rid of it. */
if (TREE_CODE (*use->op_p) == SSA_NAME) cost = get_computation_cost (data, use, cand, false, &depends_on);
record_invariant (data, *use->op_p, true);
else cond = *use->op_p;
if (TREE_CODE (cond) != SSA_NAME)
{ {
record_invariant (data, TREE_OPERAND (*use->op_p, 0), true); op = TREE_OPERAND (cond, 0);
record_invariant (data, TREE_OPERAND (*use->op_p, 1), true); if (TREE_CODE (op) == SSA_NAME && !zero_p (get_iv (data, op)->step))
op = TREE_OPERAND (cond, 1);
if (TREE_CODE (op) == SSA_NAME)
{
op = get_iv (data, op)->base;
fd_ivopts_data = data;
walk_tree (&op, find_depends, &depends_on, NULL);
}
} }
return determine_use_iv_cost_generic (data, use, cand); set_use_iv_cost (data, use, cand, cost, depends_on, NULL);
return cost != INFTY;
} }
/* Checks whether it is possible to replace the final value of USE by /* Checks whether it is possible to replace the final value of USE by
...@@ -3525,7 +3550,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data, ...@@ -3525,7 +3550,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data,
bitmap depends_on; bitmap depends_on;
unsigned cost; unsigned cost;
edge exit; edge exit;
tree value; tree value = NULL_TREE;
struct loop *loop = data->current_loop; struct loop *loop = data->current_loop;
/* The simple case first -- if we need to express value of the preserved /* The simple case first -- if we need to express value of the preserved
...@@ -3535,7 +3560,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data, ...@@ -3535,7 +3560,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data,
if (cand->pos == IP_ORIGINAL if (cand->pos == IP_ORIGINAL
&& cand->incremented_at == use->stmt) && cand->incremented_at == use->stmt)
{ {
set_use_iv_cost (data, use, cand, 0, NULL); set_use_iv_cost (data, use, cand, 0, NULL, NULL_TREE);
return true; return true;
} }
...@@ -3543,7 +3568,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data, ...@@ -3543,7 +3568,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data,
{ {
if (!may_replace_final_value (data, use, &value)) if (!may_replace_final_value (data, use, &value))
{ {
set_use_iv_cost (data, use, cand, INFTY, NULL); set_use_iv_cost (data, use, cand, INFTY, NULL, NULL_TREE);
return false; return false;
} }
...@@ -3552,7 +3577,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data, ...@@ -3552,7 +3577,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data,
cost /= AVG_LOOP_NITER (loop); cost /= AVG_LOOP_NITER (loop);
set_use_iv_cost (data, use, cand, cost, depends_on); set_use_iv_cost (data, use, cand, cost, depends_on, value);
return cost != INFTY; return cost != INFTY;
} }
...@@ -3572,7 +3597,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data, ...@@ -3572,7 +3597,7 @@ determine_use_iv_cost_outer (struct ivopts_data *data,
cost = get_computation_cost (data, use, cand, false, &depends_on); cost = get_computation_cost (data, use, cand, false, &depends_on);
} }
set_use_iv_cost (data, use, cand, cost, depends_on); set_use_iv_cost (data, use, cand, cost, depends_on, NULL_TREE);
return cost != INFTY; return cost != INFTY;
} }
...@@ -4907,12 +4932,15 @@ rewrite_use_compare (struct ivopts_data *data, ...@@ -4907,12 +4932,15 @@ rewrite_use_compare (struct ivopts_data *data,
tree *op_p, cond, op, stmts, bound; tree *op_p, cond, op, stmts, bound;
block_stmt_iterator bsi = bsi_for_stmt (use->stmt); block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
enum tree_code compare; enum tree_code compare;
struct cost_pair *cp = get_use_iv_cost (data, use, cand);
if (may_eliminate_iv (data, use, cand, &compare, &bound)) bound = cp->value;
if (bound)
{ {
tree var = var_at_stmt (data->current_loop, cand, use->stmt); tree var = var_at_stmt (data->current_loop, cand, use->stmt);
tree var_type = TREE_TYPE (var); tree var_type = TREE_TYPE (var);
compare = iv_elimination_compare (data, use);
bound = fold_convert (var_type, bound); bound = fold_convert (var_type, bound);
op = force_gimple_operand (unshare_expr (bound), &stmts, op = force_gimple_operand (unshare_expr (bound), &stmts,
true, NULL_TREE); true, NULL_TREE);
...@@ -5087,8 +5115,8 @@ rewrite_use_outer (struct ivopts_data *data, ...@@ -5087,8 +5115,8 @@ rewrite_use_outer (struct ivopts_data *data,
{ {
if (!cand->iv) if (!cand->iv)
{ {
bool ok = may_replace_final_value (data, use, &value); struct cost_pair *cp = get_use_iv_cost (data, use, cand);
gcc_assert (ok); value = cp->value;
} }
else else
value = get_computation_at (data->current_loop, value = get_computation_at (data->current_loop,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment