Add param flags to adjust the memcpy/memove/memset inlining threshold.
The threshold can be updated with --param=<routine>-size-threshold=

Default is currently set for disabled.

gcc/ChangeLog:

        * config/riscv/riscv-string.cc (riscv_expand_block_move_scalar):
        Add length check.
        (expand_block_move): Ditto.
        (expand_vec_setmem): Ditto.
        * config/riscv/riscv.opt: Add param flags.

Signed-off-by: Edwin Lu <[email protected]>
---
 gcc/config/riscv/riscv-string.cc | 29 +++++++++++++++++++++++++++++
 gcc/config/riscv/riscv.opt       | 12 ++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc
index 61c4a095ab4..2d662b4ce49 100644
--- a/gcc/config/riscv/riscv-string.cc
+++ b/gcc/config/riscv/riscv-string.cc
@@ -923,6 +923,10 @@ riscv_expand_block_move_scalar (rtx dest, rtx src, rtx 
length)
   unsigned HOST_WIDE_INT hwi_length = UINTVAL (length);
   unsigned HOST_WIDE_INT factor, align;
 
+  if (riscv_memcpy_size_threshold >= 0
+      && hwi_length > riscv_memcpy_size_threshold)
+    return false;
+
   if (riscv_slow_unaligned_access_p)
     {
       align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD);
@@ -1233,6 +1237,21 @@ expand_block_move (rtx dst_in, rtx src_in, rtx 
length_in, bool movmem_p)
   if (!use_vector_stringop_p (info, potential_ew, length_in))
     return false;
 
+  if (CONST_INT_P (length_in))
+    {
+      HOST_WIDE_INT length = INTVAL (length_in);
+      if (movmem_p
+         && riscv_memmove_size_threshold >= 0
+         && length > riscv_memmove_size_threshold)
+       return false;
+      else if (!movmem_p
+              && riscv_memmove_size_threshold >= 0
+              && length > riscv_memcpy_size_threshold)
+       return false;
+    }
+  else
+    return false;
+
   /* Inlining general memmove is a pessimisation: we can't avoid having to
      decide which direction to go at runtime, which is costly in instruction
      count however for situations where the entire move fits in one vector
@@ -1615,6 +1634,16 @@ expand_vec_setmem (rtx dst_in, rtx length_in, rtx 
fill_value_in)
   if (!use_vector_stringop_p (info, 1, length_in) || info.need_loop)
     return false;
 
+  if (CONST_INT_P (length_in))
+    {
+      HOST_WIDE_INT length = INTVAL (length_in);
+      if (riscv_memset_size_threshold >= 0
+         && length > riscv_memset_size_threshold)
+       return false;
+    }
+  else
+    return false;
+
   rtx dst_addr = copy_addr_to_reg (XEXP (dst_in, 0));
   rtx dst = change_address (dst_in, info.vmode, dst_addr);
 
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 6543fd1c4a7..b334e6c10c8 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -361,6 +361,18 @@ mstringop-strategy=
 Target RejectNegative Joined Enum(stringop_strategy) Var(stringop_strategy) 
Init(STRATEGY_AUTO)
 Specify stringop expansion strategy.
 
+-param=memcpy-size-threshold=
+Target Joined UInteger Var(riscv_memcpy_size_threshold) Init(-1) Param
+Constant memcpy size in bytes above which to start using libcalls over 
inlining.
+
+-param=memmove-size-threshold=
+Target Joined UInteger Var(riscv_memmove_size_threshold) Init(-1) Param
+Constant memmove size in bytes above which to start using libcalls over 
inlining.
+
+-param=memset-size-threshold=
+Target Joined UInteger Var(riscv_memset_size_threshold) Init(-1) Param
+Constant memset size in bytes above which to start using libcalls over 
inlining.
+
 Enum
 Name(rvv_vector_bits) Type(enum rvv_vector_bits_enum)
 The possible RVV vector register lengths:
-- 
2.43.0

Reply via email to