[AArch64 costs 9/18] Better cost logical operations 73/41173/1
authorjgreenhalgh <jgreenhalgh@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 May 2014 08:59:07 +0000 (08:59 +0000)
committerNikolai Bozhenov <n.bozhenov@samsung.com>
Thu, 11 Jun 2015 11:06:30 +0000 (14:06 +0300)
git cherry-pick 69ddbb9

gcc/

* config/aarch64/aarch64.c (aarch64_rtx_costs): Improve cost for
logical operations.

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

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

index d648b71..2eef3cf 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): Improve cost for
+       logical operations.
+
+2014-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
+           Philipp Tomsich  <philipp.tomsich@theobroma-systems.com>
+
        * config/aarch64/aarch64.c (aarch64_rtx_costs): Use address
        costs when costing loads and stores to memory.
 
index 03810fc..b2e615c 100644 (file)
@@ -5138,25 +5138,80 @@ cost_minus:
       op0 = XEXP (x, 0);
       op1 = XEXP (x, 1);
 
+      if (code == AND
+          && GET_CODE (op0) == MULT
+          && CONST_INT_P (XEXP (op0, 1))
+          && CONST_INT_P (op1)
+          && aarch64_uxt_size (exact_log2 (INTVAL (XEXP (op0, 1))),
+                               INTVAL (op1)) != 0)
+        {
+          /* This is a UBFM/SBFM.  */
+          *cost += rtx_cost (XEXP (op0, 0), ZERO_EXTRACT, 0, speed);
+         if (speed)
+           *cost += extra_cost->alu.bfx;
+          return true;
+        }
+
       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
        {
+         /* We possibly get the immediate for free, this is not
+            modelled.  */
          if (CONST_INT_P (op1)
              && aarch64_bitmask_imm (INTVAL (op1), GET_MODE (x)))
            {
-             *cost += rtx_cost (op0, AND, 0, speed);
+             *cost += rtx_cost (op0, (enum rtx_code) code, 0, speed);
+
+             if (speed)
+               *cost += extra_cost->alu.logical;
+
+             return true;
            }
          else
            {
+             rtx new_op0 = op0;
+
+             /* Handle ORN, EON, or BIC.  */
              if (GET_CODE (op0) == NOT)
                op0 = XEXP (op0, 0);
-             op0 = aarch64_strip_shift (op0);
-             *cost += (rtx_cost (op0, AND, 0, speed)
-                       + rtx_cost (op1, AND, 1, speed));
+
+             new_op0 = aarch64_strip_shift (op0);
+
+             /* If we had a shift on op0 then this is a logical-shift-
+                by-register/immediate operation.  Otherwise, this is just
+                a logical operation.  */
+             if (speed)
+               {
+                 if (new_op0 != op0)
+                   {
+                     /* Shift by immediate.  */
+                     if (CONST_INT_P (XEXP (op0, 1)))
+                       *cost += extra_cost->alu.log_shift;
+                     else
+                       *cost += extra_cost->alu.log_shift_reg;
+                   }
+                 else
+                   *cost += extra_cost->alu.logical;
+               }
+
+             /* In both cases we want to cost both operands.  */
+             *cost += rtx_cost (new_op0, (enum rtx_code) code, 0, speed)
+                      + rtx_cost (op1, (enum rtx_code) code, 1, speed);
+
+             return true;
            }
-         return true;
        }
       return false;
 
+    case NOT:
+      /* MVN.  */
+      if (speed)
+       *cost += extra_cost->alu.logical;
+
+      /* The logical instruction could have the shifted register form,
+         but the cost is the same if the shift is processed as a separate
+         instruction, so we don't bother with it here.  */
+      return false;
+
     case ZERO_EXTEND:
       if ((GET_MODE (x) == DImode
           && GET_MODE (XEXP (x, 0)) == SImode)