[AArch64] Tweak aarch64_classify_address interface
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 21 Dec 2017 06:57:04 +0000 (06:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 21 Dec 2017 06:57:04 +0000 (06:57 +0000)
Previously aarch64_classify_address used an rtx code to distinguish
LDP/STP addresses from normal addresses; the code was PARALLEL
to select LDP/STP and anything else to select normal addresses.
This patch replaces that parameter with a dedicated enum.

The SVE port will add another enum value that didn't map naturally
to an rtx code.

2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* config/aarch64/aarch64-protos.h (aarch64_addr_query_type): New enum.
(aarch64_legitimate_address_p): Use it instead of an rtx code,
as an optional final parameter.
* config/aarch64/aarch64.c (aarch64_classify_address): Likewise.
(aarch64_legitimate_address_p): Likewise.
(aarch64_print_address_internal): Take an aarch64_addr_query_type
instead of an rtx code.
(aarch64_address_valid_for_prefetch_p): Update calls accordingly.
(aarch64_legitimate_address_hook_p): Likewise.
(aarch64_print_ldpstp_address): Likewise.
(aarch64_print_operand_address): Likewise.
(aarch64_address_cost): Likewise.
* config/aarch64/constraints.md (Uml, Umq, Ump, Utq): Likewise.
* config/aarch64/predicates.md (aarch64_mem_pair_operand): Likewise.
(aarch64_mem_pair_lanes_operand): Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255911

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/constraints.md
gcc/config/aarch64/predicates.md

index aa7d1c364f37cf4c856fe9f832f8cbe8581cab3e..adb02ee10e147f4072678801e6e589088fba0162 100644 (file)
@@ -1,3 +1,23 @@
+2017-12-21  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * config/aarch64/aarch64-protos.h (aarch64_addr_query_type): New enum.
+       (aarch64_legitimate_address_p): Use it instead of an rtx code,
+       as an optional final parameter.
+       * config/aarch64/aarch64.c (aarch64_classify_address): Likewise.
+       (aarch64_legitimate_address_p): Likewise.
+       (aarch64_print_address_internal): Take an aarch64_addr_query_type
+       instead of an rtx code.
+       (aarch64_address_valid_for_prefetch_p): Update calls accordingly.
+       (aarch64_legitimate_address_hook_p): Likewise.
+       (aarch64_print_ldpstp_address): Likewise.
+       (aarch64_print_operand_address): Likewise.
+       (aarch64_address_cost): Likewise.
+       * config/aarch64/constraints.md (Uml, Umq, Ump, Utq): Likewise.
+       * config/aarch64/predicates.md (aarch64_mem_pair_operand): Likewise.
+       (aarch64_mem_pair_lanes_operand): Likewise.
+
 2017-12-20  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-dom.c (dom_opt_dom_walker::optimize_stmt): Call
index 15c3b46ebef8f305f960e60a8b4e85d8be07e8c7..002ac330c6da73a8de35ff1eefa787f7662b3027 100644 (file)
@@ -111,6 +111,19 @@ enum aarch64_symbol_type
   SYMBOL_FORCE_TO_MEM
 };
 
+/* Classifies the type of an address query.
+
+   ADDR_QUERY_M
+      Query what is valid for an "m" constraint and a memory_operand
+      (the rules are the same for both).
+
+   ADDR_QUERY_LDP_STP
+      Query what is valid for a load/store pair.  */
+enum aarch64_addr_query_type {
+  ADDR_QUERY_M,
+  ADDR_QUERY_LDP_STP
+};
+
 /* A set of tuning parameters contains references to size and time
    cost models and vectors for address cost calculations, register
    move costs and memory move costs.  */
@@ -440,7 +453,8 @@ bool aarch64_float_const_representable_p (rtx);
 
 #if defined (RTX_CODE)
 
-bool aarch64_legitimate_address_p (machine_mode, rtx, RTX_CODE, bool);
+bool aarch64_legitimate_address_p (machine_mode, rtx, bool,
+                                  aarch64_addr_query_type = ADDR_QUERY_M);
 machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx);
 rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx);
 rtx aarch64_load_tp (rtx);
index d10fa1688757ecdfe869e3dc14fde16c6bf43732..fc27b4073dd88402ab6e7ab05f6cafacca256494 100644 (file)
@@ -4437,21 +4437,21 @@ virt_or_elim_regno_p (unsigned regno)
          || regno == ARG_POINTER_REGNUM);
 }
 
-/* Return true if X is a valid address for machine mode MODE.  If it is,
-   fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
-   effect.  OUTER_CODE is PARALLEL for a load/store pair.  */
+/* Return true if X is a valid address of type TYPE for machine mode MODE.
+   If it is, fill in INFO appropriately.  STRICT_P is true if
+   REG_OK_STRICT is in effect.  */
 
 static bool
 aarch64_classify_address (struct aarch64_address_info *info,
-                         rtx x, machine_mode mode,
-                         RTX_CODE outer_code, bool strict_p)
+                         rtx x, machine_mode mode, bool strict_p,
+                         aarch64_addr_query_type type = ADDR_QUERY_M)
 {
   enum rtx_code code = GET_CODE (x);
   rtx op0, op1;
 
   /* On BE, we use load/store pair for all large int mode load/stores.
      TI/TFmode may also use a load/store pair.  */
-  bool load_store_pair_p = (outer_code == PARALLEL
+  bool load_store_pair_p = (type == ADDR_QUERY_LDP_STP
                            || mode == TImode
                            || mode == TFmode
                            || (BYTES_BIG_ENDIAN
@@ -4683,7 +4683,7 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p)
   struct aarch64_address_info addr;
 
   /* PRFM accepts the same addresses as DImode...  */
-  bool res = aarch64_classify_address (&addr, x, DImode, MEM, strict_p);
+  bool res = aarch64_classify_address (&addr, x, DImode, strict_p);
   if (!res)
     return false;
 
@@ -4719,19 +4719,18 @@ aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p)
 {
   struct aarch64_address_info addr;
 
-  return aarch64_classify_address (&addr, x, mode, MEM, strict_p);
+  return aarch64_classify_address (&addr, x, mode, strict_p);
 }
 
-/* Return TRUE if X is a legitimate address for accessing memory in
-   mode MODE.  OUTER_CODE will be PARALLEL if this is a load/store
-   pair operation.  */
+/* Return TRUE if X is a legitimate address of type TYPE for accessing
+   memory in mode MODE.  STRICT_P is true if REG_OK_STRICT is in effect.  */
 bool
-aarch64_legitimate_address_p (machine_mode mode, rtx x,
-                             RTX_CODE outer_code, bool strict_p)
+aarch64_legitimate_address_p (machine_mode mode, rtx x, bool strict_p,
+                             aarch64_addr_query_type type)
 {
   struct aarch64_address_info addr;
 
-  return aarch64_classify_address (&addr, x, mode, outer_code, strict_p);
+  return aarch64_classify_address (&addr, x, mode, strict_p, type);
 }
 
 /* Split an out-of-range address displacement into a base and offset.
@@ -5630,14 +5629,15 @@ aarch64_print_operand (FILE *f, rtx x, int code)
    'op' is the context required by aarch64_classify_address.  It can either be
    MEM for a normal memory access or PARALLEL for LDP/STP.  */
 static bool
-aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op)
+aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x,
+                               aarch64_addr_query_type type)
 {
   struct aarch64_address_info addr;
 
   /* Check all addresses are Pmode - including ILP32.  */
   gcc_assert (GET_MODE (x) == Pmode);
 
-  if (aarch64_classify_address (&addr, x, mode, op, true))
+  if (aarch64_classify_address (&addr, x, mode, true, type))
     switch (addr.type)
       {
       case ADDRESS_REG_IMM:
@@ -5725,14 +5725,14 @@ aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, RTX_CODE op)
 static bool
 aarch64_print_ldpstp_address (FILE *f, machine_mode mode, rtx x)
 {
-  return aarch64_print_address_internal (f, mode, x, PARALLEL);
+  return aarch64_print_address_internal (f, mode, x, ADDR_QUERY_LDP_STP);
 }
 
 /* Print address 'x' of a memory access with mode 'mode'.  */
 static void
 aarch64_print_operand_address (FILE *f, machine_mode mode, rtx x)
 {
-  if (!aarch64_print_address_internal (f, mode, x, MEM))
+  if (!aarch64_print_address_internal (f, mode, x, ADDR_QUERY_M))
     output_addr_const (f, x);
 }
 
@@ -6561,7 +6561,7 @@ aarch64_address_cost (rtx x,
   int cost = 0;
   info.shift = 0;
 
-  if (!aarch64_classify_address (&info, x, mode, c, false))
+  if (!aarch64_classify_address (&info, x, mode, false))
     {
       if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
        {
index af4143ef756464afac29d17f124b436520f90451..70ea3cde686914db4e0fc93819774b0b7ff17ee5 100644 (file)
    A memory address which uses a base register with an offset small enough for
    a load/store pair operation in DI mode."
    (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (DImode, XEXP (op, 0),
-                                                  PARALLEL, false)")))
+       (match_test "aarch64_legitimate_address_p (DImode, XEXP (op, 0), false,
+                                                  ADDR_QUERY_LDP_STP)")))
 
 (define_memory_constraint "Ump"
   "@internal
   A memory address suitable for a load/store pair operation."
   (and (match_code "mem")
        (match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0),
-                                                 PARALLEL, 1)")))
+                                                 true, ADDR_QUERY_LDP_STP)")))
 
 ;; Used for storing two 64-bit values in an AdvSIMD register using an STP
 ;; as a 128-bit vec_concat.
   "@internal
   A memory address suitable for a load/store pair operation."
   (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0),
-                                                  PARALLEL, 1)")))
+       (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), 1,
+                                                 ADDR_QUERY_LDP_STP)")))
 
 (define_memory_constraint "Utv"
   "@internal
   "@internal
    An address valid for loading or storing a 128-bit AdvSIMD register"
   (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (V2DImode, XEXP (op, 0),
-                                                 MEM, 1)")))
+       (match_test "aarch64_legitimate_address_p (V2DImode,
+                                                 XEXP (op, 0), 1)")))
 
 (define_constraint "Ufc"
   "A floating point constant which can be used with an\
index 2eaf0a7630169c3f4c23632d2a90be9ca15680df..d5593d1c8584f06b3900ec1de39fe9823d2808dc 100644 (file)
 
 (define_predicate "aarch64_mem_pair_operand"
   (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,
-                                              0)")))
+       (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), false,
+                                                 ADDR_QUERY_LDP_STP)")))
 
 ;; Used for storing two 64-bit values in an AdvSIMD register using an STP
 ;; as a 128-bit vec_concat.
 (define_predicate "aarch64_mem_pair_lanes_operand"
   (and (match_code "mem")
-       (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0),
-                                                  PARALLEL, 1)")))
+       (match_test "aarch64_legitimate_address_p (DFmode, XEXP (op, 0), 1,
+                                                 ADDR_QUERY_LDP_STP)")))
 
 (define_predicate "aarch64_prefetch_operand"
   (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))