diff options
author | Richard Guenther <rguenther@suse.de> | 2011-05-25 15:20:36 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-05-25 15:20:36 +0000 |
commit | 29f8b8449c6aafc8e6633871fd8783d61d5dcb04 (patch) | |
tree | 686d21ac2371d5fa3c2b17b35fa4fe12d40b057c | |
parent | b60f3408700c850bec15b0735f3955213b384b8a (diff) | |
download | gcc-29f8b8449c6aafc8e6633871fd8783d61d5dcb04.zip gcc-29f8b8449c6aafc8e6633871fd8783d61d5dcb04.tar.gz gcc-29f8b8449c6aafc8e6633871fd8783d61d5dcb04.tar.bz2 |
tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Fix type-based offset disambiguation...
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.
From-SVN: r174206
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 65 |
2 files changed, 51 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aee6a13..a22c5d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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. + 2011-05-25 H.J. Lu <hongjiu.lu@intel.com> * config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_PAUSE. diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index ba76ae1..3656b39 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, |