This patch adds legitimize_address_displacement hook so that stack accesses...
authorWilco Dijkstra <wdijkstr@arm.com>
Thu, 1 Sep 2016 11:34:49 +0000 (11:34 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Thu, 1 Sep 2016 11:34:49 +0000 (11:34 +0000)
This patch adds legitimize_address_displacement hook so that stack accesses
with large offsets are split into a more efficient sequence.  Unaligned and
TI/TFmode use a 256-byte range, byte and halfword accesses use a 4KB range,
wider accesses use a 16KB range to maximise the available addressing range
and increase opportunities to share the base address.

int f(int x)
{
  int arr[8192];
  arr[4096] = 0;
  arr[6000] = 0;
  arr[7000] = 0;
  arr[8191] = 0;
  return arr[x];
}

Now generates:

  sub   sp, sp, #32768
  add   x1, sp, 16384
  str   wzr, [x1]
  str   wzr, [x1, 7616]
  str   wzr, [x1, 11616]
  str   wzr, [x1, 16380]
  ldr   w0, [sp, w0, sxtw 2]
  add   sp, sp, 32768
  ret

    gcc/
* config/aarch64/aarch64.c (aarch64_legitimize_address_displacement):
New function.
(TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT): Define.

From-SVN: r239923

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

index bf5c54901e7930fbd8d378011250d5c21b9cdff5..dca92035308f6a2bec92458fe0a604953b77c422 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-01  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_legitimize_address_displacement):
+       New function.
+       (TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT): Define.
+
 2016-09-01  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/aarch64/aarch64.md (*ands<mode>_compare0): New pattern.
index e813d66b40a6a9abce0a913f3d643153917bfd05..5efad462f11f2954a65386b3b6b8d51bd61c51c1 100644 (file)
@@ -4191,6 +4191,24 @@ aarch64_legitimate_address_p (machine_mode mode, rtx x,
   return aarch64_classify_address (&addr, x, mode, outer_code, strict_p);
 }
 
+/* Split an out-of-range address displacement into a base and offset.
+   Use 4KB range for 1- and 2-byte accesses and a 16KB range otherwise
+   to increase opportunities for sharing the base address of different sizes.
+   For TI/TFmode and unaligned accesses use a 256-byte range.  */
+static bool
+aarch64_legitimize_address_displacement (rtx *disp, rtx *off, machine_mode mode)
+{
+  HOST_WIDE_INT mask = GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3fff;
+
+  if (mode == TImode || mode == TFmode ||
+      (INTVAL (*disp) & (GET_MODE_SIZE (mode) - 1)) != 0)
+    mask = 0xff;
+
+  *off = GEN_INT (INTVAL (*disp) & ~mask);
+  *disp = GEN_INT (INTVAL (*disp) & mask);
+  return true;
+}
+
 /* Return TRUE if rtx X is immediate constant 0.0 */
 bool
 aarch64_float_const_zero_rtx_p (rtx x)
@@ -14135,6 +14153,10 @@ aarch64_optab_supported_p (int op, machine_mode mode1, machine_mode,
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P aarch64_legitimate_constant_p
 
+#undef TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT
+#define TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT \
+  aarch64_legitimize_address_displacement
+
 #undef TARGET_LIBGCC_CMP_RETURN_MODE
 #define TARGET_LIBGCC_CMP_RETURN_MODE aarch64_libgcc_cmp_return_mode