Re: Aliasing violation generated by fold_builtin_memcmp?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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.
Re: Aliasing violation generated by fold_builtin_memcmp?
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?
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?
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)