[patch] arm: Improve arm_rtx_costs_1 for Thumb2.

Kazu Hirata kazu@codesourcery.com
Mon Dec 21 05:38:00 GMT 2009


Hi,

Attached is a patch to improve arm_rtx_costs_1 for Thumb2.

Without this patch, arm_rtx_costs_1 provides an early return when
TARGET_THUMB2 is true.  However, most of the "if" statements in the
MINUS case and fall-through cases (PLUS, AND, XOR, and IOR) seem to be
applicable on Thumb-2.  As a result, the compiler fails to combine
"sub" and "lsl", which would produce:

  sub r1, r2, r3, lsl #4

The patch fixes the problem by removing the early return.

There may be a minor issue like:

      subcode = GET_CODE (XEXP (x, 1));
      if (subcode == ASHIFT || subcode == ASHIFTRT
	  || subcode == LSHIFTRT
	  || subcode == ROTATE || subcode == ROTATERT)
	{
	  *total += rtx_cost (XEXP (x, 0), code, speed);
	  *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, speed);
	  return true;
	}

which would probably underestimate costs on Thumb-2 if a shift by a
register is given, but I am thinking about putting it off for now as
that shouldn't be very common.

Tested on arm-none-eabi.  OK to apply once the mainline is open again?

Kazu Hirata

2009-12-20  Kazu Hirata  <kazu@codesourcery.com>

	* config/arm/arm.c (arm_rtx_costs_1): Don't special case for
	Thumb-2 in the MINUS case.

Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 155195)
+++ gcc/config/arm/arm.c	(working copy)
@@ -6391,23 +6391,6 @@ arm_rtx_costs_1 (rtx x, enum rtx_code ou
       return true;
 
     case MINUS:
-      if (TARGET_THUMB2)
-	{
-	  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
-	    {
-	      if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
-		*total = COSTS_N_INSNS (1);
-	      else
-		*total = COSTS_N_INSNS (20);
-	    }
-	  else
-	    *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
-	  /* Thumb2 does not have RSB, so all arguments must be
-	     registers (subtracting a constant is canonicalized as
-	     addition of the negated constant).  */
-	  return false;
-	}
-
       if (mode == DImode)
 	{
 	  *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));



More information about the Gcc-patches mailing list