[PATCH][mem-ref2] Fix some corner-cases wrt TBAA
Richard Guenther
rguenther@suse.de
Mon Jun 21 00:21:00 GMT 2010
This fixes some latent problems.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2010-06-20 Richard Guenther <rguenther@suse.de>
* tree-ssa-alias.c (ao_ref_base_alias_set): Properly differentiate
base object for offset and TBAA.
(indirect_ref_may_alias_decl_p): Add tbaa_p parameter and test it.
(indirect_refs_may_alias_p): Likewise.
(refs_may_alias_p_1): Use ao_ref_base_alias_set for the
pointer-vs-decl case.
* alias.c (ao_ref_from_mem): Do not set base_alias_set here.
(get_alias_set): Split MEM_REF and INDIRECT_REF case again
and fix MEM_REF case.
* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Init
base_alias_set.
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c (revision 161049)
--- gcc/tree-ssa-alias.c (working copy)
*************** ao_ref_base (ao_ref *ref)
*** 474,485 ****
/* Returns the base object alias set of the memory reference *REF. */
! static alias_set_type ATTRIBUTE_UNUSED
ao_ref_base_alias_set (ao_ref *ref)
{
if (ref->base_alias_set != -1)
return ref->base_alias_set;
! ref->base_alias_set = get_alias_set (ao_ref_base (ref));
return ref->base_alias_set;
}
--- 474,491 ----
/* Returns the base object alias set of the memory reference *REF. */
! static alias_set_type
ao_ref_base_alias_set (ao_ref *ref)
{
+ tree base_ref;
if (ref->base_alias_set != -1)
return ref->base_alias_set;
! if (!ref->ref)
! return 0;
! base_ref = ref->ref;
! while (handled_component_p (base_ref))
! base_ref = TREE_OPERAND (base_ref, 0);
! ref->base_alias_set = get_alias_set (base_ref);
return ref->base_alias_set;
}
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 678,684 ****
tree ref2 ATTRIBUTE_UNUSED, tree base2,
HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
alias_set_type ref2_alias_set,
! alias_set_type base2_alias_set)
{
tree ptr1 = TREE_OPERAND (base1, 0);
tree ptrtype1;
--- 684,690 ----
tree ref2 ATTRIBUTE_UNUSED, tree base2,
HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
alias_set_type ref2_alias_set,
! alias_set_type base2_alias_set, bool tbaa_p)
{
tree ptr1 = TREE_OPERAND (base1, 0);
tree ptrtype1;
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 698,704 ****
return false;
/* Disambiguations that rely on strict aliasing rules follow. */
! if (!flag_strict_aliasing)
return true;
if (TREE_CODE (base1) == MEM_REF)
--- 704,710 ----
return false;
/* Disambiguations that rely on strict aliasing rules follow. */
! if (!flag_strict_aliasing || !tbaa_p)
return true;
if (TREE_CODE (base1) == MEM_REF)
*************** indirect_refs_may_alias_p (tree ref1 ATT
*** 763,769 ****
tree ref2 ATTRIBUTE_UNUSED, tree base2,
HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
alias_set_type ref2_alias_set,
! alias_set_type base2_alias_set)
{
tree ptr1 = TREE_OPERAND (base1, 0);
tree ptr2 = TREE_OPERAND (base2, 0);
--- 769,775 ----
tree ref2 ATTRIBUTE_UNUSED, tree base2,
HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
alias_set_type ref2_alias_set,
! alias_set_type base2_alias_set, bool tbaa_p)
{
tree ptr1 = TREE_OPERAND (base1, 0);
tree ptr2 = TREE_OPERAND (base2, 0);
*************** indirect_refs_may_alias_p (tree ref1 ATT
*** 784,790 ****
return false;
/* Disambiguations that rely on strict aliasing rules follow. */
! if (!flag_strict_aliasing)
return true;
if (TREE_CODE (base1) == MEM_REF)
--- 790,796 ----
return false;
/* Disambiguations that rely on strict aliasing rules follow. */
! if (!flag_strict_aliasing || !tbaa_p)
return true;
if (TREE_CODE (base1) == MEM_REF)
*************** refs_may_alias_p_1 (ao_ref *ref1, ao_ref
*** 849,855 ****
HOST_WIDE_INT offset1 = 0, offset2 = 0;
HOST_WIDE_INT max_size1 = -1, max_size2 = -1;
bool var1_p, var2_p, ind1_p, ind2_p;
- alias_set_type set;
gcc_assert ((!ref1->ref
|| SSA_VAR_P (ref1->ref)
--- 855,860 ----
*************** refs_may_alias_p_1 (ao_ref *ref1, ao_ref
*** 935,955 ****
return true;
/* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */
- set = tbaa_p ? -1 : 0;
if (var1_p && ind2_p)
return indirect_ref_may_alias_decl_p (ref2->ref, base2,
offset2, max_size2,
! ao_ref_alias_set (ref2), set,
ref1->ref, base1,
offset1, max_size1,
! ao_ref_alias_set (ref1), set);
else if (ind1_p && ind2_p)
return indirect_refs_may_alias_p (ref1->ref, base1,
offset1, max_size1,
! ao_ref_alias_set (ref1), set,
ref2->ref, base2,
offset2, max_size2,
! ao_ref_alias_set (ref2), set);
gcc_unreachable ();
}
--- 940,962 ----
return true;
/* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */
if (var1_p && ind2_p)
return indirect_ref_may_alias_decl_p (ref2->ref, base2,
offset2, max_size2,
! ao_ref_alias_set (ref2), -1,
ref1->ref, base1,
offset1, max_size1,
! ao_ref_alias_set (ref1),
! ao_ref_base_alias_set (ref1),
! tbaa_p);
else if (ind1_p && ind2_p)
return indirect_refs_may_alias_p (ref1->ref, base1,
offset1, max_size1,
! ao_ref_alias_set (ref1), -1,
ref2->ref, base2,
offset2, max_size2,
! ao_ref_alias_set (ref2), -1,
! tbaa_p);
gcc_unreachable ();
}
Index: gcc/alias.c
===================================================================
*** gcc/alias.c (revision 161049)
--- gcc/alias.c (working copy)
*************** ao_ref_from_mem (ao_ref *ref, const_rtx
*** 294,303 ****
void *namep;
namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
if (namep)
! {
! ref->base_alias_set = get_alias_set (base);
! ref->base = build_simple_mem_ref (*(tree *)namep);
! }
}
ref->ref_alias_set = MEM_ALIAS_SET (mem);
--- 294,300 ----
void *namep;
namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
if (namep)
! ref->base = build_simple_mem_ref (*(tree *)namep);
}
ref->ref_alias_set = MEM_ALIAS_SET (mem);
*************** get_alias_set (tree t)
*** 674,686 ****
/* Handle pointer dereferences here, they can override the
alias-set. */
! if (INDIRECT_REF_P (inner)
! || TREE_CODE (inner) == MEM_REF)
{
set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0));
if (set != -1)
return set;
}
/* If the innermost reference is a MEM_REF that has a
conversion embedded treat it like a VIEW_CONVERT_EXPR above,
--- 671,688 ----
/* Handle pointer dereferences here, they can override the
alias-set. */
! if (INDIRECT_REF_P (inner))
{
set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0));
if (set != -1)
return set;
}
+ else if (TREE_CODE (inner) == MEM_REF)
+ {
+ set = get_deref_alias_set_1 (TREE_OPERAND (inner, 1));
+ if (set != -1)
+ return set;
+ }
/* If the innermost reference is a MEM_REF that has a
conversion embedded treat it like a VIEW_CONVERT_EXPR above,
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c (revision 161049)
+++ gcc/tree-ssa-sccvn.c (working copy)
@@ -889,7 +889,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
ref->size = size;
ref->max_size = max_size;
ref->ref_alias_set = set;
- ref->base_alias_set = -1;
+ ref->base_alias_set = get_alias_set (base);
return true;
}
More information about the Gcc-patches
mailing list