Enable instruction fusion of dependent AESE; AESMC and AESD; AESIMC pairs.
authorwilco <wilco@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Feb 2016 12:52:23 +0000 (12:52 +0000)
committerwilco <wilco@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Feb 2016 12:52:23 +0000 (12:52 +0000)
This can give up to 2x speedup on many AArch64 implementations. Also model
the crypto instructions on Cortex-A57 according to the Optimization Guide.

    gcc/
        * config/aarch64/aarch64.c (cortexa53_tunings): Enable AES fusion.
        (cortexa57_tunings): Likewise.
        (cortexa72_tunings): Likewise.
        (arch_macro_fusion_pair_p): Add support for AES fusion.
        * config/aarch64/aarch64-fusion-pairs.def: Add AES_AESMC entry.
        * config/arm/aarch-common.c (aarch_crypto_can_dual_issue):
        Allow virtual registers before reload so early scheduling works.
        * config/arm/cortex-a57.md (cortex_a57_crypto_simple): Use
        correct latency and pipeline.
        (cortex_a57_crypto_complex): Likewise.
        (cortex_a57_crypto_xor): Likewise.
        (define_bypass): Add AES bypass.

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

gcc/ChangeLog
gcc/config/aarch64/aarch64-fusion-pairs.def
gcc/config/aarch64/aarch64.c
gcc/config/arm/aarch-common.c
gcc/config/arm/cortex-a57.md

index 23100e0..742d555 100644 (file)
@@ -1,3 +1,18 @@
+2016-02-10  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/aarch64/aarch64.c (cortexa53_tunings): Enable AES fusion.
+       (cortexa57_tunings): Likewise.
+       (cortexa72_tunings): Likewise.
+       (arch_macro_fusion_pair_p): Add support for AES fusion.
+       * config/aarch64/aarch64-fusion-pairs.def: Add AES_AESMC entry.
+       * config/arm/aarch-common.c (aarch_crypto_can_dual_issue):
+       Allow virtual registers before reload so early scheduling works.
+       * config/arm/cortex-a57.md (cortex_a57_crypto_simple): Use
+       correct latency and pipeline.
+       (cortex_a57_crypto_complex): Likewise.
+       (cortex_a57_crypto_xor): Likewise.
+       (define_bypass): Add AES bypass.
+
 2016-02-10  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/69726
index 8261da0..f488671 100644 (file)
@@ -33,4 +33,5 @@ AARCH64_FUSION_PAIR ("adrp+add", ADRP_ADD)
 AARCH64_FUSION_PAIR ("movk+movk", MOVK_MOVK)
 AARCH64_FUSION_PAIR ("adrp+ldr", ADRP_LDR)
 AARCH64_FUSION_PAIR ("cmp+branch", CMP_BRANCH)
+AARCH64_FUSION_PAIR ("aes+aesmc", AES_AESMC)
 
index 7ab5ec8..cb0892e 100644 (file)
@@ -451,7 +451,7 @@ static const struct tune_params cortexa53_tunings =
   &generic_branch_cost,
   4, /* memmov_cost  */
   2, /* issue_rate  */
-  (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+  (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
    | AARCH64_FUSE_MOVK_MOVK | AARCH64_FUSE_ADRP_LDR), /* fusible_ops  */
   8,   /* function_align.  */
   8,   /* jump_align.  */
@@ -476,7 +476,7 @@ static const struct tune_params cortexa57_tunings =
   &cortexa57_branch_cost,
   4, /* memmov_cost  */
   3, /* issue_rate  */
-  (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+  (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
    | AARCH64_FUSE_MOVK_MOVK), /* fusible_ops  */
   16,  /* function_align.  */
   8,   /* jump_align.  */
@@ -502,7 +502,7 @@ static const struct tune_params cortexa72_tunings =
   &generic_branch_cost,
   4, /* memmov_cost  */
   3, /* issue_rate  */
-  (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
+  (AARCH64_FUSE_AES_AESMC | AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD
    | AARCH64_FUSE_MOVK_MOVK), /* fusible_ops  */
   16,  /* function_align.  */
   8,   /* jump_align.  */
@@ -13328,6 +13328,10 @@ aarch_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
         }
     }
 
+  if ((aarch64_tune_params.fusible_ops & AARCH64_FUSE_AES_AESMC)
+       && aarch_crypto_can_dual_issue (prev, curr))
+    return true;
+
   if ((aarch64_tune_params.fusible_ops & AARCH64_FUSE_CMP_BRANCH)
       && any_condjump_p (curr))
     {
index 13058b7..dd37be0 100644 (file)
@@ -58,8 +58,11 @@ aarch_crypto_can_dual_issue (rtx_insn *producer_insn, rtx_insn *consumer_insn)
   {
     unsigned int regno = REGNO (SET_DEST (producer_set));
 
-    return REGNO (SET_DEST (consumer_set)) == regno
-           && REGNO (XVECEXP (consumer_src, 0, 0)) == regno;
+    /* Before reload the registers are virtual, so the destination of
+       consumer_set doesn't need to match.  */
+
+    return (REGNO (SET_DEST (consumer_set)) == regno || !reload_completed)
+           && REGNO (XVECEXP (consumer_src, 0, 0)) == regno;
   }
 
   return 0;
index 0d28951..758d382 100644 (file)
                         neon_fp_sqrt_s_q, neon_fp_sqrt_d_q"))
   "ca57_cx2_block*3")
 
-(define_insn_reservation "cortex_a57_crypto_simple" 4
+(define_insn_reservation "cortex_a57_crypto_simple" 3
   (and (eq_attr "tune" "cortexa57")
        (eq_attr "type" "crypto_aese,crypto_aesmc,crypto_sha1_fast,crypto_sha256_fast"))
-  "ca57_cx2")
+  "ca57_cx1")
 
-(define_insn_reservation "cortex_a57_crypto_complex" 7
+(define_insn_reservation "cortex_a57_crypto_complex" 6
   (and (eq_attr "tune" "cortexa57")
        (eq_attr "type" "crypto_sha1_slow,crypto_sha256_slow"))
-  "ca57_cx2+(ca57_cx2_issue,ca57_cx2)")
+  "ca57_cx1*2")
 
-(define_insn_reservation "cortex_a57_crypto_xor" 7
+(define_insn_reservation "cortex_a57_crypto_xor" 6
   (and (eq_attr "tune" "cortexa57")
        (eq_attr "type" "crypto_sha1_xor"))
-  "(ca57_cx1+ca57_cx2)")
+  "(ca57_cx1*2)|(ca57_cx2*2)")
 
 ;; We lie with calls.  They take up all issue slots, but are otherwise
 ;; not harmful.
 (define_bypass 1 "cortex_a57_*"
                 "cortex_a57_call,cortex_a57_branch")
 
+;; AESE+AESMC and AESD+AESIMC pairs forward with zero latency
+(define_bypass 0 "cortex_a57_crypto_simple"
+                "cortex_a57_crypto_simple"
+                "aarch_crypto_can_dual_issue")
+