2013-09-24 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Sep 2013 11:04:04 +0000 (11:04 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Sep 2013 11:04:04 +0000 (11:04 +0000)
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
gcc/alias.c
gcc/alias.h
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/pr58513.cc [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index 7fd7409..72bca64 100644 (file)
@@ -1,5 +1,24 @@
 2013-09-24  Richard Biener  <rguenther@suse.de>
 
+       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  <rguenther@suse.de>
+
        * tree-vrp.c (vrp_finalize): Check for SSA name presence.
 
 2013-09-23  Michael Meissner  <meissner@linux.vnet.ibm.com>
index 966e9d2..7d28267 100644 (file)
@@ -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
index af739a8..dd4b641 100644 (file)
@@ -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
index d23c173..d435b54 100644 (file)
@@ -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:
index 18e16f0..6443e3e 100644 (file)
@@ -1,3 +1,8 @@
+2013-09-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/58513
+       * g++.dg/vect/pr58513.cc: New testcase.
+
 2013-09-24  Yvan Roux  <yvan.roux@linaro.org>
 
        * 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 (file)
index 0000000..2563047
--- /dev/null
@@ -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" } }
index 6593cf8..a7b66c5 100644 (file)
@@ -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.  */
 
index d68b284..b1d168b 100644 (file)
@@ -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);