Patchwork [SH] PR 54089 - adjust shift costs

login
register
mail settings
Submitter Oleg Endo
Date July 26, 2012, 9:02 p.m.
Message ID <1343336524.2185.84.camel@yam-132-YW-E178-FTW>
Download mbox | patch
Permalink /patch/173510/
State New
Headers show

Comments

Oleg Endo - July 26, 2012, 9:02 p.m.
Hello,

This adjusts the cost calculations for shifts on SH.
I tried out Richard's advice
( http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01206.html )
and it seems to work OK to just leave out the mentioned CONST_INT_P
case.
Tested on rev 189870 with
make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m2a-single/-mb,-m4/-ml,-m4/-mb,-m4-single/-ml,
-m4-single/-mb,-m4a-single/-ml,-m4a-single/-mb}"

and no new failures.
I've also confirmed that the example function in
tree-switch-conversion.c:184 now is transformed as expected.  The CSiBE
set shows a few improvements here and there, where these kind of
transformations can be applied for when dynamic shifts are available
(SH3+).  For SH2 (no dynamic shifts) there also seem to be some minor
improvements.

OK?

Cheers,
Oleg

ChangeLog

	PR target/54089
	* config/sh/sh.c (shiftcosts): Remove case where first operand 
	is a const_int.  Move COSTS_N_INSNS usage into caller ...
	(sh_rtx_costs) ... here.  Return false when shiftcosts cannot be
	calculated instead of MAX_COST.
Kaz Kojima - July 27, 2012, 1:37 a.m.
Oleg Endo <oleg.endo@t-online.de> wrote:
> This adjusts the cost calculations for shifts on SH.
> I tried out Richard's advice
> ( http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01206.html )
> and it seems to work OK to just leave out the mentioned CONST_INT_P
> case.
> Tested on rev 189870 with
> make -k check RUNTESTFLAGS="--target_board=sh-sim
> \{-m2/-ml,-m2/-mb,-m2a/-mb,-m2a-single/-mb,-m4/-ml,-m4/-mb,-m4-single/-ml,
> -m4-single/-mb,-m4a-single/-ml,-m4a-single/-mb}"
> 
> and no new failures.
> I've also confirmed that the example function in
> tree-switch-conversion.c:184 now is transformed as expected.  The CSiBE
> set shows a few improvements here and there, where these kind of
> transformations can be applied for when dynamic shifts are available
> (SH3+).  For SH2 (no dynamic shifts) there also seem to be some minor
> improvements.
> 
> OK?

OK.

Regards,
	kaz

Patch

Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 189877)
+++ gcc/config/sh/sh.c	(working copy)
@@ -2859,26 +2859,22 @@ 
 {
   int value;
 
-  /* There is no pattern for constant first operand.  */
-  if (CONST_INT_P (XEXP (x, 0)))
-    return MAX_COST;
-
   if (TARGET_SHMEDIA)
-    return COSTS_N_INSNS (1);
+    return 1;
 
   if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
     {
       if (GET_MODE (x) == DImode
 	  && CONST_INT_P (XEXP (x, 1))
 	  && INTVAL (XEXP (x, 1)) == 1)
-	return COSTS_N_INSNS (2);
+	return 2;
 
       /* Everything else is invalid, because there is no pattern for it.  */
-      return MAX_COST;
+      return -1;
     }
   /* If shift by a non constant, then this will be expensive.  */
   if (!CONST_INT_P (XEXP (x, 1)))
-    return COSTS_N_INSNS (SH_DYNAMIC_SHIFT_COST);
+    return SH_DYNAMIC_SHIFT_COST;
 
   /* Otherwise, return the true cost in instructions.  Cope with out of range
      shift counts more or less arbitrarily.  */
@@ -2887,13 +2883,14 @@ 
   if (GET_CODE (x) == ASHIFTRT)
     {
       int cost = ashiftrt_insns[value];
-      /* If SH3, then we put the constant in a reg and use shad.  */
+      /* If dynamic shifts are available and profitable in this case, then we
+	 put the constant in a reg and use shad.  */
       if (cost > 1 + SH_DYNAMIC_SHIFT_COST)
 	cost = 1 + SH_DYNAMIC_SHIFT_COST;
-      return COSTS_N_INSNS (cost);
+      return cost;
     }
   else
-    return COSTS_N_INSNS (shift_insns[value]);
+    return shift_insns[value];
 }
 
 /* Return the cost of an AND/XOR/IOR operation.  */
@@ -3147,8 +3144,13 @@ 
     case ASHIFT:
     case ASHIFTRT:
     case LSHIFTRT:
-      *total = shiftcosts (x);
-      return true;
+      {
+	int cost = shiftcosts (x);
+	if (cost < 0)
+	  return false;
+	*total = COSTS_N_INSNS (cost);
+	return true;
+      }
 
     case DIV:
     case UDIV: