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: Richard Biener <richard.guenther@gmail.com>,
	    Martin Jambor <mjambor@suse.cz>,
	Bernd Schmidt <bschmidt@redhat.com>,
	    gcc-patches@gcc.gnu.org
Subject: Re: Enable pointer TBAA for LTO
Date: Tue, 24 Nov 2015 08:38:00 -0000	[thread overview]
Message-ID: <alpine.LSU.2.11.1511240937250.4884@t29.fhfr.qr> (raw)
In-Reply-To: <20151124061000.GA4494@kam.mff.cuni.cz>

On Tue, 24 Nov 2015, Jan Hubicka wrote:

> > On November 23, 2015 5:50:25 PM GMT+01:00, Jan Hubicka <hubicka@ucw.cz> wrote:
> > >> 
> > >> I think it also causes the following and one related ICE
> > >> 
> > >> FAIL: gcc.dg/vect/pr62021.c -flto -ffat-lto-objects (internal
> > >compiler 
> > >> error)
> > >> 
> > >>
> > >/space/rguenther/src/svn/trunk3/gcc/testsuite/gcc.dg/vect/pr62021.c:7:1:
> > >
> > >> internal compiler error: in get_alias_set, at alias.c:880^M
> > >> 0x7528a7 get_alias_set(tree_node*)^M
> > >>         /space/rguenther/src/svn/trunk3/gcc/alias.c:880^M
> > >
> > >Does this one reproduce with mainline?
> > 
> > Yes, testsuite run on x86_64
> > 
> >  All thee ICEs are on the sanity
> > >check:
> > >gcc_checking_assert (!in_lto_p || !type_with_alias_set_p (t));
> > >which check that in LTO all types that ought to have CANONICAL_TYPE
> > >gets CANONICAL_TYPE
> > >computed.  ICE here probalby means that the type somehow bypassed LTO
> > >canonical type merging
> > >as well as the TYPE_CANONICAL=MAIN_VARIANT set in lto-streamer.c
> 
> Hi,
> all the ICE seems to be caused by fact that the simd streaming code creates
> array of pointers at ltrans time. Because pointers are now
> TYPE_STRUCTURAL_EQUALITY_P, we get array with TYPE_STRUCTURAL_EQUALITY_P
> and that sanity check is there to verify that this doesn't happen (because
> we lose optimization then)
> 
> This patch makes arrays and vectors to be handled same way as pointers:
> the canonical type is not computed because it is unused by get_alias_set
> anyway.
> 
> I implemented it for different reason - my TBAA checking in lto-symtab got
> false positives on arrays during the LTO bootstrap.  THe problem was again
> the overly generous globbing of TYPE_CANONICAL.
> 
> get_alias_set first does
> 
>  t = TYPE_CANONICAL (t)
> 
> and then for arrays recurses
> 
>  set = get_alias_set (TREE_TYPE (t));
> 
> Now we can have type
> 
>  int *[10];
> 
> with TYPE_CANONICAL
> 
>  float *[10];
> 
> and then get_alias_set (int *[10]) will return get_alias_set (float *)
> which is wrong, because then the array does not conflict with its elements.
> I did not managed to get any wrong code out of this, but it is an obvious bug.
> This problem reproduced prior the pointer patch, too, on other types which are
> globed at TYPE_CANONICAL computation.
> 
> This also fixeds semi-latent bug with Ada where TYPE_STRUCTURAL_EQUALITY_P type
> may win the merging and turn all interoperable arrays into
> TYPE_STRUCTURAL_EQUALITY_P.
> 
> For next stage1 I think I can move frontends away from computing TYPE_CANONICAL
> for those types. At least my initial test for C and C++ seemed to work just fine.
> 
> Bootstrapped/regtested x86_64-linux, OK?

I don't like the in_lto_p checks in tree.c but as you say they'll be 
removed next stage1 ok.

Thanks,
Richard.

> 	* lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL
> 	only for types where LTO sets them.
> 	* tree.c (build_array_type_1): Do ont set TYPE_CANONICAL for LTO.
> 	(make_vector_type): Likewise.
> 	(gimple_canonical_types_compatible_p): Use canonical_type_used_p.
> 	* tree.h (canonical_type_used_p): New inline.
> 	* alias.c (get_alias_set): Handle structural equality for all
> 	types that pass canonical_type_used_p.
> 	(record_component_aliases): Look through all types with
> 	record_component_aliases for possible pointers; sanity check that
> 	the alias sets match.
> 
> 	* lto.c (iterative_hash_canonical_type): Recruse for all types
> 	which pass !canonical_type_used_p.
> 	(gimple_register_canonical_type_1): Sanity check we do not compute
> 	canonical type of anything with !canonical_type_used_p.
> 	(gimple_register_canonical_type): Skip all types that are
> 	!canonical_type_used_p
> 
> Index: lto-streamer-in.c
> ===================================================================
> --- lto-streamer-in.c	(revision 230718)
> +++ lto-streamer-in.c	(working copy)
> @@ -1231,7 +1231,9 @@ lto_read_body_or_constructor (struct lto
>  	      if (TYPE_P (t))
>  		{
>  		  gcc_assert (TYPE_CANONICAL (t) == NULL_TREE);
> -		  TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
> +		  if (type_with_alias_set_p (t)
> +		      && canonical_type_used_p (t))
> +		    TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
>  		  if (TYPE_MAIN_VARIANT (t) != t)
>  		    {
>  		      gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE);
> Index: tree.c
> ===================================================================
> --- tree.c	(revision 230718)
> +++ tree.c	(working copy)
> @@ -8236,7 +8243,8 @@ build_array_type_1 (tree elt_type, tree
>    if (TYPE_CANONICAL (t) == t)
>      {
>        if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
> -	  || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
> +	  || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
> +	  || in_lto_p)
>  	SET_TYPE_STRUCTURAL_EQUALITY (t);
>        else if (TYPE_CANONICAL (elt_type) != elt_type
>  	       || (index_type && TYPE_CANONICAL (index_type) != index_type))
> @@ -9849,13 +9857,13 @@ make_vector_type (tree innertype, int nu
>    SET_TYPE_VECTOR_SUBPARTS (t, nunits);
>    SET_TYPE_MODE (t, mode);
>  
> -  if (TYPE_STRUCTURAL_EQUALITY_P (innertype))
> +  if (TYPE_STRUCTURAL_EQUALITY_P (innertype) || in_lto_p)
>      SET_TYPE_STRUCTURAL_EQUALITY (t);
>    else if ((TYPE_CANONICAL (innertype) != innertype
>  	    || mode != VOIDmode)
>  	   && !VECTOR_BOOLEAN_TYPE_P (t))
>      TYPE_CANONICAL (t)
> -      = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode);
> +      = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode);
>  
>    layout_type (t);
>  
> @@ -13279,7 +13292,8 @@ gimple_canonical_types_compatible_p (con
>  	 TYPE_CANONICAL is more fine grained than the equivalnce we test (where
>  	 all pointers are considered equal.  Be sure to not return false
>  	 negatives.  */
> -      gcc_checking_assert (!POINTER_TYPE_P (t1) && !POINTER_TYPE_P (t2));
> +      gcc_checking_assert (canonical_type_used_p (t1)
> +			   && canonical_type_used_p (t2));
>        return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
>      }
>  
> Index: tree.h
> ===================================================================
> --- tree.h	(revision 230718)
> +++ tree.h	(working copy)
> @@ -4807,7 +4807,9 @@ extern void DEBUG_FUNCTION verify_type (
>  extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
>  						 bool trust_type_canonical = true);
>  extern bool type_with_interoperable_signedness (const_tree);
> -/* Return simplified tree code of type that is used for canonical type merging.  */
> +
> +/* Return simplified tree code of type that is used for canonical type
> +   merging.  */
>  inline enum tree_code
>  tree_code_for_canonical_type_merging (enum tree_code code)
>  {
> @@ -4829,6 +4831,23 @@ tree_code_for_canonical_type_merging (en
>    return code;
>  }
>  
> +/* Return ture if get_alias_set care about TYPE_CANONICAL of given type.
> +   We don't define the types for pointers, arrays and vectors.  The reason is
> +   that pointers are handled specially: ptr_type_node accesses conflict with
> +   accesses to all other pointers.  This is done by alias.c.
> +   Because alias sets of arrays and vectors are the same as types of their
> +   elements, we can't compute canonical type either.  Otherwise we could go
> +   form void *[10] to int *[10] (because they are equivalent for canonical type
> +   machinery) and get wrong TBAA.  */
> +
> +inline bool
> +canonical_type_used_p (const_tree t)
> +{
> +  return !(POINTER_TYPE_P (t)
> +	   || TREE_CODE (t) == ARRAY_TYPE
> +	   || TREE_CODE (t) == VECTOR_TYPE);
> +}
> +
>  #define tree_map_eq tree_map_base_eq
>  extern unsigned int tree_map_hash (const void *);
>  #define tree_map_marked_p tree_map_base_marked_p
> Index: alias.c
> ===================================================================
> --- alias.c	(revision 230718)
> +++ alias.c	(working copy)
> @@ -869,11 +870,11 @@ get_alias_set (tree t)
>        set = lang_hooks.get_alias_set (t);
>        if (set != -1)
>  	return set;
> -      /* Handle structure type equality for pointer types.  This is easy
> -	 to do, because the code bellow ignore canonical types on these anyway.
> -	 This is important for LTO, where TYPE_CANONICAL for pointers can not
> -	 be meaningfuly computed by the frotnend.  */
> -      if (!POINTER_TYPE_P (t))
> +      /* Handle structure type equality for pointer types, arrays and vectors.
> +	 This is easy to do, because the code bellow ignore canonical types on
> +	 these anyway.  This is important for LTO, where TYPE_CANONICAL for
> +	 pointers can not be meaningfuly computed by the frotnend.  */
> +      if (canonical_type_used_p (t))
>  	{
>  	  /* In LTO we set canonical types for all types where it makes
>  	     sense to do so.  Double check we did not miss some type.  */
> @@ -929,7 +931,9 @@ get_alias_set (tree t)
>       integer(kind=4)[4] the same alias set or not.
>       Just be pragmatic here and make sure the array and its element
>       type get the same alias set assigned.  */
> -  else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t))
> +  else if (TREE_CODE (t) == ARRAY_TYPE
> +	   && (!TYPE_NONALIASED_COMPONENT (t)
> +	       || TYPE_STRUCTURAL_EQUALITY_P (t)))
>      set = get_alias_set (TREE_TYPE (t));
>  
>    /* From the former common C and C++ langhook implementation:
> @@ -971,7 +975,10 @@ get_alias_set (tree t)
>  	 We also want to make pointer to array/vector equivalent to pointer to
>  	 its element (see the reasoning above). Skip all those types, too.  */
>        for (p = t; POINTER_TYPE_P (p)
> -	   || (TREE_CODE (p) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (p))
> +	   || (TREE_CODE (p) == ARRAY_TYPE
> +	       && (!TYPE_NONALIASED_COMPONENT (p)
> +		   || !COMPLETE_TYPE_P (p)
> +		   || TYPE_STRUCTURAL_EQUALITY_P (p)))
>  	   || TREE_CODE (p) == VECTOR_TYPE;
>  	   p = TREE_TYPE (p))
>  	{
> @@ -1195,20 +1203,23 @@ record_component_aliases (tree type)
>  	       Accesses to it conflicts with accesses to any other pointer
>  	       type.  */
>  	    tree t = TREE_TYPE (field);
> -	    if (in_lto_p)
> +	    if (in_lto_p)
>  	      {
>  		/* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
>  		   element type and that type has to be normalized to void *,
>  		   too, in the case it is a pointer. */
> -		while ((TREE_CODE (t) == ARRAY_TYPE
> -			&& (!COMPLETE_TYPE_P (t)
> -			    || TYPE_NONALIASED_COMPONENT (t)))
> -		       || TREE_CODE (t) == VECTOR_TYPE)
> -		  t = TREE_TYPE (t);
> +		while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
> +		  {
> +		    gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
> +		    t = TREE_TYPE (t);
> +		  }
>  		if (POINTER_TYPE_P (t))
>  		  t = ptr_type_node;
> +		else if (flag_checking)
> +		  gcc_checking_assert (get_alias_set (t)
> +				       == get_alias_set (TREE_TYPE (field)));
>  	      }
> -	   
> +
>  	    record_alias_subset (superset, get_alias_set (t));
>  	  }
>        break;
> Index: lto/lto.c
> ===================================================================
> --- lto/lto.c	(revision 230718)
> +++ lto/lto.c	(working copy)
> @@ -389,9 +389,7 @@ iterative_hash_canonical_type (tree type
>    /* All type variants have same TYPE_CANONICAL.  */
>    type = TYPE_MAIN_VARIANT (type);
>  
> -  /* We do not compute TYPE_CANONICAl of POINTER_TYPE because the aliasing
> -     code never use it anyway.  */
> -  if (POINTER_TYPE_P (type))
> +  if (!canonical_type_used_p (type))
>      v = hash_canonical_type (type);
>    /* An already processed type.  */
>    else if (TYPE_CANONICAL (type))
> @@ -444,7 +442,7 @@ gimple_register_canonical_type_1 (tree t
>  
>    gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t)
>  		       && type_with_alias_set_p (t)
> -		       && !POINTER_TYPE_P (t));
> +		       && canonical_type_used_p (t));
>  
>    slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT);
>    if (*slot)
> @@ -477,7 +475,8 @@ gimple_register_canonical_type_1 (tree t
>  static void
>  gimple_register_canonical_type (tree t)
>  {
> -  if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t) || POINTER_TYPE_P (t))
> +  if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t)
> +      || !canonical_type_used_p (t))
>      return;
>  
>    /* Canonical types are same among all complete variants.  */
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

  reply	other threads:[~2015-11-24  8:38 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-08 20:46 Jan Hubicka
2015-11-10 12:27 ` Richard Biener
2015-11-10 18:15   ` Jan Hubicka
2015-11-11  9:21     ` Richard Biener
2015-11-11 12:43       ` Bernd Schmidt
2015-11-11 22:14         ` Jan Hubicka
2015-11-11 22:31           ` Jan Hubicka
2015-11-22 23:19             ` Jan Hubicka
2015-11-22 23:22               ` Eric Botcazou
2015-11-23  1:20                 ` Jan Hubicka
2015-11-23  8:34                   ` Eric Botcazou
2015-11-23 17:26                     ` Jan Hubicka
2015-11-23 10:39               ` Richard Biener
2015-11-23 17:08                 ` Jan Hubicka
2015-11-24  8:34                   ` Richard Biener
2015-11-24 19:05                     ` Jan Hubicka
2015-11-25 10:49                       ` Richard Biener
2015-11-25 18:35                         ` Jan Hubicka
2015-11-24  5:01                 ` Jan Hubicka
2015-11-23 13:52               ` Martin Jambor
2015-11-23 15:33                 ` Richard Biener
2015-11-23 15:35                   ` Ilya Verbin
2015-11-27  8:24                     ` Thomas Schwinge
2015-11-23 16:52                   ` Jan Hubicka
2015-11-23 17:18                     ` Richard Biener
2015-11-24  6:23                       ` Jan Hubicka
2015-11-24  8:38                         ` Richard Biener [this message]
2015-11-25 10:10                         ` James Greenhalgh

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.11.1511240937250.4884@t29.fhfr.qr \
    --to=rguenther@suse.de \
    --cc=bschmidt@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hubicka@ucw.cz \
    --cc=mjambor@suse.cz \
    --cc=richard.guenther@gmail.com \
    /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).