On Tue, May 31, 2022 at 5:37 AM Takayuki 'January June' Suwa via
Gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>
> Hi all,
>
> In some targets, initialization code for char array may be split into two
> parts even if the initialization consists of all zeros:
>
> /* example */
> extern void foo(char*);
> void test(void) {
>    char a[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
>    foo(a);
> }
>
> ;; Xtensa (xtensa-lx106)
> .LC0:
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .zero   246
> test:
>         movi    a9, 0x110
>         sub     sp, sp, a9
>         l32r    a3, .LC1
>         movi.n  a4, 0xa
>         mov.n   a2, sp
>         s32i    a0, sp, 268
>         call0   memcpy
>         movi    a4, 0xf6
>         movi.n  a3, 0
>         addi.n  a2, sp, 10
>         call0   memset
>         mov.n   a2, sp
>         call0   foo
>         l32i    a0, sp, 268
>         movi    a9, 0x110
>         add.n   sp, sp, a9
>         ret.n
>
> ;; H8/300 (-mh -mint32)
> .LC0:
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .string ""
>         .zero   246
> _test:
>         sub.l   #256,er7
>         sub.l   er2,er2
>         add.b   #10,r2l
>         mov.l   #.LC0,er1
>         mov.l   er7,er0
>         jsr     @_memcpy
>         sub.l   er2,er2
>         add.b   #246,r2l
>         sub.l   er1,er1
>         sub.l   er0,er0
>         add.b   #10,r0l
>         add.l   er7,er0
>         jsr     @_memset
>         mov.l   er7,er0
>         jsr     @_foo
>         add.l   #256,er7
>         rts
>
> i386 target (both 32 and 64bit) does not show such behavior.
>
>      gcc/ChangeLog:
>
>         * expr.cc (store_expr): Add check if the initialization content
>         consists of all zeros.
> ---
>   gcc/expr.cc | 7 +++++++
>   1 file changed, 7 insertions(+)
>
> diff --git a/gcc/expr.cc b/gcc/expr.cc
> index 7197996cec7..f94310dc7b9 100644
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -6015,6 +6015,7 @@ store_expr (tree exp, rtx target, int call_param_p,
>         rtx dest_mem;
>         tree str = TREE_CODE (exp) == STRING_CST
>                  ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
> +      char ch;
>
>         exp_len = int_expr_size (exp);
>         if (exp_len <= 0)
> @@ -6032,6 +6033,12 @@ store_expr (tree exp, rtx target, int call_param_p,
>         }
>
>         str_copy_len = TREE_STRING_LENGTH (str);
> +      /* If str contains only zeroes, no need to store to target.  */
> +      ch = 0;
> +      for (HOST_WIDE_INT i = 0; i < str_copy_len; ++i)
> +       ch |= TREE_STRING_POINTER (str)[i];
> +      if (ch == 0)
> +       str_copy_len = 0;

Not sure if I decipher the current code correctly but maybe we instead
want to prune str_copy_len from the end for trailing \0 bytes instead of
just special-casing all-zero initializers?

>         if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
>         {
>           str_copy_len += STORE_MAX_PIECES - 1;
> --
> 2.20.1

Reply via email to