diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-02 11:58:27 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-02 11:58:27 +0000 |
commit | f85fb8196d7727fb5c14a7fa86dd7ab7768b5812 (patch) | |
tree | 8abc37f10cdf2132775fb5ee7b794240831fd6ec | |
parent | 4ebafe4966ff659ebc423d7b50bfd4ec5066db15 (diff) | |
download | ppe42-gcc-f85fb8196d7727fb5c14a7fa86dd7ab7768b5812.tar.gz ppe42-gcc-f85fb8196d7727fb5c14a7fa86dd7ab7768b5812.zip |
2009-09-02 Richard Guenther <rguenther@suse.de>
Revert
2009-08-31 Richard Guenther <rguenther@suse.de>
* builtins.c (fold_builtin_memory_op): Use the alias oracle
to query if the memory regions for memmove overlap.
* tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Relax the
asserts on pointers, instead deal with odd trees.
(ptr_derefs_may_alias_p): Likewise.
(refs_may_alias_p_1): Constructor bases also never alias.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151320 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/builtins.c | 58 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 30 |
3 files changed, 82 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e369e31b10..a35edee60a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-09-02 Richard Guenther <rguenther@suse.de> + + Revert + 2009-08-31 Richard Guenther <rguenther@suse.de> + + * builtins.c (fold_builtin_memory_op): Use the alias oracle + to query if the memory regions for memmove overlap. + * tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Relax the + asserts on pointers, instead deal with odd trees. + (ptr_derefs_may_alias_p): Likewise. + (refs_may_alias_p_1): Constructor bases also never alias. + 2009-08-01 Christian Bruel <christian.bruel@st.com> Revert: diff --git a/gcc/builtins.c b/gcc/builtins.c index 7ea899d19ba..b657275720e 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8990,8 +8990,6 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, if (endp == 3) { - ao_ref srcref, destref; - src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); @@ -9014,16 +9012,62 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, } /* If *src and *dest can't overlap, optimize into memcpy as well. */ - ao_ref_init_from_ptr_and_size (&srcref, src, len); - ao_ref_init_from_ptr_and_size (&destref, dest, len); - if (!refs_may_alias_p_1 (&srcref, &destref, false)) + srcvar = build_fold_indirect_ref_loc (loc, src); + destvar = build_fold_indirect_ref_loc (loc, dest); + if (srcvar + && !TREE_THIS_VOLATILE (srcvar) + && destvar + && !TREE_THIS_VOLATILE (destvar)) { - tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; + tree src_base, dest_base, fn; + HOST_WIDE_INT src_offset = 0, dest_offset = 0; + HOST_WIDE_INT size = -1; + HOST_WIDE_INT maxsize = -1; + + src_base = srcvar; + if (handled_component_p (src_base)) + src_base = get_ref_base_and_extent (src_base, &src_offset, + &size, &maxsize); + dest_base = destvar; + if (handled_component_p (dest_base)) + dest_base = get_ref_base_and_extent (dest_base, &dest_offset, + &size, &maxsize); + if (host_integerp (len, 1)) + { + maxsize = tree_low_cst (len, 1); + if (maxsize + > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT) + maxsize = -1; + else + maxsize *= BITS_PER_UNIT; + } + else + maxsize = -1; + if (SSA_VAR_P (src_base) + && SSA_VAR_P (dest_base)) + { + if (operand_equal_p (src_base, dest_base, 0) + && ranges_overlap_p (src_offset, maxsize, + dest_offset, maxsize)) + return NULL_TREE; + } + else if (TREE_CODE (src_base) == INDIRECT_REF + && TREE_CODE (dest_base) == INDIRECT_REF) + { + if (! operand_equal_p (TREE_OPERAND (src_base, 0), + TREE_OPERAND (dest_base, 0), 0) + || ranges_overlap_p (src_offset, maxsize, + dest_offset, maxsize)) + return NULL_TREE; + } + else + return NULL_TREE; + + fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; if (!fn) return NULL_TREE; return build_call_expr_loc (loc, fn, 3, dest, src, len); } - return NULL_TREE; } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 14f1fb47006..7e83a84b82c 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -168,9 +168,12 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl) { struct ptr_info_def *pi; - gcc_assert (TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == RESULT_DECL); + 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)) @@ -194,9 +197,9 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl) return true; } - /* We can end up with dereferencing non-SSA name pointers. + /* We can end up with dereferencing constant pointers. Just bail out in this case. */ - if (TREE_CODE (ptr) != SSA_NAME) + if (TREE_CODE (ptr) == INTEGER_CST) return true; /* If we do not have useful points-to information for this pointer @@ -217,6 +220,13 @@ 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)); + /* ADDR_EXPR pointers either just offset another pointer or directly specify the pointed-to set. */ if (TREE_CODE (ptr1) == ADDR_EXPR) @@ -244,10 +254,10 @@ ptr_derefs_may_alias_p (tree ptr1, tree ptr2) return true; } - /* We can end up with dereferencing non-SSA name pointers. + /* We can end up with dereferencing constant pointers. Just bail out in this case. */ - if (TREE_CODE (ptr1) != SSA_NAME - || TREE_CODE (ptr2) != SSA_NAME) + 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. @@ -771,9 +781,7 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) if (TREE_CODE (base1) == SSA_NAME || TREE_CODE (base2) == SSA_NAME || is_gimple_min_invariant (base1) - || is_gimple_min_invariant (base2) - || TREE_CODE (base1) == CONSTRUCTOR - || TREE_CODE (base2) == CONSTRUCTOR) + || is_gimple_min_invariant (base2)) return false; /* Defer to simple offset based disambiguation if we have |