[PATCH] Optimiza aggregate a = b = c = {} (PR c/78408)

Jakub Jelinek jakub@redhat.com
Tue Dec 13 11:36:00 GMT 2016


Hi!

Sorry for not getting to this earlier.

On Mon, Nov 28, 2016 at 10:50:26AM +0100, Richard Biener wrote:
> > +  else if (gimple_call_builtin_p (defstmt, BUILT_IN_MEMSET)
> > +	   && TREE_CODE (gimple_call_arg (defstmt, 0)) == ADDR_EXPR
> > +	   && TREE_CODE (gimple_call_arg (defstmt, 1)) == INTEGER_CST
> > +	   && TREE_CODE (gimple_call_arg (defstmt, 2)) == INTEGER_CST)
> > +    {
> > +      HOST_WIDE_INT ssize, max_size, off;
> > +      bool reverse;
> > +      src2 = TREE_OPERAND (gimple_call_arg (defstmt, 0), 0);
> > +      get_ref_base_and_extent (src2, &off, &ssize, &max_size, &reverse);
> > +      if (ssize != max_size
> > +	  || (ssize % BITS_PER_UNIT) != 0
> > +	  || !wi::eq_p (gimple_call_arg (defstmt, 2), ssize / BITS_PER_UNIT))
> > +	src2 = NULL_TREE;
> 
> I wonder why you jump through the hoops of get_ref_base_and_extent
> given the call args will be invariant addresses and thus
> get_addr_base_and_unit_offset would be more appropriate here.

get_addr_base_and_unit_offset does not give me the size though,
which is what I wanted to compute.  Even if as you suggest I'd
accept other INTEGER_CST sizes, it would still be better to punt
if the memset is clearly invalid.  And for the case where the
memset call is followed by assignment, not memcpy (very common, as
memcpy is often folded into the assignment), the verification needs
to be done.

> Also not sure why you want to restrict the size with the wi::eq_p
> (probably for the a = b case where the size isn't given explicitely
> but then you don't check whether off is 0 ...).  I'd say passing

But I'm not comparing the result of get_ref_base_and_extent, but
the argument as is.  Perhaps where it does above the src2 = NULL_TREE;
I could save the size into one var, off into another one and set
src2 to the result of get_ref_base_and_extent in that case, then
if those vars are set require the second stmt to be a memset and do the same
stuff there?

> in base, offset and size for src and dest into this function will
> simplify things and should allow to handle
> 
>   memset (p+10, 0, 24);
>   memcpy (q, p+10, 24);
> 
> if you compare bases with operand_equal_p.
> 
> > +  if (refs_may_alias_p (dest, src))
> > +    return;
> 
> Why's that?

I admit I'm not sure if GIMPLE_ASSIGN may be between overlapping objects or
not, memset can't.

	Jakub



More information about the Gcc-patches mailing list