aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKazu Hirata <kazu@codesourcery.com>2009-05-03 23:31:18 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2009-05-03 23:31:18 +0000
commitddc2690ac0b80de267c5046b524638a40a24d572 (patch)
tree5f5db59d20cd73e728d53fddc169aa78116c6f00 /gcc
parentef268d34b78bed8d3e253fa00143b16817f68816 (diff)
downloadgcc-ddc2690ac0b80de267c5046b524638a40a24d572.zip
gcc-ddc2690ac0b80de267c5046b524638a40a24d572.tar.gz
gcc-ddc2690ac0b80de267c5046b524638a40a24d572.tar.bz2
expmed.c (synth_mult): When trying out a shift, pass the result of a signed shift.
* expmed.c (synth_mult): When trying out a shift, pass the result of a signed shift. From-SVN: r147087
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/expmed.c32
2 files changed, 37 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b67be5b..dcc0070 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2009-05-04 Kazu Hirata <kazu@codesourcery.com>
+ * expmed.c (synth_mult): When trying out a shift, pass the result
+ of a signed shift.
+
+2009-05-04 Kazu Hirata <kazu@codesourcery.com>
+
* expmed.c (shiftsub_cost): Rename to shiftsub0_cost.
(shiftsub1_cost): New.
(init_expmed): Compute shiftsub1_cost.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 7ffb693..d0c1621 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2551,6 +2551,38 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
best_alg->log[best_alg->ops] = m;
best_alg->op[best_alg->ops] = alg_shift;
}
+
+ /* See if treating ORIG_T as a signed number yields a better
+ sequence. Try this sequence only for a negative ORIG_T
+ as it would be useless for a non-negative ORIG_T. */
+ if ((HOST_WIDE_INT) orig_t < 0)
+ {
+ /* Shift ORIG_T as follows because a right shift of a
+ negative-valued signed type is implementation
+ defined. */
+ q = ~(~orig_t >> m);
+ /* The function expand_shift will choose between a shift
+ and a sequence of additions, so the observed cost is
+ given as MIN (m * add_cost[speed][mode],
+ shift_cost[speed][mode][m]). */
+ op_cost = m * add_cost[speed][mode];
+ if (shift_cost[speed][mode][m] < op_cost)
+ op_cost = shift_cost[speed][mode][m];
+ new_limit.cost = best_cost.cost - op_cost;
+ new_limit.latency = best_cost.latency - op_cost;
+ synth_mult (alg_in, q, &new_limit, mode);
+
+ alg_in->cost.cost += op_cost;
+ alg_in->cost.latency += op_cost;
+ if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
+ {
+ struct algorithm *x;
+ best_cost = alg_in->cost;
+ x = alg_in, alg_in = best_alg, best_alg = x;
+ best_alg->log[best_alg->ops] = m;
+ best_alg->op[best_alg->ops] = alg_shift;
+ }
+ }
}
if (cache_hit)
goto done;