[PATCH] Assign the same alias-set to all pointers
Richard Guenther
rguenther@suse.de
Tue Jun 1 16:16:00 GMT 2010
See $subject. Main reasoning can be seen in the huge comment
before the case in get_alias_set below.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Comments?
Thanks,
Richard.
2010-06-01 Richard Guenther <rguenther@suse.de>
* gimple.c (gimple_get_alias_set): Remove pointer special-casing.
* alias.c (get_alias_set): Canonicalize pointers with the same mode.
Fix incomplete array type fallback alias-set.
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c (revision 160100)
--- gcc/gimple.c (working copy)
*************** gimple_get_alias_set (tree t)
*** 4310,4372 ****
if (t1 != t)
return get_alias_set (t1);
}
- else if (POINTER_TYPE_P (t))
- {
- /* From the common C and C++ langhook implementation:
-
- Unfortunately, there is no canonical form of a pointer type.
- In particular, if we have `typedef int I', then `int *', and
- `I *' are different types. So, we have to pick a canonical
- representative. We do this below.
-
- Technically, this approach is actually more conservative that
- it needs to be. In particular, `const int *' and `int *'
- should be in different alias sets, according to the C and C++
- standard, since their types are not the same, and so,
- technically, an `int **' and `const int **' cannot point at
- the same thing.
-
- But, the standard is wrong. In particular, this code is
- legal C++:
-
- int *ip;
- int **ipp = &ip;
- const int* const* cipp = ipp;
- And, it doesn't make sense for that to be legal unless you
- can dereference IPP and CIPP. So, we ignore cv-qualifiers on
- the pointed-to types. This issue has been reported to the
- C++ committee. */
-
- /* In addition to the above canonicalization issue with LTO
- we should also canonicalize `T (*)[]' to `T *' avoiding
- alias issues with pointer-to element types and pointer-to
- array types.
-
- Likewise we need to deal with the situation of incomplete
- pointed-to types and make `*(struct X **)&a' and
- `*(struct X {} **)&a' alias. Otherwise we will have to
- guarantee that all pointer-to incomplete type variants
- will be replaced by pointer-to complete type variants if
- they are available.
-
- With LTO the convenient situation of using `void *' to
- access and store any pointer type will also become
- more apparent (and `void *' is just another pointer-to
- incomplete type). Assigning alias-set zero to `void *'
- and all pointer-to incomplete types is a not appealing
- solution. Assigning an effective alias-set zero only
- affecting pointers might be - by recording proper subset
- relationships of all pointer alias-sets.
-
- Pointer-to function types are another grey area which
- needs caution. Globbing them all into one alias-set
- or the above effective zero set would work. */
-
- /* For now just assign the same alias-set to all pointers.
- That's simple and avoids all the above problems. */
- if (t != ptr_type_node)
- return get_alias_set (ptr_type_node);
- }
return -1;
}
--- 4310,4315 ----
Index: gcc/alias.c
===================================================================
*** gcc/alias.c (revision 160100)
--- gcc/alias.c (working copy)
*************** get_alias_set (tree t)
*** 694,719 ****
t = TREE_TYPE (t);
}
! /* Variant qualifiers don't affect the alias set, so get the main
! variant. */
! t = TYPE_MAIN_VARIANT (t);
!
! /* Always use the canonical type as well. If this is a type that
! requires structural comparisons to identify compatible types
! use alias set zero. */
! if (TYPE_STRUCTURAL_EQUALITY_P (t))
{
! /* Allow the language to specify another alias set for this
! type. */
! set = lang_hooks.get_alias_set (t);
! if (set != -1)
! return set;
! return 0;
}
- t = TYPE_CANONICAL (t);
- /* Canonical types shouldn't form a tree nor should the canonical
- type require structural equality checks. */
- gcc_assert (!TYPE_STRUCTURAL_EQUALITY_P (t) && TYPE_CANONICAL (t) == t);
/* If this is a type with a known alias set, return it. */
if (TYPE_ALIAS_SET_KNOWN_P (t))
--- 694,785 ----
t = TREE_TYPE (t);
}
! /* Canonicalize the type. */
! if (POINTER_TYPE_P (t))
{
! /* From the common C and C++ langhook implementation:
!
! Unfortunately, there is no canonical form of a pointer type.
! In particular, if we have `typedef int I', then `int *', and
! `I *' are different types. So, we have to pick a canonical
! representative. We do this below.
!
! Technically, this approach is actually more conservative that
! it needs to be. In particular, `const int *' and `int *'
! should be in different alias sets, according to the C and C++
! standard, since their types are not the same, and so,
! technically, an `int **' and `const int **' cannot point at
! the same thing.
!
! But, the standard is wrong. In particular, this code is
! legal C++:
!
! int *ip;
! int **ipp = &ip;
! const int* const* cipp = ipp;
! And, it doesn't make sense for that to be legal unless you
! can dereference IPP and CIPP. So, we ignore cv-qualifiers on
! the pointed-to types. This issue has been reported to the
! C++ committee. */
!
! /* In addition to the above canonicalization issue with LTO
! we should also canonicalize `T (*)[]' to `T *' avoiding
! alias issues with pointer-to element types and pointer-to
! array types.
!
! Likewise we need to deal with the situation of incomplete
! pointed-to types and make `*(struct X **)&a' and
! `*(struct X {} **)&a' alias. Otherwise we will have to
! guarantee that all pointer-to incomplete type variants
! will be replaced by pointer-to complete type variants if
! they are available.
!
! With LTO the convenient situation of using `void *' to
! access and store any pointer type will also become
! more apparent (and `void *' is just another pointer-to
! incomplete type). Assigning alias-set zero to `void *'
! and all pointer-to incomplete types is a not appealing
! solution. Assigning an effective alias-set zero only
! affecting pointers might be - by recording proper subset
! relationships of all pointer alias-sets.
!
! Pointer-to function types are another grey area which
! needs caution. Globbing them all into one alias-set
! or the above effective zero set would work. */
!
! /* For now just assign the same alias-set to all pointers.
! That's simple and avoids all the above problems.
! Do so by canonicalizing all pointer types to void * pointers,
! but allow different pointer modes to have different alias-sets. */
! if (TYPE_MODE (t) == TYPE_MODE (ptr_type_node))
! t = ptr_type_node;
! else
! t = build_pointer_type_for_mode (void_type_node,
! TYPE_MODE (t), false);
! }
! else
! {
! /* Variant qualifiers don't affect the alias set, so get the main
! variant. */
! t = TYPE_MAIN_VARIANT (t);
!
! /* Always use the canonical type as well. If this is a type that
! requires structural comparisons to identify compatible types
! use alias set zero. */
! if (TYPE_STRUCTURAL_EQUALITY_P (t))
! {
! /* Allow the language to specify another alias set for this
! type. */
! set = lang_hooks.get_alias_set (t);
! if (set != -1)
! return set;
! return 0;
! }
! t = TYPE_CANONICAL (t);
! /* Canonical types shouldn't form a tree nor should the canonical
! type require structural equality checks. */
! gcc_assert (!TYPE_STRUCTURAL_EQUALITY_P (t) && TYPE_CANONICAL (t) == t);
}
/* If this is a type with a known alias set, return it. */
if (TYPE_ALIAS_SET_KNOWN_P (t))
*************** get_alias_set (tree t)
*** 724,730 ****
{
/* For arrays with unknown size the conservative answer is the
alias set of the element type. */
! if (TREE_CODE (t) == ARRAY_TYPE)
return get_alias_set (TREE_TYPE (t));
/* But return zero as a conservative answer for incomplete types. */
--- 790,797 ----
{
/* For arrays with unknown size the conservative answer is the
alias set of the element type. */
! if (TREE_CODE (t) == ARRAY_TYPE
! && !TYPE_NONALIASED_COMPONENT (t))
return get_alias_set (TREE_TYPE (t));
/* But return zero as a conservative answer for incomplete types. */
*************** get_alias_set (tree t)
*** 739,746 ****
/* There are no objects of FUNCTION_TYPE, so there's no point in
using up an alias set for them. (There are, of course, pointers
and references to functions, but that's different.) */
! else if (TREE_CODE (t) == FUNCTION_TYPE
! || TREE_CODE (t) == METHOD_TYPE)
set = 0;
/* Unless the language specifies otherwise, let vector types alias
--- 806,813 ----
/* There are no objects of FUNCTION_TYPE, so there's no point in
using up an alias set for them. (There are, of course, pointers
and references to functions, but that's different.) */
! if (TREE_CODE (t) == FUNCTION_TYPE
! || TREE_CODE (t) == METHOD_TYPE)
set = 0;
/* Unless the language specifies otherwise, let vector types alias
More information about the Gcc-patches
mailing list