public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Jan Hubicka <hubicka@ucw.cz>
Cc: gcc-patches@gcc.gnu.org, d@dcepelik.cz
Subject: Re: indirect_ref_may_alias_decl_p fix
Date: Thu, 13 Jun 2019 12:15:00 -0000	[thread overview]
Message-ID: <alpine.LSU.2.20.1906131408280.10704@zhemvz.fhfr.qr> (raw)
In-Reply-To: <20190613120550.7wtzpieeszazjn7i@kam.mff.cuni.cz>

[-- Attachment #1: Type: text/plain, Size: 7568 bytes --]

On Thu, 13 Jun 2019, Jan Hubicka wrote:

> Hi,
> after spending some time on the view converting MEM_REFs, I noticed that
> most of reasons we give up on view converts is not actually MEM_REF created
> but test
>  same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (base2))
> in indirect_ref_may_alias_decl_p
> 
> Here base2 is VAR_DECL while dbase2 is MEM_REF used to access it.
> 
> In the testcase:
> struct a {int a1; int a2;};
> struct b:a {};
> 
> struct b bvar,*bptr2;
> int
> test(void)
> {
>   struct a *bptr = &bvar;
>   bptr->a2=0;
>   bptr2->a1=1;
>   return bptr->a2;
> }
> 
> We have variable of type b, while we access it via its basetype.
> This mean that TREE_TYPE (base) is "struct b" while TREE_TYPE (dbase)
> is "struct a" which is perfectly normal and we could to the access path
> tests at least in the same strength as we would do if bptr=$bvar was 
> not visible to compiler (in that case we optimize things correctly).
> 
> Of course later in aliasing_component_refs_p we should not assume that
> "struct a" is the type of memory slot since the access path may contain
> b, but I think we can not assume that about "struct b" either, see below.
> 
> We should not give up on this case and just proceed the same way as
> indirect_refs_may_alias_p does.  In fact I would like to commonize the
> access path oracle of these functions incremetally but first I want to 
> drop main differences. In particular
> 
>  1) indirect_refs_may_alias_decl_p passing ref2_is_decl as true to 
>     aliasing_component_refs_p.
> 
>     This makes aliasing_component_refs_p to assume that all access paths
>     conflicting with REF2 must start by type of BASE2 or its subtype.
> 
>     IMO this is not quite right in gimple memory model where decls are just
>     untyped memory slots, since I can, for example, I can rewrite decl
>     of type a by a new data of type struct b {struct a a;};
>     which will confuse this logic.

The above check you complain about guards against this.

>     I will try to get rid of this incrementally - I would like to have it
>     logged how much optimization we lose here.
> 
>  2) indirect_refs_may_alias_decl_p does
> 
>   if ((TREE_CODE (base1) != TARGET_MEM_REF                                      
>        || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))                          
>       && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1        
>       && (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE                           
>           || (TYPE_SIZE (TREE_TYPE (base1))                                     
>               && TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))    
>     return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);   
> 
>      while indirect_refs_may_alias_p does:
> 
>   if ((TREE_CODE (base1) != TARGET_MEM_REF                                      
>        || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))                          
>       && (TREE_CODE (base2) != TARGET_MEM_REF                                   
>           || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))                       
>       && same_type_for_tbaa (TREE_TYPE (ptrtype1),                              
>                              TREE_TYPE (ptrtype2)) == 1                         
>       /* But avoid treating arrays as "objects", instead assume they            
>          can overlap by an exact multiple of their element size.                
>          See gcc.dg/torture/alias-2.c.  */                                      
>       && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)                        
>     return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);     
> 
>      Sincce we already checked that TREEE_TYPE (ptrtype) is same as TREE_TYPE (base1)
>      the same_type_for_tbaa check is equivalent in both.
> 
>      Notice however that first tests that array is VLA, while other
>      supports partial overlaps on all array types.  I suppose we want to
>      choose which way we support that and go with one or another.

Let's go with the stricter check for the purpose of unification and work
on this issue as followup.

>      Of course even in that case overlap check is not completely lost,
>      I attached testcase for that to
>      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90869
>      All we need is to wrap the checks by array size.
> 
>   With these differences sorted out I think both functions may dispatch to
>   common access path oracle after doing the case specific work.
> 
> Bootstrapped/regtested x86_64-linux, makes sense?

Yes, the patch below makes sense.

Thanks,
Richard.

> 	PR tree-optimize/90869
> 	* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Watch for view
> 	converts in MEM_REF referencing decl rather than view converts
> 	from decl type to MEM_REF type.
> 
> 	* g++.dg/tree-ssa/alias-access-path-1.C: New testcase.
> Index: tree-ssa-alias.c
> ===================================================================
> --- tree-ssa-alias.c	(revision 272037)
> +++ tree-ssa-alias.c	(working copy)
> @@ -1370,11 +1410,16 @@ indirect_ref_may_alias_decl_p (tree ref1
>    poly_offset_int doffset2 = offset2;
>    if (TREE_CODE (dbase2) == MEM_REF
>        || TREE_CODE (dbase2) == TARGET_MEM_REF)
> -    doffset2 -= mem_ref_offset (dbase2) << LOG2_BITS_PER_UNIT;
> +    {
> +      doffset2 -= mem_ref_offset (dbase2) << LOG2_BITS_PER_UNIT;
> +      tree ptrtype2 = TREE_TYPE (TREE_OPERAND (dbase2, 1));
> +      /* If second reference is view-converted, give up now.  */
> +      if (same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (ptrtype2)) != 1)
> +	return true;
> +    }
>  
> -  /* If either reference is view-converted, give up now.  */
> -  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1
> -      || same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (base2)) != 1)
> +  /* If first reference is view-converted, give up now.  */
> +  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1)
>      return true;
>  
>    /* If both references are through the same type, they do not alias
> @@ -1408,7 +1457,13 @@ indirect_ref_may_alias_decl_p (tree ref1
>  				      offset1, max_size1,
>  				      ref2,
>  				      ref2_alias_set, base2_alias_set,
> -				      offset2, max_size2, true);
> +				      offset2, max_size2, 
> +				      /* Only if the other reference is actual
> +					 decl we can safely check only toplevel
> +					 part of access path 1.  */
> +				      same_type_for_tbaa (TREE_TYPE (dbase2),
> +					                  TREE_TYPE (base2))
> +				      == 1);
>  
>    return true;
>  }
> Index: testsuite/g++.dg/tree-ssa/alias-access-path-1.C
> ===================================================================
> --- testsuite/g++.dg/tree-ssa/alias-access-path-1.C	(nonexistent)
> +++ testsuite/g++.dg/tree-ssa/alias-access-path-1.C	(working copy)
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -fdump-tree-fre1" } */
> +
> +struct a {int a1; int a2;};
> +struct b:a {};
> +
> +struct b bvar,*bptr2;
> +int
> +test(void)
> +{
> +  struct a *bptr = &bvar;
> +  bptr->a2=0;
> +  bptr2->a1=1;
> +  return bptr->a2;
> +}
> +int
> +test2(void)
> +{
> +  struct b *bptr = &bvar;
> +  bptr->a2=0;
> +  bptr2->a1=1;
> +  return bptr->a2;
> +}
> +/* { dg-final { scan-tree-dump-times "return 0" 2 "fre1" } } */
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)

  reply	other threads:[~2019-06-13 12:15 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-13 12:06 Jan Hubicka
2019-06-13 12:15 ` Richard Biener [this message]
2019-06-13 12:29   ` Jan Hubicka
2019-06-13 20:17     ` Christophe Lyon
2019-06-13 20:28       ` Jan Hubicka
2019-06-13 20:33       ` Rainer Orth
2019-06-13 20:55         ` Jan Hubicka
2019-06-13 21:15         ` Jan Hubicka
2019-06-14  6:59           ` Rainer Orth
2019-06-14  8:00             ` Jan Hubicka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LSU.2.20.1906131408280.10704@zhemvz.fhfr.qr \
    --to=rguenther@suse.de \
    --cc=d@dcepelik.cz \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hubicka@ucw.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).