]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AArch64 costs 9/18] Better cost logical operations
authorJames Greenhalgh <james.greenhalgh@arm.com>
Fri, 16 May 2014 08:59:07 +0000 (08:59 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Fri, 16 May 2014 08:59:07 +0000 (08:59 +0000)
gcc/

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

Co-Authored-By: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
From-SVN: r210501

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

index a084ca98aecbbc3e4777c745a089c87bf846ec5a..e648140387b973534888fb2885b0290311d28ccc 100644 (file)
@@ -1,3 +1,9 @@
+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>
 
index d0a5e49eb9010671ccb225f04836805f13133718..6b20d4a757f07d9576f1c32d7dc396a9231bcb14 100644 (file)
@@ -5206,25 +5206,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)