From bd93e4f84bf2fe3913990b1a3e706ee8a8529eda Mon Sep 17 00:00:00 2001 From: rguenth Date: Tue, 24 Sep 2013 11:04:04 +0000 Subject: [PATCH] 2013-09-24 Richard Biener PR middle-end/58513 * tree.c (reference_alias_ptr_type): Move ... * alias.c (reference_alias_ptr_type): ... here and implement in terms of the new reference_alias_ptr_type_1. (ref_all_alias_ptr_type_p): New helper. (get_deref_alias_set_1): Drop flag_strict_aliasing here, use ref_all_alias_ptr_type_p. (get_deref_alias_set): Add flag_strict_aliasing check here. (reference_alias_ptr_type_1): New function, split out from ... (get_alias_set): ... here. (alias_ptr_types_compatible_p): New function. * alias.h (reference_alias_ptr_type): Declare. (alias_ptr_types_compatible_p): Likewise. * tree.h (reference_alias_ptr_type): Remove. * fold-const.c (operand_equal_p): Use alias_ptr_types_compatible_p to compare MEM_REF alias types. * g++.dg/vect/pr58513.cc: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202865 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 ++++ gcc/alias.c | 172 ++++++++++++++++++++++++----------- gcc/alias.h | 2 + gcc/fold-const.c | 5 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/vect/pr58513.cc | 13 +++ gcc/tree.c | 18 ---- gcc/tree.h | 1 - 8 files changed, 160 insertions(+), 75 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/pr58513.cc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7fd7409..72bca64 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,24 @@ 2013-09-24 Richard Biener + PR middle-end/58513 + * tree.c (reference_alias_ptr_type): Move ... + * alias.c (reference_alias_ptr_type): ... here and implement + in terms of the new reference_alias_ptr_type_1. + (ref_all_alias_ptr_type_p): New helper. + (get_deref_alias_set_1): Drop flag_strict_aliasing here, + use ref_all_alias_ptr_type_p. + (get_deref_alias_set): Add flag_strict_aliasing check here. + (reference_alias_ptr_type_1): New function, split out from ... + (get_alias_set): ... here. + (alias_ptr_types_compatible_p): New function. + * alias.h (reference_alias_ptr_type): Declare. + (alias_ptr_types_compatible_p): Likewise. + * tree.h (reference_alias_ptr_type): Remove. + * fold-const.c (operand_equal_p): Use alias_ptr_types_compatible_p + to compare MEM_REF alias types. + +2013-09-24 Richard Biener + * tree-vrp.c (vrp_finalize): Check for SSA name presence. 2013-09-23 Michael Meissner diff --git a/gcc/alias.c b/gcc/alias.c index 966e9d2..7d28267 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -547,6 +547,18 @@ component_uses_parent_alias_set (const_tree t) } } + +/* Return whether the pointer-type T effective for aliasing may + access everything and thus the reference has to be assigned + alias-set zero. */ + +static bool +ref_all_alias_ptr_type_p (const_tree t) +{ + return (TREE_CODE (TREE_TYPE (t)) == VOID_TYPE + || TYPE_REF_CAN_ALIAS_ALL (t)); +} + /* Return the alias set for the memory pointed to by T, which may be either a type or an expression. Return -1 if there is nothing special about dereferencing T. */ @@ -554,11 +566,6 @@ component_uses_parent_alias_set (const_tree t) static alias_set_type get_deref_alias_set_1 (tree t) { - /* If we're not doing any alias analysis, just assume everything - aliases everything else. */ - if (!flag_strict_aliasing) - return 0; - /* All we care about is the type. */ if (! TYPE_P (t)) t = TREE_TYPE (t); @@ -566,8 +573,7 @@ get_deref_alias_set_1 (tree t) /* If we have an INDIRECT_REF via a void pointer, we don't know anything about what that might alias. Likewise if the pointer is marked that way. */ - if (TREE_CODE (TREE_TYPE (t)) == VOID_TYPE - || TYPE_REF_CAN_ALIAS_ALL (t)) + if (ref_all_alias_ptr_type_p (t)) return 0; return -1; @@ -579,6 +585,11 @@ get_deref_alias_set_1 (tree t) alias_set_type get_deref_alias_set (tree t) { + /* If we're not doing any alias analysis, just assume everything + aliases everything else. */ + if (!flag_strict_aliasing) + return 0; + alias_set_type set = get_deref_alias_set_1 (t); /* Fall back to the alias-set of the pointed-to type. */ @@ -592,6 +603,101 @@ get_deref_alias_set (tree t) return set; } +/* Return the pointer-type relevant for TBAA purposes from the + memory reference tree *T or NULL_TREE in which case *T is + adjusted to point to the outermost component reference that + can be used for assigning an alias set. */ + +static tree +reference_alias_ptr_type_1 (tree *t) +{ + tree inner; + + /* Get the base object of the reference. */ + inner = *t; + while (handled_component_p (inner)) + { + /* If there is a VIEW_CONVERT_EXPR in the chain we cannot use + the type of any component references that wrap it to + determine the alias-set. */ + if (TREE_CODE (inner) == VIEW_CONVERT_EXPR) + *t = TREE_OPERAND (inner, 0); + inner = TREE_OPERAND (inner, 0); + } + + /* Handle pointer dereferences here, they can override the + alias-set. */ + if (INDIRECT_REF_P (inner) + && ref_all_alias_ptr_type_p (TREE_TYPE (TREE_OPERAND (inner, 0)))) + return TREE_TYPE (TREE_OPERAND (inner, 0)); + else if (TREE_CODE (inner) == TARGET_MEM_REF) + return TREE_TYPE (TMR_OFFSET (inner)); + else if (TREE_CODE (inner) == MEM_REF + && ref_all_alias_ptr_type_p (TREE_TYPE (TREE_OPERAND (inner, 1)))) + return TREE_TYPE (TREE_OPERAND (inner, 1)); + + /* If the innermost reference is a MEM_REF that has a + conversion embedded treat it like a VIEW_CONVERT_EXPR above, + using the memory access type for determining the alias-set. */ + if (TREE_CODE (inner) == MEM_REF + && (TYPE_MAIN_VARIANT (TREE_TYPE (inner)) + != TYPE_MAIN_VARIANT + (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1)))))) + return TREE_TYPE (TREE_OPERAND (inner, 1)); + + /* Otherwise, pick up the outermost object that we could have a pointer + to, processing conversions as above. */ + /* ??? Ick, this is worse than quadratic! */ + while (component_uses_parent_alias_set (*t)) + { + *t = TREE_OPERAND (*t, 0); + STRIP_NOPS (*t); + } + + return NULL_TREE; +} + +/* Return the pointer-type relevant for TBAA purposes from the + gimple memory reference tree T. This is the type to be used for + the offset operand of MEM_REF or TARGET_MEM_REF replacements of T + and guarantees that get_alias_set will return the same alias + set for T and the replacement. */ + +tree +reference_alias_ptr_type (tree t) +{ + tree ptype = reference_alias_ptr_type_1 (&t); + /* If there is a given pointer type for aliasing purposes, return it. */ + if (ptype != NULL_TREE) + return ptype; + + /* Otherwise build one from the outermost component reference we + may use. */ + if (TREE_CODE (t) == MEM_REF + || TREE_CODE (t) == TARGET_MEM_REF) + return TREE_TYPE (TREE_OPERAND (t, 1)); + else + return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (t))); +} + +/* Return whether the pointer-types T1 and T2 used to determine + two alias sets of two references will yield the same answer + from get_deref_alias_set. */ + +bool +alias_ptr_types_compatible_p (tree t1, tree t2) +{ + if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) + return true; + + if (ref_all_alias_ptr_type_p (t1) + || ref_all_alias_ptr_type_p (t2)) + return false; + + return (TYPE_MAIN_VARIANT (TREE_TYPE (t1)) + == TYPE_MAIN_VARIANT (TREE_TYPE (t2))); +} + /* Return the alias set for T, which may be either a type or an expression. Call language-specific routine for help, if needed. */ @@ -615,8 +721,6 @@ get_alias_set (tree t) aren't types. */ if (! TYPE_P (t)) { - tree inner; - /* Give the language a chance to do something with this tree before we look at it. */ STRIP_NOPS (t); @@ -624,51 +728,11 @@ get_alias_set (tree t) if (set != -1) return set; - /* Get the base object of the reference. */ - inner = t; - while (handled_component_p (inner)) - { - /* If there is a VIEW_CONVERT_EXPR in the chain we cannot use - the type of any component references that wrap it to - determine the alias-set. */ - if (TREE_CODE (inner) == VIEW_CONVERT_EXPR) - t = TREE_OPERAND (inner, 0); - inner = TREE_OPERAND (inner, 0); - } - - /* 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) == TARGET_MEM_REF) - return get_deref_alias_set (TMR_OFFSET (inner)); - 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, - using the memory access type for determining the alias-set. */ - if (TREE_CODE (inner) == MEM_REF - && TYPE_MAIN_VARIANT (TREE_TYPE (inner)) - != TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1))))) - return get_deref_alias_set (TREE_OPERAND (inner, 1)); - - /* Otherwise, pick up the outermost object that we could have a pointer - to, processing conversions as above. */ - while (component_uses_parent_alias_set (t)) - { - t = TREE_OPERAND (t, 0); - STRIP_NOPS (t); - } + /* Get the alias pointer-type to use or the outermost object + that we could have a pointer to. */ + tree ptype = reference_alias_ptr_type_1 (&t); + if (ptype != NULL) + return get_deref_alias_set (ptype); /* If we've already determined the alias set for a decl, just return it. This is necessary for C++ anonymous unions, whose component diff --git a/gcc/alias.h b/gcc/alias.h index af739a8..dd4b641 100644 --- a/gcc/alias.h +++ b/gcc/alias.h @@ -41,6 +41,8 @@ extern int alias_sets_conflict_p (alias_set_type, alias_set_type); extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type); extern int objects_must_conflict_p (tree, tree); extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool); +tree reference_alias_ptr_type (tree); +bool alias_ptr_types_compatible_p (tree, tree); /* This alias set can be used to force a memory to conflict with all other memories, creating a barrier across which no memory reference diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d23c173..d435b54 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2693,8 +2693,9 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) && operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)), TYPE_SIZE (TREE_TYPE (arg1)), flags))) && types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)) - && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg0, 1))) - == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg1, 1)))) + && alias_ptr_types_compatible_p + (TREE_TYPE (TREE_OPERAND (arg0, 1)), + TREE_TYPE (TREE_OPERAND (arg1, 1))) && OP_SAME (0) && OP_SAME (1)); case ARRAY_REF: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 18e16f0..6443e3e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-09-24 Richard Biener + + PR middle-end/58513 + * g++.dg/vect/pr58513.cc: New testcase. + 2013-09-24 Yvan Roux * gcc.target/arm/atomic-comp-swap-release-acquire.c: Adjust expected diff --git a/gcc/testsuite/g++.dg/vect/pr58513.cc b/gcc/testsuite/g++.dg/vect/pr58513.cc new file mode 100644 index 0000000..2563047 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr58513.cc @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-require-effective-target vect_int } + +int op (const int& x, const int& y) { return x + y; } + +void foo(int* a) +{ + for (int i = 0; i < 1000; ++i) + a[i] = op(a[i], 1); +} + +// { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } +// { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/tree.c b/gcc/tree.c index 6593cf8..a7b66c5 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4263,24 +4263,6 @@ mem_ref_offset (const_tree t) return tree_to_double_int (toff).sext (TYPE_PRECISION (TREE_TYPE (toff))); } -/* Return the pointer-type relevant for TBAA purposes from the - gimple memory reference tree T. This is the type to be used for - the offset operand of MEM_REF or TARGET_MEM_REF replacements of T. */ - -tree -reference_alias_ptr_type (const_tree t) -{ - const_tree base = t; - while (handled_component_p (base)) - base = TREE_OPERAND (base, 0); - if (TREE_CODE (base) == MEM_REF) - return TREE_TYPE (TREE_OPERAND (base, 1)); - else if (TREE_CODE (base) == TARGET_MEM_REF) - return TREE_TYPE (TMR_OFFSET (base)); - else - return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base))); -} - /* Return an invariant ADDR_EXPR of type TYPE taking the address of BASE offsetted by OFFSET units. */ diff --git a/gcc/tree.h b/gcc/tree.h index d68b284..b1d168b 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4345,7 +4345,6 @@ extern tree build_simple_mem_ref_loc (location_t, tree); #define build_simple_mem_ref(T)\ build_simple_mem_ref_loc (UNKNOWN_LOCATION, T) extern double_int mem_ref_offset (const_tree); -extern tree reference_alias_ptr_type (const_tree); extern tree build_invariant_address (tree, tree, HOST_WIDE_INT); extern tree constant_boolean_node (bool, tree); extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree); -- 2.7.4