diff mbox

Do not compute alias sets for types that don't need them

Message ID 20150522121552.GC91616@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka May 22, 2015, 12:15 p.m. UTC
Hi,
this patch fixes few cases where we compute alias type and don't need to
that are found by adding type_with_alias_set_p check to alias.c (I will send
this patch separately as there is still one ICE caught by it I believe
originating from ipa-icf-gimple, I have more involved fix for that)

The point of all this is to check that we don't make bogus querries to alias
oracle and don't try to use them somehow - we did in ipa-icf-gimple.  This is a
bug as the alias oracle gives stupid answers to stupid questions and sometimes
think the types conflicts sometimes thinks they doesn't.  The other three cases
are sort of just pointless computations.

Next part I would like to break out is the path computing equivalences considering
incomplete types (i.e. where all strucutres are equivalent and so all unions or
all functions of a given return value)

Bootstrapped/regtested x86_64-linux, OK?

Honza

	* tree-streamer-out.c (pack_ts_type_common_value_fields): Only consider
	alias set for types that have them.
	* lto-streamer-out.c (DFS::DFS_write_tree_body): Likewise.
	* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
	* ipa-icf-gimple.c (func_checker::compatible_types_p): Likewise.

Comments

Richard Biener May 22, 2015, 1:17 p.m. UTC | #1
On Fri, 22 May 2015, Jan Hubicka wrote:

> Hi,
> this patch fixes few cases where we compute alias type and don't need to
> that are found by adding type_with_alias_set_p check to alias.c (I will send
> this patch separately as there is still one ICE caught by it I believe
> originating from ipa-icf-gimple, I have more involved fix for that)
> 
> The point of all this is to check that we don't make bogus querries to alias
> oracle and don't try to use them somehow - we did in ipa-icf-gimple.  This is a
> bug as the alias oracle gives stupid answers to stupid questions and sometimes
> think the types conflicts sometimes thinks they doesn't.  The other three cases
> are sort of just pointless computations.
> 
> Next part I would like to break out is the path computing equivalences considering
> incomplete types (i.e. where all strucutres are equivalent and so all unions or
> all functions of a given return value)
> 
> Bootstrapped/regtested x86_64-linux, OK?
> 
> Honza
> 
> 	* tree-streamer-out.c (pack_ts_type_common_value_fields): Only consider
> 	alias set for types that have them.
> 	* lto-streamer-out.c (DFS::DFS_write_tree_body): Likewise.
> 	* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
> 	* ipa-icf-gimple.c (func_checker::compatible_types_p): Likewise.
> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c	(revision 223508)
> +++ tree-streamer-out.c	(working copy)
> @@ -346,6 +346,7 @@ pack_ts_type_common_value_fields (struct
>       alias-set zero to this type.  */
>    bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
>  			    || (!in_lto_p
> +				&& type_with_alias_set_p (expr)
>  				&& get_alias_set (expr) == 0)) ? 0 : -1);
>  }
>  
> Index: lto-streamer-out.c
> ===================================================================
> --- lto-streamer-out.c	(revision 223508)
> +++ lto-streamer-out.c	(working copy)
> @@ -1146,6 +1146,7 @@ hash_tree (struct streamer_tree_cache_d
>        hstate.add_int (TYPE_ALIGN (t));
>        hstate.add_int ((TYPE_ALIAS_SET (t) == 0
>  					 || (!in_lto_p
> +					     && type_with_alias_set_p (t)
>  					     && get_alias_set (t) == 0))
>  					? 0 : -1);
>      }
> Index: emit-rtl.c
> ===================================================================
> --- emit-rtl.c	(revision 223508)
> +++ emit-rtl.c	(working copy)
> @@ -1787,8 +1787,15 @@ set_mem_attributes_minus_bitpos (rtx ref
>    memset (&attrs, 0, sizeof (attrs));
>  
>    /* Get the alias set from the expression or type (perhaps using a
> -     front-end routine) and use it.  */
> -  attrs.alias = get_alias_set (t);
> +     front-end routine) and use it.
> +
> +     We may be called to produce MEM RTX for variable of incomplete type.
> +     This MEM RTX will only be used to produce address of a vairable, so
> +     we do not need to compute alias set.  */

But why do we set mem_attributes for it then?

> +  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
> +    attrs.alias = get_alias_set (t);
> +  else
> +    gcc_assert (DECL_P (t) && TREE_ADDRESSABLE (t));

This assert also looks fishy to me...  (also just use 'type' instead
of TREE_TYPE (t), not sure why you need to pun to the main variant
here either - get_alias_set will do that for you and so should
type_with_alias_set_p if that is necessary).

The rest of the patch looks ok.

Thanks,
Richard.

>    MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
>    MEM_POINTER (ref) = POINTER_TYPE_P (type);
> Index: ipa-icf-gimple.c
> ===================================================================
> --- ipa-icf-gimple.c	(revision 223508)
> +++ ipa-icf-gimple.c	(working copy)
> @@ -274,6 +274,12 @@ func_checker::compatible_types_p (tree t
>    if (!types_compatible_p (t1, t2))
>      return return_false_with_msg ("types are not compatible");
>  
> +  /* FIXME: type compatiblity checks for types that are never stored
> +     to memory is not very useful.  We should update the code to avoid
> +     calling compatible_types_p on types that will never be used.  */
> +  if (!type_with_alias_set_p (t1) || !type_with_alias_set_p (t2))
> +    return true;
> +
>    if (get_alias_set (t1) != get_alias_set (t2))
>      return return_false_with_msg ("alias sets are different");
>  
> 
>
Jan Hubicka May 22, 2015, 1:33 p.m. UTC | #2
> > Index: emit-rtl.c
> > ===================================================================
> > --- emit-rtl.c	(revision 223508)
> > +++ emit-rtl.c	(working copy)
> > @@ -1787,8 +1787,15 @@ set_mem_attributes_minus_bitpos (rtx ref
> >    memset (&attrs, 0, sizeof (attrs));
> >  
> >    /* Get the alias set from the expression or type (perhaps using a
> > -     front-end routine) and use it.  */
> > -  attrs.alias = get_alias_set (t);
> > +     front-end routine) and use it.
> > +
> > +     We may be called to produce MEM RTX for variable of incomplete type.
> > +     This MEM RTX will only be used to produce address of a vairable, so
> > +     we do not need to compute alias set.  */
> 
> But why do we set mem_attributes for it then?

Because we are stupid.  We want to produce &var, where var is of incomplete type
and to do it, we need to compute DECL_RTL of var and that is MEM RTX and we assign
attributes to every DECL_RTL MEM we produce.  I do not see how to cut this down
except for having something like DECL_RTL_ADDR and have way to build it without
actually making MEM expr... (which would save some memory for the MEM RTX and for
attributes but it would make it difficult to hook that value somewhere)
> 
> > +  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
> > +    attrs.alias = get_alias_set (t);
> > +  else
> > +    gcc_assert (DECL_P (t) && TREE_ADDRESSABLE (t));
> 
> This assert also looks fishy to me...  (also just use 'type' instead
> of TREE_TYPE (t), not sure why you need to pun to the main variant
> here either - get_alias_set will do that for you and so should
> type_with_alias_set_p if that is necessary).

I am not sure if TYPE_MAIN_VARIANT is really needed here.  What I know is that
complete types may have incomplete variants.  I was bit worried that I can
disable calculation of alias set of something that do matter by not checking
main variant in case we somehow manage to have a variable of incomplete vairant
type but still access it because we know its complete main variant (that would
be somewhat broken).

That is also why I added the check - the idea is that at least I can check that this
particular var is indeed having address taken.   Other option would be to define
an invalid alias set and assign MEM RTX this invalid alias set and make alias.c
bomb when it trips across it.

I actually noticed it triggers during producing some libjava glue where we
forgot to set TREE_ADDRESSABLE for artificial variable that takes address.
I will look into fix later today or tomorrow.

Honza
> 
> The rest of the patch looks ok.
> 
> Thanks,
> Richard.
> 
> >    MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
> >    MEM_POINTER (ref) = POINTER_TYPE_P (type);
> > Index: ipa-icf-gimple.c
> > ===================================================================
> > --- ipa-icf-gimple.c	(revision 223508)
> > +++ ipa-icf-gimple.c	(working copy)
> > @@ -274,6 +274,12 @@ func_checker::compatible_types_p (tree t
> >    if (!types_compatible_p (t1, t2))
> >      return return_false_with_msg ("types are not compatible");
> >  
> > +  /* FIXME: type compatiblity checks for types that are never stored
> > +     to memory is not very useful.  We should update the code to avoid
> > +     calling compatible_types_p on types that will never be used.  */
> > +  if (!type_with_alias_set_p (t1) || !type_with_alias_set_p (t2))
> > +    return true;
> > +
> >    if (get_alias_set (t1) != get_alias_set (t2))
> >      return return_false_with_msg ("alias sets are different");
> >  
> > 
> > 
> 
> -- 
> Richard Biener <rguenther@suse.de>
> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)
Richard Biener May 26, 2015, 7:49 a.m. UTC | #3
On Fri, 22 May 2015, Jan Hubicka wrote:

> > > Index: emit-rtl.c
> > > ===================================================================
> > > --- emit-rtl.c	(revision 223508)
> > > +++ emit-rtl.c	(working copy)
> > > @@ -1787,8 +1787,15 @@ set_mem_attributes_minus_bitpos (rtx ref
> > >    memset (&attrs, 0, sizeof (attrs));
> > >  
> > >    /* Get the alias set from the expression or type (perhaps using a
> > > -     front-end routine) and use it.  */
> > > -  attrs.alias = get_alias_set (t);
> > > +     front-end routine) and use it.
> > > +
> > > +     We may be called to produce MEM RTX for variable of incomplete type.
> > > +     This MEM RTX will only be used to produce address of a vairable, so
> > > +     we do not need to compute alias set.  */
> > 
> > But why do we set mem_attributes for it then?
> 
> Because we are stupid.  We want to produce &var, where var is of incomplete type
> and to do it, we need to compute DECL_RTL of var and that is MEM RTX and we assign
> attributes to every DECL_RTL MEM we produce.  I do not see how to cut this down
> except for having something like DECL_RTL_ADDR and have way to build it without
> actually making MEM expr... (which would save some memory for the MEM RTX and for
> attributes but it would make it difficult to hook that value somewhere)

Ok, I see...

> > 
> > > +  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
> > > +    attrs.alias = get_alias_set (t);
> > > +  else
> > > +    gcc_assert (DECL_P (t) && TREE_ADDRESSABLE (t));
> > 
> > This assert also looks fishy to me...  (also just use 'type' instead
> > of TREE_TYPE (t), not sure why you need to pun to the main variant
> > here either - get_alias_set will do that for you and so should
> > type_with_alias_set_p if that is necessary).
> 
> I am not sure if TYPE_MAIN_VARIANT is really needed here.  What I know is that
> complete types may have incomplete variants.

How can that be?  TYPE_FIELDS is shared across variants and all variants
should be layed out.

>  I was bit worried that I can
> disable calculation of alias set of something that do matter by not checking
> main variant in case we somehow manage to have a variable of incomplete vairant
> type but still access it because we know its complete main variant (that would
> be somewhat broken).
> 
> That is also why I added the check - the idea is that at least I can check that this
> particular var is indeed having address taken.   Other option would be to define
> an invalid alias set and assign MEM RTX this invalid alias set and make alias.c
> bomb when it trips across it.
> 
> I actually noticed it triggers during producing some libjava glue where we
> forgot to set TREE_ADDRESSABLE for artificial variable that takes address.
> I will look into fix later today or tomorrow.

Ok, thanks.

Richard.

> Honza
> > 
> > The rest of the patch looks ok.
> > 
> > Thanks,
> > Richard.
> > 
> > >    MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
> > >    MEM_POINTER (ref) = POINTER_TYPE_P (type);
> > > Index: ipa-icf-gimple.c
> > > ===================================================================
> > > --- ipa-icf-gimple.c	(revision 223508)
> > > +++ ipa-icf-gimple.c	(working copy)
> > > @@ -274,6 +274,12 @@ func_checker::compatible_types_p (tree t
> > >    if (!types_compatible_p (t1, t2))
> > >      return return_false_with_msg ("types are not compatible");
> > >  
> > > +  /* FIXME: type compatiblity checks for types that are never stored
> > > +     to memory is not very useful.  We should update the code to avoid
> > > +     calling compatible_types_p on types that will never be used.  */
> > > +  if (!type_with_alias_set_p (t1) || !type_with_alias_set_p (t2))
> > > +    return true;
> > > +
> > >    if (get_alias_set (t1) != get_alias_set (t2))
> > >      return return_false_with_msg ("alias sets are different");
> > >  
> > > 
> > > 
> > 
> > -- 
> > Richard Biener <rguenther@suse.de>
> > SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)
> 
>
Michael Matz May 26, 2015, 1:51 p.m. UTC | #4
Hi,

On Fri, 22 May 2015, Jan Hubicka wrote:

> Index: tree-streamer-out.c
> ===================================================================
> --- tree-streamer-out.c	(revision 223508)
> +++ tree-streamer-out.c	(working copy)
> @@ -346,6 +346,7 @@ pack_ts_type_common_value_fields (struct
>       alias-set zero to this type.  */
>    bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
>  			    || (!in_lto_p
> +				&& type_with_alias_set_p (expr)
>  				&& get_alias_set (expr) == 0)) ? 0 : -1);

I find such interfaces very ugly.  IOW, when it's always (or often) 
necessary to call check_foo_p() before foo() can be called then the 
checking should be part of foo() (and it should then return a conservative 
value, i.e. alias set 0), and that requirement not be imposed on the 
callers of foo().  I.e. why can't whatever checks you do in 
type_with_alias_set_p be included in get_alias_set?

> +     front-end routine) and use it.
> +
> +     We may be called to produce MEM RTX for variable of incomplete type.
> +     This MEM RTX will only be used to produce address of a vairable, so
> +     we do not need to compute alias set.  */
> +  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
> +    attrs.alias = get_alias_set (t);

And if the checking needs to go down the main-variant chain then this 
should be done inside type_with_alias_set_p(), not in the caller, 
otherwise even the symmetry between arguments of type_with_alias_set_p(xy) 
and get_alias_set(xy) is destroyed (but see above for why I think 
type_with_alias_set_p shouldn't even exist).


Ciao,
Michael.
Jan Hubicka May 26, 2015, 5:34 p.m. UTC | #5
> Hi,
> 
> On Fri, 22 May 2015, Jan Hubicka wrote:
> 
> > Index: tree-streamer-out.c
> > ===================================================================
> > --- tree-streamer-out.c	(revision 223508)
> > +++ tree-streamer-out.c	(working copy)
> > @@ -346,6 +346,7 @@ pack_ts_type_common_value_fields (struct
> >       alias-set zero to this type.  */
> >    bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
> >  			    || (!in_lto_p
> > +				&& type_with_alias_set_p (expr)
> >  				&& get_alias_set (expr) == 0)) ? 0 : -1);
> 
> I find such interfaces very ugly.  IOW, when it's always (or often) 
> necessary to call check_foo_p() before foo() can be called then the 
> checking should be part of foo() (and it should then return a conservative 
> value, i.e. alias set 0), and that requirement not be imposed on the 
> callers of foo().  I.e. why can't whatever checks you do in 
> type_with_alias_set_p be included in get_alias_set?

Because of sanity checking: I want to make alias sets of those types undefined
rather than having random values.  The point is that using the alias set in
alias oracle querry is wrong.

Now I run into the case that we do produce MEM exprs for incomplete variants
just to take their address so I was thinking the other day about defining an
invalid alias set -2, making get_alias_set to return it and ICE later when query
is actually made?

We do have wrong query problems at least in ipa-icf, so I think it is worthwhile
sanity check.
> 
> > +     front-end routine) and use it.
> > +
> > +     We may be called to produce MEM RTX for variable of incomplete type.
> > +     This MEM RTX will only be used to produce address of a vairable, so
> > +     we do not need to compute alias set.  */
> > +  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
> > +    attrs.alias = get_alias_set (t);
> 
> And if the checking needs to go down the main-variant chain then this 
> should be done inside type_with_alias_set_p(), not in the caller, 
> otherwise even the symmetry between arguments of type_with_alias_set_p(xy) 
> and get_alias_set(xy) is destroyed (but see above for why I think 
> type_with_alias_set_p shouldn't even exist).

Yep, good point - I will cleanup this.

Honza
Jan Hubicka May 27, 2015, 5:22 a.m. UTC | #6
> > 
> > I am not sure if TYPE_MAIN_VARIANT is really needed here.  What I know is that
> > complete types may have incomplete variants.
> 
> How can that be?  TYPE_FIELDS is shared across variants and all variants
> should be layed out.

Because TYPE_FILEDS are not always shared across variants.  For example
gfc_nonrestricted_type builds variants of types that have their own TYPE_FIELDS
lists whose types are variants of the original TYPE_FIELDs.  C++ FE used to do
the same for member pointers, but I noticed that last stage1 with early version
of type verifier and as far as I can remember Jason changed that.

Honza
Jan Hubicka May 27, 2015, 5:44 a.m. UTC | #7
> > > 
> > > I am not sure if TYPE_MAIN_VARIANT is really needed here.  What I know is that
> > > complete types may have incomplete variants.
> > 
> > How can that be?  TYPE_FIELDS is shared across variants and all variants
> > should be layed out.
> 
> Because TYPE_FILEDS are not always shared across variants.  For example
> gfc_nonrestricted_type builds variants of types that have their own TYPE_FIELDS
> lists whose types are variants of the original TYPE_FIELDs.  C++ FE used to do
> the same for member pointers, but I noticed that last stage1 with early version
> of type verifier and as far as I can remember Jason changed that.

And also I am positive that we do have incomplete variants of complete types in
IL. Those seem to happen for C++ templates.  I can dig more into reason for
these appearing.

We also also get wrong self-referring builtin types. This we discussed in
https://gcc.gnu.org/ml/gcc-patches/2014-07/msg00562.html gcov_info_type still
fails the type verifier because we produce variant that has TYPE_SIZE but no
TYPE_FIELDS.  It does not happen on mainline only becuase we moved verify_type
into dwarf2out and that type never gets into debug info.  I don't see how to
fix this other way than by my original patch in the thread above - upon
completing builtin type we should copy its fields from main variant at the same
time we copy size.  FEs are doing that.

Honza
> 
> Honza
Richard Biener May 27, 2015, 8:28 a.m. UTC | #8
On Tue, 26 May 2015, Jan Hubicka wrote:

> > Hi,
> > 
> > On Fri, 22 May 2015, Jan Hubicka wrote:
> > 
> > > Index: tree-streamer-out.c
> > > ===================================================================
> > > --- tree-streamer-out.c	(revision 223508)
> > > +++ tree-streamer-out.c	(working copy)
> > > @@ -346,6 +346,7 @@ pack_ts_type_common_value_fields (struct
> > >       alias-set zero to this type.  */
> > >    bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
> > >  			    || (!in_lto_p
> > > +				&& type_with_alias_set_p (expr)
> > >  				&& get_alias_set (expr) == 0)) ? 0 : -1);
> > 
> > I find such interfaces very ugly.  IOW, when it's always (or often) 
> > necessary to call check_foo_p() before foo() can be called then the 
> > checking should be part of foo() (and it should then return a conservative 
> > value, i.e. alias set 0), and that requirement not be imposed on the 
> > callers of foo().  I.e. why can't whatever checks you do in 
> > type_with_alias_set_p be included in get_alias_set?
> 
> Because of sanity checking: I want to make alias sets of those types undefined
> rather than having random values.  The point is that using the alias set in
> alias oracle querry is wrong.

You could have just returned 0 for the alias-set for 
!type_with_alias_set_p in get_alias_set.  That avoids polluting the
alias data structures and is neither random or wrong.

> Now I run into the case that we do produce MEM exprs for incomplete variants
> just to take their address so I was thinking the other day about defining an
> invalid alias set -2, making get_alias_set to return it and ICE later when query
> is actually made?
> 
> We do have wrong query problems at least in ipa-icf, so I think it is worthwhile
> sanity check.
> > 
> > > +     front-end routine) and use it.
> > > +
> > > +     We may be called to produce MEM RTX for variable of incomplete type.
> > > +     This MEM RTX will only be used to produce address of a vairable, so
> > > +     we do not need to compute alias set.  */
> > > +  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
> > > +    attrs.alias = get_alias_set (t);
> > 
> > And if the checking needs to go down the main-variant chain then this 
> > should be done inside type_with_alias_set_p(), not in the caller, 
> > otherwise even the symmetry between arguments of type_with_alias_set_p(xy) 
> > and get_alias_set(xy) is destroyed (but see above for why I think 
> > type_with_alias_set_p shouldn't even exist).
> 
> Yep, good point - I will cleanup this.
> 
> Honza
> 
>
Richard Biener May 27, 2015, 8:39 a.m. UTC | #9
On Wed, 27 May 2015, Jan Hubicka wrote:

> > > 
> > > I am not sure if TYPE_MAIN_VARIANT is really needed here.  What I know is that
> > > complete types may have incomplete variants.
> > 
> > How can that be?  TYPE_FIELDS is shared across variants and all variants
> > should be layed out.
> 
> Because TYPE_FILEDS are not always shared across variants.  For example 
> gfc_nonrestricted_type builds variants of types that have their own 
> TYPE_FIELDS lists whose types are variants of the original TYPE_FIELDs.  
> C++ FE used to do the same for member pointers, but I noticed that last 
> stage1 with early version of type verifier and as far as I can remember 
> Jason changed that.

The fortran one needs to be "fixed" to use the new MEM_REF restrict
support.

Richard.
Jan Hubicka May 27, 2015, 4:11 p.m. UTC | #10
> On Tue, 26 May 2015, Jan Hubicka wrote:
> 
> > > Hi,
> > > 
> > > On Fri, 22 May 2015, Jan Hubicka wrote:
> > > 
> > > > Index: tree-streamer-out.c
> > > > ===================================================================
> > > > --- tree-streamer-out.c	(revision 223508)
> > > > +++ tree-streamer-out.c	(working copy)
> > > > @@ -346,6 +346,7 @@ pack_ts_type_common_value_fields (struct
> > > >       alias-set zero to this type.  */
> > > >    bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
> > > >  			    || (!in_lto_p
> > > > +				&& type_with_alias_set_p (expr)
> > > >  				&& get_alias_set (expr) == 0)) ? 0 : -1);
> > > 
> > > I find such interfaces very ugly.  IOW, when it's always (or often) 
> > > necessary to call check_foo_p() before foo() can be called then the 
> > > checking should be part of foo() (and it should then return a conservative 
> > > value, i.e. alias set 0), and that requirement not be imposed on the 
> > > callers of foo().  I.e. why can't whatever checks you do in 
> > > type_with_alias_set_p be included in get_alias_set?
> > 
> > Because of sanity checking: I want to make alias sets of those types undefined
> > rather than having random values.  The point is that using the alias set in
> > alias oracle querry is wrong.
> 
> You could have just returned 0 for the alias-set for 
> !type_with_alias_set_p in get_alias_set.  That avoids polluting the
> alias data structures and is neither random or wrong.

Take the example of bug in ipa-ICF. It is digging out completely random types
from the IL and thinks it absolutely must compare alias sets of all of them
(the bug obviously is that it really should compare only those that matters).
It then throws random incomplete type to get_alias_set and obtain 0.  Which will
make it to silently give up if the "matching" random type is complete.

ICE here is a friendly reminder to the author of the optimization pass that he
is doing something fishy. It will also catch the cases where we throw memory access
of incomplete type to the function body by frontend/middleend bug instead of just
silently disabling optimization. I caught the Java interface glue issue with this.
(still need to fix that)

Now pack_ts_type_common_value_fields and RTL generation are differnt from the usual use of
alias set oracle in a sense that they do compute unnecesary alias sets by design.
They are not optimizations, they are IL stage transitions.

Honza
diff mbox

Patch

Index: tree-streamer-out.c
===================================================================
--- tree-streamer-out.c	(revision 223508)
+++ tree-streamer-out.c	(working copy)
@@ -346,6 +346,7 @@  pack_ts_type_common_value_fields (struct
      alias-set zero to this type.  */
   bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
 			    || (!in_lto_p
+				&& type_with_alias_set_p (expr)
 				&& get_alias_set (expr) == 0)) ? 0 : -1);
 }
 
Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 223508)
+++ lto-streamer-out.c	(working copy)
@@ -1146,6 +1146,7 @@  hash_tree (struct streamer_tree_cache_d
       hstate.add_int (TYPE_ALIGN (t));
       hstate.add_int ((TYPE_ALIAS_SET (t) == 0
 					 || (!in_lto_p
+					     && type_with_alias_set_p (t)
 					     && get_alias_set (t) == 0))
 					? 0 : -1);
     }
Index: emit-rtl.c
===================================================================
--- emit-rtl.c	(revision 223508)
+++ emit-rtl.c	(working copy)
@@ -1787,8 +1787,15 @@  set_mem_attributes_minus_bitpos (rtx ref
   memset (&attrs, 0, sizeof (attrs));
 
   /* Get the alias set from the expression or type (perhaps using a
-     front-end routine) and use it.  */
-  attrs.alias = get_alias_set (t);
+     front-end routine) and use it.
+
+     We may be called to produce MEM RTX for variable of incomplete type.
+     This MEM RTX will only be used to produce address of a vairable, so
+     we do not need to compute alias set.  */
+  if (!DECL_P (t) || type_with_alias_set_p (TYPE_MAIN_VARIANT (TREE_TYPE (t))))
+    attrs.alias = get_alias_set (t);
+  else
+    gcc_assert (DECL_P (t) && TREE_ADDRESSABLE (t));
 
   MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
   MEM_POINTER (ref) = POINTER_TYPE_P (type);
Index: ipa-icf-gimple.c
===================================================================
--- ipa-icf-gimple.c	(revision 223508)
+++ ipa-icf-gimple.c	(working copy)
@@ -274,6 +274,12 @@  func_checker::compatible_types_p (tree t
   if (!types_compatible_p (t1, t2))
     return return_false_with_msg ("types are not compatible");
 
+  /* FIXME: type compatiblity checks for types that are never stored
+     to memory is not very useful.  We should update the code to avoid
+     calling compatible_types_p on types that will never be used.  */
+  if (!type_with_alias_set_p (t1) || !type_with_alias_set_p (t2))
+    return true;
+
   if (get_alias_set (t1) != get_alias_set (t2))
     return return_false_with_msg ("alias sets are different");