aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-05-25 15:20:36 +0000
committerRichard Guenther <rguenther@suse.de>2011-05-25 15:20:36 +0000
commit513ad7e0447dccc798c10f83b51bd691bf7c272c (patch)
tree686d21ac2371d5fa3c2b17b35fa4fe12d40b057c /gcc/tree-ssa-alias.c
parenta19a42628773fd517fbb0713046d5da045e1edf3 (diff)
2011-05-25 Richard Guenther <rguenther@suse.de>
* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Fix type-based offset disambiguation, streamline MEM_REF and TARGET_MEM_REF handling. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@174206 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ba76ae10ab1..3656b396d86 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -718,8 +718,9 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
alias_set_type base2_alias_set, bool tbaa_p)
{
tree ptr1;
- tree ptrtype1;
+ tree ptrtype1, dbase2;
HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
+ HOST_WIDE_INT doffset1, doffset2;
double_int moff;
gcc_checking_assert ((TREE_CODE (base1) == MEM_REF
@@ -766,20 +767,6 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
if (base2_alias_set == -1)
base2_alias_set = get_alias_set (base2);
- /* If both references are through the same type, they do not alias
- if the accesses do not overlap. This does extra disambiguation
- for mixed/pointer accesses but requires strict aliasing.
- For MEM_REFs we require that the component-ref offset we computed
- is relative to the start of the type which we ensure by
- comparing rvalue and access type and disregarding the constant
- pointer offset. */
- if ((TREE_CODE (base1) != TARGET_MEM_REF
- || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
- && (TREE_CODE (base1) != MEM_REF
- || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1)
- && same_type_for_tbaa (TREE_TYPE (ptrtype1), TREE_TYPE (base2)) == 1)
- return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
-
/* When we are trying to disambiguate an access with a pointer dereference
as base versus one with a decl as base we can use both the size
of the decl and its dynamic type for extra disambiguation.
@@ -809,13 +796,51 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
&& tree_int_cst_lt (DECL_SIZE (base2), TYPE_SIZE (TREE_TYPE (ptrtype1))))
return false;
+ if (!ref2)
+ return true;
+
+ /* If the decl is accressed via a MEM_REF, reconstruct the base
+ we can use for TBAA and an appropriately adjusted offset. */
+ dbase2 = ref2;
+ while (handled_component_p (dbase2))
+ dbase2 = TREE_OPERAND (dbase2, 0);
+ doffset1 = offset1;
+ doffset2 = offset2;
+ if (TREE_CODE (dbase2) == MEM_REF
+ || TREE_CODE (dbase2) == TARGET_MEM_REF)
+ {
+ double_int moff = mem_ref_offset (dbase2);
+ moff = double_int_lshift (moff,
+ BITS_PER_UNIT == 8
+ ? 3 : exact_log2 (BITS_PER_UNIT),
+ HOST_BITS_PER_DOUBLE_INT, true);
+ if (double_int_negative_p (moff))
+ doffset1 -= double_int_neg (moff).low;
+ else
+ doffset2 -= moff.low;
+ }
+
+ /* If either reference is view-converted, give up now. */
+ if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1
+ || same_type_for_tbaa (TREE_TYPE (dbase2),
+ TREE_TYPE (reference_alias_ptr_type (dbase2))) != 1)
+ return true;
+
+ /* If both references are through the same type, they do not alias
+ if the accesses do not overlap. This does extra disambiguation
+ for mixed/pointer accesses but requires strict aliasing.
+ For MEM_REFs we require that the component-ref offset we computed
+ is relative to the start of the type which we ensure by
+ comparing rvalue and access type and disregarding the constant
+ pointer offset. */
+ if ((TREE_CODE (base1) != TARGET_MEM_REF
+ || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
+ && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1)
+ return ranges_overlap_p (doffset1, max_size1, doffset2, max_size2);
+
/* Do access-path based disambiguation. */
if (ref1 && ref2
- && handled_component_p (ref1)
- && handled_component_p (ref2)
- && TREE_CODE (base1) != TARGET_MEM_REF
- && (TREE_CODE (base1) != MEM_REF
- || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1))
+ && (handled_component_p (ref1) || handled_component_p (ref2)))
return aliasing_component_refs_p (ref1,
ref1_alias_set, base1_alias_set,
offset1, max_size1,