Commit 5322d07e by Nathan Froyd

expmed.h (alg_hash, [...]): Delete macro definitions and re-purpose as inline functions.

	* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
	smod_pow2_cheap, zero_cost, add_cost, neg_cost, shift_cost)
	shiftadd_cost, shiftsub0_cost, shiftsub1_cost, mul_cost,
	sdiv_cost, udiv_cost, mul_widen_cost, mul_highpart_cost): Delete
	macro definitions and re-purpose as inline functions.
	(alg_hash_entry_ptr, set_alg_hash_used_p, sdiv_pow2_cheap_ptr,
	set_sdiv_pow2_cheap, smod_pow2_cheap_ptr, set_smod_pow2_cheap,
	zero_cost_ptr, set_zero_cost, add_cost_ptr, set_add_cost,
	neg_cost_ptr, set_neg_cost, shift_cost_ptr, set_shift_cost,
	shiftadd_cost_ptr, set_shiftadd_cost, shiftsub0_cost_ptr,
	set_shiftsub0_cost, shiftsub1_cost_ptr, set_shiftsub1_cost,
	mul_cost_ptr, set_mul_cost, sdiv_cost_ptr, set_sdiv_cost,
	udiv_cost_ptr, set_udiv_cost, mul_widen_cost_ptr,
	set_mul_widen_cost, mul_highpart_cost_ptr, set_mul_highpart_cost):
	New functions.
	(convert_cost_ptr): New function, split out from...
	(set_convert_cost, convert_cost): ...here.
	* expmed.c, tree-ssa-loop-ivopts.c: Update for new functions.
	* gimple-ssa-strength-reduction.c: Likewise.

From-SVN: r189919
parent ccbc132f
2012-07-27 Nathan Froyd <froydnj@gcc.gnu.org>
* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
smod_pow2_cheap, zero_cost, add_cost, neg_cost, shift_cost)
shiftadd_cost, shiftsub0_cost, shiftsub1_cost, mul_cost,
sdiv_cost, udiv_cost, mul_widen_cost, mul_highpart_cost): Delete
macro definitions and re-purpose as inline functions.
(alg_hash_entry_ptr, set_alg_hash_used_p, sdiv_pow2_cheap_ptr,
set_sdiv_pow2_cheap, smod_pow2_cheap_ptr, set_smod_pow2_cheap,
zero_cost_ptr, set_zero_cost, add_cost_ptr, set_add_cost,
neg_cost_ptr, set_neg_cost, shift_cost_ptr, set_shift_cost,
shiftadd_cost_ptr, set_shiftadd_cost, shiftsub0_cost_ptr,
set_shiftsub0_cost, shiftsub1_cost_ptr, set_shiftsub1_cost,
mul_cost_ptr, set_mul_cost, sdiv_cost_ptr, set_sdiv_cost,
udiv_cost_ptr, set_udiv_cost, mul_widen_cost_ptr,
set_mul_widen_cost, mul_highpart_cost_ptr, set_mul_highpart_cost):
New functions.
(convert_cost_ptr): New function, split out from...
(set_convert_cost, convert_cost): ...here.
* expmed.c, tree-ssa-loop-ivopts.c: Update for new functions.
* gimple-ssa-strength-reduction.c: Likewise.
2012-07-20 Ryan Mansfield <rmansfield@qnx.com> 2012-07-20 Ryan Mansfield <rmansfield@qnx.com>
* gcc.c (main): Move GCC_DRIVER_HOST_INITIALIZATION after * gcc.c (main): Move GCC_DRIVER_HOST_INITIALIZATION after
......
...@@ -143,20 +143,24 @@ init_expmed_one_mode (struct init_expmed_rtl *all, ...@@ -143,20 +143,24 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
PUT_MODE (&all->shift_sub1, mode); PUT_MODE (&all->shift_sub1, mode);
PUT_MODE (&all->convert, mode); PUT_MODE (&all->convert, mode);
add_cost[speed][mode] = set_src_cost (&all->plus, speed); set_add_cost (speed, mode, set_src_cost (&all->plus, speed));
neg_cost[speed][mode] = set_src_cost (&all->neg, speed); set_neg_cost (speed, mode, set_src_cost (&all->neg, speed));
mul_cost[speed][mode] = set_src_cost (&all->mult, speed); set_mul_cost (speed, mode, set_src_cost (&all->mult, speed));
sdiv_cost[speed][mode] = set_src_cost (&all->sdiv, speed); set_sdiv_cost (speed, mode, set_src_cost (&all->sdiv, speed));
udiv_cost[speed][mode] = set_src_cost (&all->udiv, speed); set_udiv_cost (speed, mode, set_src_cost (&all->udiv, speed));
sdiv_pow2_cheap[speed][mode] = (set_src_cost (&all->sdiv_32, speed) set_sdiv_pow2_cheap (speed, mode, (set_src_cost (&all->sdiv_32, speed)
<= 2 * add_cost[speed][mode]); <= 2 * add_cost (speed, mode)));
smod_pow2_cheap[speed][mode] = (set_src_cost (&all->smod_32, speed) set_smod_pow2_cheap (speed, mode, (set_src_cost (&all->smod_32, speed)
<= 4 * add_cost[speed][mode]); <= 4 * add_cost (speed, mode)));
shift_cost[speed][mode][0] = 0; set_shift_cost (speed, mode, 0, 0);
shiftadd_cost[speed][mode][0] = shiftsub0_cost[speed][mode][0] {
= shiftsub1_cost[speed][mode][0] = add_cost[speed][mode]; int cost = add_cost (speed, mode);
set_shiftadd_cost (speed, mode, 0, cost);
set_shiftsub0_cost (speed, mode, 0, cost);
set_shiftsub1_cost (speed, mode, 0, cost);
}
n = MIN (MAX_BITS_PER_WORD, mode_bitsize); n = MIN (MAX_BITS_PER_WORD, mode_bitsize);
for (m = 1; m < n; m++) for (m = 1; m < n; m++)
...@@ -164,10 +168,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all, ...@@ -164,10 +168,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
XEXP (&all->shift, 1) = all->cint[m]; XEXP (&all->shift, 1) = all->cint[m];
XEXP (&all->shift_mult, 1) = all->pow2[m]; XEXP (&all->shift_mult, 1) = all->pow2[m];
shift_cost[speed][mode][m] = set_src_cost (&all->shift, speed); set_shift_cost (speed, mode, m, set_src_cost (&all->shift, speed));
shiftadd_cost[speed][mode][m] = set_src_cost (&all->shift_add, speed); set_shiftadd_cost (speed, mode, m, set_src_cost (&all->shift_add, speed));
shiftsub0_cost[speed][mode][m] = set_src_cost (&all->shift_sub0, speed); set_shiftsub0_cost (speed, mode, m, set_src_cost (&all->shift_sub0, speed));
shiftsub1_cost[speed][mode][m] = set_src_cost (&all->shift_sub1, speed); set_shiftsub1_cost (speed, mode, m, set_src_cost (&all->shift_sub1, speed));
} }
if (SCALAR_INT_MODE_P (mode)) if (SCALAR_INT_MODE_P (mode))
...@@ -181,10 +185,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all, ...@@ -181,10 +185,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
PUT_MODE (&all->wide_lshr, wider_mode); PUT_MODE (&all->wide_lshr, wider_mode);
XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize); XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize);
mul_widen_cost[speed][wider_mode] set_mul_widen_cost (speed, wider_mode, set_src_cost (&all->wide_mult, speed));
= set_src_cost (&all->wide_mult, speed); set_mul_highpart_cost (speed, mode, set_src_cost (&all->wide_trunc, speed));
mul_highpart_cost[speed][mode]
= set_src_cost (&all->wide_trunc, speed);
} }
for (mode_from = GET_CLASS_NARROWEST_MODE (MODE_INT); for (mode_from = GET_CLASS_NARROWEST_MODE (MODE_INT);
...@@ -295,7 +297,7 @@ init_expmed (void) ...@@ -295,7 +297,7 @@ init_expmed (void)
for (speed = 0; speed < 2; speed++) for (speed = 0; speed < 2; speed++)
{ {
crtl->maybe_hot_insn_p = speed; crtl->maybe_hot_insn_p = speed;
zero_cost[speed] = set_src_cost (const0_rtx, speed); set_zero_cost (speed, set_src_cost (const0_rtx, speed));
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode; mode != VOIDmode;
...@@ -308,10 +310,13 @@ init_expmed (void) ...@@ -308,10 +310,13 @@ init_expmed (void)
init_expmed_one_mode (&all, mode, speed); init_expmed_one_mode (&all, mode, speed);
} }
if (alg_hash_used_p) if (alg_hash_used_p ())
memset (alg_hash, 0, sizeof (alg_hash)); {
struct alg_hash_entry *p = alg_hash_entry_ptr (0);
memset (p, 0, sizeof (*p) * NUM_ALG_HASH_ENTRIES);
}
else else
alg_hash_used_p = true; set_alg_hash_used_p (true);
default_rtl_profile (); default_rtl_profile ();
} }
...@@ -2259,8 +2264,9 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, ...@@ -2259,8 +2264,9 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
&& INTVAL (op1) > 0 && INTVAL (op1) > 0
&& INTVAL (op1) < GET_MODE_PRECISION (mode) && INTVAL (op1) < GET_MODE_PRECISION (mode)
&& INTVAL (op1) < MAX_BITS_PER_WORD && INTVAL (op1) < MAX_BITS_PER_WORD
&& shift_cost[speed][mode][INTVAL (op1)] > INTVAL (op1) * add_cost[speed][mode] && (shift_cost (speed, mode, INTVAL (op1))
&& shift_cost[speed][mode][INTVAL (op1)] != MAX_COST) > INTVAL (op1) * add_cost (speed, mode))
&& shift_cost (speed, mode, INTVAL (op1)) != MAX_COST)
{ {
int i; int i;
for (i = 0; i < INTVAL (op1); i++) for (i = 0; i < INTVAL (op1); i++)
...@@ -2436,6 +2442,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2436,6 +2442,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
enum alg_code cache_alg = alg_zero; enum alg_code cache_alg = alg_zero;
bool speed = optimize_insn_for_speed_p (); bool speed = optimize_insn_for_speed_p ();
enum machine_mode imode; enum machine_mode imode;
struct alg_hash_entry *entry_ptr;
/* Indicate that no algorithm is yet found. If no algorithm /* Indicate that no algorithm is yet found. If no algorithm
is found, this value will be returned and indicate failure. */ is found, this value will be returned and indicate failure. */
...@@ -2470,13 +2477,13 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2470,13 +2477,13 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
fail now. */ fail now. */
if (t == 0) if (t == 0)
{ {
if (MULT_COST_LESS (cost_limit, zero_cost[speed])) if (MULT_COST_LESS (cost_limit, zero_cost (speed)))
return; return;
else else
{ {
alg_out->ops = 1; alg_out->ops = 1;
alg_out->cost.cost = zero_cost[speed]; alg_out->cost.cost = zero_cost (speed);
alg_out->cost.latency = zero_cost[speed]; alg_out->cost.latency = zero_cost (speed);
alg_out->op[0] = alg_zero; alg_out->op[0] = alg_zero;
return; return;
} }
...@@ -2492,19 +2499,20 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2492,19 +2499,20 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
hash_index = (t ^ (unsigned int) mode ^ (speed * 256)) % NUM_ALG_HASH_ENTRIES; hash_index = (t ^ (unsigned int) mode ^ (speed * 256)) % NUM_ALG_HASH_ENTRIES;
/* See if we already know what to do for T. */ /* See if we already know what to do for T. */
if (alg_hash[hash_index].t == t entry_ptr = alg_hash_entry_ptr (hash_index);
&& alg_hash[hash_index].mode == mode if (entry_ptr->t == t
&& alg_hash[hash_index].mode == mode && entry_ptr->mode == mode
&& alg_hash[hash_index].speed == speed && entry_ptr->mode == mode
&& alg_hash[hash_index].alg != alg_unknown) && entry_ptr->speed == speed
&& entry_ptr->alg != alg_unknown)
{ {
cache_alg = alg_hash[hash_index].alg; cache_alg = entry_ptr->alg;
if (cache_alg == alg_impossible) if (cache_alg == alg_impossible)
{ {
/* The cache tells us that it's impossible to synthesize /* The cache tells us that it's impossible to synthesize
multiplication by T within alg_hash[hash_index].cost. */ multiplication by T within entry_ptr->cost. */
if (!CHEAPER_MULT_COST (&alg_hash[hash_index].cost, cost_limit)) if (!CHEAPER_MULT_COST (&entry_ptr->cost, cost_limit))
/* COST_LIMIT is at least as restrictive as the one /* COST_LIMIT is at least as restrictive as the one
recorded in the hash table, in which case we have no recorded in the hash table, in which case we have no
hope of synthesizing a multiplication. Just hope of synthesizing a multiplication. Just
...@@ -2518,7 +2526,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2518,7 +2526,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
} }
else else
{ {
if (CHEAPER_MULT_COST (cost_limit, &alg_hash[hash_index].cost)) if (CHEAPER_MULT_COST (cost_limit, &entry_ptr->cost))
/* The cached algorithm shows that this multiplication /* The cached algorithm shows that this multiplication
requires more cost than COST_LIMIT. Just return. This requires more cost than COST_LIMIT. Just return. This
way, we don't clobber this cache entry with way, we don't clobber this cache entry with
...@@ -2564,10 +2572,10 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2564,10 +2572,10 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
q = t >> m; q = t >> m;
/* The function expand_shift will choose between a shift and /* The function expand_shift will choose between a shift and
a sequence of additions, so the observed cost is given as a sequence of additions, so the observed cost is given as
MIN (m * add_cost[speed][mode], shift_cost[speed][mode][m]). */ MIN (m * add_cost(speed, mode), shift_cost(speed, mode, m)). */
op_cost = m * add_cost[speed][mode]; op_cost = m * add_cost (speed, mode);
if (shift_cost[speed][mode][m] < op_cost) if (shift_cost (speed, mode, m) < op_cost)
op_cost = shift_cost[speed][mode][m]; op_cost = shift_cost (speed, mode, m);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, q, &new_limit, mode); synth_mult (alg_in, q, &new_limit, mode);
...@@ -2594,11 +2602,11 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2594,11 +2602,11 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
q = ~(~orig_t >> m); q = ~(~orig_t >> m);
/* The function expand_shift will choose between a shift /* The function expand_shift will choose between a shift
and a sequence of additions, so the observed cost is and a sequence of additions, so the observed cost is
given as MIN (m * add_cost[speed][mode], given as MIN (m * add_cost(speed, mode),
shift_cost[speed][mode][m]). */ shift_cost(speed, mode, m)). */
op_cost = m * add_cost[speed][mode]; op_cost = m * add_cost (speed, mode);
if (shift_cost[speed][mode][m] < op_cost) if (shift_cost (speed, mode, m) < op_cost)
op_cost = shift_cost[speed][mode][m]; op_cost = shift_cost (speed, mode, m);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, q, &new_limit, mode); synth_mult (alg_in, q, &new_limit, mode);
...@@ -2640,7 +2648,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2640,7 +2648,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
{ {
/* T ends with ...111. Multiply by (T + 1) and subtract 1. */ /* T ends with ...111. Multiply by (T + 1) and subtract 1. */
op_cost = add_cost[speed][mode]; op_cost = add_cost (speed, mode);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, t + 1, &new_limit, mode); synth_mult (alg_in, t + 1, &new_limit, mode);
...@@ -2660,7 +2668,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2660,7 +2668,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
{ {
/* T ends with ...01 or ...011. Multiply by (T - 1) and add 1. */ /* T ends with ...01 or ...011. Multiply by (T - 1) and add 1. */
op_cost = add_cost[speed][mode]; op_cost = add_cost (speed, mode);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, t - 1, &new_limit, mode); synth_mult (alg_in, t - 1, &new_limit, mode);
...@@ -2682,7 +2690,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2682,7 +2690,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
m = exact_log2 (-orig_t + 1); m = exact_log2 (-orig_t + 1);
if (m >= 0 && m < maxm) if (m >= 0 && m < maxm)
{ {
op_cost = shiftsub1_cost[speed][mode][m]; op_cost = shiftsub1_cost (speed, mode, m);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m, synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m,
...@@ -2729,14 +2737,14 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2729,14 +2737,14 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
equal to its cost, otherwise assume that on superscalar equal to its cost, otherwise assume that on superscalar
hardware the shift may be executed concurrently with the hardware the shift may be executed concurrently with the
earlier steps in the algorithm. */ earlier steps in the algorithm. */
op_cost = add_cost[speed][mode] + shift_cost[speed][mode][m]; op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
if (shiftadd_cost[speed][mode][m] < op_cost) if (shiftadd_cost (speed, mode, m) < op_cost)
{ {
op_cost = shiftadd_cost[speed][mode][m]; op_cost = shiftadd_cost (speed, mode, m);
op_latency = op_cost; op_latency = op_cost;
} }
else else
op_latency = add_cost[speed][mode]; op_latency = add_cost (speed, mode);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_latency; new_limit.latency = best_cost.latency - op_latency;
...@@ -2768,14 +2776,14 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2768,14 +2776,14 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
equal to it's cost, otherwise assume that on superscalar equal to it's cost, otherwise assume that on superscalar
hardware the shift may be executed concurrently with the hardware the shift may be executed concurrently with the
earlier steps in the algorithm. */ earlier steps in the algorithm. */
op_cost = add_cost[speed][mode] + shift_cost[speed][mode][m]; op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
if (shiftsub0_cost[speed][mode][m] < op_cost) if (shiftsub0_cost (speed, mode, m) < op_cost)
{ {
op_cost = shiftsub0_cost[speed][mode][m]; op_cost = shiftsub0_cost (speed, mode, m);
op_latency = op_cost; op_latency = op_cost;
} }
else else
op_latency = add_cost[speed][mode]; op_latency = add_cost (speed, mode);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_latency; new_limit.latency = best_cost.latency - op_latency;
...@@ -2809,7 +2817,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2809,7 +2817,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
m = exact_log2 (q); m = exact_log2 (q);
if (m >= 0 && m < maxm) if (m >= 0 && m < maxm)
{ {
op_cost = shiftadd_cost[speed][mode][m]; op_cost = shiftadd_cost (speed, mode, m);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, (t - 1) >> m, &new_limit, mode); synth_mult (alg_in, (t - 1) >> m, &new_limit, mode);
...@@ -2834,7 +2842,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2834,7 +2842,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
m = exact_log2 (q); m = exact_log2 (q);
if (m >= 0 && m < maxm) if (m >= 0 && m < maxm)
{ {
op_cost = shiftsub0_cost[speed][mode][m]; op_cost = shiftsub0_cost (speed, mode, m);
new_limit.cost = best_cost.cost - op_cost; new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost; new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, (t + 1) >> m, &new_limit, mode); synth_mult (alg_in, (t + 1) >> m, &new_limit, mode);
...@@ -2863,23 +2871,23 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, ...@@ -2863,23 +2871,23 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
we are asked to find an algorithm for T within the same or we are asked to find an algorithm for T within the same or
lower COST_LIMIT, we can immediately return to the lower COST_LIMIT, we can immediately return to the
caller. */ caller. */
alg_hash[hash_index].t = t; entry_ptr->t = t;
alg_hash[hash_index].mode = mode; entry_ptr->mode = mode;
alg_hash[hash_index].speed = speed; entry_ptr->speed = speed;
alg_hash[hash_index].alg = alg_impossible; entry_ptr->alg = alg_impossible;
alg_hash[hash_index].cost = *cost_limit; entry_ptr->cost = *cost_limit;
return; return;
} }
/* Cache the result. */ /* Cache the result. */
if (!cache_hit) if (!cache_hit)
{ {
alg_hash[hash_index].t = t; entry_ptr->t = t;
alg_hash[hash_index].mode = mode; entry_ptr->mode = mode;
alg_hash[hash_index].speed = speed; entry_ptr->speed = speed;
alg_hash[hash_index].alg = best_alg->op[best_alg->ops]; entry_ptr->alg = best_alg->op[best_alg->ops];
alg_hash[hash_index].cost.cost = best_cost.cost; entry_ptr->cost.cost = best_cost.cost;
alg_hash[hash_index].cost.latency = best_cost.latency; entry_ptr->cost.latency = best_cost.latency;
} }
/* If we are getting a too long sequence for `struct algorithm' /* If we are getting a too long sequence for `struct algorithm'
...@@ -2925,7 +2933,7 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val, ...@@ -2925,7 +2933,7 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
/* Ensure that mult_cost provides a reasonable upper bound. /* Ensure that mult_cost provides a reasonable upper bound.
Any constant multiplication can be performed with less Any constant multiplication can be performed with less
than 2 * bits additions. */ than 2 * bits additions. */
op_cost = 2 * GET_MODE_UNIT_BITSIZE (mode) * add_cost[speed][mode]; op_cost = 2 * GET_MODE_UNIT_BITSIZE (mode) * add_cost (speed, mode);
if (mult_cost > op_cost) if (mult_cost > op_cost)
mult_cost = op_cost; mult_cost = op_cost;
...@@ -2938,7 +2946,7 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val, ...@@ -2938,7 +2946,7 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
`unsigned int' */ `unsigned int' */
if (HOST_BITS_PER_INT >= GET_MODE_UNIT_BITSIZE (mode)) if (HOST_BITS_PER_INT >= GET_MODE_UNIT_BITSIZE (mode))
{ {
op_cost = neg_cost[speed][mode]; op_cost = neg_cost(speed, mode);
if (MULT_COST_LESS (&alg->cost, mult_cost)) if (MULT_COST_LESS (&alg->cost, mult_cost))
{ {
limit.cost = alg->cost.cost - op_cost; limit.cost = alg->cost.cost - op_cost;
...@@ -2958,7 +2966,7 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val, ...@@ -2958,7 +2966,7 @@ choose_mult_variant (enum machine_mode mode, HOST_WIDE_INT val,
} }
/* This proves very useful for division-by-constant. */ /* This proves very useful for division-by-constant. */
op_cost = add_cost[speed][mode]; op_cost = add_cost (speed, mode);
if (MULT_COST_LESS (&alg->cost, mult_cost)) if (MULT_COST_LESS (&alg->cost, mult_cost))
{ {
limit.cost = alg->cost.cost - op_cost; limit.cost = alg->cost.cost - op_cost;
...@@ -3249,7 +3257,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, ...@@ -3249,7 +3257,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
Exclude cost of op0 from max_cost to match the cost Exclude cost of op0 from max_cost to match the cost
calculation of the synth_mult. */ calculation of the synth_mult. */
max_cost = (set_src_cost (gen_rtx_MULT (mode, fake_reg, op1), speed) max_cost = (set_src_cost (gen_rtx_MULT (mode, fake_reg, op1), speed)
- neg_cost[speed][mode]); - neg_cost(speed, mode));
if (max_cost > 0 if (max_cost > 0
&& choose_mult_variant (mode, -coeff, &algorithm, && choose_mult_variant (mode, -coeff, &algorithm,
&variant, max_cost)) &variant, max_cost))
...@@ -3350,7 +3358,7 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, ...@@ -3350,7 +3358,7 @@ expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
/* Exclude cost of op0 from max_cost to match the cost /* Exclude cost of op0 from max_cost to match the cost
calculation of the synth_mult. */ calculation of the synth_mult. */
max_cost = mul_widen_cost[speed][mode]; max_cost = mul_widen_cost (speed, mode);
if (choose_mult_variant (mode, coeff, &algorithm, &variant, if (choose_mult_variant (mode, coeff, &algorithm, &variant,
max_cost)) max_cost))
{ {
...@@ -3564,7 +3572,7 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1, ...@@ -3564,7 +3572,7 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
/* Firstly, try using a multiplication insn that only generates the needed /* Firstly, try using a multiplication insn that only generates the needed
high part of the product, and in the sign flavor of unsignedp. */ high part of the product, and in the sign flavor of unsignedp. */
if (mul_highpart_cost[speed][mode] < max_cost) if (mul_highpart_cost (speed, mode) < max_cost)
{ {
moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab; moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
tem = expand_binop (mode, moptab, op0, narrow_op1, target, tem = expand_binop (mode, moptab, op0, narrow_op1, target,
...@@ -3576,8 +3584,9 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1, ...@@ -3576,8 +3584,9 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
/* Secondly, same as above, but use sign flavor opposite of unsignedp. /* Secondly, same as above, but use sign flavor opposite of unsignedp.
Need to adjust the result after the multiplication. */ Need to adjust the result after the multiplication. */
if (size - 1 < BITS_PER_WORD if (size - 1 < BITS_PER_WORD
&& (mul_highpart_cost[speed][mode] + 2 * shift_cost[speed][mode][size-1] && (mul_highpart_cost (speed, mode)
+ 4 * add_cost[speed][mode] < max_cost)) + 2 * shift_cost (speed, mode, size-1)
+ 4 * add_cost (speed, mode) < max_cost))
{ {
moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab; moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
tem = expand_binop (mode, moptab, op0, narrow_op1, target, tem = expand_binop (mode, moptab, op0, narrow_op1, target,
...@@ -3591,7 +3600,7 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1, ...@@ -3591,7 +3600,7 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
/* Try widening multiplication. */ /* Try widening multiplication. */
moptab = unsignedp ? umul_widen_optab : smul_widen_optab; moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
&& mul_widen_cost[speed][wider_mode] < max_cost) && mul_widen_cost (speed, wider_mode) < max_cost)
{ {
tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0, tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0,
unsignedp, OPTAB_WIDEN); unsignedp, OPTAB_WIDEN);
...@@ -3602,7 +3611,8 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1, ...@@ -3602,7 +3611,8 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
/* Try widening the mode and perform a non-widening multiplication. */ /* Try widening the mode and perform a non-widening multiplication. */
if (optab_handler (smul_optab, wider_mode) != CODE_FOR_nothing if (optab_handler (smul_optab, wider_mode) != CODE_FOR_nothing
&& size - 1 < BITS_PER_WORD && size - 1 < BITS_PER_WORD
&& mul_cost[speed][wider_mode] + shift_cost[speed][mode][size-1] < max_cost) && (mul_cost (speed, wider_mode) + shift_cost (speed, mode, size-1)
< max_cost))
{ {
rtx insns, wop0, wop1; rtx insns, wop0, wop1;
...@@ -3629,8 +3639,9 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1, ...@@ -3629,8 +3639,9 @@ expmed_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
moptab = unsignedp ? smul_widen_optab : umul_widen_optab; moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing if (widening_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
&& size - 1 < BITS_PER_WORD && size - 1 < BITS_PER_WORD
&& (mul_widen_cost[speed][wider_mode] + 2 * shift_cost[speed][mode][size-1] && (mul_widen_cost (speed, wider_mode)
+ 4 * add_cost[speed][mode] < max_cost)) + 2 * shift_cost (speed, mode, size-1)
+ 4 * add_cost (speed, mode) < max_cost))
{ {
tem = expand_binop (wider_mode, moptab, op0, narrow_op1, tem = expand_binop (wider_mode, moptab, op0, narrow_op1,
NULL_RTX, ! unsignedp, OPTAB_WIDEN); NULL_RTX, ! unsignedp, OPTAB_WIDEN);
...@@ -3684,13 +3695,13 @@ expmed_mult_highpart (enum machine_mode mode, rtx op0, rtx op1, ...@@ -3684,13 +3695,13 @@ expmed_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
return expmed_mult_highpart_optab (mode, op0, op1, target, return expmed_mult_highpart_optab (mode, op0, op1, target,
unsignedp, max_cost); unsignedp, max_cost);
extra_cost = shift_cost[speed][mode][GET_MODE_BITSIZE (mode) - 1]; extra_cost = shift_cost (speed, mode, GET_MODE_BITSIZE (mode) - 1);
/* Check whether we try to multiply by a negative constant. */ /* Check whether we try to multiply by a negative constant. */
if (!unsignedp && ((cnst1 >> (GET_MODE_BITSIZE (mode) - 1)) & 1)) if (!unsignedp && ((cnst1 >> (GET_MODE_BITSIZE (mode) - 1)) & 1))
{ {
sign_adjust = true; sign_adjust = true;
extra_cost += add_cost[speed][mode]; extra_cost += add_cost (speed, mode);
} }
/* See whether shift/add multiplication is cheap enough. */ /* See whether shift/add multiplication is cheap enough. */
...@@ -3880,7 +3891,8 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) ...@@ -3880,7 +3891,8 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
temp = gen_reg_rtx (mode); temp = gen_reg_rtx (mode);
temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1); temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1);
if (shift_cost[optimize_insn_for_speed_p ()][mode][ushift] > COSTS_N_INSNS (1)) if (shift_cost (optimize_insn_for_speed_p (), mode, ushift)
> COSTS_N_INSNS (1))
temp = expand_binop (mode, and_optab, temp, GEN_INT (d - 1), temp = expand_binop (mode, and_optab, temp, GEN_INT (d - 1),
NULL_RTX, 0, OPTAB_LIB_WIDEN); NULL_RTX, 0, OPTAB_LIB_WIDEN);
else else
...@@ -4083,10 +4095,13 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4083,10 +4095,13 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
/* Only deduct something for a REM if the last divide done was /* Only deduct something for a REM if the last divide done was
for a different constant. Then set the constant of the last for a different constant. Then set the constant of the last
divide. */ divide. */
max_cost = unsignedp ? udiv_cost[speed][compute_mode] : sdiv_cost[speed][compute_mode]; max_cost = (unsignedp
? udiv_cost (speed, compute_mode)
: sdiv_cost (speed, compute_mode));
if (rem_flag && ! (last_div_const != 0 && op1_is_constant if (rem_flag && ! (last_div_const != 0 && op1_is_constant
&& INTVAL (op1) == last_div_const)) && INTVAL (op1) == last_div_const))
max_cost -= mul_cost[speed][compute_mode] + add_cost[speed][compute_mode]; max_cost -= (mul_cost (speed, compute_mode)
+ add_cost (speed, compute_mode));
last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0; last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0;
...@@ -4200,9 +4215,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4200,9 +4215,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
goto fail1; goto fail1;
extra_cost extra_cost
= (shift_cost[speed][compute_mode][post_shift - 1] = (shift_cost (speed, compute_mode, post_shift - 1)
+ shift_cost[speed][compute_mode][1] + shift_cost (speed, compute_mode, 1)
+ 2 * add_cost[speed][compute_mode]); + 2 * add_cost (speed, compute_mode));
t1 = expmed_mult_highpart (compute_mode, op0, t1 = expmed_mult_highpart (compute_mode, op0,
GEN_INT (ml), GEN_INT (ml),
NULL_RTX, 1, NULL_RTX, 1,
...@@ -4233,8 +4248,8 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4233,8 +4248,8 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
(RSHIFT_EXPR, compute_mode, op0, (RSHIFT_EXPR, compute_mode, op0,
pre_shift, NULL_RTX, 1); pre_shift, NULL_RTX, 1);
extra_cost extra_cost
= (shift_cost[speed][compute_mode][pre_shift] = (shift_cost (speed, compute_mode, pre_shift)
+ shift_cost[speed][compute_mode][post_shift]); + shift_cost (speed, compute_mode, post_shift));
t2 = expmed_mult_highpart (compute_mode, t1, t2 = expmed_mult_highpart (compute_mode, t1,
GEN_INT (ml), GEN_INT (ml),
NULL_RTX, 1, NULL_RTX, 1,
...@@ -4293,8 +4308,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4293,8 +4308,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
goto fail1; goto fail1;
} }
else if (EXACT_POWER_OF_2_OR_ZERO_P (d) else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
&& (rem_flag ? smod_pow2_cheap[speed][compute_mode] && (rem_flag
: sdiv_pow2_cheap[speed][compute_mode]) ? smod_pow2_cheap (speed, compute_mode)
: sdiv_pow2_cheap (speed, compute_mode))
/* We assume that cheap metric is true if the /* We assume that cheap metric is true if the
optab has an expander for this mode. */ optab has an expander for this mode. */
&& ((optab_handler ((rem_flag ? smod_optab && ((optab_handler ((rem_flag ? smod_optab
...@@ -4314,7 +4330,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4314,7 +4330,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
return gen_lowpart (mode, remainder); return gen_lowpart (mode, remainder);
} }
if (sdiv_pow2_cheap[speed][compute_mode] if (sdiv_pow2_cheap (speed, compute_mode)
&& ((optab_handler (sdiv_optab, compute_mode) && ((optab_handler (sdiv_optab, compute_mode)
!= CODE_FOR_nothing) != CODE_FOR_nothing)
|| (optab_handler (sdivmod_optab, compute_mode) || (optab_handler (sdivmod_optab, compute_mode)
...@@ -4358,9 +4374,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4358,9 +4374,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
|| size - 1 >= BITS_PER_WORD) || size - 1 >= BITS_PER_WORD)
goto fail1; goto fail1;
extra_cost = (shift_cost[speed][compute_mode][post_shift] extra_cost = (shift_cost (speed, compute_mode, post_shift)
+ shift_cost[speed][compute_mode][size - 1] + shift_cost (speed, compute_mode, size - 1)
+ add_cost[speed][compute_mode]); + add_cost (speed, compute_mode));
t1 = expmed_mult_highpart (compute_mode, op0, t1 = expmed_mult_highpart (compute_mode, op0,
GEN_INT (ml), NULL_RTX, 0, GEN_INT (ml), NULL_RTX, 0,
max_cost - extra_cost); max_cost - extra_cost);
...@@ -4393,9 +4409,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4393,9 +4409,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1); ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1);
mlr = gen_int_mode (ml, compute_mode); mlr = gen_int_mode (ml, compute_mode);
extra_cost = (shift_cost[speed][compute_mode][post_shift] extra_cost = (shift_cost (speed, compute_mode, post_shift)
+ shift_cost[speed][compute_mode][size - 1] + shift_cost (speed, compute_mode, size - 1)
+ 2 * add_cost[speed][compute_mode]); + 2 * add_cost (speed, compute_mode));
t1 = expmed_mult_highpart (compute_mode, op0, mlr, t1 = expmed_mult_highpart (compute_mode, op0, mlr,
NULL_RTX, 0, NULL_RTX, 0,
max_cost - extra_cost); max_cost - extra_cost);
...@@ -4481,9 +4497,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, ...@@ -4481,9 +4497,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
size - 1, NULL_RTX, 0); size - 1, NULL_RTX, 0);
t2 = expand_binop (compute_mode, xor_optab, op0, t1, t2 = expand_binop (compute_mode, xor_optab, op0, t1,
NULL_RTX, 0, OPTAB_WIDEN); NULL_RTX, 0, OPTAB_WIDEN);
extra_cost = (shift_cost[speed][compute_mode][post_shift] extra_cost = (shift_cost (speed, compute_mode, post_shift)
+ shift_cost[speed][compute_mode][size - 1] + shift_cost (speed, compute_mode, size - 1)
+ 2 * add_cost[speed][compute_mode]); + 2 * add_cost (speed, compute_mode));
t3 = expmed_mult_highpart (compute_mode, t2, t3 = expmed_mult_highpart (compute_mode, t2,
GEN_INT (ml), NULL_RTX, 1, GEN_INT (ml), NULL_RTX, 1,
max_cost - extra_cost); max_cost - extra_cost);
......
...@@ -171,63 +171,392 @@ extern struct target_expmed *this_target_expmed; ...@@ -171,63 +171,392 @@ extern struct target_expmed *this_target_expmed;
#define this_target_expmed (&default_target_expmed) #define this_target_expmed (&default_target_expmed)
#endif #endif
#define alg_hash \ /* Return a pointer to the alg_hash_entry at IDX. */
(this_target_expmed->x_alg_hash)
#define alg_hash_used_p \
(this_target_expmed->x_alg_hash_used_p)
#define sdiv_pow2_cheap \
(this_target_expmed->x_sdiv_pow2_cheap)
#define smod_pow2_cheap \
(this_target_expmed->x_smod_pow2_cheap)
#define zero_cost \
(this_target_expmed->x_zero_cost)
#define add_cost \
(this_target_expmed->x_add_cost)
#define neg_cost \
(this_target_expmed->x_neg_cost)
#define shift_cost \
(this_target_expmed->x_shift_cost)
#define shiftadd_cost \
(this_target_expmed->x_shiftadd_cost)
#define shiftsub0_cost \
(this_target_expmed->x_shiftsub0_cost)
#define shiftsub1_cost \
(this_target_expmed->x_shiftsub1_cost)
#define mul_cost \
(this_target_expmed->x_mul_cost)
#define sdiv_cost \
(this_target_expmed->x_sdiv_cost)
#define udiv_cost \
(this_target_expmed->x_udiv_cost)
#define mul_widen_cost \
(this_target_expmed->x_mul_widen_cost)
#define mul_highpart_cost \
(this_target_expmed->x_mul_highpart_cost)
/* Set the COST for converting from FROM_MODE to TO_MODE when optimizing static inline struct alg_hash_entry *
alg_hash_entry_ptr (int idx)
{
return &this_target_expmed->x_alg_hash[idx];
}
/* Return true if the x_alg_hash field might have been used. */
static inline bool
alg_hash_used_p (void)
{
return this_target_expmed->x_alg_hash_used_p;
}
/* Set whether the x_alg_hash field might have been used. */
static inline void
set_alg_hash_used_p (bool usedp)
{
this_target_expmed->x_alg_hash_used_p = usedp;
}
/* Subroutine of {set_,}sdiv_pow2_cheap. Not to be used otherwise. */
static inline bool *
sdiv_pow2_cheap_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_sdiv_pow2_cheap[speed][mode];
}
/* Set whether a signed division by a power of 2 is cheap in MODE
when optimizing for SPEED. */
static inline void
set_sdiv_pow2_cheap (bool speed, enum machine_mode mode, bool cheap_p)
{
*sdiv_pow2_cheap_ptr (speed, mode) = cheap_p;
}
/* Return whether a signed division by a power of 2 is cheap in MODE
when optimizing for SPEED. */
static inline bool
sdiv_pow2_cheap (bool speed, enum machine_mode mode)
{
return *sdiv_pow2_cheap_ptr (speed, mode);
}
/* Subroutine of {set_,}smod_pow2_cheap. Not to be used otherwise. */
static inline bool *
smod_pow2_cheap_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_smod_pow2_cheap[speed][mode];
}
/* Set whether a signed modulo by a power of 2 is CHEAP in MODE when
optimizing for SPEED. */
static inline void
set_smod_pow2_cheap (bool speed, enum machine_mode mode, bool cheap)
{
*smod_pow2_cheap_ptr (speed, mode) = cheap;
}
/* Return whether a signed modulo by a power of 2 is cheap in MODE
when optimizing for SPEED. */
static inline bool
smod_pow2_cheap (bool speed, enum machine_mode mode)
{
return *smod_pow2_cheap_ptr (speed, mode);
}
/* Subroutine of {set_,}zero_cost. Not to be used otherwise. */
static inline int *
zero_cost_ptr (bool speed)
{
return &this_target_expmed->x_zero_cost[speed];
}
/* Set the COST of loading zero when optimizing for SPEED. */
static inline void
set_zero_cost (bool speed, int cost)
{
*zero_cost_ptr (speed) = cost;
}
/* Return the COST of loading zero when optimizing for SPEED. */
static inline int
zero_cost (bool speed)
{
return *zero_cost_ptr (speed);
}
/* Subroutine of {set_,}add_cost. Not to be used otherwise. */
static inline int *
add_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_add_cost[speed][mode];
}
/* Set the COST of computing an add in MODE when optimizing for SPEED. */
static inline void
set_add_cost (bool speed, enum machine_mode mode, int cost)
{
*add_cost_ptr (speed, mode) = cost;
}
/* Return the cost of computing an add in MODE when optimizing for SPEED. */
static inline int
add_cost (bool speed, enum machine_mode mode)
{
return *add_cost_ptr (speed, mode);
}
/* Subroutine of {set_,}neg_cost. Not to be used otherwise. */
static inline int *
neg_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_neg_cost[speed][mode];
}
/* Set the COST of computing a negation in MODE when optimizing for SPEED. */
static inline void
set_neg_cost (bool speed, enum machine_mode mode, int cost)
{
*neg_cost_ptr (speed, mode) = cost;
}
/* Return the cost of computing a negation in MODE when optimizing for
SPEED. */
static inline int
neg_cost (bool speed, enum machine_mode mode)
{
return *neg_cost_ptr (speed, mode);
}
/* Subroutine of {set_,}shift_cost. Not to be used otherwise. */
static inline int *
shift_cost_ptr (bool speed, enum machine_mode mode, int bits)
{
return &this_target_expmed->x_shift_cost[speed][mode][bits];
}
/* Set the COST of doing a shift in MODE by BITS when optimizing for SPEED. */
static inline void
set_shift_cost (bool speed, enum machine_mode mode, int bits, int cost)
{
*shift_cost_ptr (speed, mode, bits) = cost;
}
/* Return the cost of doing a shift in MODE by BITS when optimizing for
SPEED. */
static inline int
shift_cost (bool speed, enum machine_mode mode, int bits)
{
return *shift_cost_ptr (speed, mode, bits);
}
/* Subroutine of {set_,}shiftadd_cost. Not to be used otherwise. */
static inline int *
shiftadd_cost_ptr (bool speed, enum machine_mode mode, int bits)
{
return &this_target_expmed->x_shiftadd_cost[speed][mode][bits];
}
/* Set the COST of doing a shift in MODE by BITS followed by an add when
optimizing for SPEED. */
static inline void
set_shiftadd_cost (bool speed, enum machine_mode mode, int bits, int cost)
{
*shiftadd_cost_ptr (speed, mode, bits) = cost;
}
/* Return the cost of doing a shift in MODE by BITS followed by an add
when optimizing for SPEED. */
static inline int
shiftadd_cost (bool speed, enum machine_mode mode, int bits)
{
return *shiftadd_cost_ptr (speed, mode, bits);
}
/* Subroutine of {set_,}shiftsub0_cost. Not to be used otherwise. */
static inline int *
shiftsub0_cost_ptr (bool speed, enum machine_mode mode, int bits)
{
return &this_target_expmed->x_shiftsub0_cost[speed][mode][bits];
}
/* Set the COST of doing a shift in MODE by BITS and then subtracting a
value when optimizing for SPEED. */
static inline void
set_shiftsub0_cost (bool speed, enum machine_mode mode, int bits, int cost)
{
*shiftsub0_cost_ptr (speed, mode, bits) = cost;
}
/* Return the cost of doing a shift in MODE by BITS and then subtracting
a value when optimizing for SPEED. */
static inline int
shiftsub0_cost (bool speed, enum machine_mode mode, int bits)
{
return *shiftsub0_cost_ptr (speed, mode, bits);
}
/* Subroutine of {set_,}shiftsub1_cost. Not to be used otherwise. */
static inline int *
shiftsub1_cost_ptr (bool speed, enum machine_mode mode, int bits)
{
return &this_target_expmed->x_shiftsub1_cost[speed][mode][bits];
}
/* Set the COST of subtracting a shift in MODE by BITS from a value when
optimizing for SPEED. */
static inline void
set_shiftsub1_cost (bool speed, enum machine_mode mode, int bits, int cost)
{
*shiftsub1_cost_ptr (speed, mode, bits) = cost;
}
/* Return the cost of subtracting a shift in MODE by BITS from a value
when optimizing for SPEED. */
static inline int
shiftsub1_cost (bool speed, enum machine_mode mode, int bits)
{
return *shiftsub1_cost_ptr (speed, mode, bits);
}
/* Subroutine of {set_,}mul_cost. Not to be used otherwise. */
static inline int *
mul_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_mul_cost[speed][mode];
}
/* Set the COST of doing a multiplication in MODE when optimizing for
SPEED. */
static inline void
set_mul_cost (bool speed, enum machine_mode mode, int cost)
{
*mul_cost_ptr (speed, mode) = cost;
}
/* Return the cost of doing a multiplication in MODE when optimizing
for SPEED. */
static inline int
mul_cost (bool speed, enum machine_mode mode)
{
return *mul_cost_ptr (speed, mode);
}
/* Subroutine of {set_,}sdiv_cost. Not to be used otherwise. */
static inline int *
sdiv_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_sdiv_cost[speed][mode];
}
/* Set the COST of doing a signed division in MODE when optimizing
for SPEED. */ for SPEED. */
static inline void static inline void
set_convert_cost (enum machine_mode to_mode, enum machine_mode from_mode, set_sdiv_cost (bool speed, enum machine_mode mode, int cost)
bool speed, int cost)
{ {
int to_idx, from_idx; *sdiv_cost_ptr (speed, mode) = cost;
}
gcc_assert (to_mode >= MIN_MODE_INT /* Return the cost of doing a signed division in MODE when optimizing
&& to_mode <= MAX_MODE_INT for SPEED. */
&& from_mode >= MIN_MODE_INT
&& from_mode <= MAX_MODE_INT);
to_idx = to_mode - MIN_MODE_INT; static inline int
from_idx = from_mode - MIN_MODE_INT; sdiv_cost (bool speed, enum machine_mode mode)
this_target_expmed->x_convert_cost[speed][to_idx][from_idx] = cost; {
return *sdiv_cost_ptr (speed, mode);
} }
/* Return the cost for converting from FROM_MODE to TO_MODE when optimizing /* Subroutine of {set_,}udiv_cost. Not to be used otherwise. */
static inline int *
udiv_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_udiv_cost[speed][mode];
}
/* Set the COST of doing an unsigned division in MODE when optimizing
for SPEED. */ for SPEED. */
static inline void
set_udiv_cost (bool speed, enum machine_mode mode, int cost)
{
*udiv_cost_ptr (speed, mode) = cost;
}
/* Return the cost of doing an unsigned division in MODE when
optimizing for SPEED. */
static inline int static inline int
convert_cost (enum machine_mode to_mode, enum machine_mode from_mode, udiv_cost (bool speed, enum machine_mode mode)
{
return *udiv_cost_ptr (speed, mode);
}
/* Subroutine of {set_,}mul_widen_cost. Not to be used otherwise. */
static inline int *
mul_widen_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_mul_widen_cost[speed][mode];
}
/* Set the COST for computing a widening multiplication in MODE when
optimizing for SPEED. */
static inline void
set_mul_widen_cost (bool speed, enum machine_mode mode, int cost)
{
*mul_widen_cost_ptr (speed, mode) = cost;
}
/* Return the cost for computing a widening multiplication in MODE when
optimizing for SPEED. */
static inline int
mul_widen_cost (bool speed, enum machine_mode mode)
{
return *mul_widen_cost_ptr (speed, mode);
}
/* Subroutine of {set_,}mul_highpart_cost. Not to be used otherwise. */
static inline int *
mul_highpart_cost_ptr (bool speed, enum machine_mode mode)
{
return &this_target_expmed->x_mul_highpart_cost[speed][mode];
}
/* Set the COST for computing the high part of a multiplication in MODE
when optimizing for SPEED. */
static inline void
set_mul_highpart_cost (bool speed, enum machine_mode mode, int cost)
{
*mul_highpart_cost_ptr (speed, mode) = cost;
}
/* Return the cost for computing the high part of a multiplication in MODE
when optimizing for SPEED. */
static inline int
mul_highpart_cost (bool speed, enum machine_mode mode)
{
return *mul_highpart_cost_ptr (speed, mode);
}
/* Subroutine of {set_,}convert_cost. Not to be used otherwise. */
static inline int *
convert_cost_ptr (enum machine_mode to_mode, enum machine_mode from_mode,
bool speed) bool speed)
{ {
int to_idx, from_idx; int to_idx, from_idx;
...@@ -239,7 +568,27 @@ convert_cost (enum machine_mode to_mode, enum machine_mode from_mode, ...@@ -239,7 +568,27 @@ convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
to_idx = to_mode - MIN_MODE_INT; to_idx = to_mode - MIN_MODE_INT;
from_idx = from_mode - MIN_MODE_INT; from_idx = from_mode - MIN_MODE_INT;
return this_target_expmed->x_convert_cost[speed][to_idx][from_idx]; return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
}
/* Set the COST for converting from FROM_MODE to TO_MODE when optimizing
for SPEED. */
static inline void
set_convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
bool speed, int cost)
{
*convert_cost_ptr (to_mode, from_mode, speed) = cost;
}
/* Return the cost for converting from FROM_MODE to TO_MODE when optimizing
for SPEED. */
static inline int
convert_cost (enum machine_mode to_mode, enum machine_mode from_mode,
bool speed)
{
return *convert_cost_ptr (to_mode, from_mode, speed);
} }
extern int mult_by_coeff_cost (HOST_WIDE_INT, enum machine_mode, bool); extern int mult_by_coeff_cost (HOST_WIDE_INT, enum machine_mode, bool);
......
...@@ -344,16 +344,16 @@ stmt_cost (gimple gs, bool speed) ...@@ -344,16 +344,16 @@ stmt_cost (gimple gs, bool speed)
return mult_by_coeff_cost (TREE_INT_CST_LOW (rhs2), lhs_mode, speed); return mult_by_coeff_cost (TREE_INT_CST_LOW (rhs2), lhs_mode, speed);
gcc_assert (TREE_CODE (rhs1) != INTEGER_CST); gcc_assert (TREE_CODE (rhs1) != INTEGER_CST);
return mul_cost[speed][lhs_mode]; return mul_cost (speed, lhs_mode);
case PLUS_EXPR: case PLUS_EXPR:
case POINTER_PLUS_EXPR: case POINTER_PLUS_EXPR:
case MINUS_EXPR: case MINUS_EXPR:
rhs2 = gimple_assign_rhs2 (gs); rhs2 = gimple_assign_rhs2 (gs);
return add_cost[speed][lhs_mode]; return add_cost (speed, lhs_mode);
case NEGATE_EXPR: case NEGATE_EXPR:
return neg_cost[speed][lhs_mode]; return neg_cost (speed, lhs_mode);
case NOP_EXPR: case NOP_EXPR:
return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed); return convert_cost (lhs_mode, TYPE_MODE (TREE_TYPE (rhs1)), speed);
......
...@@ -3308,7 +3308,7 @@ get_address_cost (bool symbol_present, bool var_present, ...@@ -3308,7 +3308,7 @@ get_address_cost (bool symbol_present, bool var_present,
If VAR_PRESENT is true, try whether the mode with If VAR_PRESENT is true, try whether the mode with
SYMBOL_PRESENT = false is cheaper even with cost of addition, and SYMBOL_PRESENT = false is cheaper even with cost of addition, and
if this is the case, use it. */ if this is the case, use it. */
add_c = add_cost[speed][address_mode]; add_c = add_cost (speed, address_mode);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
var_p = i & 1; var_p = i & 1;
...@@ -3392,7 +3392,7 @@ get_address_cost (bool symbol_present, bool var_present, ...@@ -3392,7 +3392,7 @@ get_address_cost (bool symbol_present, bool var_present,
cost += mult_by_coeff_cost (ratio, address_mode, speed); cost += mult_by_coeff_cost (ratio, address_mode, speed);
if (s_offset && !offset_p && !symbol_present) if (s_offset && !offset_p && !symbol_present)
cost += add_cost[speed][address_mode]; cost += add_cost (speed, address_mode);
if (may_autoinc) if (may_autoinc)
*may_autoinc = autoinc; *may_autoinc = autoinc;
...@@ -3422,10 +3422,10 @@ get_shiftadd_cost (tree expr, enum machine_mode mode, comp_cost cost0, ...@@ -3422,10 +3422,10 @@ get_shiftadd_cost (tree expr, enum machine_mode mode, comp_cost cost0,
return false; return false;
sa_cost = (TREE_CODE (expr) != MINUS_EXPR sa_cost = (TREE_CODE (expr) != MINUS_EXPR
? shiftadd_cost[speed][mode][m] ? shiftadd_cost (speed, mode, m)
: (mult == op1 : (mult == op1
? shiftsub1_cost[speed][mode][m] ? shiftsub1_cost (speed, mode, m)
: shiftsub0_cost[speed][mode][m])); : shiftsub0_cost (speed, mode, m)));
res = new_cost (sa_cost, 0); res = new_cost (sa_cost, 0);
res = add_costs (res, mult == op1 ? cost0 : cost1); res = add_costs (res, mult == op1 ? cost0 : cost1);
...@@ -3559,7 +3559,7 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -3559,7 +3559,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 = new_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;
...@@ -3571,8 +3571,8 @@ force_expr_to_var_cost (tree expr, bool speed) ...@@ -3571,8 +3571,8 @@ force_expr_to_var_cost (tree expr, bool speed)
if (mult != NULL_TREE if (mult != NULL_TREE
&& cst_and_fits_in_hwi (TREE_OPERAND (mult, 1)) && cst_and_fits_in_hwi (TREE_OPERAND (mult, 1))
&& get_shiftadd_cost (expr, mode, cost0, cost1, mult, speed, && get_shiftadd_cost (expr, mode, cost0, cost1, mult,
&sa_cost)) speed, &sa_cost))
return sa_cost; return sa_cost;
} }
break; break;
...@@ -4060,7 +4060,7 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4060,7 +4060,7 @@ get_computation_cost_at (struct ivopts_data *data,
&symbol_present, &var_present, &symbol_present, &var_present,
&offset, depends_on)); &offset, depends_on));
cost.cost /= avg_loop_niter (data->current_loop); cost.cost /= avg_loop_niter (data->current_loop);
cost.cost += add_cost[data->speed][TYPE_MODE (ctype)]; cost.cost += add_cost (data->speed, TYPE_MODE (ctype));
} }
if (inv_expr_id) if (inv_expr_id)
...@@ -4101,14 +4101,14 @@ get_computation_cost_at (struct ivopts_data *data, ...@@ -4101,14 +4101,14 @@ get_computation_cost_at (struct ivopts_data *data,
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.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
symbol, but it increases complexity. */ symbol, but it increases complexity. */
if (offset) if (offset)
cost.complexity++; cost.complexity++;
cost.cost += add_cost[speed][TYPE_MODE (ctype)]; cost.cost += add_cost (speed, TYPE_MODE (ctype));
aratio = ratio > 0 ? ratio : -ratio; aratio = ratio > 0 ? ratio : -ratio;
if (aratio != 1) if (aratio != 1)
...@@ -4958,7 +4958,7 @@ determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand) ...@@ -4958,7 +4958,7 @@ determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand)
or a const set. */ or a const set. */
if (cost_base.cost == 0) if (cost_base.cost == 0)
cost_base.cost = COSTS_N_INSNS (1); cost_base.cost = COSTS_N_INSNS (1);
cost_step = add_cost[data->speed][TYPE_MODE (TREE_TYPE (base))]; cost_step = add_cost (data->speed, TYPE_MODE (TREE_TYPE (base)));
cost = cost_step + adjust_setup_cost (data, cost_base.cost); cost = cost_step + adjust_setup_cost (data, cost_base.cost);
......
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