summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-01 04:27:09 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-01 04:27:09 +0000
commit617cc55dce3d877dfd8973a511257e9cc9b7c3fe (patch)
treea9c7e9bbd5c7b7753ecf1aed3dfa709751ef1a6e
parent60ea93bb72e070f6830453db1cfe3a39714de467 (diff)
downloadgcc-617cc55dce3d877dfd8973a511257e9cc9b7c3fe.tar.gz
* expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a
constant as a sequence of additions depending upon the rtx_costs. (synth_mult): Update the "observed" cost of a shift, based upon the above optimization. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83956 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expmed.c25
2 files changed, 31 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 46f33600eef..92a4d69b804 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-06-30 Roger Sayle <roger@eyesopen.com>
+
+ * expmed.c (expand_shift): Consider expanding LSHIFT_EXPR by a
+ constant as a sequence of additions depending upon the rtx_costs.
+ (synth_mult): Update the "observed" cost of a shift, based upon
+ the above optimization.
+
2004-06-28 Geoffrey Keating <geoffk@apple.com>
Andreas Tobler <a.tobler@schweiz.ch>
diff --git a/gcc/expmed.c b/gcc/expmed.c
index a2278b9d8c1..e95a62643fc 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2017,6 +2017,24 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
if (op1 == const0_rtx)
return shifted;
+ /* Check whether its cheaper to implement a left shift by a constant
+ bit count by a sequence of additions. */
+ if (code == LSHIFT_EXPR
+ && GET_CODE (op1) == CONST_INT
+ && INTVAL (op1) > 0
+ && INTVAL (op1) < GET_MODE_BITSIZE (mode)
+ && shift_cost[mode][INTVAL (op1)] > INTVAL (op1) * add_cost[mode])
+ {
+ int i;
+ for (i = 0; i < INTVAL (op1); i++)
+ {
+ temp = force_reg (mode, shifted);
+ shifted = expand_binop (mode, add_optab, temp, temp, NULL_RTX,
+ unsignedp, OPTAB_LIB_WIDEN);
+ }
+ return shifted;
+ }
+
for (try = 0; temp == 0 && try < 3; try++)
{
enum optab_methods methods;
@@ -2242,7 +2260,12 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
if (m < maxm)
{
q = t >> m;
- cost = shift_cost[mode][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[mode], shift_cost[mode][m]). */
+ cost = m * add_cost[mode];
+ if (shift_cost[mode][m] < cost)
+ cost = shift_cost[mode][m];
synth_mult (alg_in, q, cost_limit - cost, mode);
cost += alg_in->cost;