From: Matthew Fortune <[email protected]>
Add -mblockmov-limit to control which constant-sized block moves are
eligible for inline expansion. Use straight-line code for larger
word-aligned copies when optimizing for speed, avoiding loop overhead.
gcc/ChangeLog:
* config/mips/mips-protos.h (mips_expand_block_move): Add alignment
argument.
* config/mips/mips.cc (mips_expand_block_move): Add support to
control size of inlined memcpy. A memcpy strictly less than the
limit determined with an option -mblockmov-limit will be
considered for inlining. Improve aligned straight line memcpy.
* config/mips/mips.h (MIPS_MAX_MOVE_MEM_STRAIGHT): Define macro.
* config/mips/mips.md (cpymemsi): Pass the alignment to
mips_expand_block_move.
* config/mips/mips.opt (mblockmov-limit): New option.
gcc/testsuite/ChangeLog:
* gcc.target/mips/inline-memcpy-limit.c: New test.
* gcc.target/mips/inline-memcpy-straight.c: New test.
* gcc.target/mips/align-1-o32.c:
* gcc.target/mips/mips.exp: Add blockmov-limit to the list of
supported options.
Cherry-picked cf1e4960a4f80301e4c8f71a35cbbc8fef1ce6fd,
and 4194c529fade9b3106d118cac63b71bc8b13f7be
from https://github.com/MIPS/gcc
Signed-off-by: Matthew Fortune <[email protected]>
Signed-off-by: Robert Suchanek <[email protected]>
Signed-off-by: Faraz Shahbazker <[email protected]>
Signed-off-by: Aleksandar Rakic <[email protected]>
Signed-off-by: Eldar Osmanovic <[email protected]>
---
gcc/config/mips/mips-protos.h | 2 +-
gcc/config/mips/mips.cc | 29 ++++++++++++-------
gcc/config/mips/mips.h | 5 ++++
gcc/config/mips/mips.md | 2 +-
gcc/config/mips/mips.opt | 3 ++
gcc/testsuite/gcc.target/mips/align-1-o32.c | 2 +-
.../gcc.target/mips/inline-memcpy-limit.c | 17 +++++++++++
.../gcc.target/mips/inline-memcpy-straight.c | 18 ++++++++++++
gcc/testsuite/gcc.target/mips/mips.exp | 1 +
9 files changed, 66 insertions(+), 13 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/mips/inline-memcpy-limit.c
create mode 100644 gcc/testsuite/gcc.target/mips/inline-memcpy-straight.c
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 49ba91d88cb..64d80613e9e 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -242,7 +242,7 @@ extern bool mips_get_pic_call_symbol (rtx *, int);
extern void mips_set_return_address (rtx, rtx);
extern bool mips_move_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int);
extern bool mips_store_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int);
-extern bool mips_expand_block_move (rtx, rtx, rtx);
+extern bool mips_expand_block_move (rtx, rtx, rtx, rtx);
extern void mips_expand_synci_loop (rtx, rtx);
extern void mips_init_cumulative_args (CUMULATIVE_ARGS *, tree);
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index c3be68c15f7..1c79d980790 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -9472,7 +9472,7 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT
length,
memory reference SRC to memory reference DEST. */
bool
-mips_expand_block_move (rtx dest, rtx src, rtx length)
+mips_expand_block_move (rtx dest, rtx src, rtx length, rtx alignment)
{
if (!CONST_INT_P (length))
return false;
@@ -9482,16 +9482,25 @@ mips_expand_block_move (rtx dest, rtx src, rtx length)
|| MEM_ALIGN (dest) < MIPS_MIN_MOVE_MEM_ALIGN))
return false;
- if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER)
+ if (mips_movmem_limit == -1 || INTVAL (length) < mips_movmem_limit)
{
- mips_block_move_straight (dest, src, INTVAL (length));
- return true;
- }
- else if (optimize)
- {
- mips_block_move_loop (dest, src, INTVAL (length),
- MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
- return true;
+ if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER
+ /* We increase slightly the maximum number of bytes in
+ a straight-line block if the source and destination
+ are aligned to the register width. */
+ || (!optimize_size
+ && INTVAL (alignment) == UNITS_PER_WORD
+ && INTVAL (length) <= MIPS_MAX_MOVE_MEM_STRAIGHT))
+ {
+ mips_block_move_straight (dest, src, INTVAL (length));
+ return true;
+ }
+ else if (optimize)
+ {
+ mips_block_move_loop (dest, src, INTVAL (length),
+ MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
+ return true;
+ }
}
return false;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index ae34159ed37..b43f4c4dbe3 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -3158,6 +3158,11 @@ while (0)
#define MIPS_MAX_MOVE_BYTES_STRAIGHT \
(MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER * 2)
+/* The maximum number of bytes that can be copied by any expanded block move;
+ see mips_expand_block_move. */
+#define MIPS_MAX_MOVE_MEM_STRAIGHT \
+ (MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER * 3)
+
/* The base cost of a memcpy call, for MOVE_RATIO and friends. These
values were determined experimentally by benchmarking with CSiBE.
In theory, the call overhead is higher for TARGET_ABICALLS (especially
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 62cb1c270af..27cac8ba932 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5875,7 +5875,7 @@
(use (match_operand:SI 3 "const_int_operand"))])]
"!TARGET_MIPS16 && !TARGET_MEMCPY"
{
- if (mips_expand_block_move (operands[0], operands[1], operands[2]))
+ if (mips_expand_block_move (operands[0], operands[1], operands[2],
operands[3]))
DONE;
else
FAIL;
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index d2967aecd38..f48f22b53a6 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -550,6 +550,9 @@ mfunc-opt-list=
Target RejectNegative Joined Var(mips_func_opt_list_file) Init(0) Defer
mfunc-opt-list=FILE Use to specify per function optimizations.
+mblockmov-limit=
+Target RejectNegative Undocumented Joined UInteger Var(mips_movmem_limit)
Init(-1)
+
minline-intermix
Target Var(TARGET_INLINE_INTERMIX)
Allow inlining even if the compression flags differ between caller and callee.
diff --git a/gcc/testsuite/gcc.target/mips/align-1-o32.c
b/gcc/testsuite/gcc.target/mips/align-1-o32.c
index e043d6a3eca..965b192abfd 100644
--- a/gcc/testsuite/gcc.target/mips/align-1-o32.c
+++ b/gcc/testsuite/gcc.target/mips/align-1-o32.c
@@ -1,7 +1,7 @@
/* Check that typedef alignment does not affect passing of function
parameters for O32 ABI. */
/* { dg-do compile { target { "mips*-*-*" } } } */
-/* { dg-options "-mabi=32" } */
+/* { dg-options "-mabi=32 -mblockmov-limit=0" } */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
typedef struct ui8
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-limit.c
b/gcc/testsuite/gcc.target/mips/inline-memcpy-limit.c
new file mode 100644
index 00000000000..4755e100dda
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-limit.c
@@ -0,0 +1,17 @@
+/* { dg-options "-mabi=32 -mblockmov-limit=16" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } } */
+
+/* -mblockmov-limit should prevent a constant-sized copy at the limit from
+ being expanded inline. */
+
+unsigned int a[4];
+unsigned int b[4];
+
+NOCOMPRESSION void
+foo (void)
+{
+ __builtin_memcpy (a, b, sizeof (a));
+}
+
+/* { dg-final { scan-assembler "\tmemcpy" } } */
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-straight.c
b/gcc/testsuite/gcc.target/mips/inline-memcpy-straight.c
new file mode 100644
index 00000000000..50093c64d9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-straight.c
@@ -0,0 +1,18 @@
+/* { dg-options "-mabi=32" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } } */
+
+/* A word-aligned copy of up to MIPS_MAC_MOVE_MEM_STRAIGHT bytes should be
+ expanded as straight-line code rather than as block-move loop. */
+
+unsigned int a[4];
+unsigned int b[4];
+
+NOCOMPRESSION void
+foo (void)
+{
+ __builtin_memcpy (a, b, sizeof (a));
+}
+
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-not "\tbne\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp
b/gcc/testsuite/gcc.target/mips/mips.exp
index 8a5a1fa3134..5993be2aa03 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -312,6 +312,7 @@ foreach option {
# Add -mfoo= options to mips_option_groups.
foreach option {
abs
+ blockmov-limit
branch-cost
code-readable
func-opt-list
--
2.43.0