Re: [PATCH] expr.cc: Optimize if char array initialization consists of all zeros
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
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
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