public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] expr.cc: Optimize if char array initialization consists of all zeros
@ 2022-05-31  3:35 Takayuki 'January June' Suwa
  2022-06-01  8:57 ` Richard Biener
  2022-06-26 19:34 ` Jeff Law
  0 siblings, 2 replies; 3+ messages in thread
From: Takayuki 'January June' Suwa @ 2022-05-31  3:35 UTC (permalink / raw)
  To: 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:
	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;
        if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
  	{
  	  str_copy_len += STORE_MAX_PIECES - 1;
-- 
2.20.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] expr.cc: Optimize if char array initialization consists of all zeros
  2022-05-31  3:35 [PATCH] expr.cc: Optimize if char array initialization consists of all zeros Takayuki 'January June' Suwa
@ 2022-06-01  8:57 ` Richard Biener
  2022-06-26 19:34 ` Jeff Law
  1 sibling, 0 replies; 3+ messages in thread
From: Richard Biener @ 2022-06-01  8:57 UTC (permalink / raw)
  To: Takayuki 'January June' Suwa; +Cc: GCC Patches

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] expr.cc: Optimize if char array initialization consists of all zeros
  2022-05-31  3:35 [PATCH] expr.cc: Optimize if char array initialization consists of all zeros Takayuki 'January June' Suwa
  2022-06-01  8:57 ` Richard Biener
@ 2022-06-26 19:34 ` Jeff Law
  1 sibling, 0 replies; 3+ messages in thread
From: Jeff Law @ 2022-06-26 19:34 UTC (permalink / raw)
  To: 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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-06-26 19:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-31  3:35 [PATCH] expr.cc: Optimize if char array initialization consists of all zeros Takayuki 'January June' Suwa
2022-06-01  8:57 ` Richard Biener
2022-06-26 19:34 ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).