public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Make alias_sets_conflict_p less conservative
@ 2008-03-04 20:59 Richard Guenther
  2008-03-04 23:54 ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-04 20:59 UTC (permalink / raw)
  To: gcc-patches; +Cc: kenner


This makes alias_sets_conflict_p less conservative.  rev 34373 (Kenner)
added a check that makes a structure containing a member with alias
set zero alias everything.  Which IMHO is non-obvious and pessimizes
for example the testcase in PR27799.  Richard, can you explain this
change?

I'll bootstrap and test this, but posted for enlightening comments early.
(I can imagine latent bugs that make this necessary, but not a
fundamental alias rule?)

Thanks,
Richard.

2008-03-04  Richard Guenther  <rguenther@suse.de>

	PR middle-end/27799
	* alias.c (alias_sets_conflict_p): A alias set zero member
	in a structure does not mean the structure aliases with
	everything.

	* gcc.dg/alias-2.c: Adjust.
	* gcc.dg/alias-12.c: New testcase.

Index: alias.c
===================================================================
*** alias.c	(revision 132816)
--- alias.c	(working copy)
*************** alias_sets_conflict_p (alias_set_type se
*** 325,341 ****
    /* See if the first alias set is a subset of the second.  */
    ase = get_alias_set_entry (set1);
    if (ase != 0
!       && (ase->has_zero_child
! 	  || splay_tree_lookup (ase->children,
! 				(splay_tree_key) set2)))
      return 1;
  
    /* Now do the same, but with the alias sets reversed.  */
    ase = get_alias_set_entry (set2);
    if (ase != 0
!       && (ase->has_zero_child
! 	  || splay_tree_lookup (ase->children,
! 				(splay_tree_key) set1)))
      return 1;
  
    /* The two alias sets are distinct and neither one is the
--- 325,339 ----
    /* See if the first alias set is a subset of the second.  */
    ase = get_alias_set_entry (set1);
    if (ase != 0
!       && splay_tree_lookup (ase->children,
! 			    (splay_tree_key) set2))
      return 1;
  
    /* Now do the same, but with the alias sets reversed.  */
    ase = get_alias_set_entry (set2);
    if (ase != 0
!       && splay_tree_lookup (ase->children,
! 			    (splay_tree_key) set1))
      return 1;
  
    /* The two alias sets are distinct and neither one is the
Index: testsuite/gcc.dg/alias-2.c
===================================================================
*** testsuite/gcc.dg/alias-2.c	(revision 132816)
--- testsuite/gcc.dg/alias-2.c	(working copy)
*************** struct foo {
*** 11,16 ****
  int
  sub1 (long long int foobar)
  {
!   struct foo *tmp = (struct foo *) &foobar; // { dg-warning "type-punned pointer might" "" }
    return tmp->i;
  }
--- 11,16 ----
  int
  sub1 (long long int foobar)
  {
!   struct foo *tmp = (struct foo *) &foobar; // { dg-warning "type-punned pointer will" "" }
    return tmp->i;
  }
Index: testsuite/gcc.dg/alias-12.c
===================================================================
*** testsuite/gcc.dg/alias-12.c	(revision 0)
--- testsuite/gcc.dg/alias-12.c	(revision 0)
***************
*** 0 ****
--- 1,27 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ extern void abort (void);
+ 
+ struct X {double m; int x;};
+ struct Y {int y; short d;};
+ struct YY {int y; short d; char c;};
+ 
+ int foo(struct X *x,  struct Y *y)
+ {
+   x->x =  0;
+   y->y =  1;
+   if (x->x != 0)
+     abort ();
+ }
+ 
+ int foo_no(struct X *x,  struct YY *y)
+ {
+   x->x =  0;
+   y->y =  1;
+   if (x->x != 0)
+     abort ();
+ }
+ 
+ /* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-04 20:59 [PATCH] Make alias_sets_conflict_p less conservative Richard Guenther
@ 2008-03-04 23:54 ` Richard Kenner
  2008-03-05  0:20   ` Daniel Berlin
  2008-03-05  9:21   ` Richard Guenther
  0 siblings, 2 replies; 42+ messages in thread
From: Richard Kenner @ 2008-03-04 23:54 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches

> This makes alias_sets_conflict_p less conservative.  rev 34373 (Kenner)
> added a check that makes a structure containing a member with alias
> set zero alias everything.  Which IMHO is non-obvious and pessimizes
> for example the testcase in PR27799.  Richard, can you explain this
> change?

I'm not certain, but I think it goes like this: if a structure has
a member with alias set X (nonzero), we normally mark the alias sets
in such a way that the alias set of the structure as a whole conflicts
with alias set X.  But if X is zero, the subsetting mechanism doesn't
allow doing that.  So we have to do it explicitly, like in this code.

In other words, this is exactly analogous to the non-zero alias set
of a field case.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-04 23:54 ` Richard Kenner
@ 2008-03-05  0:20   ` Daniel Berlin
  2008-03-05  1:35     ` Richard Kenner
  2008-03-05  9:21   ` Richard Guenther
  1 sibling, 1 reply; 42+ messages in thread
From: Daniel Berlin @ 2008-03-05  0:20 UTC (permalink / raw)
  To: Richard Kenner; +Cc: rguenther, gcc-patches

On Tue, Mar 4, 2008 at 6:55 PM, Richard Kenner
<kenner@vlsi1.ultra.nyu.edu> wrote:
> > This makes alias_sets_conflict_p less conservative.  rev 34373 (Kenner)
>  > added a check that makes a structure containing a member with alias
>  > set zero alias everything.  Which IMHO is non-obvious and pessimizes
>  > for example the testcase in PR27799.  Richard, can you explain this
>  > change?
>
>  I'm not certain, but I think it goes like this: if a structure has
>  a member with alias set X (nonzero), we normally mark the alias sets
>  in such a way that the alias set of the structure as a whole conflicts
>  with alias set X.  But if X is zero, the subsetting mechanism doesn't
>  allow doing that.  So we have to do it explicitly, like in this code.
>
>  In other words, this is exactly analogous to the non-zero alias set
>  of a field case.
>

Sadly, you are right about how the subsetting mechanism works, but he
is right in what the result we want should be.

This is because the the type based rules (at least for C) say "access
through pointer char can validly alias anything" but not "access
through pointer to anything can validly alias char".

Because alias_sets_conflicts_p checks both ways, it ends up claiming
the second statement is true as well.

In reality, you need a directional aliasing test here, not
alias_sets_conflict_p (IE you want something that says "can a pointer
of this point to this type over there)

--Dan

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05  0:20   ` Daniel Berlin
@ 2008-03-05  1:35     ` Richard Kenner
  2008-03-05 10:00       ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05  1:35 UTC (permalink / raw)
  To: dberlin; +Cc: gcc-patches, rguenther

> This is because the the type based rules (at least for C) say "access
> through pointer char can validly alias anything" but not "access
> through pointer to anything can validly alias char".

I note there is no char * in sight there.  Are we, by some chance, assigning
char to alias set zero? That seems wrong.  Rather char * should be
marked as type-pointed-to-can-alias-all.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-04 23:54 ` Richard Kenner
  2008-03-05  0:20   ` Daniel Berlin
@ 2008-03-05  9:21   ` Richard Guenther
  2008-03-05 11:29     ` Richard Kenner
  2008-03-05 14:10     ` Richard Guenther
  1 sibling, 2 replies; 42+ messages in thread
From: Richard Guenther @ 2008-03-05  9:21 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Tue, 4 Mar 2008, Richard Kenner wrote:

> > This makes alias_sets_conflict_p less conservative.  rev 34373 (Kenner)
> > added a check that makes a structure containing a member with alias
> > set zero alias everything.  Which IMHO is non-obvious and pessimizes
> > for example the testcase in PR27799.  Richard, can you explain this
> > change?
> 
> I'm not certain, but I think it goes like this: if a structure has
> a member with alias set X (nonzero), we normally mark the alias sets
> in such a way that the alias set of the structure as a whole conflicts
> with alias set X.  But if X is zero, the subsetting mechanism doesn't
> allow doing that.  So we have to do it explicitly, like in this code.

Well, this is not what happens.  The subsetting code doesn't allow
for _sub_setting alias set zero, not for putting alias set zero in
a subset.

So, if we have

struct S { int i; char c; };
struct B { double x; };

then we at the moment say that the alias sets of S and B conflict
just because S has a subset that includes alias set zero.

This is bogus.  Alias set zero only comes into play if either
argument of alias_sets_conflict_p is zero, which is handled by
the alias_sets_must_conflict_p code already.

It actually doesn't matter if we insert alias set zero into subsets
at all here, as alias set zero is special.

> In other words, this is exactly analogous to the non-zero alias set
> of a field case.

?  It is not.

The patch bootstrapped fine with a single failure,

FAIL: gcc.c-torture/execute/20071219-1.c execution

where it looks we get things right on the tree level but break it
on the RTL level.  (It's test3 () that is broken, from a quick
look we DSE *p = a; which of course is wrong as p points to b)

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05  1:35     ` Richard Kenner
@ 2008-03-05 10:00       ` Richard Guenther
  2008-03-05 11:10         ` Paolo Bonzini
  2008-03-05 11:31         ` Richard Kenner
  0 siblings, 2 replies; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 10:00 UTC (permalink / raw)
  To: Richard Kenner; +Cc: dberlin, gcc-patches

On Tue, 4 Mar 2008, Richard Kenner wrote:

> > This is because the the type based rules (at least for C) say "access
> > through pointer char can validly alias anything" but not "access
> > through pointer to anything can validly alias char".
> 
> I note there is no char * in sight there.  Are we, by some chance, assigning
> char to alias set zero? That seems wrong.  Rather char * should be
> marked as type-pointed-to-can-alias-all.

Yes, char is assigned alias set zero.  And this is correct.

  char a[4];
  int *p;

an access through *p conflicts with a.  (note there is no char * involved
here)

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 10:00       ` Richard Guenther
@ 2008-03-05 11:10         ` Paolo Bonzini
  2008-03-05 11:17           ` Eric Botcazou
  2008-03-05 11:31         ` Richard Kenner
  1 sibling, 1 reply; 42+ messages in thread
From: Paolo Bonzini @ 2008-03-05 11:10 UTC (permalink / raw)
  To: gcc-patches


> Yes, char is assigned alias set zero.  And this is correct.
> 
>   char a[4];
>   int *p;
> 
> an access through *p conflicts with a.  (note there is no char * involved
> here)

Would it be considered a good cleanup to assign it a different alias 
set, and make C char* a TYPE_REF_CAN_ALIAS_ALL variant?  Other languages 
may not have this behavior.

Paolo

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 11:10         ` Paolo Bonzini
@ 2008-03-05 11:17           ` Eric Botcazou
  2008-03-05 12:05             ` Paolo Bonzini
  0 siblings, 1 reply; 42+ messages in thread
From: Eric Botcazou @ 2008-03-05 11:17 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: gcc-patches

> Would it be considered a good cleanup to assign it a different alias
> set, and make C char* a TYPE_REF_CAN_ALIAS_ALL variant?  Other languages
> may not have this behavior.

This is done only the C family of languages.  In Ada we do something similar 
for our own "universal aliasing" type.

-- 
Eric Botcazou

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05  9:21   ` Richard Guenther
@ 2008-03-05 11:29     ` Richard Kenner
  2008-03-20  7:09       ` Mark Mitchell
  2008-03-05 14:10     ` Richard Guenther
  1 sibling, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 11:29 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches

> So, if we have
> 
> struct S { int i; char c; };
> struct B { double x; };
> 
> then we at the moment say that the alias sets of S and B conflict
> just because S has a subset that includes alias set zero.

As I asked in a different message, why does char have alias set zero?
*That's* what seems bogus to me.  Not having to do that is exactly why
TYPE_REF_CAN_ALIAS_ALL exists in the first place!  There's nothing special
about "char", but only about "char *".

> This is bogus.  Alias set zero only comes into play if either
> argument of alias_sets_conflict_p is zero, which is handled by
> the alias_sets_must_conflict_p code already.

I disagree.  Unless field C is nonaddressable (not the case in C),
some accesses to struct S will be accessing that field.  Those will be
accessing something in alias set zero.  That must conflict with any other
reference and that's what the code does.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 10:00       ` Richard Guenther
  2008-03-05 11:10         ` Paolo Bonzini
@ 2008-03-05 11:31         ` Richard Kenner
  2008-03-05 11:47           ` Richard Guenther
  1 sibling, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 11:31 UTC (permalink / raw)
  To: rguenther; +Cc: dberlin, gcc-patches

> Yes, char is assigned alias set zero.  And this is correct.
> 
>   char a[4];
>   int *p;
> 
> an access through *p conflicts with a. 

By what rule?  I was under the impression that this was a special rule
applying to "char *".

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 11:31         ` Richard Kenner
@ 2008-03-05 11:47           ` Richard Guenther
  2008-03-05 12:25             ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 11:47 UTC (permalink / raw)
  To: Richard Kenner; +Cc: dberlin, gcc-patches

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > Yes, char is assigned alias set zero.  And this is correct.
> > 
> >   char a[4];
> >   int *p;
> > 
> > an access through *p conflicts with a. 
> 
> By what rule?  I was under the impression that this was a special rule
> applying to "char *".

6.5/7

  An object shall have its stored value accessed only by an lvalue
  expression that has one of the following types:

  ...

  - a character type

you are right if for

  char c[4];

c has a declared type of char.  Which would make

  char c[4];
  int *p = c;
  *p = 0;

undefined.  But the above is commonly used enough to make any
declared character array handled the same as allocated storage is.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 11:17           ` Eric Botcazou
@ 2008-03-05 12:05             ` Paolo Bonzini
  2008-03-05 12:09               ` Eric Botcazou
  2008-03-05 12:29               ` Richard Kenner
  0 siblings, 2 replies; 42+ messages in thread
From: Paolo Bonzini @ 2008-03-05 12:05 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

Eric Botcazou wrote:
>> Would it be considered a good cleanup to assign it a different alias
>> set, and make C char* a TYPE_REF_CAN_ALIAS_ALL variant?  Other languages
>> may not have this behavior.
> 
> This is done only the C family of languages.  In Ada we do something similar 
> for our own "universal aliasing" type.

Yes, I was asking if it was meaningful to do it for C too -- especially 
for LTO it could make sense.

Paolo

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 12:05             ` Paolo Bonzini
@ 2008-03-05 12:09               ` Eric Botcazou
  2008-03-05 12:29               ` Richard Kenner
  1 sibling, 0 replies; 42+ messages in thread
From: Eric Botcazou @ 2008-03-05 12:09 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: gcc-patches

> Yes, I was asking if it was meaningful to do it for C too -- especially
> for LTO it could make sense.

You probably misunderstood my message.  Giving char alias set 0 is C-family 
specific, in Ada we give alias set 0 to something else.  This is orthogonal 
to the TYPE_REF_CAN_ALIAS_ALL flag on pointers.

-- 
Eric Botcazou

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 11:47           ` Richard Guenther
@ 2008-03-05 12:25             ` Richard Kenner
  2008-03-05 12:42               ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 12:25 UTC (permalink / raw)
  To: rguenther; +Cc: dberlin, gcc-patches

> you are right if for
> 
>   char c[4];
> 
> c has a declared type of char.  Which would make
> 
>   char c[4];
>   int *p = c;
>   *p = 0;
> 
> undefined.  But the above is commonly used enough to make any
> declared character array handled the same as allocated storage is.

So you feel that we need to support it?

But we're actually creating an object of char * here in that second
statement.  Perhaps we can use that knowlege somehow.

But pessimizing "char" with no pointers in sight just to support this
seems very bad.  There must be some approach that works.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 12:05             ` Paolo Bonzini
  2008-03-05 12:09               ` Eric Botcazou
@ 2008-03-05 12:29               ` Richard Kenner
  1 sibling, 0 replies; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 12:29 UTC (permalink / raw)
  To: bonzini; +Cc: ebotcazou, gcc-patches

> Yes, I was asking if it was meaningful to do it for C too -- especially 
> for LTO it could make sense.

If you work globally, you can do far better and can do essentially the same
as we do for Ada.  What you do is to detect all cases of other pointers
(e.g., int *) that get assigned from char * and use a TYPE_CAN_ALIAS_ALL
variant of that pointer for those int * variables.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 12:25             ` Richard Kenner
@ 2008-03-05 12:42               ` Richard Guenther
  2008-03-05 12:55                 ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 12:42 UTC (permalink / raw)
  To: Richard Kenner; +Cc: dberlin, gcc-patches

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > you are right if for
> > 
> >   char c[4];
> > 
> > c has a declared type of char.  Which would make
> > 
> >   char c[4];
> >   int *p = c;
> >   *p = 0;
> > 
> > undefined.  But the above is commonly used enough to make any
> > declared character array handled the same as allocated storage is.
> 
> So you feel that we need to support it?
> 
> But we're actually creating an object of char * here in that second
> statement.  Perhaps we can use that knowlege somehow.
> 
> But pessimizing "char" with no pointers in sight just to support this
> seems very bad.  There must be some approach that works.

Well, my C-fu is from interpreting the words in the standard and looking
at existing use.

So you agree that your change introducing this handling of alias set zero
was not with the fact in mind that C assigns alias set zero to 'char'?

Note that apart from the bug in RTL dse which is uncovered by the patch
everything still seems to work fine.  The fact that we assign alias set
zero to char should not matter, and I still do not understand the
reasoning behind

struct alias_set_entry GTY(())
{
...
  /* Nonzero if would have a child of zero: this effectively makes this
     alias set the same as alias set zero.  */
  int has_zero_child;

and the purpose and reasoning of

alias_sets_conflict_p (alias_set_type set1, alias_set_type set2)
{
...
  /* See if the first alias set is a subset of the second.  */
  ase = get_alias_set_entry (set1);
  if (ase != 0
      && (ase->has_zero_child
        ^^^^^^^^^^^^^^^^^^^^^^
          || splay_tree_lookup (ase->children,
                                (splay_tree_key) set2)))
    return 1;

Can you explain again why a alias-set zero child of set1 or set2
makes any alias set conflict with such set?  This effectively makes
a set with an alias-set zero child equivalent to alias-set zero itself,
which doesn't make sense.

In which case would the above (alias-set zero member) happen for Ada
(which does not assign alias set zero to char, but to "something else")?

Thanks,
Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 12:42               ` Richard Guenther
@ 2008-03-05 12:55                 ` Richard Kenner
  2008-03-05 14:07                   ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 12:55 UTC (permalink / raw)
  To: rguenther; +Cc: dberlin, gcc-patches

> So you agree that your change introducing this handling of alias set zero
> was not with the fact in mind that C assigns alias set zero to 'char'?

I don't understand precisely what you're asking here, but let me try to
answer.  My change was made because it's *required* by the rules we're using
to determine alias sets and subsetting rules.  It's been quite a while,
but I do *not* think it was motivated by any bug, just a realization that
the current code was wrong.

I'm certain that the change was not *motivated* by the fact that C's 'char'
is alias set zero.  I'm not even sure if that was the case back when the
change was made.  I doubt I was thinking about that issue then.

> Can you explain again why a alias-set zero child of set1 or set2
> makes any alias set conflict with such set?  

For the same reason that the alias set of a parent conflicts with the
alias set of a child if it's nonzero.

> This effectively makes a set with an alias-set zero child equivalent
> to alias-set zero itself, which doesn't make sense.

It's not equivalent, but close.

I really feel that the problem here is the assignment of alias set zero
to C's 'char'.  It's *totally* unnecessary.  char * should certainly
be TYPE_REF_CAN_ALIAS_ALL and perhaps char[] should be alias set zero,
but not 'char'.  The assumption here is that having *objects* (as opposed
to indirect references) of alias set zero is relatively rare.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 12:55                 ` Richard Kenner
@ 2008-03-05 14:07                   ` Richard Guenther
  2008-03-05 14:24                     ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 14:07 UTC (permalink / raw)
  To: Richard Kenner; +Cc: dberlin, gcc-patches

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > So you agree that your change introducing this handling of alias set zero
> > was not with the fact in mind that C assigns alias set zero to 'char'?
> 
> I don't understand precisely what you're asking here, but let me try to
> answer.  My change was made because it's *required* by the rules we're using
> to determine alias sets and subsetting rules.  It's been quite a while,
> but I do *not* think it was motivated by any bug, just a realization that
> the current code was wrong.
> 
> I'm certain that the change was not *motivated* by the fact that C's 'char'
> is alias set zero.  I'm not even sure if that was the case back when the
> change was made.  I doubt I was thinking about that issue then.
> 
> > Can you explain again why a alias-set zero child of set1 or set2
> > makes any alias set conflict with such set?  
> 
> For the same reason that the alias set of a parent conflicts with the
> alias set of a child if it's nonzero.

I don't see that.  in alias_sets_conflict_p (set1, set2) we ask if
set1 conflicts with set2.  In this context it is only relevant if
either of set1 or set2 is alias set zero (which implicitly contains
all alias sets in its child set) or whether set1 is contained in set2
or set2 is contained in set1.

It is not relevant if set2 contains alias set zero.

Oh - ok.  I can follow your logic.  If set2 contains alias set zero it
contains all alias sets, but then

> > This effectively makes a set with an alias-set zero child equivalent
> > to alias-set zero itself, which doesn't make sense.
> 
> It's not equivalent, but close.

It _is_ equivalent to alias set zero, as every member in either set
is a member of the other set.

Now, lets assume we don't want a alias set zero member to leak all its
children.  Then my patch does exactly that.  (whether giving alias
set zero to char makes sense - apart from making *(char *) alias set
zero this way automatically - is another question, but this way
things fall out nicely at least)

The question remains, in which practical cases we _do_ want the
behavior that an alias set zero member makes the set itself effectively
alias set zero.  If you look where subsets are added, it happens
from record_component_aliases (I can't think of a C structure
where we want this behavior), and from get_alias_set in the case of
computing DECL_POINTER_ALIAS_SET which is computed from the pointed
to type again (it wouldn't work for char here).

So even if it somewhat breaks the symmetry of alias set zero I believe
my patch is the right thing to do, otherwise there is no need to for
example add any further children once the parent has_zero_child
(which we should rename to is_alias_set_zero).

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05  9:21   ` Richard Guenther
  2008-03-05 11:29     ` Richard Kenner
@ 2008-03-05 14:10     ` Richard Guenther
  1 sibling, 0 replies; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 14:10 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Wed, 5 Mar 2008, Richard Guenther wrote:

> The patch bootstrapped fine with a single failure,
> 
> FAIL: gcc.c-torture/execute/20071219-1.c execution
> 
> where it looks we get things right on the tree level but break it
> on the RTL level.  (It's test3 () that is broken, from a quick
> look we DSE *p = a; which of course is wrong as p points to b)

We break it at tree level already, a tree-level DSE bug is exposed
by this change (PR35472).  We go from (before the patch)

  # VUSE <p_16>
  p.3_1 = p;
  # p_20 = VDEF <p_16>
  # a_21 = VDEF <a_17>
  # b_22 = VDEF <b_18>
  # SMT.29_23 = VDEF <SMT.29_19>
  *p.3_1 = a;
  # VUSE <p_20>
  p.3_2 = p;
  # p_24 = VDEF <p_20>
  # a_25 = VDEF <a_21>
  # b_26 = VDEF <b_22>
  # SMT.29_27 = VDEF <SMT.29_23>
  *p.3_2 = b;

(note how the store to *p wrongly affects p itself, and thus we store
to two different pointer SSA_NAMEs)

to (after the patch)

  # VUSE <p_16>
  p.3_1 = p;
  # a_20 = VDEF <a_17>
  # b_21 = VDEF <b_18>
  # SMT.29_22 = VDEF <SMT.29_19>
  *p.3_1 = a; 
  # a_23 = VDEF <a_20>
  # b_24 = VDEF <b_21>
  # SMT.29_25 = VDEF <SMT.29_22>
  *p.3_1 = b; 

where DSE now wrongly decides to delete the *p.3_1 = a; store.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 14:07                   ` Richard Guenther
@ 2008-03-05 14:24                     ` Richard Kenner
  2008-03-05 15:01                       ` Richard Guenther
  2008-03-05 15:18                       ` Michael Matz
  0 siblings, 2 replies; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 14:24 UTC (permalink / raw)
  To: rguenther; +Cc: dberlin, gcc-patches

> > > This effectively makes a set with an alias-set zero child equivalent
> > > to alias-set zero itself, which doesn't make sense.
> > 
> > It's not equivalent, but close.
> 
> It _is_ equivalent to alias set zero, as every member in either set
> is a member of the other set.

This is a distinction without a difference.  Just because something
conflicts with all other alias sets doesn't mean that it *is* alias
set zero, just that it *acts* like it.

> Now, lets assume we don't want a alias set zero member to leak all its
> children.  

But why do you assume that?  It's wrong.  It's no more correct than
saying that it shouldn't "leak" a child of some other particular alias set.

> The question remains, in which practical cases we _do_ want the
> behavior that an alias set zero member makes the set itself effectively
> alias set zero. 

In any case where a member is alias set zero for a reason.

> (I can't think of a C structure where we want this behavior)

I can't either, but the fix is to not make 'char' alias set zero!

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 14:24                     ` Richard Kenner
@ 2008-03-05 15:01                       ` Richard Guenther
  2008-03-05 15:13                         ` Richard Kenner
  2008-03-05 15:18                       ` Michael Matz
  1 sibling, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 15:01 UTC (permalink / raw)
  To: Richard Kenner; +Cc: dberlin, gcc-patches

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > > > This effectively makes a set with an alias-set zero child equivalent
> > > > to alias-set zero itself, which doesn't make sense.
> > > 
> > > It's not equivalent, but close.
> > 
> > It _is_ equivalent to alias set zero, as every member in either set
> > is a member of the other set.
> 
> This is a distinction without a difference.  Just because something
> conflicts with all other alias sets doesn't mean that it *is* alias
> set zero, just that it *acts* like it.
> 
> > Now, lets assume we don't want a alias set zero member to leak all its
> > children.  
> 
> But why do you assume that?  It's wrong.  It's no more correct than
> saying that it shouldn't "leak" a child of some other particular alias set.
> 
> > The question remains, in which practical cases we _do_ want the
> > behavior that an alias set zero member makes the set itself effectively
> > alias set zero. 
> 
> In any case where a member is alias set zero for a reason.
> 
> > (I can't think of a C structure where we want this behavior)
> 
> I can't either, but the fix is to not make 'char' alias set zero!

Well, that's true.  But this fix will be way more involved than my
patch which works as well (fix for PR35472 is in testing).

So I'm still inclined to go with my patch with adding a big'n'fat
comment.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:01                       ` Richard Guenther
@ 2008-03-05 15:13                         ` Richard Kenner
  2008-03-05 15:21                           ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 15:13 UTC (permalink / raw)
  To: rguenther; +Cc: dberlin, gcc-patches

> So I'm still inclined to go with my patch with adding a big'n'fat
> comment.

I think your patch is wrong: it says that two alias set don't conflict
when, in fact, they do.

Bugs caused by this are notoriously hard to find because they come and go
so I'd be very much against introducing this into GCC even if the only
bug is a latent one.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 14:24                     ` Richard Kenner
  2008-03-05 15:01                       ` Richard Guenther
@ 2008-03-05 15:18                       ` Michael Matz
  2008-03-05 15:28                         ` Richard Kenner
  1 sibling, 1 reply; 42+ messages in thread
From: Michael Matz @ 2008-03-05 15:18 UTC (permalink / raw)
  To: Richard Kenner; +Cc: rguenther, dberlin, gcc-patches

Hi,

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > > > This effectively makes a set with an alias-set zero child equivalent
> > > > to alias-set zero itself, which doesn't make sense.
> > > 
> > > It's not equivalent, but close.
> > 
> > It _is_ equivalent to alias set zero, as every member in either set
> > is a member of the other set.
> 
> This is a distinction without a difference.  Just because something
> conflicts with all other alias sets doesn't mean that it *is* alias
> set zero, just that it *acts* like it.

Well, if it acts like set zero, then it's equivalent to set zero, so we 
can simply use set zero in places where we formerly used set X (now found 
to be equivalent to zero).  If it's not distinguishable from set zero 
(except by it's number) there's no reason for it to exist.

> > The question remains, in which practical cases we _do_ want the
> > behavior that an alias set zero member makes the set itself effectively
> > alias set zero. 
> 
> In any case where a member is alias set zero for a reason.

I think this would still fail (or be suboptimal, imprecise, whatever), if 
char wouldn't have set zero, but e.g. char* would have.  Namely in this 
situation:

struct S { char *p; int i;};
struct T { double d; };

Now S.p would have alias set zero, and again accesses to the whole S would 
again conflict with everything (because it contains a member of set zero).  
This is clearly wrong.  An access to *S.p can alias everything, but not an 
access to S (or even to S.p, which itself can only conflict with 
accesses through any other char**).

Is it possible that our subsetting of alias sets based on structure 
members is non-sensical?  After all, in the end real accesses conflict 
with each other, so they are the ones with alias sets.  And for accesses 
we have the final type, for which we can determine conflict sets, I don't 
see why we would have to make all member sets subsets of the alias set of 
structure types to implement that.

Alternatively I think we are confused about what the alias set numbers on 
types actually mean. In particular I think we are confusing accesses to 
objects of type T and accesses through pointer to type T and glob them 
together.

Maybe the alias set of struct S needs to conflict with the alias sets of 
all _pointers_ to member types (not to alias sets of member types itself).  
Hmm.


Ciao,
Michael.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:13                         ` Richard Kenner
@ 2008-03-05 15:21                           ` Richard Guenther
  2008-03-05 15:29                             ` Michael Matz
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 15:21 UTC (permalink / raw)
  To: Richard Kenner; +Cc: joseph, gcc-patches

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > So I'm still inclined to go with my patch with adding a big'n'fat
> > comment.
> 
> I think your patch is wrong: it says that two alias set don't conflict
> when, in fact, they do.
> 
> Bugs caused by this are notoriously hard to find because they come and go
> so I'd be very much against introducing this into GCC even if the only
> bug is a latent one.

Meh.  It is not going to work out to make char not alias set zero.
Look:

alias_set_type
c_common_get_alias_set (tree t)
{
...
  /* The C standard guarantees that any object may be accessed via an
     lvalue that has character type.  */
  if (t == char_type_node
      || t == signed_char_type_node
      || t == unsigned_char_type_node)
    return 0;

an 'lvalue' isn't a pointer, so I don't see how you can possibly preserve
(with reasonable amount of hackery) Cs special handling of character
lvalues.

But - Joseph, do you have any idea if it in theory could be made to
work with char not being alias set zero?  The FE would need to mark
every lvalue of type char with a special flag.

Thanks,
Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:18                       ` Michael Matz
@ 2008-03-05 15:28                         ` Richard Kenner
  0 siblings, 0 replies; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 15:28 UTC (permalink / raw)
  To: matz; +Cc: dberlin, gcc-patches, rguenther

> Well, if it acts like set zero, then it's equivalent to set zero, so we 
> can simply use set zero in places where we formerly used set X (now found 
> to be equivalent to zero).  If it's not distinguishable from set zero 
> (except by it's number) there's no reason for it to exist.

Sure there is.  For one thing, if we set the alias set to zero, then
an access to a field inside the struct of nonzero alias set would be
treated as zero.  Moreover, is it really the case that the *only* thing we
do with alias sets is check for conflicts and, if so, will that always
be the case?  Why lose information?

> struct S { char *p; int i;};
> struct T { double d; };
> 
> Now S.p would have alias set zero, 

No, it wouldn't.  char * isn't alias set zero.  It's marked as
TYPE_REF_CAN_ALIAS_ALL, which means that *S.p is alias set zero, not
S.p itself.

> Is it possible that our subsetting of alias sets based on structure 
> members is non-sensical?

No, not at all.  It's *quite* important, actually.

> Alternatively I think we are confused about what the alias set numbers on 
> types actually mean. In particular I think we are confusing accesses to 
> objects of type T and accesses through pointer to type T and glob them 
> together.

There has been a discussion a long time ago about differentiating precisely
those two types of objects.  But the difference is very small except in
the case where you don't take the address of an object.  But that latter
case, except for globals, is one we can and do detect.  So I think this would
add lots of complexity and buy little.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:21                           ` Richard Guenther
@ 2008-03-05 15:29                             ` Michael Matz
  2008-03-05 15:38                               ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Michael Matz @ 2008-03-05 15:29 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Richard Kenner, joseph, gcc-patches

Hi,

On Wed, 5 Mar 2008, Richard Guenther wrote:

> But - Joseph, do you have any idea if it in theory could be made to work 
> with char not being alias set zero?  The FE would need to mark every 
> lvalue of type char with a special flag.

If that should be possible, it's no different to making 'char' have alias 
set zero.  Given:

struct S {char c; int i;};
struct T {double d;};

f () {
  struct S s;
  s.c = 0;
}

Here the lvalue s.c would then have the "special flag" (i suppose the 
semantic you had in mind for that flag would be "alias everything"), so it 
would conflict with everything which of course it can't.  It won't 
conflict with T.d for instance, so we're back to square one.


Ciao,
Michael.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:29                             ` Michael Matz
@ 2008-03-05 15:38                               ` Richard Guenther
  2008-03-05 15:42                                 ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 15:38 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Kenner, joseph, gcc-patches

On Wed, 5 Mar 2008, Michael Matz wrote:

> Hi,
> 
> On Wed, 5 Mar 2008, Richard Guenther wrote:
> 
> > But - Joseph, do you have any idea if it in theory could be made to work 
> > with char not being alias set zero?  The FE would need to mark every 
> > lvalue of type char with a special flag.
> 
> If that should be possible, it's no different to making 'char' have alias 
> set zero.  Given:
> 
> struct S {char c; int i;};
> struct T {double d;};
> 
> f () {
>   struct S s;
>   s.c = 0;
> }
> 
> Here the lvalue s.c would then have the "special flag" (i suppose the 
> semantic you had in mind for that flag would be "alias everything"), so it 
> would conflict with everything which of course it can't.  It won't 
> conflict with T.d for instance, so we're back to square one.

Hm.  As I said I know of enough code that uses an array of chars as
"memory", even if embedded in a struct.  So,

struct S { int size; char mem[1]; } s;
struct T { double d; } *p;

double f ()
{
  p->d = 1.0;
  s.mem[0] = 0;
  return p->d;
}

here indeed the store to s.mem[0] should conflict with the store and
load from p->d.

But in the case we are trying to fix, the current alias behavior would
make

  s.size = 0;

conflict with the store and load from p->d, which is incorrect.  That
said, somehow we end up asking for the alias set of 's' here instead
of that for 's.size' - or we make that one of 's.size' a different
one from its type.  Which would move the problem we run into in
PR27799 to get_alias_set and away from alias_sets_conflict_p.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:38                               ` Richard Guenther
@ 2008-03-05 15:42                                 ` Richard Kenner
  2008-03-05 15:52                                   ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 15:42 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches, joseph, matz

> But in the case we are trying to fix, the current alias behavior would
> make
> 
>   s.size = 0;
> 
> conflict with the store and load from p->d, which is incorrect.

I don't think so.  In that case, we look at the alias set of s.size, not of s.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:42                                 ` Richard Kenner
@ 2008-03-05 15:52                                   ` Richard Guenther
  2008-03-05 15:59                                     ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 15:52 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, joseph, matz

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > But in the case we are trying to fix, the current alias behavior would
> > make
> > 
> >   s.size = 0;
> > 
> > conflict with the store and load from p->d, which is incorrect.
> 
> I don't think so.  In that case, we look at the alias set of s.size, not of s.

Ok, so the problem (of PR27799) is that our tree aliasing machinery
creates SMTs (structure-memory-tags) that represent all structures
with a given type.  TBAA relations here are computed by asking wheter
for example a pointer can access struct X which is done by asking for
alias_sets_conflict_p (get_alias_set (*ptr), get_alias_set (struct-type))
which in this case returns true (as struc-type has a char member).
[this all happens in may_alias_p]

Later during operand scanning we (could) ask again, but only the
same question -- does the access p->x alias a SMT?  And the answer
would be the same.  [access_can_touch_variable]

So we are lost here, as we obviously cannot ask the question this way
with the current scheme. (?)

To recap:

struct A { int i; char c; };
struct B { float f; };

the question we ask is, can you access any struct A through a pointer
to struct B?  And, can ((struct B *)p)->f touch any struct A?

For this sort of questions (with char having alias set zero and the
subsetting work as is), we can only answer yes.  With my patch
we can start to say no here.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:52                                   ` Richard Guenther
@ 2008-03-05 15:59                                     ` Richard Kenner
  2008-03-05 16:07                                       ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 15:59 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches, joseph, matz

> Ok, so the problem (of PR27799) is that our tree aliasing machinery
> creates SMTs (structure-memory-tags) that represent all structures
> with a given type.  TBAA relations here are computed by asking wheter
> for example a pointer can access struct X which is done by asking for
> alias_sets_conflict_p (get_alias_set (*ptr), get_alias_set (struct-type))
> which in this case returns true (as struc-type has a char member).
> [this all happens in may_alias_p]

That seems *very* wrong and very inefficient.

The definition of the alias set for a field x.y as used by the RTL
passes has always been:

if alias_set (x) == 0 (not this case), then alias set zero
else if y is addressable, then alias_set (y)
else alias_set (x)

If the tree level does anything else, it is *seriously* inefficient since
the entire aliasing subsetting mechanism was designed around alias sets of
fields being computed in the above way.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 15:59                                     ` Richard Kenner
@ 2008-03-05 16:07                                       ` Richard Guenther
  2008-03-05 16:13                                         ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 16:07 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, joseph, matz

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > Ok, so the problem (of PR27799) is that our tree aliasing machinery
> > creates SMTs (structure-memory-tags) that represent all structures
> > with a given type.  TBAA relations here are computed by asking wheter
> > for example a pointer can access struct X which is done by asking for
> > alias_sets_conflict_p (get_alias_set (*ptr), get_alias_set (struct-type))
> > which in this case returns true (as struc-type has a char member).
> > [this all happens in may_alias_p]
> 
> That seems *very* wrong and very inefficient.

It's not wrong and not inefficient.  tree aliasing just models
alias-sets as SMTs, thus tries to re-create the subsetting (SMTs
have a set of other SMTs it aliases) by this querying.  Obviously
it doesn't work out in this case ;)

So it basically asks -- is struct A in the alias set of struct B.
Maybe it shouldn't use alias_sets_conflict_p for this kind of query
but should use alias_set_subset_of (), but that would need a similar
fix for set2->has_zero_subset:

/* Return true if the first alias set is a subset of the second.  */

bool
alias_set_subset_of (alias_set_type set1, alias_set_type set2)
{
  alias_set_entry ase;

  /* Everything is a subset of the "aliases everything" set.  */
  if (set2 == 0)
    return true;

  /* Otherwise, check if set1 is a subset of set2.  */
  ase = get_alias_set_entry (set2);
  if (ase != 0
      && (splay_tree_lookup (ase->children,
                             (splay_tree_key) set1)))
    return true;
  return false;
}

so it wouldn't help either.

> The definition of the alias set for a field x.y as used by the RTL
> passes has always been:
> 
> if alias_set (x) == 0 (not this case), then alias set zero
> else if y is addressable, then alias_set (y)
> else alias_set (x)
> 
> If the tree level does anything else, it is *seriously* inefficient since
> the entire aliasing subsetting mechanism was designed around alias sets of
> fields being computed in the above way.

but alias_set (x) _is_ zero in this case.  Because x has a char
member.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:07                                       ` Richard Guenther
@ 2008-03-05 16:13                                         ` Richard Kenner
  2008-03-05 16:17                                           ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 16:13 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches, joseph, matz

> So it basically asks -- is struct A in the alias set of struct B.

But that's *totally wrong* if the two access are, for example, a.x and
b.y and (as is usually the case in C) x and y are addressable.  In
that case, the alias sets of A and B are *completely irrelevant* and
*all* you care about are the alias sets of x and y.  Any code that does
something else is broken.

> > The definition of the alias set for a field x.y as used by the RTL
> > passes has always been:
> > 
> > if alias_set (x) == 0 (not this case), then alias set zero
> > else if y is addressable, then alias_set (y)
> > else alias_set (x)
> > 
> > If the tree level does anything else, it is *seriously* inefficient since
> > the entire aliasing subsetting mechanism was designed around alias sets of
> > fields being computed in the above way.
> 
> but alias_set (x) _is_ zero in this case.  Because x has a char
> member.

NO!  We DO NOT set the set to zero, but rather handle it as conflicting
with all other alias sets.  The difference between those is *precisely*
this algorithm.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:13                                         ` Richard Kenner
@ 2008-03-05 16:17                                           ` Richard Guenther
  2008-03-05 16:21                                             ` Richard Guenther
  2008-03-05 16:23                                             ` Richard Kenner
  0 siblings, 2 replies; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 16:17 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, joseph, matz

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > So it basically asks -- is struct A in the alias set of struct B.
> 
> But that's *totally wrong* if the two access are, for example, a.x and
> b.y and (as is usually the case in C) x and y are addressable.  In
> that case, the alias sets of A and B are *completely irrelevant* and
> *all* you care about are the alias sets of x and y.  Any code that does
> something else is broken.
> 
> > > The definition of the alias set for a field x.y as used by the RTL
> > > passes has always been:
> > > 
> > > if alias_set (x) == 0 (not this case), then alias set zero
> > > else if y is addressable, then alias_set (y)
> > > else alias_set (x)
> > > 
> > > If the tree level does anything else, it is *seriously* inefficient since
> > > the entire aliasing subsetting mechanism was designed around alias sets of
> > > fields being computed in the above way.
> > 
> > but alias_set (x) _is_ zero in this case.  Because x has a char
> > member.
> 
> NO!  We DO NOT set the set to zero, but rather handle it as conflicting
> with all other alias sets.  The difference between those is *precisely*
> this algorithm.

Err, right.  But tree aliasing is computing a representation for TBAA,
using alias set conflict queries but _not_ looking at individual accesses.

So, is alias_set_subset_of () wrong as currently implemented?  Does
it lack the ase->has_zero_child test in your opinion?  Otherwise I'll
try using that for these queries.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:17                                           ` Richard Guenther
@ 2008-03-05 16:21                                             ` Richard Guenther
  2008-03-05 16:55                                               ` Daniel Berlin
  2008-03-05 16:23                                             ` Richard Kenner
  1 sibling, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 16:21 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, Daniel Berlin, matz

On Wed, 5 Mar 2008, Richard Guenther wrote:

> On Wed, 5 Mar 2008, Richard Kenner wrote:
> 
> > > So it basically asks -- is struct A in the alias set of struct B.
> > 
> > But that's *totally wrong* if the two access are, for example, a.x and
> > b.y and (as is usually the case in C) x and y are addressable.  In
> > that case, the alias sets of A and B are *completely irrelevant* and
> > *all* you care about are the alias sets of x and y.  Any code that does
> > something else is broken.
> > 
> > > > The definition of the alias set for a field x.y as used by the RTL
> > > > passes has always been:
> > > > 
> > > > if alias_set (x) == 0 (not this case), then alias set zero
> > > > else if y is addressable, then alias_set (y)
> > > > else alias_set (x)
> > > > 
> > > > If the tree level does anything else, it is *seriously* inefficient since
> > > > the entire aliasing subsetting mechanism was designed around alias sets of
> > > > fields being computed in the above way.
> > > 
> > > but alias_set (x) _is_ zero in this case.  Because x has a char
> > > member.
> > 
> > NO!  We DO NOT set the set to zero, but rather handle it as conflicting
> > with all other alias sets.  The difference between those is *precisely*
> > this algorithm.
> 
> Err, right.  But tree aliasing is computing a representation for TBAA,
> using alias set conflict queries but _not_ looking at individual accesses.
> 
> So, is alias_set_subset_of () wrong as currently implemented?  Does
> it lack the ase->has_zero_child test in your opinion?  Otherwise I'll
> try using that for these queries.

Which means like the following (untested) patch, also fixes PR27799.

Richard.

Index: tree-ssa-alias.c
===================================================================
*** tree-ssa-alias.c	(revision 132898)
--- tree-ssa-alias.c	(working copy)
*************** may_alias_p (tree ptr, alias_set_type me
*** 2869,2875 ****
        alias_stats.tbaa_queries++;
  
        /* If the alias sets don't conflict then MEM cannot alias VAR.  */
!       if (!alias_sets_conflict_p (mem_alias_set, var_alias_set))
  	{
  	  alias_stats.alias_noalias++;
  	  alias_stats.tbaa_resolved++;
--- 2869,2875 ----
        alias_stats.tbaa_queries++;
  
        /* If the alias sets don't conflict then MEM cannot alias VAR.  */
!       if (!alias_set_subset_of (mem_alias_set, var_alias_set))
  	{
  	  alias_stats.alias_noalias++;
  	  alias_stats.tbaa_resolved++;
Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c	(revision 132898)
--- tree-ssa-structalias.c	(working copy)
*************** set_uids_in_ptset (tree ptr, bitmap into
*** 4780,4786 ****
  		  var_alias_set = get_alias_set (sft);
  		  if (no_tbaa_pruning
  		      || (!is_derefed && !vi->directly_dereferenced)
! 		      || alias_sets_conflict_p (ptr_alias_set, var_alias_set))
  		    {
  		      bitmap_set_bit (into, DECL_UID (sft));
  		      
--- 4780,4786 ----
  		  var_alias_set = get_alias_set (sft);
  		  if (no_tbaa_pruning
  		      || (!is_derefed && !vi->directly_dereferenced)
! 		      || alias_set_subset_of (ptr_alias_set, var_alias_set))
  		    {
  		      bitmap_set_bit (into, DECL_UID (sft));
  		      
*************** set_uids_in_ptset (tree ptr, bitmap into
*** 4808,4814 ****
  		  var_alias_set = get_alias_set (vi->decl);
  		  if (no_tbaa_pruning
  		      || (!is_derefed && !vi->directly_dereferenced)
! 		      || alias_sets_conflict_p (ptr_alias_set, var_alias_set))
  		    bitmap_set_bit (into, DECL_UID (vi->decl));
  		}
  	    }
--- 4808,4814 ----
  		  var_alias_set = get_alias_set (vi->decl);
  		  if (no_tbaa_pruning
  		      || (!is_derefed && !vi->directly_dereferenced)
! 		      || alias_set_subset_of (ptr_alias_set, var_alias_set))
  		    bitmap_set_bit (into, DECL_UID (vi->decl));
  		}
  	    }

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:17                                           ` Richard Guenther
  2008-03-05 16:21                                             ` Richard Guenther
@ 2008-03-05 16:23                                             ` Richard Kenner
  2008-03-05 16:27                                               ` Richard Guenther
  1 sibling, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 16:23 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches, joseph, matz

> Err, right.  But tree aliasing is computing a representation for TBAA,
> using alias set conflict queries but _not_ looking at individual accesses.

That seems quite wrong to me.

> So, is alias_set_subset_of () wrong as currently implemented?  Does
> it lack the ase->has_zero_child test in your opinion?  Otherwise I'll
> try using that for these queries.

I don't know enough to answer those questions.

What I *do* know is that if you have x.y, with y addressable, any code
that looks at the alias set of X *for any reason* is broken.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:23                                             ` Richard Kenner
@ 2008-03-05 16:27                                               ` Richard Guenther
  2008-03-05 16:28                                                 ` Richard Kenner
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 16:27 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, joseph, matz

On Wed, 5 Mar 2008, Richard Kenner wrote:

> > Err, right.  But tree aliasing is computing a representation for TBAA,
> > using alias set conflict queries but _not_ looking at individual accesses.
> 
> That seems quite wrong to me.
> 
> > So, is alias_set_subset_of () wrong as currently implemented?  Does
> > it lack the ase->has_zero_child test in your opinion?  Otherwise I'll
> > try using that for these queries.
> 
> I don't know enough to answer those questions.

That is sad, because you knew enough to fix exactly the same code
in alias_sets_conflict_p.

> What I *do* know is that if you have x.y, with y addressable, any code
> that looks at the alias set of X *for any reason* is broken.

Well, you obviously do not have enough knowledge of the alias 
representation used in tree-ssa and I won't try to start to explain.
If you want, take the testcase in PR27799, build with
-O2 -fdump-tree-salias-vops-details and look at the 052t.salias dump.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:27                                               ` Richard Guenther
@ 2008-03-05 16:28                                                 ` Richard Kenner
  2008-03-05 16:57                                                   ` Daniel Berlin
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Kenner @ 2008-03-05 16:28 UTC (permalink / raw)
  To: rguenther; +Cc: gcc-patches, joseph, matz

> That is sad, because you knew enough to fix exactly the same code
> in alias_sets_conflict_p.

Yes, but you're now asking about a different set of functions used in
different ways and ...

> Well, you obviously do not have enough knowledge of the alias 
> representation used in tree-ssa

... this is quite correct.

But if it can't handle very simple cases correctly, I'd say it has some
serious problems.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:21                                             ` Richard Guenther
@ 2008-03-05 16:55                                               ` Daniel Berlin
  2008-03-05 16:55                                                 ` Richard Guenther
  0 siblings, 1 reply; 42+ messages in thread
From: Daniel Berlin @ 2008-03-05 16:55 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Richard Kenner, gcc-patches, matz

On Wed, Mar 5, 2008 at 11:21 AM, Richard Guenther <rguenther@suse.de> wrote:
>
>  Which means like the following (untested) patch, also fixes PR27799.
>
>  Richard.
>

This looks right to me because we always know which one is the pointer
and which one is the pointed-to var.
So it's fine assuming it passes bootstrap and regtest

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:55                                               ` Daniel Berlin
@ 2008-03-05 16:55                                                 ` Richard Guenther
  2008-03-05 17:00                                                   ` Daniel Berlin
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Guenther @ 2008-03-05 16:55 UTC (permalink / raw)
  To: Daniel Berlin; +Cc: Richard Kenner, gcc-patches, matz

On Wed, 5 Mar 2008, Daniel Berlin wrote:

> On Wed, Mar 5, 2008 at 11:21 AM, Richard Guenther <rguenther@suse.de> wrote:
> >
> >  Which means like the following (untested) patch, also fixes PR27799.
> >
> >  Richard.
> >
> 
> This looks right to me because we always know which one is the pointer
> and which one is the pointed-to var.
> So it's fine assuming it passes bootstrap and regtest

It doesn't work.

Richard.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:28                                                 ` Richard Kenner
@ 2008-03-05 16:57                                                   ` Daniel Berlin
  0 siblings, 0 replies; 42+ messages in thread
From: Daniel Berlin @ 2008-03-05 16:57 UTC (permalink / raw)
  To: Richard Kenner; +Cc: rguenther, gcc-patches, joseph, matz

On Wed, Mar 5, 2008 at 11:30 AM, Richard Kenner
<kenner@vlsi1.ultra.nyu.edu> wrote:
> > That is sad, because you knew enough to fix exactly the same code
>  > in alias_sets_conflict_p.
>
>  Yes, but you're now asking about a different set of functions used in
>  different ways and ...
>
>
>  > Well, you obviously do not have enough knowledge of the alias
>  > representation used in tree-ssa
>
>  ... this is quite correct.
>
>  But if it can't handle very simple cases correctly, I'd say it has some
>  serious problems.

I await your design for a completely accurate def-use chain
representation for memory accesses that does not take infinite amounts
of memory at compile time.
Until then, i have to laugh at your claim of "serious problems".
We knew what we were doing when we made it, and we knew it would have
some issues that would take further disambiguation to solve.
This just happens to be one of those cases.

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 16:55                                                 ` Richard Guenther
@ 2008-03-05 17:00                                                   ` Daniel Berlin
  0 siblings, 0 replies; 42+ messages in thread
From: Daniel Berlin @ 2008-03-05 17:00 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Richard Kenner, gcc-patches, matz

On Wed, Mar 5, 2008 at 11:55 AM, Richard Guenther <rguenther@suse.de> wrote:
>
> On Wed, 5 Mar 2008, Daniel Berlin wrote:
>
>  > On Wed, Mar 5, 2008 at 11:21 AM, Richard Guenther <rguenther@suse.de> wrote:
>  > >
>  > >  Which means like the following (untested) patch, also fixes PR27799.
>  > >
>  > >  Richard.
>  > >
>  >
>  > This looks right to me because we always know which one is the pointer
>  > and which one is the pointed-to var.
>  > So it's fine assuming it passes bootstrap and regtest
>
>  It doesn't work.
>

You reversed the arguments.

alias_set_subset_of tells you if the first is a subset of the second.

So you want to know if the var is a subset (actually subset or equal
to) of the ptr.
The way the arguments are in your patch, you are asking if ptr is a
subset of var.
>

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

* Re: [PATCH] Make alias_sets_conflict_p less conservative
  2008-03-05 11:29     ` Richard Kenner
@ 2008-03-20  7:09       ` Mark Mitchell
  0 siblings, 0 replies; 42+ messages in thread
From: Mark Mitchell @ 2008-03-20  7:09 UTC (permalink / raw)
  To: Richard Kenner; +Cc: rguenther, gcc-patches

Richard Kenner wrote:

> As I asked in a different message, why does char have alias set zero?
> *That's* what seems bogus to me.  Not having to do that is exactly why
> TYPE_REF_CAN_ALIAS_ALL exists in the first place!  There's nothing special
> about "char", but only about "char *".

Although this debate seems to have died down, I found it in plowing 
through back email.  I agree that Richard G.'s original proposed patch 
to alias_set_conflicts_p (which appears to have gone into limbo anyhow) 
  seems wrong, and that alias set zero shouldn't be special with respect 
to the handling of children of structures.

However, I do think that people may well write code like this:

   __attribute__((aligned)) char buffer[1024];
   int *p = (int *) buffer[0];
   double *d = (double *) buffer[8];
   *p = 3;
   *d = 7.0;

This is "poor man's placement-new".  (Placement new is the bit in C++ 
that allows this:

   __attribute__((aligned)) char buffer[1024];
   int *p = new (buffer) int;
   int *d = new (buffer + 8) double;

If we want to make the C code above work, we'd need character arrays (at 
least) to have alias set zero.  However, my recollection was that in C++ 
we're now requiring the placement-new construct and that Richard G. and 
Ian did quite a bit of work (CHANGE_DYNAMIC_TYPE_EXPR) to (a) make 
placement-new work, and (b) not unduly pessimize other uses of casts. 
If that's correct, then I'd expect the C usage above is already broken, 
for the same reasons that placement-new used to be broken -- and that, 
therefore, we don't really need "char" itself to be in alias set zero, 
so long as "char *" is somehow specially marked.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

end of thread, other threads:[~2008-03-20  2:01 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-04 20:59 [PATCH] Make alias_sets_conflict_p less conservative Richard Guenther
2008-03-04 23:54 ` Richard Kenner
2008-03-05  0:20   ` Daniel Berlin
2008-03-05  1:35     ` Richard Kenner
2008-03-05 10:00       ` Richard Guenther
2008-03-05 11:10         ` Paolo Bonzini
2008-03-05 11:17           ` Eric Botcazou
2008-03-05 12:05             ` Paolo Bonzini
2008-03-05 12:09               ` Eric Botcazou
2008-03-05 12:29               ` Richard Kenner
2008-03-05 11:31         ` Richard Kenner
2008-03-05 11:47           ` Richard Guenther
2008-03-05 12:25             ` Richard Kenner
2008-03-05 12:42               ` Richard Guenther
2008-03-05 12:55                 ` Richard Kenner
2008-03-05 14:07                   ` Richard Guenther
2008-03-05 14:24                     ` Richard Kenner
2008-03-05 15:01                       ` Richard Guenther
2008-03-05 15:13                         ` Richard Kenner
2008-03-05 15:21                           ` Richard Guenther
2008-03-05 15:29                             ` Michael Matz
2008-03-05 15:38                               ` Richard Guenther
2008-03-05 15:42                                 ` Richard Kenner
2008-03-05 15:52                                   ` Richard Guenther
2008-03-05 15:59                                     ` Richard Kenner
2008-03-05 16:07                                       ` Richard Guenther
2008-03-05 16:13                                         ` Richard Kenner
2008-03-05 16:17                                           ` Richard Guenther
2008-03-05 16:21                                             ` Richard Guenther
2008-03-05 16:55                                               ` Daniel Berlin
2008-03-05 16:55                                                 ` Richard Guenther
2008-03-05 17:00                                                   ` Daniel Berlin
2008-03-05 16:23                                             ` Richard Kenner
2008-03-05 16:27                                               ` Richard Guenther
2008-03-05 16:28                                                 ` Richard Kenner
2008-03-05 16:57                                                   ` Daniel Berlin
2008-03-05 15:18                       ` Michael Matz
2008-03-05 15:28                         ` Richard Kenner
2008-03-05  9:21   ` Richard Guenther
2008-03-05 11:29     ` Richard Kenner
2008-03-20  7:09       ` Mark Mitchell
2008-03-05 14:10     ` Richard Guenther

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).