diff mbox

[GCC/ARM] Fix rtx cost for Thumb1

Message ID 002601ce29fc$afd803b0$0f880b10$@cheng@arm.com
State New
Headers show

Commit Message

Bin Cheng March 26, 2013, 8:34 a.m. UTC
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.

Comments

Richard Earnshaw March 26, 2013, 10:57 a.m. UTC | #1
On 26/03/13 08:34, Bin Cheng wrote:
> 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.
>

OK.

R.
diff mbox

Patch

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))));