expr.c (store_expr): Optimize initialization of an array with STRING_CST.
* expr.c (store_expr): Optimize initialization of an array with STRING_CST. * expr.h (builtin_strncpy_read_str): New prototype. * builtins.c (builtin_strncpy_read_str): Remove prototype. No longer static. * gcc.dg/array-init-1.c: New test. From-SVN: r127769
This commit is contained in:
parent
492fc3e65a
commit
14a43348bc
|
@ -1,3 +1,11 @@
|
|||
2007-08-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* expr.c (store_expr): Optimize initialization of an array
|
||||
with STRING_CST.
|
||||
* expr.h (builtin_strncpy_read_str): New prototype.
|
||||
* builtins.c (builtin_strncpy_read_str): Remove prototype.
|
||||
No longer static.
|
||||
|
||||
2007-08-24 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR middle-end/33157
|
||||
|
|
|
@ -125,7 +125,6 @@ static rtx expand_builtin_bcopy (tree, int);
|
|||
static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
|
||||
static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
|
||||
static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
|
||||
static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
||||
static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
|
||||
static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
|
||||
static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
|
||||
|
@ -3734,7 +3733,7 @@ expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
|
|||
bytes from constant string DATA + OFFSET and return it as target
|
||||
constant. */
|
||||
|
||||
static rtx
|
||||
rtx
|
||||
builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
|
||||
enum machine_mode mode)
|
||||
{
|
||||
|
|
42
gcc/expr.c
42
gcc/expr.c
|
@ -4472,10 +4472,52 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal)
|
|||
|
||||
return NULL_RTX;
|
||||
}
|
||||
else if (TREE_CODE (exp) == STRING_CST
|
||||
&& !nontemporal && !call_param_p
|
||||
&& TREE_STRING_LENGTH (exp) > 0
|
||||
&& TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
|
||||
{
|
||||
/* Optimize initialization of an array with a STRING_CST. */
|
||||
HOST_WIDE_INT exp_len, str_copy_len;
|
||||
rtx dest_mem;
|
||||
|
||||
exp_len = int_expr_size (exp);
|
||||
if (exp_len <= 0)
|
||||
goto normal_expr;
|
||||
|
||||
str_copy_len = strlen (TREE_STRING_POINTER (exp));
|
||||
if (str_copy_len < TREE_STRING_LENGTH (exp) - 1)
|
||||
goto normal_expr;
|
||||
|
||||
str_copy_len = TREE_STRING_LENGTH (exp);
|
||||
if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
|
||||
{
|
||||
str_copy_len += STORE_MAX_PIECES - 1;
|
||||
str_copy_len &= ~(STORE_MAX_PIECES - 1);
|
||||
}
|
||||
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)))
|
||||
goto normal_expr;
|
||||
|
||||
dest_mem = target;
|
||||
|
||||
dest_mem = store_by_pieces (dest_mem,
|
||||
str_copy_len, builtin_strncpy_read_str,
|
||||
(void *) TREE_STRING_POINTER (exp),
|
||||
MEM_ALIGN (target),
|
||||
exp_len > str_copy_len ? 1 : 0);
|
||||
if (exp_len > str_copy_len)
|
||||
clear_storage (dest_mem, GEN_INT (exp_len - str_copy_len),
|
||||
BLOCK_OP_NORMAL);
|
||||
return NULL_RTX;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx tmp_target;
|
||||
|
||||
normal_expr:
|
||||
/* If we want to use a nontemporal store, force the value to
|
||||
register first. */
|
||||
tmp_target = nontemporal ? NULL_RTX : target;
|
||||
|
|
|
@ -341,6 +341,7 @@ extern void expand_builtin_setjmp_setup (rtx, rtx);
|
|||
extern void expand_builtin_setjmp_receiver (rtx);
|
||||
extern rtx expand_builtin_saveregs (void);
|
||||
extern void expand_builtin_trap (void);
|
||||
extern rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
||||
|
||||
/* Functions from expr.c: */
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
2007-08-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/array-init-1.c: New test.
|
||||
|
||||
PR c++/32567
|
||||
* g++.dg/parse/crash36.C: New test.
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* Test that both arrays are initialized by store_by_pieces. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
struct A { char c[10]; };
|
||||
extern void baz (struct A *);
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
struct A a = { "abcdefghi" };
|
||||
baz (&a);
|
||||
}
|
||||
|
||||
void
|
||||
bar (void)
|
||||
{
|
||||
struct A a;
|
||||
__builtin_strcpy (&a.c[0], "abcdefghi");
|
||||
baz (&a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "abcdefghi" { target i?86-*-* x86_64-*-* ia64-*-* } } } */
|
||||
/* { dg-final { scan-assembler-times "7523094288207667809\|6867666564636261\|1684234849\|64636261" 2 { target i?86-*-* x86_64-*-* ia64-*-* } } } */
|
Loading…
Reference in New Issue