aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 97116b3..2446040 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -186,8 +186,15 @@ static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
#endif
/* This macro is used to determine whether store_by_pieces should be
- called to "memset" storage with byte values other than zero, or
- to "memcpy" storage when the source is a constant string. */
+ called to "memset" storage with byte values other than zero. */
+#ifndef SET_BY_PIECES_P
+#define SET_BY_PIECES_P(SIZE, ALIGN) \
+ (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
+ < (unsigned int) SET_RATIO)
+#endif
+
+/* This macro is used to determine whether store_by_pieces should be
+ called to "memcpy" storage when the source is a constant string. */
#ifndef STORE_BY_PIECES_P
#define STORE_BY_PIECES_P(SIZE, ALIGN) \
(move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
@@ -2191,13 +2198,14 @@ use_group_regs (rtx *call_fusage, rtx regs)
/* Determine whether the LEN bytes generated by CONSTFUN can be
stored to memory using several move instructions. CONSTFUNDATA is
a pointer which will be passed as argument in every CONSTFUN call.
- ALIGN is maximum alignment we can assume. Return nonzero if a
- call to store_by_pieces should succeed. */
+ ALIGN is maximum alignment we can assume. MEMSETP is true if this is
+ a memset operation and false if it's a copy of a constant string.
+ Return nonzero if a call to store_by_pieces should succeed. */
int
can_store_by_pieces (unsigned HOST_WIDE_INT len,
rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
- void *constfundata, unsigned int align)
+ void *constfundata, unsigned int align, bool memsetp)
{
unsigned HOST_WIDE_INT l;
unsigned int max_size;
@@ -2210,7 +2218,9 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
if (len == 0)
return 1;
- if (! STORE_BY_PIECES_P (len, align))
+ if (! (memsetp
+ ? SET_BY_PIECES_P (len, align)
+ : STORE_BY_PIECES_P (len, align)))
return 0;
tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
@@ -2285,7 +2295,8 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
/* Generate several move instructions to store LEN bytes generated by
CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
pointer which will be passed as argument in every CONSTFUN call.
- ALIGN is maximum alignment we can assume.
+ ALIGN is maximum alignment we can assume. MEMSETP is true if this is
+ a memset operation and false if it's a copy of a constant string.
If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
mempcpy, and if ENDP is 2 return memory the end minus one byte ala
stpcpy. */
@@ -2293,7 +2304,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
rtx
store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
- void *constfundata, unsigned int align, int endp)
+ void *constfundata, unsigned int align, bool memsetp, int endp)
{
struct store_by_pieces data;
@@ -2303,7 +2314,9 @@ store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
return to;
}
- gcc_assert (STORE_BY_PIECES_P (len, align));
+ gcc_assert (memsetp
+ ? SET_BY_PIECES_P (len, align)
+ : STORE_BY_PIECES_P (len, align));
data.constfun = constfun;
data.constfundata = constfundata;
data.len = len;
@@ -4498,7 +4511,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
str_copy_len = MIN (str_copy_len, exp_len);
if (!can_store_by_pieces (str_copy_len, builtin_strncpy_read_str,
(void *) TREE_STRING_POINTER (exp),
- MEM_ALIGN (target)))
+ MEM_ALIGN (target), false))
goto normal_expr;
dest_mem = target;
@@ -4507,7 +4520,8 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
str_copy_len, builtin_strncpy_read_str,
(void *) TREE_STRING_POINTER (exp),
MEM_ALIGN (target),
- exp_len > str_copy_len ? 1 : 0);
+ exp_len > str_copy_len ? 1 : 0,
+ false);
if (exp_len > str_copy_len)
clear_storage (dest_mem, GEN_INT (exp_len - str_copy_len),
BLOCK_OP_NORMAL);