[AArch64 costs 10/18] Improve costs for sign/zero extend operations 74/41174/1
authorjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 May 2014 09:01:28 +0000 (09:01 +0000)
committerNikolai Bozhenov <n.bozhenov@samsung.com>
Thu, 11 Jun 2015 11:06:34 +0000 (14:06 +0300)
git cherry-pick 81d1eb9

gcc/

* config/aarch64/aarch64.c (aarch64_rtx_costs): Cost
ZERO_EXTEND and SIGN_EXTEND better.

Change-Id: Ifa42bd83302971230562416fa1e948977d824ba5
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210502 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/aarch64/aarch64.c

index 2eef3cf..fdb5795 100644 (file)
@@ -1,6 +1,12 @@
 2014-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
            Philipp Tomsich  <philipp.tomsich@theobroma-systems.com>
 
+       * config/aarch64/aarch64.c (aarch64_rtx_costs): Cost
+       ZERO_EXTEND and SIGN_EXTEND better.
+
+2014-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
+           Philipp Tomsich  <philipp.tomsich@theobroma-systems.com>
+
        * config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for
        logical operations.
 
index b2e615c..a56cb88 100644 (file)
@@ -5213,21 +5213,62 @@ cost_minus:
       return false;
 
     case ZERO_EXTEND:
-      if ((GET_MODE (x) == DImode
-          && GET_MODE (XEXP (x, 0)) == SImode)
-         || GET_CODE (XEXP (x, 0)) == MEM)
+
+      op0 = XEXP (x, 0);
+      /* If a value is written in SI mode, then zero extended to DI
+        mode, the operation will in general be free as a write to
+        a 'w' register implicitly zeroes the upper bits of an 'x'
+        register.  However, if this is
+
+          (set (reg) (zero_extend (reg)))
+
+        we must cost the explicit register move.  */
+      if (mode == DImode
+         && GET_MODE (op0) == SImode
+         && outer == SET)
+       {
+         int op_cost = rtx_cost (XEXP (x, 0), ZERO_EXTEND, 0, speed);
+
+         if (!op_cost && speed)
+           /* MOV.  */
+           *cost += extra_cost->alu.extend;
+         else
+           /* Free, the cost is that of the SI mode operation.  */
+           *cost = op_cost;
+
+         return true;
+       }
+      else if (MEM_P (XEXP (x, 0)))
        {
-         *cost += rtx_cost (XEXP (x, 0), ZERO_EXTEND, 0, speed);
+         /* All loads can zero extend to any size for free.  */
+         *cost = rtx_cost (XEXP (x, 0), ZERO_EXTEND, param, speed);
          return true;
        }
+
+      /* UXTB/UXTH.  */
+      if (speed)
+       *cost += extra_cost->alu.extend;
+
       return false;
 
     case SIGN_EXTEND:
-      if (GET_CODE (XEXP (x, 0)) == MEM)
+      if (MEM_P (XEXP (x, 0)))
        {
-         *cost += rtx_cost (XEXP (x, 0), SIGN_EXTEND, 0, speed);
+         /* LDRSH.  */
+         if (speed)
+           {
+             rtx address = XEXP (XEXP (x, 0), 0);
+             *cost += extra_cost->ldst.load_sign_extend;
+
+             *cost +=
+               COSTS_N_INSNS (aarch64_address_cost (address, mode,
+                                                    0, speed));
+           }
          return true;
        }
+
+      if (speed)
+       *cost += extra_cost->alu.extend;
       return false;
 
     case ROTATE: