diff options
author | Kazu Hirata <kazu@codesourcery.com> | 2009-05-03 23:31:18 +0000 |
---|---|---|
committer | Kazu Hirata <kazu@gcc.gnu.org> | 2009-05-03 23:31:18 +0000 |
commit | ddc2690ac0b80de267c5046b524638a40a24d572 (patch) | |
tree | 5f5db59d20cd73e728d53fddc169aa78116c6f00 /gcc | |
parent | ef268d34b78bed8d3e253fa00143b16817f68816 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/expmed.c | 32 |
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; |