Commit c6b84edb by Jan Hubicka Committed by Jan Hubicka

tree-ssa-alias.c (compare_sizes): New function.


	* tree-ssa-alias.c (compare_sizes): New function.
	(sompare_type_sizes): New function
	(aliasing_component_refs_p): Use it.
	(indirect_ref_may_alias_decl_p): Likewise.

From-SVN: r271413
parent 58487c21
2019-05-20 Jan Hubicka <hubicka@ucw.cz>
* tree-ssa-alias.c (compare_sizes): New function.
(sompare_type_sizes): New function
(aliasing_component_refs_p): Use it.
(indirect_ref_may_alias_decl_p): Likewise.
2019-05-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2019-05-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config/i386/sol2.h (CC1_SPEC): Reject -mx32. * config/i386/sol2.h (CC1_SPEC): Reject -mx32.
......
...@@ -735,6 +735,48 @@ ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size) ...@@ -735,6 +735,48 @@ ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size)
ref->volatile_p = false; ref->volatile_p = false;
} }
/* S1 and S2 are TYPE_SIZE or DECL_SIZE. Compare them:
Return -1 if S1 < S2
Return 1 if S1 > S2
Return 0 if equal or incomparable. */
static int
compare_sizes (tree s1, tree s2)
{
if (!s1 || !s2)
return 0;
poly_uint64 size1 = poly_int_tree_p (s1, &size1);
poly_uint64 size2 = poly_int_tree_p (s2, &size2);
if (!poly_int_tree_p (s1, &size1) || !poly_int_tree_p (s2, &size2))
return 0;
if (known_lt (size1, size2))
return -1;
if (known_lt (size2, size1))
return 1;
return 0;
}
/* Compare TYPE1 and TYPE2 by its size.
Return -1 if size of TYPE1 < size of TYPE2
Return 1 if size of TYPE1 > size of TYPE2
Return 0 if types are of equal sizes or we can not compare them. */
static int
compare_type_sizes (tree type1, tree type2)
{
/* Be conservative for arrays and vectors. We want to support partial
overlap on int[3] and int[3] as tested in gcc.dg/torture/alias-2.c. */
while (TREE_CODE (type1) == ARRAY_TYPE
|| TREE_CODE (type1) == VECTOR_TYPE)
type1 = TREE_TYPE (type1);
while (TREE_CODE (type2) == ARRAY_TYPE
|| TREE_CODE (type2) == VECTOR_TYPE)
type2 = TREE_TYPE (type2);
return compare_sizes (TYPE_SIZE (type1), TYPE_SIZE (type2));
}
/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the /* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the
purpose of TBAA. Return 0 if they are distinct and -1 if we cannot purpose of TBAA. Return 0 if they are distinct and -1 if we cannot
decide. */ decide. */
...@@ -803,7 +845,7 @@ aliasing_component_refs_p (tree ref1, ...@@ -803,7 +845,7 @@ aliasing_component_refs_p (tree ref1,
tree base1, base2; tree base1, base2;
tree type1, type2; tree type1, type2;
tree *refp; tree *refp;
int same_p, same_p2; int same_p1 = 0, same_p2 = 0;
/* Choose bases and base types to search for. */ /* Choose bases and base types to search for. */
base1 = ref1; base1 = ref1;
...@@ -816,13 +858,32 @@ aliasing_component_refs_p (tree ref1, ...@@ -816,13 +858,32 @@ aliasing_component_refs_p (tree ref1,
type2 = TREE_TYPE (base2); type2 = TREE_TYPE (base2);
/* Now search for the type1 in the access path of ref2. This /* Now search for the type1 in the access path of ref2. This
would be a common base for doing offset based disambiguation on. */ would be a common base for doing offset based disambiguation on.
This however only makes sense if type2 is big enough to hold type1. */
int cmp_outer = compare_type_sizes (type2, type1);
if (cmp_outer >= 0)
{
refp = &ref2; refp = &ref2;
while (handled_component_p (*refp) while (true)
&& same_type_for_tbaa (TREE_TYPE (*refp), type1) == 0) {
/* We walk from inner type to the outer types. If type we see is
already too large to be part of type1, terminate the search. */
int cmp = compare_type_sizes (type1, TREE_TYPE (*refp));
if (cmp < 0)
break;
/* If types may be of same size, see if we can decide about their
equality. */
if (cmp >= 0)
{
same_p2 = same_type_for_tbaa (TREE_TYPE (*refp), type1);
if (same_p2 != 0)
break;
}
if (!handled_component_p (*refp))
break;
refp = &TREE_OPERAND (*refp, 0); refp = &TREE_OPERAND (*refp, 0);
same_p = same_type_for_tbaa (TREE_TYPE (*refp), type1); }
if (same_p == 1) if (same_p2 == 1)
{ {
poly_int64 offadj, sztmp, msztmp; poly_int64 offadj, sztmp, msztmp;
bool reverse; bool reverse;
...@@ -841,14 +902,30 @@ aliasing_component_refs_p (tree ref1, ...@@ -841,14 +902,30 @@ aliasing_component_refs_p (tree ref1,
return false; return false;
} }
} }
}
/* If we didn't find a common base, try the other way around. */ /* If we didn't find a common base, try the other way around. */
if (cmp_outer <= 0)
{
refp = &ref1; refp = &ref1;
while (handled_component_p (*refp) while (true)
&& same_type_for_tbaa (TREE_TYPE (*refp), type2) == 0) {
int cmp = compare_type_sizes (type2, TREE_TYPE (*refp));
if (cmp < 0)
break;
/* If types may be of same size, see if we can decide about their
equality. */
if (cmp >= 0)
{
same_p1 = same_type_for_tbaa (TREE_TYPE (*refp), type2);
if (same_p1 != 0)
break;
}
if (!handled_component_p (*refp))
break;
refp = &TREE_OPERAND (*refp, 0); refp = &TREE_OPERAND (*refp, 0);
same_p2 = same_type_for_tbaa (TREE_TYPE (*refp), type2); }
if (same_p2 == 1) if (same_p1 == 1)
{ {
poly_int64 offadj, sztmp, msztmp; poly_int64 offadj, sztmp, msztmp;
bool reverse; bool reverse;
...@@ -868,13 +945,6 @@ aliasing_component_refs_p (tree ref1, ...@@ -868,13 +945,6 @@ aliasing_component_refs_p (tree ref1,
return false; return false;
} }
} }
/* In the remaining test we assume that there is no overlapping type
at all. So if we are unsure, we need to give up. */
if (same_p == -1 || same_p2 == -1)
{
++alias_stats.aliasing_component_refs_p_may_alias;
return true;
} }
/* If we have two type access paths B1.path1 and B2.path2 they may /* If we have two type access paths B1.path1 and B2.path2 they may
...@@ -883,15 +953,19 @@ aliasing_component_refs_p (tree ref1, ...@@ -883,15 +953,19 @@ aliasing_component_refs_p (tree ref1,
a part that we do not see. So we can only disambiguate now a part that we do not see. So we can only disambiguate now
if there is no B2 in the tail of path1 and no B1 on the if there is no B2 in the tail of path1 and no B1 on the
tail of path2. */ tail of path2. */
if (base1_alias_set == ref2_alias_set if (compare_type_sizes (TREE_TYPE (ref2), type1) >= 0
|| alias_set_subset_of (base1_alias_set, ref2_alias_set)) && (same_p2 == -1
|| base1_alias_set == ref2_alias_set
|| alias_set_subset_of (base1_alias_set, ref2_alias_set)))
{ {
++alias_stats.aliasing_component_refs_p_may_alias; ++alias_stats.aliasing_component_refs_p_may_alias;
return true; return true;
} }
/* If this is ptr vs. decl then we know there is no ptr ... decl path. */ /* If this is ptr vs. decl then we know there is no ptr ... decl path. */
if (!ref2_is_decl if (!ref2_is_decl
&& (base2_alias_set == ref1_alias_set && compare_type_sizes (TREE_TYPE (ref1), type2) >= 0
&& (same_p1 == -1
|| base2_alias_set == ref1_alias_set
|| alias_set_subset_of (base2_alias_set, ref1_alias_set))) || alias_set_subset_of (base2_alias_set, ref1_alias_set)))
{ {
++alias_stats.aliasing_component_refs_p_may_alias; ++alias_stats.aliasing_component_refs_p_may_alias;
...@@ -1221,16 +1295,13 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, ...@@ -1221,16 +1295,13 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
/* If the size of the access relevant for TBAA through the pointer /* If the size of the access relevant for TBAA through the pointer
is bigger than the size of the decl we can't possibly access the is bigger than the size of the decl we can't possibly access the
decl via that pointer. */ decl via that pointer. */
if (DECL_SIZE (base2) && COMPLETE_TYPE_P (TREE_TYPE (ptrtype1)) if (/* ??? This in turn may run afoul when a decl of type T which is
&& poly_int_tree_p (DECL_SIZE (base2))
&& poly_int_tree_p (TYPE_SIZE (TREE_TYPE (ptrtype1)))
/* ??? This in turn may run afoul when a decl of type T which is
a member of union type U is accessed through a pointer to a member of union type U is accessed through a pointer to
type U and sizeof T is smaller than sizeof U. */ type U and sizeof T is smaller than sizeof U. */
&& TREE_CODE (TREE_TYPE (ptrtype1)) != UNION_TYPE TREE_CODE (TREE_TYPE (ptrtype1)) != UNION_TYPE
&& TREE_CODE (TREE_TYPE (ptrtype1)) != QUAL_UNION_TYPE && TREE_CODE (TREE_TYPE (ptrtype1)) != QUAL_UNION_TYPE
&& known_lt (wi::to_poly_widest (DECL_SIZE (base2)), && compare_sizes (DECL_SIZE (base2),
wi::to_poly_widest (TYPE_SIZE (TREE_TYPE (ptrtype1))))) TYPE_SIZE (TREE_TYPE (ptrtype1))) < 0)
return false; return false;
if (!ref2) if (!ref2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment