Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Olivier Hainque
Richard Henderson wrote:
 Try
 
   cst_uchar_ptr_node
 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
 
 which is apparently in use by the Ada front end, but only if a
 certain pragma is given.  Dunno how reliably that's likely to work.

 We are seeing regressions in our local testsuite on cases exercising
 that pragma.

 Passing 'true' as CAN_ALIAS_ALL sets TYPE_REF_CAN_ALIAS_ALL (t), but
 this apparently has no influence on what tree-ssa-alias computes.

 Out of a preliminary look into this code (new to me), a possible place
 to address that appears to be 'get_tmt_for', which presumably should assign
 a zero alias set to tags for pointer types with that bit set.

 The current code doesn't do that:

   tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
   HOST_WIDE_INT tag_set = get_alias_set (tag_type);


 I'd be happy to work-on and submit a patch to deal with this the proper
 way. I'd welcome hints or directions on what the proper way should be, as
 I don't yet have a global view of the complete alias analysis circuitry.

 The 'tag alias set should be zero if ...' idea above seems logical to me.
 I still may well not yet see a number of other options.





 




 
 


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Daniel Berlin
On Fri, 2005-09-30 at 11:23 +0200, Olivier Hainque wrote:
 Richard Henderson wrote:
  Try
  
cst_uchar_ptr_node
  = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
  
  which is apparently in use by the Ada front end, but only if a
  certain pragma is given.  Dunno how reliably that's likely to work.
 
  We are seeing regressions in our local testsuite on cases exercising
  that pragma.
 
  Passing 'true' as CAN_ALIAS_ALL sets TYPE_REF_CAN_ALIAS_ALL (t), but
  this apparently has no influence on what tree-ssa-alias computes.
 
  Out of a preliminary look into this code (new to me), a possible place
  to address that appears to be 'get_tmt_for', which presumably should assign
  a zero alias set to tags for pointer types with that bit set.

Actually, you just want it to assign the same tag, not change the alias
set of every tag it assigns.




Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Olivier Hainque
Daniel Berlin wrote:
   Out of a preliminary look into this code (new to me), a possible
   place to address that appears to be 'get_tmt_for', which
   presumably should assign a zero alias set to tags for pointer
   types with that bit set.
 
 Actually, you just want it to assign the same tag, not change the alias
 set of every tag it assigns.

 Humm, and still have the corresponding alias set zero to ensure it conflicts
 with everything, right ?

 In which case almost all the bits are in already, since get_tmt_for
 already reuses a previously created tag if it assigned the same alias set.

 I tried this on a couple of testcases yesterday, and it worked fine.

 I am still unclear on one point: is it fine to reuse the same tag for
 possibly different designated types ?











Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Daniel Berlin
On Fri, 2005-09-30 at 15:54 +0200, Olivier Hainque wrote:
 Daniel Berlin wrote:
Out of a preliminary look into this code (new to me), a possible
place to address that appears to be 'get_tmt_for', which
presumably should assign a zero alias set to tags for pointer
types with that bit set.
  
  Actually, you just want it to assign the same tag, not change the alias
  set of every tag it assigns.
 
  Humm, and still have the corresponding alias set zero to ensure it conflicts
  with everything, right ?

Yes. :)

 
  In which case almost all the bits are in already, since get_tmt_for
  already reuses a previously created tag if it assigned the same alias set.
 
  I tried this on a couple of testcases yesterday, and it worked fine.
 
  I am still unclear on one point: is it fine to reuse the same tag for
  possibly different designated types ?

Yes, as long as they have the same alias set.

 
 
 
 
 
 
 
 
 



Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Olivier Hainque
Daniel Berlin wrote:
   I am still unclear on one point: is it fine to reuse the same tag for
   possibly different designated types ?
 
 Yes, as long as they have the same alias set.

 OK. A last detail:

 On the first tag_set 0 creation, we get into:

  if (var_ann (ptr)-type_mem_tag == NULL_TREE)
tag = create_memory_tag (tag_type, true);

 and, if doing nothing special, trip on

 /* Make sure that the type tag has the same alias set as the
pointed-to type.  */
 gcc_assert (tag_set == get_alias_set (tag));

 I've relaxed the assert expression for experimentation purposes, but
 this is probably not the best thing to do.

 How would you prefer to see this addressed ?





 


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Daniel Berlin
On Fri, 2005-09-30 at 16:29 +0200, Olivier Hainque wrote:
 Daniel Berlin wrote:
I am still unclear on one point: is it fine to reuse the same tag for
possibly different designated types ?
  
  Yes, as long as they have the same alias set.
 
  OK. A last detail:
 
  On the first tag_set 0 creation, we get into:
 
   if (var_ann (ptr)-type_mem_tag == NULL_TREE)
   tag = create_memory_tag (tag_type, true);
 
  and, if doing nothing special, trip on
 
  /* Make sure that the type tag has the same alias set as the
   pointed-to type.  */
  gcc_assert (tag_set == get_alias_set (tag));

Well, doesn't the pointed-to type have set 0 because of
TYPE_REF_CAN_ALIAS_ALL (or whatever it's named :P)?
I'm a bit confused.




Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Olivier Hainque
Daniel Berlin wrote:
 Well, doesn't the pointed-to type have set 0 because of
 TYPE_REF_CAN_ALIAS_ALL (or whatever it's named :P)?

 Not quite: the pointer type has TYPE_REF_CAN_ALIAS_ALL, not the
 pointed-to type:

   /* Nonzero in a pointer or reference type means the data pointed to
  by this type can alias anything.  */
   #define TYPE_REF_CAN_ALIAS_ALL(NODE) \
 (PTR_OR_REF_CHECK (NODE)-common.static_flag)

 It seems to me that get_tmt does not do the right thing today
 because it assigns the tag alias set from the alias set of the
 pointed-to type, even if CAN_ALIAS_ALL is set on the pointer type.

 Here is an example input tree out of an Ada testcase:

 var_decl 0x4022f370 ksubint.2
type pointer_type 0x4025fbdc p2__integer_access
type integer_type 0x4025fb80 integer type integer_type integer
sizes-gimplified public SI
user align 32 symtab 0 alias set 3 

sizes-gimplified public static unsigned SI
^^
user align 32 symtab 0 alias set -1

 This is a pointer to integer which is declared can actually alias anything.












 


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Daniel Berlin
On Fri, 2005-09-30 at 16:53 +0200, Olivier Hainque wrote:
 Daniel Berlin wrote:
  Well, doesn't the pointed-to type have set 0 because of
  TYPE_REF_CAN_ALIAS_ALL (or whatever it's named :P)?
 
  Not quite: the pointer type has TYPE_REF_CAN_ALIAS_ALL, not the
  pointed-to type:
 
/* Nonzero in a pointer or reference type means the data pointed to
   by this type can alias anything.  */
#define TYPE_REF_CAN_ALIAS_ALL(NODE) \
  (PTR_OR_REF_CHECK (NODE)-common.static_flag)
 
  It seems to me that get_tmt does not do the right thing today
  because it assigns the tag alias set from the alias set of the
  pointed-to type, even if CAN_ALIAS_ALL is set on the pointer type.

Uh, CAN_ALIAS_ALL seems like a very bad hack then.
You should simply be creating a pointed-to type that aliases set 0, and
using that for the pointed to type.
That is, after all, what alias set 0 is for.




Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Richard Kenner
Uh, CAN_ALIAS_ALL seems like a very bad hack then.
You should simply be creating a pointed-to type that aliases set 0, and
using that for the pointed to type.
That is, after all, what alias set 0 is for.

That's easy enough for integer types, but creating multiple record types
means duplicating lots of fields and layouts and is, in general, a mess.
What's special here is the pointer type, not the underlying type.


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Daniel Berlin
On Fri, 2005-09-30 at 11:20 -0400, Richard Kenner wrote:
 Uh, CAN_ALIAS_ALL seems like a very bad hack then.
 You should simply be creating a pointed-to type that aliases set 0, and
 using that for the pointed to type.
 That is, after all, what alias set 0 is for.
 
 That's easy enough for integer types, but creating multiple record types
 means duplicating lots of fields and layouts and is, in general, a mess.

But of course, it's the right thing to do when you've got one type that
can be aliased to anything through a pointer, and the other cannot.

 What's special here is the pointer type, not the underlying type.

Which means that everywhere that handles pointer types and aliasing has
to be modified to check this magic.

I still claim it is a hack, and a very bad one.

At the absolute least, it should be encapsulated in a function, maybe
get_alias_set_of_pointed_to_type or something.

--Dan



Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Richard Kenner
 But of course, it's the right thing to do when you've got one type that
 can be aliased to anything through a pointer, and the other cannot.

Sure, if that's what were going on, but it's not.

What we have are two *pointer types*, both pointing at the same
underlying type.  Access via one of those pointer types is assumed to
be aliasing anything and the other is not.

The case in Ada is

type r1 is record ... end record;
type ar1 is access all r1;
type r2 is record ... end record;
type ar2 is access all r2;

type ar2p is access all r2;
function uc is new unchecked_conversion (ar1, ar2p);

In this case, both ar2.all and ar2p.all are accessing r2.  But accesses
through ar2p must be presumed to access anything since we know that the
underlying object might be an ar1.

  What's special here is the pointer type, not the underlying type.

 Which means that everywhere that handles pointer types and aliasing has
 to be modified to check this magic.

At the RTL level, there's just one place that computes the alias set of an
expression and it knows about that flag.  It was the only place that had
to be modified to support it, as I recall.  One would hope that knowlege
of this semantics can be similarly localized at the tree level.  Why can't it?


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Daniel Berlin
On Fri, 2005-09-30 at 12:45 -0400, Richard Kenner wrote:

   What's special here is the pointer type, not the underlying type.
 
  Which means that everywhere that handles pointer types and aliasing has
  to be modified to check this magic.
 
 At the RTL level, there's just one place that computes the alias set of an
 expression and it knows about that flag.  It was the only place that had
 to be modified to support it, as I recall.  One would hope that knowlege
 of this semantics can be similarly localized at the tree level.  Why can't it?

Because the RTL level only supports type based aliasing, and very simple
TBAA at that.

You are saying that an access through this pointer can point to
anything, regardless of what we think it points to.

This leaves 3 or 4 places at the tree level that need to be changed, and
possibly more later as more aliasing techniques are added.




Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Richard Kenner
 Because the RTL level only supports type based aliasing, and very simple
 TBAA at that.

But we're just talking about type-based aliasing.

 You are saying that an access through this pointer can point to
 anything, regardless of what we think it points to.

No.  If you know what it points to by value-based information, that can
safely be used.  The only thing is that you must use alias set 0 for
any type-based information.

 This leaves 3 or 4 places at the tree level that need to be changed,
 and possibly more later as more aliasing techniques are added.

I don't see why.  Why is there more than one place that computes the alias
set of what a pointer might point to?


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Andrew Pinski


On Sep 29, 2005, at 8:32 PM, Daniel Berlin wrote:




Any suggestions how to fix this?


The easiest thing is to store a version of unsigned_char_type_node
somewhere that has it's TYPE_ALIAS_SET set to 0, and use it there.
Whether this is the best solution, i'll leave to others :)



Something like this will fix the issue with TYPE_REF_CAN_ALIAS_ALL
by removing the use.  Maybe we could move may_alias to a bit in the
types and move TYPE_REF_CAN_ALIAS_ALL from the pointer type to the
type which is being accessed instead of this mess.

-- Pinski


Index: c-common.c
===
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.653
diff -u -p -r1.653 c-common.c
--- c-common.c  27 Sep 2005 16:04:06 -  1.653
+++ c-common.c  30 Sep 2005 17:46:42 -
@@ -2668,9 +2668,6 @@ c_common_get_alias_set (tree t)
   || t == unsigned_char_type_node)
 return 0;
 
-  /* If it has the may_alias attribute, it can alias anything.  */
-  if (lookup_attribute (may_alias, TYPE_ATTRIBUTES (t)))
-return 0;
 
   /* The C standard specifically allows aliasing between signed and
  unsigned variants of the same type.  We treat the signed
Index: alias.c
===
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.254
diff -u -p -r1.254 alias.c
--- alias.c 21 Jul 2005 22:34:33 -  1.254
+++ alias.c 30 Sep 2005 17:46:42 -
@@ -587,6 +587,10 @@ get_alias_set (tree t)
   /* Now all we care about is the type.  */
   t = TREE_TYPE (t);
 }
+  
+  /* If it has the may_alias attribute, it can alias anything.  */
+  if (lookup_attribute (may_alias, TYPE_ATTRIBUTES (t)))
+return 0;
 
   /* Variant qualifiers don't affect the alias set, so get the main
  variant. If this is a type with a known alias set, return it.  */
Index: tree.c
===
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.505
diff -u -p -r1.505 tree.c
--- tree.c  14 Sep 2005 15:04:56 -  1.505
+++ tree.c  30 Sep 2005 17:46:42 -
@@ -4705,6 +4705,17 @@ build_pointer_type_for_mode (tree to_typ
 
   if (to_type == error_mark_node)
 return error_mark_node;
+  
+  if (can_alias_all)
+{
+  to_type =
+   build_type_attribute_variant (ttype,
+ merge_attributes
+   (TYPE_ATTRIBUTES (to_type), 
+tree_cons (get_identifier 
(may_alias),
+   NULL_TREE, NULL_TREE)));
+
+}
 
   /* In some cases, languages will have things that aren't a POINTER_TYPE
  (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_POINTER_TO.
@@ -4721,14 +4732,13 @@ build_pointer_type_for_mode (tree to_typ
   /* First, if we already have a type for pointers to TO_TYPE and it's
  the proper mode, use it.  */
   for (t = TYPE_POINTER_TO (to_type); t; t = TYPE_NEXT_PTR_TO (t))
-if (TYPE_MODE (t) == mode  TYPE_REF_CAN_ALIAS_ALL (t) == can_alias_all)
+if (TYPE_MODE (t) == mode)
   return t;
 
   t = make_node (POINTER_TYPE);
 
   TREE_TYPE (t) = to_type;
   TYPE_MODE (t) = mode;
-  TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
   TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
   TYPE_POINTER_TO (to_type) = t;
 
@@ -4754,6 +4764,18 @@ build_reference_type_for_mode (tree to_t
   bool can_alias_all)
 {
   tree t;
+  
+
+  if (can_alias_all)
+{
+  to_type =
+   build_type_attribute_variant (ttype,
+ merge_attributes
+   (TYPE_ATTRIBUTES (to_type), 
+tree_cons (get_identifier 
(may_alias),
+   NULL_TREE, NULL_TREE)));
+
+}
 
   /* In some cases, languages will have things that aren't a REFERENCE_TYPE
  (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_REFERENCE_TO.
@@ -4770,14 +4792,13 @@ build_reference_type_for_mode (tree to_t
   /* First, if we already have a type for pointers to TO_TYPE and it's
  the proper mode, use it.  */
   for (t = TYPE_REFERENCE_TO (to_type); t; t = TYPE_NEXT_REF_TO (t))
-if (TYPE_MODE (t) == mode  TYPE_REF_CAN_ALIAS_ALL (t) == can_alias_all)
+if (TYPE_MODE (t) == mode)
   return t;
 
   t = make_node (REFERENCE_TYPE);
 
   TREE_TYPE (t) = to_type;
   TYPE_MODE (t) = mode;
-  TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
   TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (to_type);
   TYPE_REFERENCE_TO (to_type) = t;
 
@@ -4809,12 +4830,12 @@ build_type_no_quals (tree t)
 case POINTER_TYPE:
   return build_pointer_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
  TYPE_MODE (t),

Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Richard Henderson
On Fri, Sep 30, 2005 at 11:23:23AM +0200, Olivier Hainque wrote:
  We are seeing regressions in our local testsuite on cases exercising
  that pragma.

Hmm.

  The 'tag alias set should be zero if ...' idea above seems logical to me.
  I still may well not yet see a number of other options.

Perhaps we should instead get rid of this flag and instead
represent this as a variant of the pointed-to type with the
alias set forced to zero.  It does seem odd that there are
two ways to represent this...


r~


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-30 Thread Richard Kenner
Yeah, so?  How often do you think this feature is used, anyway?

Quite a lot in legacy Ada code.

But how often it's used doesn't matter: if it's used *at all*, we still
have to create the mechanism for duplicating record types.


Aliasing violation generated by fold_builtin_memcmp?

2005-09-29 Thread Ulrich Weigand
Hello,

in debugging the remaining Ada failures on s390x, I've come to what
looks a bug in the middle end.  See
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19382
for details.

In short, the problem appears to be this code in fold_builtin_memcmp:

  /* If len parameter is one, return an expression corresponding to
 (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
  if (host_integerp (len, 1)  tree_low_cst (len, 1) == 1)
{
  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
  tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
  tree ind1 = fold_convert (integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
fold_convert (cst_uchar_ptr_node,
  arg1)));
  tree ind2 = fold_convert (integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
fold_convert (cst_uchar_ptr_node,
  arg2)));
  return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
}

This generates code accessing the data pointed to by the arguments
using a synthesized 'const unsigned char' type.  This is only OK
if that type is allowed to alias whatever type the arguments
originally had.

Now this is not an issue in the C family of languages, due to the
special case of 'char' / 'signed char' / 'unsigned char' being
explicitly allowed to alias every other type.

However, when building for some *other* language, this assumption
is not correct -- e.g. in the Ada test case in PR 19382, the type
synthesized here is completely unknown to the front end and gets
assigned a default alias set allowing it to alias *nothing* else.

(Note that even for Ada, fold_builtin_memcmp *will* be called,
e.g. from gimplify.c:gimplify_variable_sized_compare.)

Any suggestions how to fix this?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  [EMAIL PROTECTED]


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-29 Thread Daniel Berlin

 Any suggestions how to fix this?

The easiest thing is to store a version of unsigned_char_type_node
somewhere that has it's TYPE_ALIAS_SET set to 0, and use it there.
Whether this is the best solution, i'll leave to others :)

 
 Bye,
 Ulrich
 



Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-29 Thread Richard Henderson
On Fri, Sep 30, 2005 at 02:08:18AM +0200, Ulrich Weigand wrote:
  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
  tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
...
 Any suggestions how to fix this?

Try

  cst_uchar_ptr_node
= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);

which is apparently in use by the Ada front end, but only if a
certain pragma is given.  Dunno how reliably that's likely to work.


r~


Re: Aliasing violation generated by fold_builtin_memcmp?

2005-09-29 Thread Richard Kenner
In short, the problem appears to be this code in fold_builtin_memcmp:

  /* If len parameter is one, return an expression corresponding to
 (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
  if (host_integerp (len, 1)  tree_low_cst (len, 1) == 1)
{
  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
  tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);

Any suggestions how to fix this?

Maybe change the above to
build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true)