aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
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 afd5e08..42335b5 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;