This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH GCC/ARM]Fix rtx cost for Thumb1


Hi,
As reported in PR56102, arm back end returns wrong rtx cost for pattern
SET/ASHIFT/ASHIFTRT/LSHIFTRT/ROTATERT with multi-word mode. This 
causes GCC skipping the split process in lower-subreg.c, and generating
bigger constant pool.

This patch fixes the issue. Tested on arm-none-eabi/thumb1/O2/Os, ok for
trunk?

Thanks.

2013-03-26  Bin Cheng  <bin.cheng@arm.com>

	PR target/56102
	* config/arm/arm.c (thumb1_rtx_costs, thumb1_size_rtx_costs): Fix
	rtx costs for SET/ASHIFT/ASHIFTRT/LSHIFTRT/ROTATERT patterns with
	mult-word mode.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 195355)
+++ gcc/config/arm/arm.c	(working copy)
@@ -7049,7 +7049,7 @@ static inline int
 thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
 {
   enum machine_mode mode = GET_MODE (x);
-  int total;
+  int total, factor;
 
   switch (code)
     {
@@ -7057,6 +7057,8 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum
     case ASHIFTRT:
     case LSHIFTRT:
     case ROTATERT:
+      return (mode == SImode) ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2);
+
     case PLUS:
     case MINUS:
     case COMPARE:
@@ -7080,7 +7082,13 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum
       return COSTS_N_INSNS (1) + 16;
 
     case SET:
-      return (COSTS_N_INSNS (1)
+      /* A SET doesn't have a mode, so let's look at the SET_DEST to get
+	 the mode for the factor.  */
+      factor = GET_MODE_SIZE (GET_MODE (SET_DEST (x))) / UNITS_PER_WORD;
+      if (factor  == 0)
+	factor = 1;
+
+      return (factor * COSTS_N_INSNS (1)
 	      + 4 * ((MEM_P (SET_SRC (x)))
 		     + MEM_P (SET_DEST (x))));
 
@@ -7777,6 +7785,7 @@ static inline int
 thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
 {
   enum machine_mode mode = GET_MODE (x);
+  int factor;
 
   switch (code)
     {
@@ -7784,6 +7793,8 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code,
     case ASHIFTRT:
     case LSHIFTRT:
     case ROTATERT:
+      return (mode == SImode) ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2);
+
     case PLUS:
     case MINUS:
     case COMPARE:
@@ -7802,7 +7813,13 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code,
       return COSTS_N_INSNS (1);
 
     case SET:
-      return (COSTS_N_INSNS (1)
+      /* A SET doesn't have a mode, so let's look at the SET_DEST to get
+	 the mode for the factor.  */
+      factor = GET_MODE_SIZE (GET_MODE (SET_DEST (x))) / UNITS_PER_WORD;
+      if (factor == 0)
+	factor = 1;
+
+      return (factor * COSTS_N_INSNS (1)
               + 4 * ((MEM_P (SET_SRC (x)))
                      + MEM_P (SET_DEST (x))));
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]