re PR middle-end/45098 (Missed induction variable optimization)
2011-05-19 Tom de Vries <tom@codesourcery.com> PR target/45098 * tree-ssa-loop-ivopts.c (get_expr_id): Factored new function out of get_loop_invariant_expr_id. (get_loop_invariant_expr_id): Use get_expr_id. (parm_decl_cost): New function. (determine_use_iv_cost_condition): Use get_expr_id and parm_decl_cost. Improve bound cost estimation. Use different inv_expr_id for elim and express cases. From-SVN: r173894
This commit is contained in:
parent
a53c50249f
commit
bb8d292d39
@ -1,3 +1,14 @@
|
||||
2011-05-19 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
PR target/45098
|
||||
* tree-ssa-loop-ivopts.c (get_expr_id): Factored new function out of
|
||||
get_loop_invariant_expr_id.
|
||||
(get_loop_invariant_expr_id): Use get_expr_id.
|
||||
(parm_decl_cost): New function.
|
||||
(determine_use_iv_cost_condition): Use get_expr_id and parm_decl_cost.
|
||||
Improve bound cost estimation. Use different inv_expr_id for elim and
|
||||
express cases.
|
||||
|
||||
2011-05-19 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
PR target/45098
|
||||
|
@ -3837,6 +3837,28 @@ compare_aff_trees (aff_tree *aff1, aff_tree *aff2)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stores EXPR in DATA->inv_expr_tab, and assigns it an inv_expr_id. */
|
||||
|
||||
static int
|
||||
get_expr_id (struct ivopts_data *data, tree expr)
|
||||
{
|
||||
struct iv_inv_expr_ent ent;
|
||||
struct iv_inv_expr_ent **slot;
|
||||
|
||||
ent.expr = expr;
|
||||
ent.hash = iterative_hash_expr (expr, 0);
|
||||
slot = (struct iv_inv_expr_ent **) htab_find_slot (data->inv_expr_tab,
|
||||
&ent, INSERT);
|
||||
if (*slot)
|
||||
return (*slot)->id;
|
||||
|
||||
*slot = XNEW (struct iv_inv_expr_ent);
|
||||
(*slot)->expr = expr;
|
||||
(*slot)->hash = ent.hash;
|
||||
(*slot)->id = data->inv_expr_id++;
|
||||
return (*slot)->id;
|
||||
}
|
||||
|
||||
/* Returns the pseudo expr id if expression UBASE - RATIO * CBASE
|
||||
requires a new compiler generated temporary. Returns -1 otherwise.
|
||||
ADDRESS_P is a flag indicating if the expression is for address
|
||||
@ -3849,8 +3871,6 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
||||
{
|
||||
aff_tree ubase_aff, cbase_aff;
|
||||
tree expr, ub, cb;
|
||||
struct iv_inv_expr_ent ent;
|
||||
struct iv_inv_expr_ent **slot;
|
||||
|
||||
STRIP_NOPS (ubase);
|
||||
STRIP_NOPS (cbase);
|
||||
@ -3938,18 +3958,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|
||||
aff_combination_scale (&cbase_aff, shwi_to_double_int (-1 * ratio));
|
||||
aff_combination_add (&ubase_aff, &cbase_aff);
|
||||
expr = aff_combination_to_tree (&ubase_aff);
|
||||
ent.expr = expr;
|
||||
ent.hash = iterative_hash_expr (expr, 0);
|
||||
slot = (struct iv_inv_expr_ent **) htab_find_slot (data->inv_expr_tab,
|
||||
&ent, INSERT);
|
||||
if (*slot)
|
||||
return (*slot)->id;
|
||||
|
||||
*slot = XNEW (struct iv_inv_expr_ent);
|
||||
(*slot)->expr = expr;
|
||||
(*slot)->hash = ent.hash;
|
||||
(*slot)->id = data->inv_expr_id++;
|
||||
return (*slot)->id;
|
||||
return get_expr_id (data, expr);
|
||||
}
|
||||
|
||||
|
||||
@ -4414,6 +4423,23 @@ may_eliminate_iv (struct ivopts_data *data,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Calculates the cost of BOUND, if it is a PARM_DECL. A PARM_DECL must
|
||||
be copied, if is is used in the loop body and DATA->body_includes_call. */
|
||||
|
||||
static int
|
||||
parm_decl_cost (struct ivopts_data *data, tree bound)
|
||||
{
|
||||
tree sbound = bound;
|
||||
STRIP_NOPS (sbound);
|
||||
|
||||
if (TREE_CODE (sbound) == SSA_NAME
|
||||
&& TREE_CODE (SSA_NAME_VAR (sbound)) == PARM_DECL
|
||||
&& gimple_nop_p (SSA_NAME_DEF_STMT (sbound))
|
||||
&& data->body_includes_call)
|
||||
return COSTS_N_INSNS (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Determines cost of basing replacement of USE on CAND in a condition. */
|
||||
|
||||
@ -4424,9 +4450,9 @@ determine_use_iv_cost_condition (struct ivopts_data *data,
|
||||
tree bound = NULL_TREE;
|
||||
struct iv *cmp_iv;
|
||||
bitmap depends_on_elim = NULL, depends_on_express = NULL, depends_on;
|
||||
comp_cost elim_cost, express_cost, cost;
|
||||
comp_cost elim_cost, express_cost, cost, bound_cost;
|
||||
bool ok;
|
||||
int inv_expr_id = -1;
|
||||
int elim_inv_expr_id = -1, express_inv_expr_id = -1, inv_expr_id;
|
||||
tree *control_var, *bound_cst;
|
||||
|
||||
/* Only consider real candidates. */
|
||||
@ -4440,6 +4466,21 @@ determine_use_iv_cost_condition (struct ivopts_data *data,
|
||||
if (may_eliminate_iv (data, use, cand, &bound))
|
||||
{
|
||||
elim_cost = force_var_cost (data, bound, &depends_on_elim);
|
||||
if (elim_cost.cost == 0)
|
||||
elim_cost.cost = parm_decl_cost (data, bound);
|
||||
else if (TREE_CODE (bound) == INTEGER_CST)
|
||||
elim_cost.cost = 0;
|
||||
/* If we replace a loop condition 'i < n' with 'p < base + n',
|
||||
depends_on_elim will have 'base' and 'n' set, which implies
|
||||
that both 'base' and 'n' will be live during the loop. More likely,
|
||||
'base + n' will be loop invariant, resulting in only one live value
|
||||
during the loop. So in that case we clear depends_on_elim and set
|
||||
elim_inv_expr_id instead. */
|
||||
if (depends_on_elim && bitmap_count_bits (depends_on_elim) > 1)
|
||||
{
|
||||
elim_inv_expr_id = get_expr_id (data, bound);
|
||||
bitmap_clear (depends_on_elim);
|
||||
}
|
||||
/* The bound is a loop invariant, so it will be only computed
|
||||
once. */
|
||||
elim_cost.cost = adjust_setup_cost (data, elim_cost.cost);
|
||||
@ -4467,16 +4508,25 @@ determine_use_iv_cost_condition (struct ivopts_data *data,
|
||||
|
||||
express_cost = get_computation_cost (data, use, cand, false,
|
||||
&depends_on_express, NULL,
|
||||
&inv_expr_id);
|
||||
&express_inv_expr_id);
|
||||
fd_ivopts_data = data;
|
||||
walk_tree (&cmp_iv->base, find_depends, &depends_on_express, NULL);
|
||||
|
||||
/* Count the cost of the original bound as well. */
|
||||
bound_cost = force_var_cost (data, *bound_cst, NULL);
|
||||
if (bound_cost.cost == 0)
|
||||
bound_cost.cost = parm_decl_cost (data, *bound_cst);
|
||||
else if (TREE_CODE (*bound_cst) == INTEGER_CST)
|
||||
bound_cost.cost = 0;
|
||||
express_cost.cost += bound_cost.cost;
|
||||
|
||||
/* Choose the better approach, preferring the eliminated IV. */
|
||||
if (compare_costs (elim_cost, express_cost) <= 0)
|
||||
{
|
||||
cost = elim_cost;
|
||||
depends_on = depends_on_elim;
|
||||
depends_on_elim = NULL;
|
||||
inv_expr_id = elim_inv_expr_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4484,6 +4534,7 @@ determine_use_iv_cost_condition (struct ivopts_data *data,
|
||||
depends_on = depends_on_express;
|
||||
depends_on_express = NULL;
|
||||
bound = NULL_TREE;
|
||||
inv_expr_id = express_inv_expr_id;
|
||||
}
|
||||
|
||||
set_use_iv_cost (data, use, cand, cost, depends_on, bound, inv_expr_id);
|
||||
|
Loading…
Reference in New Issue
Block a user