aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-10-14 15:51:15 +0000
committerRichard Guenther <rguenther@suse.de>2010-10-14 15:51:15 +0000
commita7f42aa2aa44fa487fb440b2f238db25d75f093f (patch)
tree136f40349648fdc45c3adcb47ada09856e717076 /gcc/tree-ssa-alias.c
parent8da6faafc76db52bfa9fdfc7336f170e7eb2c1cb (diff)
2010-10-14 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44913 * tree-data-ref.c (disjoint_objects_p): Remove. (dr_may_alias_p): Simplify. Only hand the base object to the alias-oracle. * tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Handle some more trees, bail out instead of asserting. (ptr_derefs_may_alias_p): Likewise. Export. (refs_may_alias_p_1): Handle STRING_CSTs. * tree-ssa-alias.h (ptr_derefs_may_alias_p): Declare. * gcc.dg/torture/pr44913.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@165473 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c92
1 files changed, 66 insertions, 26 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index afd5e0852cc..42335b577a5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -166,17 +166,31 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl)
{
struct ptr_info_def *pi;
- gcc_assert ((TREE_CODE (ptr) == SSA_NAME
- || TREE_CODE (ptr) == ADDR_EXPR
- || TREE_CODE (ptr) == INTEGER_CST)
- && (TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == PARM_DECL
- || TREE_CODE (decl) == RESULT_DECL));
-
- /* Non-aliased variables can not be pointed to. */
- if (!may_be_aliased (decl))
+ /* Conversions are irrelevant for points-to information and
+ data-dependence analysis can feed us those. */
+ STRIP_NOPS (ptr);
+
+ /* Anything we do not explicilty handle aliases. */
+ if ((TREE_CODE (ptr) != SSA_NAME
+ && TREE_CODE (ptr) != ADDR_EXPR
+ && TREE_CODE (ptr) != POINTER_PLUS_EXPR)
+ || !POINTER_TYPE_P (TREE_TYPE (ptr))
+ || (TREE_CODE (decl) != VAR_DECL
+ && TREE_CODE (decl) != PARM_DECL
+ && TREE_CODE (decl) != RESULT_DECL))
return false;
+ /* Disregard pointer offsetting. */
+ if (TREE_CODE (ptr) == POINTER_PLUS_EXPR)
+ {
+ do
+ {
+ ptr = TREE_OPERAND (ptr, 0);
+ }
+ while (TREE_CODE (ptr) == POINTER_PLUS_EXPR);
+ return ptr_deref_may_alias_decl_p (ptr, decl);
+ }
+
/* ADDR_EXPR pointers either just offset another pointer or directly
specify the pointed-to set. */
if (TREE_CODE (ptr) == ADDR_EXPR)
@@ -196,10 +210,9 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl)
return true;
}
- /* We can end up with dereferencing constant pointers.
- Just bail out in this case. */
- if (TREE_CODE (ptr) == INTEGER_CST)
- return true;
+ /* Non-aliased variables can not be pointed to. */
+ if (!may_be_aliased (decl))
+ return false;
/* If we do not have useful points-to information for this pointer
we cannot disambiguate anything else. */
@@ -222,17 +235,46 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl)
The caller is responsible for applying TBAA to see if accesses
through PTR1 and PTR2 may conflict at all. */
-static bool
+bool
ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
{
struct ptr_info_def *pi1, *pi2;
- gcc_assert ((TREE_CODE (ptr1) == SSA_NAME
- || TREE_CODE (ptr1) == ADDR_EXPR
- || TREE_CODE (ptr1) == INTEGER_CST)
- && (TREE_CODE (ptr2) == SSA_NAME
- || TREE_CODE (ptr2) == ADDR_EXPR
- || TREE_CODE (ptr2) == INTEGER_CST));
+ /* Conversions are irrelevant for points-to information and
+ data-dependence analysis can feed us those. */
+ STRIP_NOPS (ptr1);
+ STRIP_NOPS (ptr2);
+
+ /* Anything we do not explicilty handle aliases. */
+ if ((TREE_CODE (ptr1) != SSA_NAME
+ && TREE_CODE (ptr1) != ADDR_EXPR
+ && TREE_CODE (ptr1) != POINTER_PLUS_EXPR)
+ || (TREE_CODE (ptr2) != SSA_NAME
+ && TREE_CODE (ptr2) != ADDR_EXPR
+ && TREE_CODE (ptr2) != POINTER_PLUS_EXPR)
+ || !POINTER_TYPE_P (TREE_TYPE (ptr1))
+ || !POINTER_TYPE_P (TREE_TYPE (ptr2)))
+ return true;
+
+ /* Disregard pointer offsetting. */
+ if (TREE_CODE (ptr1) == POINTER_PLUS_EXPR)
+ {
+ do
+ {
+ ptr1 = TREE_OPERAND (ptr1, 0);
+ }
+ while (TREE_CODE (ptr1) == POINTER_PLUS_EXPR);
+ return ptr_derefs_may_alias_p (ptr1, ptr2);
+ }
+ if (TREE_CODE (ptr2) == POINTER_PLUS_EXPR)
+ {
+ do
+ {
+ ptr2 = TREE_OPERAND (ptr2, 0);
+ }
+ while (TREE_CODE (ptr2) == POINTER_PLUS_EXPR);
+ return ptr_derefs_may_alias_p (ptr1, ptr2);
+ }
/* ADDR_EXPR pointers either just offset another pointer or directly
specify the pointed-to set. */
@@ -263,12 +305,6 @@ ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
return true;
}
- /* We can end up with dereferencing constant pointers.
- Just bail out in this case. */
- if (TREE_CODE (ptr1) == INTEGER_CST
- || TREE_CODE (ptr2) == INTEGER_CST)
- return true;
-
/* We may end up with two empty points-to solutions for two same pointers.
In this case we still want to say both pointers alias, so shortcut
that here. */
@@ -938,6 +974,7 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
gcc_checking_assert ((!ref1->ref
|| TREE_CODE (ref1->ref) == SSA_NAME
|| DECL_P (ref1->ref)
+ || TREE_CODE (ref1->ref) == STRING_CST
|| handled_component_p (ref1->ref)
|| INDIRECT_REF_P (ref1->ref)
|| TREE_CODE (ref1->ref) == MEM_REF
@@ -945,6 +982,7 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
&& (!ref2->ref
|| TREE_CODE (ref2->ref) == SSA_NAME
|| DECL_P (ref2->ref)
+ || TREE_CODE (ref2->ref) == STRING_CST
|| handled_component_p (ref2->ref)
|| INDIRECT_REF_P (ref2->ref)
|| TREE_CODE (ref2->ref) == MEM_REF
@@ -965,6 +1003,8 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
|| TREE_CODE (base2) == SSA_NAME
|| TREE_CODE (base1) == CONST_DECL
|| TREE_CODE (base2) == CONST_DECL
+ || TREE_CODE (base1) == STRING_CST
+ || TREE_CODE (base2) == STRING_CST
|| is_gimple_min_invariant (base1)
|| is_gimple_min_invariant (base2))
return false;