Re: [PATCH] expr.cc: Optimize if char array initialization consists of all zeros

2022-06-26 Thread Jeff Law via Gcc-patches




On 5/30/2022 9:35 PM, Takayuki 'January June' Suwa via Gcc-patches 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.
It's not entirely clear what you're trying to accomplish.  Is it the 
.zero which allocates space in the .rodata you're trying to remove? If 
so, it looks like that is already addressed on the trunk to me (I 
checked H8 with and without optimization).


jeff



Re: [PATCH] expr.cc: Optimize if char array initialization consists of all zeros

2022-06-01 Thread Richard Biener via Gcc-patches
On Tue, May 31, 2022 at 5:37 AM Takayuki 'January June' Suwa via
Gcc-patches  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:
> movia9, 0x110
> sub sp, sp, a9
> l32ra3, .LC1
> movi.n  a4, 0xa
> mov.n   a2, sp
> s32ia0, sp, 268
> call0   memcpy
> movia4, 0xf6
> movi.n  a3, 0
> addi.n  a2, sp, 10
> call0   memset
> mov.n   a2, sp
> call0   foo
> l32ia0, sp, 268
> movia9, 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


[PATCH] expr.cc: Optimize if char array initialization consists of all zeros

2022-05-30 Thread Takayuki 'January June' Suwa via Gcc-patches

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:
movia9, 0x110
sub sp, sp, a9
l32ra3, .LC1
movi.n  a4, 0xa
mov.n   a2, sp
s32ia0, sp, 268
call0   memcpy
movia4, 0xf6
movi.n  a3, 0
addi.n  a2, sp, 10
call0   memset
mov.n   a2, sp
call0   foo
l32ia0, sp, 268
movia9, 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;
   if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
{
  str_copy_len += STORE_MAX_PIECES - 1;
--
2.20.1