Code scheduling for Cortex-A53 isn't as good as it could be.
authorWilco Dijkstra <wdijkstr@arm.com>
Fri, 5 May 2017 09:40:01 +0000 (09:40 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Fri, 5 May 2017 09:40:01 +0000 (09:40 +0000)
Code scheduling for Cortex-A53 isn't as good as it could be.  It turns out
code runs faster overall if we place loads and stores with a dependency
closer together.  To achieve this effect, this patch adds a bypass between
cortex_a53_load1 and cortex_a53_load*/cortex_a53_store* if the result of an
earlier load is used in an address calculation.  This significantly improved
benchmark scores in a proprietary benchmark suite.

    gcc/
* config/arm/aarch-common.c (arm_early_load_addr_dep_ptr):
New function.
(arm_early_store_addr_dep_ptr): Likewise.
* config/arm/aarch-common-protos.h
(arm_early_load_addr_dep_ptr): Add prototype.
(arm_early_store_addr_dep_ptr): Likewise.
* config/arm/cortex-a53.md: Add new bypasses.

From-SVN: r247631

gcc/ChangeLog
gcc/config/arm/aarch-common-protos.h
gcc/config/arm/aarch-common.c
gcc/config/arm/cortex-a53.md

index 44df0d7ecddc4d0fa1317946806537d1ba3afa3c..910658a970b53d4f1adc223a331d1d20f3e1db04 100644 (file)
@@ -1,3 +1,13 @@
+2017-05-05  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/arm/aarch-common.c (arm_early_load_addr_dep_ptr):
+       New function.
+       (arm_early_store_addr_dep_ptr): Likewise.
+       * config/arm/aarch-common-protos.h
+       (arm_early_load_addr_dep_ptr): Add prototype.
+       (arm_early_store_addr_dep_ptr): Likewise.
+       * config/arm/cortex-a53.md: Add new bypasses.
+
 2017-05-05  Jakub Jelinek  <jakub@redhat.com>
 
        * tree.c (next_type_uid): Change type to unsigned.
index 7c2bb4c2ed93728efcbd9e2811c09dddd04b37fe..35d2d96c9fdd2fe751cb1d37695f925892c9a898 100644 (file)
@@ -30,7 +30,9 @@ extern bool aarch_rev16_p (rtx);
 extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode);
 extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode);
 extern int arm_early_load_addr_dep (rtx, rtx);
+extern int arm_early_load_addr_dep_ptr (rtx, rtx);
 extern int arm_early_store_addr_dep (rtx, rtx);
+extern int arm_early_store_addr_dep_ptr (rtx, rtx);
 extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
 extern int arm_mac_accumulator_is_result (rtx, rtx);
 extern int arm_no_early_alu_shift_dep (rtx, rtx);
index 742d2ff4c7b779ae07b92f8a800e4667e32c44fb..6a04711335db292037ede5a801bdbaa830a3e524 100644 (file)
@@ -241,6 +241,24 @@ arm_early_load_addr_dep (rtx producer, rtx consumer)
   return reg_overlap_mentioned_p (value, addr);
 }
 
+/* Return nonzero if the CONSUMER instruction (a load) does need
+   a Pmode PRODUCER's value to calculate the address.  */
+
+int
+arm_early_load_addr_dep_ptr (rtx producer, rtx consumer)
+{
+  rtx value = arm_find_sub_rtx_with_code (PATTERN (producer), SET, false);
+  rtx addr = arm_find_sub_rtx_with_code (PATTERN (consumer), SET, false);
+
+  if (!value || !addr || !MEM_P (SET_SRC (value)))
+    return 0;
+
+  value = SET_DEST (value);
+  addr = SET_SRC (addr);
+
+  return GET_MODE (value) == Pmode && reg_overlap_mentioned_p (value, addr);
+}
+
 /* Return nonzero if the CONSUMER instruction (an ALU op) does not
    have an early register shift value or amount dependency on the
    result of PRODUCER.  */
@@ -336,6 +354,24 @@ arm_early_store_addr_dep (rtx producer, rtx consumer)
   return !arm_no_early_store_addr_dep (producer, consumer);
 }
 
+/* Return nonzero if the CONSUMER instruction (a store) does need
+   a Pmode PRODUCER's value to calculate the address.  */
+
+int
+arm_early_store_addr_dep_ptr (rtx producer, rtx consumer)
+{
+  rtx value = arm_find_sub_rtx_with_code (PATTERN (producer), SET, false);
+  rtx addr = arm_find_sub_rtx_with_code (PATTERN (consumer), SET, false);
+
+  if (!value || !addr || !MEM_P (SET_SRC (value)))
+    return 0;
+
+  value = SET_DEST (value);
+  addr = SET_DEST (addr);
+
+  return GET_MODE (value) == Pmode && reg_overlap_mentioned_p (value, addr);
+}
+
 /* Return non-zero iff the consumer (a multiply-accumulate or a
    multiple-subtract instruction) has an accumulator dependency on the
    result of the producer and no other dependency on that result.  It
index 7cf5fc5a0cd1d59efd0be3310b78303018138547..b7e0c9257f76b915ddccbc3eff28780fef7fc784 100644 (file)
                 "cortex_a53_store*"
                 "arm_no_early_store_addr_dep")
 
+;; Model a bypass for load to load/store address.
+
+(define_bypass 3 "cortex_a53_load1"
+                "cortex_a53_load*"
+                "arm_early_load_addr_dep_ptr")
+
+(define_bypass 3 "cortex_a53_load1"
+                "cortex_a53_store*"
+                "arm_early_store_addr_dep_ptr")
+
 ;; Model a GP->FP register move as similar to stores.
 
 (define_bypass 0 "cortex_a53_alu*,cortex_a53_shift*"