Commit 8d18b6df by Martin Liska Committed by Martin Liska

IVOPTS: make comp_cost in a more c++ fashion.

	* tree-ssa-loop-ivopts.c (comp_cost::infinite_cost_p): New
	function.
	(operator+): Likewise.
	(operator-): Likewise.
	(comp_cost::operator+=): Likewise.
	(comp_cost::operator-=): Likewise.
	(comp_cost::operator/=): Likewise.
	(comp_cost::operator*=): Likewise.
	(operator<): Likewise.
	(operator==): Likewise.
	(operator<=): Likewise.
	(new_cost): Remove.
	(infinite_cost_p): Likewise.
	(add_costs): Likewise.
	(sub_costs): Likewise.
	(compare_costs): Likewise.
	(set_group_iv_cost): Use the newly introduced functions.
	(get_address_cost): Likewise.
	(get_shiftadd_cost): Likewise.
	(force_expr_to_var_cost): Likewise.
	(split_address_cost): Likewise.
	(ptr_difference_cost): Likewise.
	(difference_cost): Likewise.
	(get_computation_cost_at): Likewise.
	(determine_group_iv_cost_generic): Likewise.
	(determine_group_iv_cost_address): Likewise.
	(determine_group_iv_cost_cond): Likewise.
	(autoinc_possible_for_pair): Likewise.
	(determine_group_iv_costs): Likewise.
	(cheaper_cost_pair): Likewise.
	(iv_ca_recount_cost): Likewise.
	(iv_ca_set_no_cp): Likewise.
	(iv_ca_set_cp): Likewise.
	(iv_ca_cost): Likewise.
	(iv_ca_new): Likewise.
	(iv_ca_dump): Likewise.
	(iv_ca_narrow): Likewise.
	(iv_ca_prune): Likewise.
	(iv_ca_replace): Likewise.
	(try_add_cand_for): Likewise.
	(try_improve_iv_set): Likewise.
	(find_optimal_iv_set): Likewise.

From-SVN: r236785
parent b3d2acb6
2016-05-26 Martin Liska <mliska@suse.cz>
* tree-ssa-loop-ivopts.c (comp_cost::infinite_cost_p): New
function.
(operator+): Likewise.
(operator-): Likewise.
(comp_cost::operator+=): Likewise.
(comp_cost::operator-=): Likewise.
(comp_cost::operator/=): Likewise.
(comp_cost::operator*=): Likewise.
(operator<): Likewise.
(operator==): Likewise.
(operator<=): Likewise.
(new_cost): Remove.
(infinite_cost_p): Likewise.
(add_costs): Likewise.
(sub_costs): Likewise.
(compare_costs): Likewise.
(set_group_iv_cost): Use the newly introduced functions.
(get_address_cost): Likewise.
(get_shiftadd_cost): Likewise.
(force_expr_to_var_cost): Likewise.
(split_address_cost): Likewise.
(ptr_difference_cost): Likewise.
(difference_cost): Likewise.
(get_computation_cost_at): Likewise.
(determine_group_iv_cost_generic): Likewise.
(determine_group_iv_cost_address): Likewise.
(determine_group_iv_cost_cond): Likewise.
(autoinc_possible_for_pair): Likewise.
(determine_group_iv_costs): Likewise.
(cheaper_cost_pair): Likewise.
(iv_ca_recount_cost): Likewise.
(iv_ca_set_no_cp): Likewise.
(iv_ca_set_cp): Likewise.
(iv_ca_cost): Likewise.
(iv_ca_new): Likewise.
(iv_ca_dump): Likewise.
(iv_ca_narrow): Likewise.
(iv_ca_prune): Likewise.
(iv_ca_replace): Likewise.
(try_add_cand_for): Likewise.
(try_improve_iv_set): Likewise.
(find_optimal_iv_set): Likewise.
2016-05-26 Richard Sandiford <richard.sandiford@arm.com> 2016-05-26 Richard Sandiford <richard.sandiford@arm.com>
* tree-ssa-loop-ivopts.c (loop_body_includes_call): Don't assume * tree-ssa-loop-ivopts.c (loop_body_includes_call): Don't assume
......
...@@ -173,16 +173,171 @@ enum use_type ...@@ -173,16 +173,171 @@ enum use_type
/* Cost of a computation. */ /* Cost of a computation. */
struct comp_cost struct comp_cost
{ {
comp_cost (): cost (0), complexity (0), scratch (0)
{}
comp_cost (int cost, unsigned complexity, int scratch = 0)
: cost (cost), complexity (complexity), scratch (scratch)
{}
/* Returns true if COST is infinite. */
bool infinite_cost_p ();
/* Adds costs COST1 and COST2. */
friend comp_cost operator+ (comp_cost cost1, comp_cost cost2);
/* Adds COST to the comp_cost. */
comp_cost operator+= (comp_cost cost);
/* Adds constant C to this comp_cost. */
comp_cost operator+= (HOST_WIDE_INT c);
/* Subtracts constant C to this comp_cost. */
comp_cost operator-= (HOST_WIDE_INT c);
/* Divide the comp_cost by constant C. */
comp_cost operator/= (HOST_WIDE_INT c);
/* Multiply the comp_cost by constant C. */
comp_cost operator*= (HOST_WIDE_INT c);
/* Subtracts costs COST1 and COST2. */
friend comp_cost operator- (comp_cost cost1, comp_cost cost2);
/* Subtracts COST from this comp_cost. */
comp_cost operator-= (comp_cost cost);
/* Returns true if COST1 is smaller than COST2. */
friend bool operator< (comp_cost cost1, comp_cost cost2);
/* Returns true if COST1 and COST2 are equal. */
friend bool operator== (comp_cost cost1, comp_cost cost2);
/* Returns true if COST1 is smaller or equal than COST2. */
friend bool operator<= (comp_cost cost1, comp_cost cost2);
int cost; /* The runtime cost. */ int cost; /* The runtime cost. */
unsigned complexity; /* The estimate of the complexity of the code for unsigned complexity; /* The estimate of the complexity of the code for
the computation (in no concrete units -- the computation (in no concrete units --
complexity field should be larger for more complexity field should be larger for more
complex expressions and addressing modes). */ complex expressions and addressing modes). */
int scratch; /* Scratch used during cost computation. */ int scratch; /* Scratch used during cost computation. */
}; };
static const comp_cost no_cost = {0, 0, 0}; static const comp_cost no_cost;
static const comp_cost infinite_cost = {INFTY, INFTY, INFTY}; static const comp_cost infinite_cost (INFTY, INFTY, INFTY);
bool
comp_cost::infinite_cost_p ()
{
return cost == INFTY;
}
comp_cost
operator+ (comp_cost cost1, comp_cost cost2)
{
if (cost1.infinite_cost_p () || cost2.infinite_cost_p ())
return infinite_cost;
cost1.cost += cost2.cost;
cost1.complexity += cost2.complexity;
return cost1;
}
comp_cost
operator- (comp_cost cost1, comp_cost cost2)
{
if (cost1.infinite_cost_p ())
return infinite_cost;
gcc_assert (!cost2.infinite_cost_p ());
cost1.cost -= cost2.cost;
cost1.complexity -= cost2.complexity;
return cost1;
}
comp_cost
comp_cost::operator+= (comp_cost cost)
{
*this = *this + cost;
return *this;
}
comp_cost
comp_cost::operator+= (HOST_WIDE_INT c)
{
if (infinite_cost_p ())
return *this;
this->cost += c;
return *this;
}
comp_cost
comp_cost::operator-= (HOST_WIDE_INT c)
{
if (infinite_cost_p ())
return *this;
this->cost -= c;
return *this;
}
comp_cost
comp_cost::operator/= (HOST_WIDE_INT c)
{
if (infinite_cost_p ())
return *this;
this->cost /= c;
return *this;
}
comp_cost
comp_cost::operator*= (HOST_WIDE_INT c)
{
if (infinite_cost_p ())
return *this;
this->cost *= c;
return *this;
}
comp_cost
comp_cost::operator-= (comp_cost cost)
{
*this = *this - cost;
return *this;
}
bool
operator< (comp_cost cost1, comp_cost cost2)
{
if (cost1.cost == cost2.cost)
return cost1.complexity < cost2.complexity;
return cost1.cost < cost2.cost;
}
bool
operator== (comp_cost cost1, comp_cost cost2)
{
return cost1.cost == cost2.cost
&& cost1.complexity == cost2.complexity;
}
bool
operator<= (comp_cost cost1, comp_cost cost2)
{
return cost1 < cost2 || cost1 == cost2;
}
struct iv_inv_expr_ent; struct iv_inv_expr_ent;
...@@ -3284,64 +3439,6 @@ alloc_use_cost_map (struct ivopts_data *data) ...@@ -3284,64 +3439,6 @@ alloc_use_cost_map (struct ivopts_data *data)
} }
} }
/* Returns description of computation cost of expression whose runtime
cost is RUNTIME and complexity corresponds to COMPLEXITY. */
static comp_cost
new_cost (unsigned runtime, unsigned complexity)
{
comp_cost cost;
cost.cost = runtime;
cost.complexity = complexity;
return cost;
}
/* Returns true if COST is infinite. */
static bool
infinite_cost_p (comp_cost cost)
{
return cost.cost == INFTY;
}
/* Adds costs COST1 and COST2. */
static comp_cost
add_costs (comp_cost cost1, comp_cost cost2)
{
if (infinite_cost_p (cost1) || infinite_cost_p (cost2))
return infinite_cost;
cost1.cost += cost2.cost;
cost1.complexity += cost2.complexity;
return cost1;
}
/* Subtracts costs COST1 and COST2. */
static comp_cost
sub_costs (comp_cost cost1, comp_cost cost2)
{
cost1.cost -= cost2.cost;
cost1.complexity -= cost2.complexity;
return cost1;
}
/* Returns a negative number if COST1 < COST2, a positive number if
COST1 > COST2, and 0 if COST1 = COST2. */
static int
compare_costs (comp_cost cost1, comp_cost cost2)
{
if (cost1.cost == cost2.cost)
return cost1.complexity - cost2.complexity;
return cost1.cost - cost2.cost;
}
/* Sets cost of (GROUP, CAND) pair to COST and record that it depends /* Sets cost of (GROUP, CAND) pair to COST and record that it depends
on invariants DEPENDS_ON and that the value used in expressing it on invariants DEPENDS_ON and that the value used in expressing it
is VALUE, and in case of iv elimination the comparison operator is COMP. */ is VALUE, and in case of iv elimination the comparison operator is COMP. */
...@@ -3354,7 +3451,7 @@ set_group_iv_cost (struct ivopts_data *data, ...@@ -3354,7 +3451,7 @@ set_group_iv_cost (struct ivopts_data *data,
{ {
unsigned i, s; unsigned i, s;
if (infinite_cost_p (cost)) if (cost.infinite_cost_p ())
{ {
BITMAP_FREE (depends_on); BITMAP_FREE (depends_on);
return; return;
...@@ -4170,7 +4267,7 @@ get_address_cost (bool symbol_present, bool var_present, ...@@ -4170,7 +4267,7 @@ get_address_cost (bool symbol_present, bool var_present,
else else
acost = data->costs[symbol_present][var_present][offset_p][ratio_p]; acost = data->costs[symbol_present][var_present][offset_p][ratio_p];
complexity = (symbol_present != 0) + (var_present != 0) + offset_p + ratio_p; complexity = (symbol_present != 0) + (var_present != 0) + offset_p + ratio_p;
return new_cost (cost + acost, complexity); return comp_cost (cost + acost, complexity);
} }
/* Calculate the SPEED or size cost of shiftadd EXPR in MODE. MULT is the /* Calculate the SPEED or size cost of shiftadd EXPR in MODE. MULT is the
...@@ -4207,12 +4304,12 @@ get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0, ...@@ -4207,12 +4304,12 @@ get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0,
? shiftsub1_cost (speed, mode, m) ? shiftsub1_cost (speed, mode, m)
: shiftsub0_cost (speed, mode, m))); : shiftsub0_cost (speed, mode, m)));
res = new_cost (MIN (as_cost, sa_cost), 0); res = comp_cost (MIN (as_cost, sa_cost), 0);
res = add_costs (res, mult_in_op1 ? cost0 : cost1); res += (mult_in_op1 ? cost0 : cost1);
STRIP_NOPS (multop); STRIP_NOPS (multop);
if (!is_gimple_val (multop)) if (!is_gimple_val (multop))
res = add_costs (res, force_expr_to_var_cost (multop, speed)); res += force_expr_to_var_cost (multop, speed);
*cost = res; *cost = res;
return true; return true;
...@@ -4277,7 +4374,7 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -4277,7 +4374,7 @@ force_expr_to_var_cost (tree expr, bool speed)
if (is_gimple_min_invariant (expr)) if (is_gimple_min_invariant (expr))
{ {
if (TREE_CODE (expr) == INTEGER_CST) if (TREE_CODE (expr) == INTEGER_CST)
return new_cost (integer_cost [speed], 0); return comp_cost (integer_cost [speed], 0);
if (TREE_CODE (expr) == ADDR_EXPR) if (TREE_CODE (expr) == ADDR_EXPR)
{ {
...@@ -4286,10 +4383,10 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -4286,10 +4383,10 @@ force_expr_to_var_cost (tree expr, bool speed)
if (TREE_CODE (obj) == VAR_DECL if (TREE_CODE (obj) == VAR_DECL
|| TREE_CODE (obj) == PARM_DECL || TREE_CODE (obj) == PARM_DECL
|| TREE_CODE (obj) == RESULT_DECL) || TREE_CODE (obj) == RESULT_DECL)
return new_cost (symbol_cost [speed], 0); return comp_cost (symbol_cost [speed], 0);
} }
return new_cost (address_cost [speed], 0); return comp_cost (address_cost [speed], 0);
} }
switch (TREE_CODE (expr)) switch (TREE_CODE (expr))
...@@ -4313,7 +4410,7 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -4313,7 +4410,7 @@ force_expr_to_var_cost (tree expr, bool speed)
default: default:
/* Just an arbitrary value, FIXME. */ /* Just an arbitrary value, FIXME. */
return new_cost (target_spill_cost[speed], 0); return comp_cost (target_spill_cost[speed], 0);
} }
if (op0 == NULL_TREE if (op0 == NULL_TREE
...@@ -4335,7 +4432,7 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -4335,7 +4432,7 @@ force_expr_to_var_cost (tree expr, bool speed)
case PLUS_EXPR: case PLUS_EXPR:
case MINUS_EXPR: case MINUS_EXPR:
case NEGATE_EXPR: case NEGATE_EXPR:
cost = new_cost (add_cost (speed, mode), 0); cost = comp_cost (add_cost (speed, mode), 0);
if (TREE_CODE (expr) != NEGATE_EXPR) if (TREE_CODE (expr) != NEGATE_EXPR)
{ {
tree mult = NULL_TREE; tree mult = NULL_TREE;
...@@ -4358,28 +4455,28 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -4358,28 +4455,28 @@ force_expr_to_var_cost (tree expr, bool speed)
tree inner_mode, outer_mode; tree inner_mode, outer_mode;
outer_mode = TREE_TYPE (expr); outer_mode = TREE_TYPE (expr);
inner_mode = TREE_TYPE (op0); inner_mode = TREE_TYPE (op0);
cost = new_cost (convert_cost (TYPE_MODE (outer_mode), cost = comp_cost (convert_cost (TYPE_MODE (outer_mode),
TYPE_MODE (inner_mode), speed), 0); TYPE_MODE (inner_mode), speed), 0);
} }
break; break;
case MULT_EXPR: case MULT_EXPR:
if (cst_and_fits_in_hwi (op0)) if (cst_and_fits_in_hwi (op0))
cost = new_cost (mult_by_coeff_cost (int_cst_value (op0), cost = comp_cost (mult_by_coeff_cost (int_cst_value (op0),
mode, speed), 0); mode, speed), 0);
else if (cst_and_fits_in_hwi (op1)) else if (cst_and_fits_in_hwi (op1))
cost = new_cost (mult_by_coeff_cost (int_cst_value (op1), cost = comp_cost (mult_by_coeff_cost (int_cst_value (op1),
mode, speed), 0); mode, speed), 0);
else else
return new_cost (target_spill_cost [speed], 0); return comp_cost (target_spill_cost [speed], 0);
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
cost = add_costs (cost, cost0); cost += cost0;
cost = add_costs (cost, cost1); cost += cost1;
/* Bound the cost by target_spill_cost. The parts of complicated /* Bound the cost by target_spill_cost. The parts of complicated
computations often are either loop invariant or at least can computations often are either loop invariant or at least can
...@@ -4438,7 +4535,7 @@ split_address_cost (struct ivopts_data *data, ...@@ -4438,7 +4535,7 @@ split_address_cost (struct ivopts_data *data,
if (depends_on) if (depends_on)
walk_tree (&addr, find_depends, depends_on, NULL); walk_tree (&addr, find_depends, depends_on, NULL);
return new_cost (target_spill_cost[data->speed], 0); return comp_cost (target_spill_cost[data->speed], 0);
} }
*offset += bitpos / BITS_PER_UNIT; *offset += bitpos / BITS_PER_UNIT;
...@@ -4538,7 +4635,7 @@ difference_cost (struct ivopts_data *data, ...@@ -4538,7 +4635,7 @@ difference_cost (struct ivopts_data *data,
if (integer_zerop (e1)) if (integer_zerop (e1))
{ {
comp_cost cost = force_var_cost (data, e2, depends_on); comp_cost cost = force_var_cost (data, e2, depends_on);
cost.cost += mult_by_coeff_cost (-1, mode, data->speed); cost += mult_by_coeff_cost (-1, mode, data->speed);
return cost; return cost;
} }
...@@ -4805,7 +4902,7 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4805,7 +4902,7 @@ get_computation_cost_at (struct ivopts_data *data,
ubase, build_int_cst (utype, 0), ubase, build_int_cst (utype, 0),
&symbol_present, &var_present, &offset, &symbol_present, &var_present, &offset,
depends_on); depends_on);
cost.cost /= avg_loop_niter (data->current_loop); cost /= avg_loop_niter (data->current_loop);
} }
else if (ratio == 1) else if (ratio == 1)
{ {
...@@ -4829,7 +4926,7 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4829,7 +4926,7 @@ get_computation_cost_at (struct ivopts_data *data,
ubase, real_cbase, ubase, real_cbase,
&symbol_present, &var_present, &offset, &symbol_present, &var_present, &offset,
depends_on); depends_on);
cost.cost /= avg_loop_niter (data->current_loop); cost /= avg_loop_niter (data->current_loop);
} }
else if (address_p else if (address_p
&& !POINTER_TYPE_P (ctype) && !POINTER_TYPE_P (ctype)
...@@ -4852,21 +4949,19 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4852,21 +4949,19 @@ get_computation_cost_at (struct ivopts_data *data,
ubase, real_cbase, ubase, real_cbase,
&symbol_present, &var_present, &offset, &symbol_present, &var_present, &offset,
depends_on); depends_on);
cost.cost /= avg_loop_niter (data->current_loop); cost /= avg_loop_niter (data->current_loop);
} }
else else
{ {
cost = force_var_cost (data, cbase, depends_on); cost = force_var_cost (data, cbase, depends_on);
cost = add_costs (cost, cost += difference_cost (data, ubase, build_int_cst (utype, 0),
difference_cost (data, &symbol_present, &var_present, &offset,
ubase, build_int_cst (utype, 0), depends_on);
&symbol_present, &var_present, cost /= avg_loop_niter (data->current_loop);
&offset, depends_on)); cost += add_cost (data->speed, TYPE_MODE (ctype));
cost.cost /= avg_loop_niter (data->current_loop);
cost.cost += add_cost (data->speed, TYPE_MODE (ctype));
} }
/* Record setup cost in scrach field. */ /* Record setup cost in scratch field. */
cost.scratch = cost.cost; cost.scratch = cost.cost;
if (inv_expr && depends_on && *depends_on) if (inv_expr && depends_on && *depends_on)
...@@ -4887,26 +4982,24 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4887,26 +4982,24 @@ get_computation_cost_at (struct ivopts_data *data,
(symbol/var1/const parts may be omitted). If we are looking for an (symbol/var1/const parts may be omitted). If we are looking for an
address, find the cost of addressing this. */ address, find the cost of addressing this. */
if (address_p) if (address_p)
return add_costs (cost, return cost + get_address_cost (symbol_present, var_present,
get_address_cost (symbol_present, var_present, offset, ratio, cstepi,
offset, ratio, cstepi, mem_mode,
mem_mode, TYPE_ADDR_SPACE (TREE_TYPE (utype)),
TYPE_ADDR_SPACE (TREE_TYPE (utype)), speed, stmt_is_after_inc, can_autoinc);
speed, stmt_is_after_inc,
can_autoinc));
/* Otherwise estimate the costs for computing the expression. */ /* Otherwise estimate the costs for computing the expression. */
if (!symbol_present && !var_present && !offset) if (!symbol_present && !var_present && !offset)
{ {
if (ratio != 1) if (ratio != 1)
cost.cost += mult_by_coeff_cost (ratio, TYPE_MODE (ctype), speed); cost += mult_by_coeff_cost (ratio, TYPE_MODE (ctype), speed);
return cost; return cost;
} }
/* Symbol + offset should be compile-time computable so consider that they /* Symbol + offset should be compile-time computable so consider that they
are added once to the variable, if present. */ are added once to the variable, if present. */
if (var_present && (symbol_present || offset)) if (var_present && (symbol_present || offset))
cost.cost += adjust_setup_cost (data, cost += adjust_setup_cost (data,
add_cost (speed, TYPE_MODE (ctype))); add_cost (speed, TYPE_MODE (ctype)));
/* Having offset does not affect runtime cost in case it is added to /* Having offset does not affect runtime cost in case it is added to
...@@ -4914,11 +5007,11 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4914,11 +5007,11 @@ get_computation_cost_at (struct ivopts_data *data,
if (offset) if (offset)
cost.complexity++; cost.complexity++;
cost.cost += add_cost (speed, TYPE_MODE (ctype)); cost += add_cost (speed, TYPE_MODE (ctype));
aratio = ratio > 0 ? ratio : -ratio; aratio = ratio > 0 ? ratio : -ratio;
if (aratio != 1) if (aratio != 1)
cost.cost += mult_by_coeff_cost (aratio, TYPE_MODE (ctype), speed); cost += mult_by_coeff_cost (aratio, TYPE_MODE (ctype), speed);
return cost; return cost;
fallback: fallback:
...@@ -4935,9 +5028,7 @@ fallback: ...@@ -4935,9 +5028,7 @@ fallback:
if (address_p) if (address_p)
comp = build_simple_mem_ref (comp); comp = build_simple_mem_ref (comp);
cost = new_cost (computation_cost (comp, speed), 0); return comp_cost (computation_cost (comp, speed), 0);
cost.scratch = 0;
return cost;
} }
} }
...@@ -4983,7 +5074,7 @@ determine_group_iv_cost_generic (struct ivopts_data *data, ...@@ -4983,7 +5074,7 @@ determine_group_iv_cost_generic (struct ivopts_data *data,
set_group_iv_cost (data, group, cand, cost, depends_on, set_group_iv_cost (data, group, cand, cost, depends_on,
NULL_TREE, ERROR_MARK, inv_expr); NULL_TREE, ERROR_MARK, inv_expr);
return !infinite_cost_p (cost); return !cost.infinite_cost_p ();
} }
/* Determines cost of computing uses in GROUP with CAND in addresses. */ /* Determines cost of computing uses in GROUP with CAND in addresses. */
...@@ -5003,10 +5094,10 @@ determine_group_iv_cost_address (struct ivopts_data *data, ...@@ -5003,10 +5094,10 @@ determine_group_iv_cost_address (struct ivopts_data *data,
&depends_on, &can_autoinc, &inv_expr); &depends_on, &can_autoinc, &inv_expr);
sum_cost = cost; sum_cost = cost;
if (!infinite_cost_p (sum_cost) && cand->ainc_use == use) if (!sum_cost.infinite_cost_p () && cand->ainc_use == use)
{ {
if (can_autoinc) if (can_autoinc)
sum_cost.cost -= cand->cost_step; sum_cost -= cand->cost_step;
/* If we generated the candidate solely for exploiting autoincrement /* If we generated the candidate solely for exploiting autoincrement
opportunities, and it turns out it can't be used, set the cost to opportunities, and it turns out it can't be used, set the cost to
infinity to make sure we ignore it. */ infinity to make sure we ignore it. */
...@@ -5015,9 +5106,9 @@ determine_group_iv_cost_address (struct ivopts_data *data, ...@@ -5015,9 +5106,9 @@ determine_group_iv_cost_address (struct ivopts_data *data,
} }
/* Uses in a group can share setup code, so only add setup cost once. */ /* Uses in a group can share setup code, so only add setup cost once. */
cost.cost -= cost.scratch; cost -= cost.scratch;
/* Compute and add costs for rest uses of this group. */ /* Compute and add costs for rest uses of this group. */
for (i = 1; i < group->vuses.length () && !infinite_cost_p (sum_cost); i++) for (i = 1; i < group->vuses.length () && !sum_cost.infinite_cost_p (); i++)
{ {
struct iv_use *next = group->vuses[i]; struct iv_use *next = group->vuses[i];
...@@ -5042,15 +5133,15 @@ determine_group_iv_cost_address (struct ivopts_data *data, ...@@ -5042,15 +5133,15 @@ determine_group_iv_cost_address (struct ivopts_data *data,
cost = get_computation_cost (data, next, cand, true, cost = get_computation_cost (data, next, cand, true,
NULL, &can_autoinc, NULL); NULL, &can_autoinc, NULL);
/* Remove setup cost. */ /* Remove setup cost. */
if (!infinite_cost_p (cost)) if (!cost.infinite_cost_p ())
cost.cost -= cost.scratch; cost -= cost.scratch;
} }
sum_cost = add_costs (sum_cost, cost); sum_cost += cost;
} }
set_group_iv_cost (data, group, cand, sum_cost, depends_on, set_group_iv_cost (data, group, cand, sum_cost, depends_on,
NULL_TREE, ERROR_MARK, inv_expr); NULL_TREE, ERROR_MARK, inv_expr);
return !infinite_cost_p (sum_cost); return !sum_cost.infinite_cost_p ();
} }
/* Computes value of candidate CAND at position AT in iteration NITER, and /* Computes value of candidate CAND at position AT in iteration NITER, and
...@@ -5513,11 +5604,11 @@ determine_group_iv_cost_cond (struct ivopts_data *data, ...@@ -5513,11 +5604,11 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
TODO: The constant that we're subtracting from the cost should TODO: The constant that we're subtracting from the cost should
be target-dependent. This information should be added to the be target-dependent. This information should be added to the
target costs for each backend. */ target costs for each backend. */
if (!infinite_cost_p (elim_cost) /* Do not try to decrease infinite! */ if (!elim_cost.infinite_cost_p () /* Do not try to decrease infinite! */
&& integer_zerop (*bound_cst) && integer_zerop (*bound_cst)
&& (operand_equal_p (*control_var, cand->var_after, 0) && (operand_equal_p (*control_var, cand->var_after, 0)
|| operand_equal_p (*control_var, cand->var_before, 0))) || operand_equal_p (*control_var, cand->var_before, 0)))
elim_cost.cost -= 1; elim_cost -= 1;
express_cost = get_computation_cost (data, use, cand, false, express_cost = get_computation_cost (data, use, cand, false,
&depends_on_express, NULL, &depends_on_express, NULL,
...@@ -5531,10 +5622,10 @@ determine_group_iv_cost_cond (struct ivopts_data *data, ...@@ -5531,10 +5622,10 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
bound_cost.cost = parm_decl_cost (data, *bound_cst); bound_cost.cost = parm_decl_cost (data, *bound_cst);
else if (TREE_CODE (*bound_cst) == INTEGER_CST) else if (TREE_CODE (*bound_cst) == INTEGER_CST)
bound_cost.cost = 0; bound_cost.cost = 0;
express_cost.cost += bound_cost.cost; express_cost += bound_cost;
/* Choose the better approach, preferring the eliminated IV. */ /* Choose the better approach, preferring the eliminated IV. */
if (compare_costs (elim_cost, express_cost) <= 0) if (elim_cost <= express_cost)
{ {
cost = elim_cost; cost = elim_cost;
depends_on = depends_on_elim; depends_on = depends_on_elim;
...@@ -5559,7 +5650,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data, ...@@ -5559,7 +5650,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
if (depends_on_express) if (depends_on_express)
BITMAP_FREE (depends_on_express); BITMAP_FREE (depends_on_express);
return !infinite_cost_p (cost); return !cost.infinite_cost_p ();
} }
/* Determines cost of computing uses in GROUP with CAND. Returns false /* Determines cost of computing uses in GROUP with CAND. Returns false
...@@ -5604,7 +5695,7 @@ autoinc_possible_for_pair (struct ivopts_data *data, struct iv_use *use, ...@@ -5604,7 +5695,7 @@ autoinc_possible_for_pair (struct ivopts_data *data, struct iv_use *use,
BITMAP_FREE (depends_on); BITMAP_FREE (depends_on);
return !infinite_cost_p (cost) && can_autoinc; return !cost.infinite_cost_p () && can_autoinc;
} }
/* Examine IP_ORIGINAL candidates to see if they are incremented next to a /* Examine IP_ORIGINAL candidates to see if they are incremented next to a
...@@ -5770,7 +5861,7 @@ determine_group_iv_costs (struct ivopts_data *data) ...@@ -5770,7 +5861,7 @@ determine_group_iv_costs (struct ivopts_data *data)
for (j = 0; j < group->n_map_members; j++) for (j = 0; j < group->n_map_members; j++)
{ {
if (!group->cost_map[j].cand if (!group->cost_map[j].cand
|| infinite_cost_p (group->cost_map[j].cost)) || group->cost_map[j].cost.infinite_cost_p ())
continue; continue;
fprintf (dump_file, " %d\t%d\t%d\t", fprintf (dump_file, " %d\t%d\t%d\t",
...@@ -5944,19 +6035,16 @@ determine_set_costs (struct ivopts_data *data) ...@@ -5944,19 +6035,16 @@ determine_set_costs (struct ivopts_data *data)
static bool static bool
cheaper_cost_pair (struct cost_pair *a, struct cost_pair *b) cheaper_cost_pair (struct cost_pair *a, struct cost_pair *b)
{ {
int cmp;
if (!a) if (!a)
return false; return false;
if (!b) if (!b)
return true; return true;
cmp = compare_costs (a->cost, b->cost); if (a->cost < b->cost)
if (cmp < 0)
return true; return true;
if (cmp > 0) if (b->cost < a->cost)
return false; return false;
/* In case the costs are the same, prefer the cheaper candidate. */ /* In case the costs are the same, prefer the cheaper candidate. */
...@@ -5982,11 +6070,11 @@ iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs) ...@@ -5982,11 +6070,11 @@ iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs)
{ {
comp_cost cost = ivs->cand_use_cost; comp_cost cost = ivs->cand_use_cost;
cost.cost += ivs->cand_cost; cost += ivs->cand_cost;
cost.cost += ivopts_global_cost_for_size (data, cost += ivopts_global_cost_for_size (data,
ivs->n_regs ivs->n_regs
+ ivs->used_inv_exprs->elements ()); + ivs->used_inv_exprs->elements ());
ivs->cost = cost; ivs->cost = cost;
} }
...@@ -6040,7 +6128,7 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6040,7 +6128,7 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_remove_invariants (ivs, cp->cand->depends_on); iv_ca_set_remove_invariants (ivs, cp->cand->depends_on);
} }
ivs->cand_use_cost = sub_costs (ivs->cand_use_cost, cp->cost); ivs->cand_use_cost -= cp->cost;
iv_ca_set_remove_invariants (ivs, cp->depends_on); iv_ca_set_remove_invariants (ivs, cp->depends_on);
...@@ -6106,7 +6194,7 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6106,7 +6194,7 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_add_invariants (ivs, cp->cand->depends_on); iv_ca_set_add_invariants (ivs, cp->cand->depends_on);
} }
ivs->cand_use_cost = add_costs (ivs->cand_use_cost, cp->cost); ivs->cand_use_cost += cp->cost;
iv_ca_set_add_invariants (ivs, cp->depends_on); iv_ca_set_add_invariants (ivs, cp->depends_on);
if (cp->inv_expr != NULL) if (cp->inv_expr != NULL)
...@@ -6350,7 +6438,8 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs) ...@@ -6350,7 +6438,8 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
unsigned i; unsigned i;
comp_cost cost = iv_ca_cost (ivs); comp_cost cost = iv_ca_cost (ivs);
fprintf (file, " cost: %d (complexity %d)\n", cost.cost, cost.complexity); fprintf (file, " cost: %d (complexity %d)\n", cost.cost,
cost.complexity);
fprintf (file, " cand_cost: %d\n cand_group_cost: %d (complexity %d)\n", fprintf (file, " cand_cost: %d\n cand_group_cost: %d (complexity %d)\n",
ivs->cand_cost, ivs->cand_use_cost.cost, ivs->cand_cost, ivs->cand_use_cost.cost,
ivs->cand_use_cost.complexity); ivs->cand_use_cost.complexity);
...@@ -6361,8 +6450,9 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs) ...@@ -6361,8 +6450,9 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
struct iv_group *group = data->vgroups[i]; struct iv_group *group = data->vgroups[i];
struct cost_pair *cp = iv_ca_cand_for_group (ivs, group); struct cost_pair *cp = iv_ca_cand_for_group (ivs, group);
if (cp) if (cp)
fprintf (file, " group:%d --> iv_cand:%d, cost=(%d,%d)\n", fprintf (file, " group:%d --> iv_cand:%d, cost=(%d,%d)\n",
group->id, cp->cand->id, cp->cost.cost, cp->cost.complexity); group->id, cp->cand->id, cp->cost.cost,
cp->cost.complexity);
else else
fprintf (file, " group:%d --> ??\n", group->id); fprintf (file, " group:%d --> ??\n", group->id);
} }
...@@ -6480,7 +6570,7 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6480,7 +6570,7 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_cp (data, ivs, group, cp); iv_ca_set_cp (data, ivs, group, cp);
acost = iv_ca_cost (ivs); acost = iv_ca_cost (ivs);
if (compare_costs (acost, best_cost) < 0) if (acost < best_cost)
{ {
best_cost = acost; best_cost = acost;
new_cp = cp; new_cp = cp;
...@@ -6503,7 +6593,7 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6503,7 +6593,7 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_cp (data, ivs, group, cp); iv_ca_set_cp (data, ivs, group, cp);
acost = iv_ca_cost (ivs); acost = iv_ca_cost (ivs);
if (compare_costs (acost, best_cost) < 0) if (acost < best_cost)
{ {
best_cost = acost; best_cost = acost;
new_cp = cp; new_cp = cp;
...@@ -6555,7 +6645,7 @@ iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6555,7 +6645,7 @@ iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs,
acost = iv_ca_narrow (data, ivs, cand, except_cand, &act_delta); acost = iv_ca_narrow (data, ivs, cand, except_cand, &act_delta);
if (compare_costs (acost, best_cost) < 0) if (acost < best_cost)
{ {
best_cost = acost; best_cost = acost;
iv_ca_delta_free (&best_delta); iv_ca_delta_free (&best_delta);
...@@ -6668,7 +6758,7 @@ iv_ca_replace (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6668,7 +6758,7 @@ iv_ca_replace (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_delta_commit (data, ivs, act_delta, false); iv_ca_delta_commit (data, ivs, act_delta, false);
act_delta = iv_ca_delta_join (act_delta, tmp_delta); act_delta = iv_ca_delta_join (act_delta, tmp_delta);
if (compare_costs (acost, orig_cost) < 0) if (acost < orig_cost)
{ {
*delta = act_delta; *delta = act_delta;
return acost; return acost;
...@@ -6737,7 +6827,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6737,7 +6827,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_no_cp (data, ivs, group); iv_ca_set_no_cp (data, ivs, group);
act_delta = iv_ca_delta_add (group, NULL, cp, act_delta); act_delta = iv_ca_delta_add (group, NULL, cp, act_delta);
if (compare_costs (act_cost, best_cost) < 0) if (act_cost < best_cost)
{ {
best_cost = act_cost; best_cost = act_cost;
...@@ -6748,7 +6838,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6748,7 +6838,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_delta_free (&act_delta); iv_ca_delta_free (&act_delta);
} }
if (infinite_cost_p (best_cost)) if (best_cost.infinite_cost_p ())
{ {
for (i = 0; i < group->n_map_members; i++) for (i = 0; i < group->n_map_members; i++)
{ {
...@@ -6777,7 +6867,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6777,7 +6867,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_cand_for_group (ivs, group), iv_ca_cand_for_group (ivs, group),
cp, act_delta); cp, act_delta);
if (compare_costs (act_cost, best_cost) < 0) if (act_cost < best_cost)
{ {
best_cost = act_cost; best_cost = act_cost;
...@@ -6793,7 +6883,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs, ...@@ -6793,7 +6883,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_delta_commit (data, ivs, best_delta, true); iv_ca_delta_commit (data, ivs, best_delta, true);
iv_ca_delta_free (&best_delta); iv_ca_delta_free (&best_delta);
return !infinite_cost_p (best_cost); return !best_cost.infinite_cost_p ();
} }
/* Finds an initial assignment of candidates to uses. */ /* Finds an initial assignment of candidates to uses. */
...@@ -6849,7 +6939,7 @@ try_improve_iv_set (struct ivopts_data *data, ...@@ -6849,7 +6939,7 @@ try_improve_iv_set (struct ivopts_data *data,
act_delta = iv_ca_delta_join (act_delta, tmp_delta); act_delta = iv_ca_delta_join (act_delta, tmp_delta);
} }
if (compare_costs (acost, best_cost) < 0) if (acost < best_cost)
{ {
best_cost = acost; best_cost = acost;
iv_ca_delta_free (&best_delta); iv_ca_delta_free (&best_delta);
...@@ -6883,7 +6973,7 @@ try_improve_iv_set (struct ivopts_data *data, ...@@ -6883,7 +6973,7 @@ try_improve_iv_set (struct ivopts_data *data,
} }
iv_ca_delta_commit (data, ivs, best_delta, true); iv_ca_delta_commit (data, ivs, best_delta, true);
gcc_assert (compare_costs (best_cost, iv_ca_cost (ivs)) == 0); gcc_assert (best_cost == iv_ca_cost (ivs));
iv_ca_delta_free (&best_delta); iv_ca_delta_free (&best_delta);
return true; return true;
} }
...@@ -6953,7 +7043,7 @@ find_optimal_iv_set (struct ivopts_data *data) ...@@ -6953,7 +7043,7 @@ find_optimal_iv_set (struct ivopts_data *data)
} }
/* Choose the one with the best cost. */ /* Choose the one with the best cost. */
if (compare_costs (origcost, cost) <= 0) if (origcost <= cost)
{ {
if (set) if (set)
iv_ca_free (&set); iv_ca_free (&set);
......
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