]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: enable muti push and pop for Zcmp when shrink-wrap-separate is ineffective
authorFei Gao <gaofei@eswincomputing.com>
Wed, 6 Sep 2023 09:39:09 +0000 (09:39 +0000)
committerKito Cheng <kito.cheng@sifive.com>
Tue, 12 Sep 2023 01:54:52 +0000 (09:54 +0800)
So that zcmp can be enabled in -Os where
shrink-wrap-separate is not effective.

To force enabling zcmp multi push/pop in speed perfered case,
fno-shrink-wrap-separate has to be explictly given.

gcc/ChangeLog:

* config/riscv/riscv.cc
(riscv_avoid_shrink_wrapping_separate): wrap the condition check in
riscv_avoid_shrink_wrapping_separate.
(riscv_avoid_multi_push):avoid multi push if shrink_wrapping_separate
is active.
(riscv_get_separate_components):call riscv_avoid_shrink_wrapping_separate

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rv32e_zcmp.c: remove -fno-shrink-wrap-separate
* gcc.target/riscv/rv32i_zcmp.c: likewise
* gcc.target/riscv/zcmp_push_fpr.c: likewise
* gcc.target/riscv/zcmp_stack_alignment.c: likewise
* gcc.target/riscv/zcmp_shrink_wrap_separate.c: New test.
* gcc.target/riscv/zcmp_shrink_wrap_separate2.c: New test.

gcc/config/riscv/riscv.cc
gcc/testsuite/gcc.target/riscv/rv32e_zcmp.c
gcc/testsuite/gcc.target/riscv/rv32i_zcmp.c
gcc/testsuite/gcc.target/riscv/zcmp_push_fpr.c
gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/zcmp_stack_alignment.c

index 12926b206ace8c657bb4479b9625a9abae3db2e6..0ecda795b3885442936e734d1a8224bb1c07d68d 100644 (file)
@@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfghooks.h"
 #include "cfgloop.h"
 #include "cfgrtl.h"
+#include "shrink-wrap.h"
 #include "sel-sched.h"
 #include "sched-int.h"
 #include "fold-const.h"
@@ -395,6 +396,7 @@ static const struct riscv_tune_param optimize_size_tune_info = {
   false,                                       /* use_divmod_expansion */
 };
 
+static bool riscv_avoid_shrink_wrapping_separate ();
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
 static void riscv_legitimize_poly_move (machine_mode, rtx, rtx, rtx);
@@ -5842,7 +5844,9 @@ riscv_avoid_multi_push (const struct riscv_frame_info *frame)
 {
   if (!TARGET_ZCMP || crtl->calls_eh_return || frame_pointer_needed
       || cfun->machine->interrupt_handler_p || cfun->machine->varargs_size != 0
-      || crtl->args.pretend_args_size != 0 || flag_shrink_wrap_separate
+      || crtl->args.pretend_args_size != 0
+      || (use_shrink_wrapping_separate ()
+         && !riscv_avoid_shrink_wrapping_separate ())
       || (frame->mask & ~MULTI_PUSH_GPR_MASK))
     return true;
 
@@ -7230,6 +7234,17 @@ riscv_epilogue_uses (unsigned int regno)
   return false;
 }
 
+static bool
+riscv_avoid_shrink_wrapping_separate ()
+{
+  if (riscv_use_save_libcall (&cfun->machine->frame)
+      || cfun->machine->interrupt_handler_p
+      || !cfun->machine->frame.gp_sp_offset.is_constant ())
+    return true;
+
+  return false;
+}
+
 /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS.  */
 
 static sbitmap
@@ -7239,9 +7254,7 @@ riscv_get_separate_components (void)
   sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
   bitmap_clear (components);
 
-  if (riscv_use_save_libcall (&cfun->machine->frame)
-      || cfun->machine->interrupt_handler_p
-      || !cfun->machine->frame.gp_sp_offset.is_constant ())
+  if (riscv_avoid_shrink_wrapping_separate ())
     return components;
 
   offset = cfun->machine->frame.gp_sp_offset.to_constant ();
index 394459c4ed76e2531bc50ffab813db1541196127..50e443573ad933d4a7c41481830327c8bffeba0d 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options " -Os -march=rv32e_zca_zcmp -mabi=ilp32e -mcmodel=medlow -fno-shrink-wrap-separate" } */
+/* { dg-options " -Os -march=rv32e_zca_zcmp -mabi=ilp32e -mcmodel=medlow" } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-O2" "-Og" "-O3" "-Oz" "-flto"} } */
 /* { dg-final { check-function-bodies "**" "" } } */
 
index f00338a9d17967a213213fe392c0b5a8d93673ce..ea562b7a233a33c2d183f3e634bf91bf8fb689fc 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options " -Os -march=rv32imaf_zca_zcmp -mabi=ilp32f -mcmodel=medlow -fno-shrink-wrap-separate" }*/
+/* { dg-options " -Os -march=rv32imaf_zca_zcmp -mabi=ilp32f -mcmodel=medlow" }*/
 /* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-O2" "-Og" "-O3" "-Oz" "-flto"} } */
 /* { dg-final { check-function-bodies "**" "" } } */
 
index 530b35b53dd07f9ed2e382b181edb362b3d7cb5b..c9d79205b31c05f02501a0ee19bbdd68ef7d9e3e 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-march=rv64imafd_zicsr_zifencei_zca_zcmp -mabi=lp64d -Os -fno-shrink-wrap-separate" } */
+/* { dg-options "-march=rv64imafd_zicsr_zifencei_zca_zcmp -mabi=lp64d -Os" } */
 /* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-O2" "-Og" "-O3" "-Oz" "-flto"} } */
 
 typedef struct
diff --git a/gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate.c b/gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate.c
new file mode 100644 (file)
index 0000000..035bc32
--- /dev/null
@@ -0,0 +1,93 @@
+/* { dg-do compile } */
+/* { dg-options " -O2 -march=rv32imaf_zca_zcmp -mabi=ilp32f" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
+
+typedef struct MAT_PARAMS_S
+{
+  int N;
+  signed short *A;
+  signed short *B;
+  signed int *C;
+} mat_params;
+
+typedef struct CORE_PORTABLE_S
+{
+  unsigned char portable_id;
+} core_portable;
+
+typedef struct RESULTS_S
+{
+  /* inputs */
+  signed short seed1;     /* Initializing seed */
+  signed short seed2;     /* Initializing seed */
+  signed short seed3;     /* Initializing seed */
+  void *memblock[4];      /* Pointer to safe memory location */
+  unsigned int size;      /* Size of the data */
+  unsigned int iterations; /* Number of iterations to execute */
+  unsigned int execs;     /* Bitmask of operations to execute */
+  struct list_head_s *list;
+  mat_params mat;
+  /* outputs */
+  unsigned short crc;
+  unsigned short crclist;
+  unsigned short crcmatrix;
+  unsigned short crcstate;
+  signed short err;
+  /* ultithread specific */
+  core_portable port;
+} core_results;
+
+extern signed short
+core_bench_state (unsigned int, void *, signed short, signed short,
+                 signed short, unsigned short);
+
+extern signed short
+core_bench_matrix (mat_params *, signed short, unsigned short);
+
+extern unsigned short
+crcu16 (signed short, unsigned short);
+
+signed short
+calc_func (signed short *pdata, core_results *res)
+{
+  signed short data = *pdata;
+  signed short retval;
+  unsigned char optype
+    = (data >> 7)
+      & 1;    /* bit 7 indicates if the function result has been cached */
+  if (optype) /* if cached, use cache */
+    return (data & 0x007f);
+  else
+    { /* otherwise calculate and cache the result */
+      signed short flag
+       = data & 0x7; /* bits 0-2 is type of function to perform */
+      signed short dtype
+       = ((data >> 3) & 0xf); /* bits 3-6 is specific data for the operation */
+      dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */
+      switch (flag)
+       {
+       case 0:
+         if (dtype < 0x22) /* set min period for bit corruption */
+           dtype = 0x22;
+         retval = core_bench_state (res->size, res->memblock[3], res->seed1,
+                                    res->seed2, dtype, res->crc);
+         if (res->crcstate == 0)
+           res->crcstate = retval;
+         break;
+       case 1:
+         retval = core_bench_matrix (&(res->mat), dtype, res->crc);
+         if (res->crcmatrix == 0)
+           res->crcmatrix = retval;
+         break;
+       default:
+         retval = data;
+         break;
+       }
+      res->crc = crcu16 (retval, res->crc);
+      retval &= 0x007f;
+      *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */
+      return retval;
+    }
+}
+
+/* { dg-final { scan-assembler-not "cm\.push" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate2.c b/gcc/testsuite/gcc.target/riscv/zcmp_shrink_wrap_separate2.c
new file mode 100644 (file)
index 0000000..47c7888
--- /dev/null
@@ -0,0 +1,93 @@
+/* { dg-do compile } */
+/* { dg-options " -O2 -fno-shrink-wrap-separate -march=rv32imaf_zca_zcmp -mabi=ilp32f" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
+
+typedef struct MAT_PARAMS_S
+{
+  int N;
+  signed short *A;
+  signed short *B;
+  signed int *C;
+} mat_params;
+
+typedef struct CORE_PORTABLE_S
+{
+  unsigned char portable_id;
+} core_portable;
+
+typedef struct RESULTS_S
+{
+  /* inputs */
+  signed short seed1;     /* Initializing seed */
+  signed short seed2;     /* Initializing seed */
+  signed short seed3;     /* Initializing seed */
+  void *memblock[4];      /* Pointer to safe memory location */
+  unsigned int size;      /* Size of the data */
+  unsigned int iterations; /* Number of iterations to execute */
+  unsigned int execs;     /* Bitmask of operations to execute */
+  struct list_head_s *list;
+  mat_params mat;
+  /* outputs */
+  unsigned short crc;
+  unsigned short crclist;
+  unsigned short crcmatrix;
+  unsigned short crcstate;
+  signed short err;
+  /* ultithread specific */
+  core_portable port;
+} core_results;
+
+extern signed short
+core_bench_state (unsigned int, void *, signed short, signed short,
+                 signed short, unsigned short);
+
+extern signed short
+core_bench_matrix (mat_params *, signed short, unsigned short);
+
+extern unsigned short
+crcu16 (signed short, unsigned short);
+
+signed short
+calc_func (signed short *pdata, core_results *res)
+{
+  signed short data = *pdata;
+  signed short retval;
+  unsigned char optype
+    = (data >> 7)
+      & 1;    /* bit 7 indicates if the function result has been cached */
+  if (optype) /* if cached, use cache */
+    return (data & 0x007f);
+  else
+    { /* otherwise calculate and cache the result */
+      signed short flag
+       = data & 0x7; /* bits 0-2 is type of function to perform */
+      signed short dtype
+       = ((data >> 3) & 0xf); /* bits 3-6 is specific data for the operation */
+      dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */
+      switch (flag)
+       {
+       case 0:
+         if (dtype < 0x22) /* set min period for bit corruption */
+           dtype = 0x22;
+         retval = core_bench_state (res->size, res->memblock[3], res->seed1,
+                                    res->seed2, dtype, res->crc);
+         if (res->crcstate == 0)
+           res->crcstate = retval;
+         break;
+       case 1:
+         retval = core_bench_matrix (&(res->mat), dtype, res->crc);
+         if (res->crcmatrix == 0)
+           res->crcmatrix = retval;
+         break;
+       default:
+         retval = data;
+         break;
+       }
+      res->crc = crcu16 (retval, res->crc);
+      retval &= 0x007f;
+      *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */
+      return retval;
+    }
+}
+
+/* { dg-final { scan-assembler "cm\.push" } } */
index 2f2fa55baac5eccb54ea48146c655a2078519626..f7d8f446b79c012235a06975bff40d3c5c2ee0cb 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options " -O0 -march=rv32e_zca_zcb_zcmp -mabi=ilp32e -mcmodel=medlow -fomit-frame-pointer -fno-shrink-wrap-separate" } */
+/* { dg-options " -O0 -march=rv32e_zca_zcb_zcmp -mabi=ilp32e -mcmodel=medlow -fomit-frame-pointer" } */
 /* { dg-skip-if "" { *-*-* } {"-O2" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
 /* { dg-final { check-function-bodies "**" "" } } */