diff options
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 92 |
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; |