diff options
author | kazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-03 23:31:18 +0000 |
---|---|---|
committer | kazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-03 23:31:18 +0000 |
commit | 5521b4c855bcd2a0682808e422d1f58ed7e1bbcf (patch) | |
tree | 5f5db59d20cd73e728d53fddc169aa78116c6f00 /gcc/expmed.c | |
parent | b592bb50fc4f0e3450be96f3e41bc980bff3bdf8 (diff) | |
download | gcc-5521b4c855bcd2a0682808e422d1f58ed7e1bbcf.tar.gz |
* expmed.c (synth_mult): When trying out a shift, pass the result
of a signed shift.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147087 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 7ffb693dcdd..d0c1621cc5e 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; |