summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-02 11:58:27 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-02 11:58:27 +0000
commitf85fb8196d7727fb5c14a7fa86dd7ab7768b5812 (patch)
tree8abc37f10cdf2132775fb5ee7b794240831fd6ec
parent4ebafe4966ff659ebc423d7b50bfd4ec5066db15 (diff)
downloadppe42-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/ChangeLog12
-rw-r--r--gcc/builtins.c58
-rw-r--r--gcc/tree-ssa-alias.c30
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
OpenPOWER on IntegriCloud