]> gcc.gnu.org Git - gcc.git/commitdiff
arm.c (arm_new_rtx_costs): Handle narrow mode add-shifts properly.
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 19 Nov 2013 17:53:33 +0000 (17:53 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 19 Nov 2013 17:53:33 +0000 (17:53 +0000)
* config/arm/arm.c (arm_new_rtx_costs):
Handle narrow mode add-shifts properly.
* config/arm/arm-common.c (arm_rtx_shift_left_p): Remove static.
* config/arm/arm-common-protos.h (arm_rtx_shift_left_p):
Declare extern.

From-SVN: r205051

gcc/ChangeLog
gcc/config/arm/aarch-common-protos.h
gcc/config/arm/aarch-common.c
gcc/config/arm/arm.c

index 797636ad2cb686ad9faddf0769a72791ea1ace36..e128ec3d794c5d387f45a1f002d1a7041e3f0bf8 100644 (file)
@@ -1,3 +1,11 @@
+2013-11-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/arm/arm.c (arm_new_rtx_costs):
+       Handle narrow mode add-shifts properly.
+       * config/arm/arm-common.c (arm_rtx_shift_left_p): Remove static.
+       * config/arm/arm-common-protos.h (arm_rtx_shift_left_p):
+       Declare extern.
+
 2013-11-19  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/arm/arm.md (zero_extend<mode>di2): Add type attribute.
index 841f544e83d0a995440c7ef2dabc1a7f37eaf07a..c3652a72c819d4566a08e90f09f912137439e47c 100644 (file)
@@ -31,6 +31,7 @@ extern int arm_no_early_alu_shift_dep (rtx, rtx);
 extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
 extern int arm_no_early_mul_dep (rtx, rtx);
 extern int arm_no_early_store_addr_dep (rtx, rtx);
+extern bool arm_rtx_shift_left_p (rtx);
 
 /* RTX cost table definitions.  These are used when tuning for speed rather
    than for size and should reflect the _additional_ cost over the cost
index 201e581a4a67fed34330aba8503bae19fcb406df..a46e6751a7b84a7179295fe845297366a71e835b 100644 (file)
@@ -40,7 +40,7 @@ typedef struct
 
 /* Return TRUE if X is either an arithmetic shift left, or
    is a multiplication by a power of two.  */
-static bool
+bool
 arm_rtx_shift_left_p (rtx x)
 {
   enum rtx_code code = GET_CODE (x);
index 2d5f8671b14356127fb774d40698d0f2de74c398..3cd53b07ca22d9b24a8c78d3ae9fd31ec12185c7 100644 (file)
@@ -8766,6 +8766,30 @@ arm_unspec_cost (rtx x, enum rtx_code /* outer_code */, bool speed_p, int *cost)
    call (one insn for -Os) and then one for processing the result.  */
 #define LIBCALL_COST(N) COSTS_N_INSNS (N + (speed_p ? 18 : 2))
 
+#define HANDLE_NARROW_SHIFT_ARITH(OP, IDX)                             \
+       do                                                              \
+         {                                                             \
+           shift_op = shifter_op_p (XEXP (x, IDX), &shift_reg);        \
+           if (shift_op != NULL                                        \
+               && arm_rtx_shift_left_p (XEXP (x, IDX)))                \
+             {                                                         \
+               if (shift_reg)                                          \
+                 {                                                     \
+                   if (speed_p)                                        \
+                     *cost += extra_cost->alu.arith_shift_reg; \
+                   *cost += rtx_cost (shift_reg, ASHIFT, 1, speed_p);  \
+                 }                                                     \
+               else if (speed_p)                                       \
+                 *cost += extra_cost->alu.arith_shift;         \
+                                                                       \
+                 *cost += (rtx_cost (shift_op, ASHIFT, 0, speed_p)     \
+                         + rtx_cost (XEXP (x, 1 - IDX),                \
+                                     OP, 1, speed_p));         \
+               return true;                                            \
+             }                                                         \
+         }                                                             \
+       while (0);
+
 /* RTX costs.  Make an estimate of the cost of executing the operation
    X, which is contained with an operation with code OUTER_CODE.
    SPEED_P indicates whether the cost desired is the performance cost,
@@ -9122,6 +9146,15 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
       if (GET_MODE_CLASS (mode) == MODE_INT
          && GET_MODE_SIZE (mode) < 4)
        {
+         rtx shift_op, shift_reg;
+         shift_reg = NULL;
+
+         /* We check both sides of the MINUS for shifter operands since,
+            unlike PLUS, it's not commutative.  */
+
+         HANDLE_NARROW_SHIFT_ARITH (MINUS, 0)
+         HANDLE_NARROW_SHIFT_ARITH (MINUS, 1)
+
          /* Slightly disparage, as we might need to widen the result.  */
          *cost = 1 + COSTS_N_INSNS (1);
          if (speed_p)
@@ -9221,11 +9254,18 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
          return false;
        }
 
+       /* Narrow modes can be synthesized in SImode, but the range
+          of useful sub-operations is limited.  Check for shift operations
+          on one of the operands.  Only left shifts can be used in the
+          narrow modes.  */
       if (GET_MODE_CLASS (mode) == MODE_INT
          && GET_MODE_SIZE (mode) < 4)
        {
-         /* Narrow modes can be synthesized in SImode, but the range
-            of useful sub-operations is limited.  */
+         rtx shift_op, shift_reg;
+         shift_reg = NULL;
+
+         HANDLE_NARROW_SHIFT_ARITH (PLUS, 0)
+
          if (CONST_INT_P (XEXP (x, 1)))
            {
              int insns = arm_gen_constant (PLUS, SImode, NULL_RTX,
@@ -10344,6 +10384,8 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
     }
 }
 
+#undef HANDLE_NARROW_SHIFT_ARITH
+
 /* RTX costs when optimizing for size.  */
 static bool
 arm_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
This page took 0.176373 seconds and 5 git commands to generate.