OSDN Git Service

* gcc.target/i386/align-main-1.c (check): Mark noinline.
[pf3gnuchains/gcc-fork.git] / gcc / alias.c
index d8d8e3f..794df75 100644 (file)
@@ -1,6 +1,6 @@
 /* Alias analysis for GNU C
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2007 Free Software Foundation, Inc.
+   2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by John Carr (jfc@mit.edu).
 
 This file is part of GCC.
@@ -128,8 +128,7 @@ along with GCC; see the file COPYING3.  If not see
    However, this is no actual entry for alias set zero.  It is an
    error to attempt to explicitly construct a subset of zero.  */
 
-struct alias_set_entry GTY(())
-{
+struct GTY(()) alias_set_entry {
   /* The alias set number, as stored in MEM_ALIAS_SET.  */
   alias_set_type alias_set;
 
@@ -436,6 +435,9 @@ find_base_decl (tree t)
   if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t)))
     return 0;
 
+  if (TREE_CODE (t) == SSA_NAME)
+    t = SSA_NAME_VAR (t);
+
   /* If this is a declaration, return it.  If T is based on a restrict
      qualified decl, return that decl.  */
   if (DECL_P (t))
@@ -518,6 +520,98 @@ component_uses_parent_alias_set (const_tree 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.  */
+
+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;
+
+  if (! TYPE_P (t))
+    {
+      tree decl = find_base_decl (t);
+
+      if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
+       {
+         /* If we haven't computed the actual alias set, do it now.  */
+         if (DECL_POINTER_ALIAS_SET (decl) == -2)
+           {
+             tree pointed_to_type = TREE_TYPE (TREE_TYPE (decl));
+
+             /* No two restricted pointers can point at the same thing.
+                However, a restricted pointer can point at the same thing
+                as an unrestricted pointer, if that unrestricted pointer
+                is based on the restricted pointer.  So, we make the
+                alias set for the restricted pointer a subset of the
+                alias set for the type pointed to by the type of the
+                decl.  */
+             alias_set_type pointed_to_alias_set
+                 = get_alias_set (pointed_to_type);
+
+             if (pointed_to_alias_set == 0)
+               /* It's not legal to make a subset of alias set zero.  */
+               DECL_POINTER_ALIAS_SET (decl) = 0;
+             else if (AGGREGATE_TYPE_P (pointed_to_type))
+               /* For an aggregate, we must treat the restricted
+                  pointer the same as an ordinary pointer.  If we
+                  were to make the type pointed to by the
+                  restricted pointer a subset of the pointed-to
+                  type, then we would believe that other subsets
+                  of the pointed-to type (such as fields of that
+                  type) do not conflict with the type pointed to
+                  by the restricted pointer.  */
+               DECL_POINTER_ALIAS_SET (decl)
+                   = pointed_to_alias_set;
+             else
+               {
+                 DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
+                 record_alias_subset (pointed_to_alias_set,
+                                      DECL_POINTER_ALIAS_SET (decl));
+               }
+           }
+
+         /* We use the alias set indicated in the declaration.  */
+         return DECL_POINTER_ALIAS_SET (decl);
+       }
+
+      /* Now all we care about is the type.  */
+      t = TREE_TYPE (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))
+    return 0;
+
+  return -1;
+}
+
+/* Return the alias set for the memory pointed to by T, which may be
+   either a type or an expression.  */
+
+alias_set_type
+get_deref_alias_set (tree t)
+{
+  alias_set_type set = get_deref_alias_set_1 (t);
+
+  /* Fall back to the alias-set of the pointed-to type.  */
+  if (set == -1)
+    {
+      if (! TYPE_P (t))
+       t = TREE_TYPE (t);
+      set = get_alias_set (TREE_TYPE (t));
+    }
+
+  return set;
+}
+
 /* Return the alias set for T, which may be either a type or an
    expression.  Call language-specific routine for help, if needed.  */
 
@@ -558,66 +652,11 @@ get_alias_set (tree t)
          STRIP_NOPS (inner);
        }
 
-      /* Check for accesses through restrict-qualified pointers.  */
       if (INDIRECT_REF_P (inner))
        {
-         tree decl;
-
-         if (TREE_CODE (TREE_OPERAND (inner, 0)) == SSA_NAME)
-           decl = SSA_NAME_VAR (TREE_OPERAND (inner, 0));
-         else
-           decl = find_base_decl (TREE_OPERAND (inner, 0));
-
-         if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
-           {
-             /* If we haven't computed the actual alias set, do it now.  */
-             if (DECL_POINTER_ALIAS_SET (decl) == -2)
-               {
-                 tree pointed_to_type = TREE_TYPE (TREE_TYPE (decl));
-
-                 /* No two restricted pointers can point at the same thing.
-                    However, a restricted pointer can point at the same thing
-                    as an unrestricted pointer, if that unrestricted pointer
-                    is based on the restricted pointer.  So, we make the
-                    alias set for the restricted pointer a subset of the
-                    alias set for the type pointed to by the type of the
-                    decl.  */
-                 alias_set_type pointed_to_alias_set
-                   = get_alias_set (pointed_to_type);
-
-                 if (pointed_to_alias_set == 0)
-                   /* It's not legal to make a subset of alias set zero.  */
-                   DECL_POINTER_ALIAS_SET (decl) = 0;
-                 else if (AGGREGATE_TYPE_P (pointed_to_type))
-                   /* For an aggregate, we must treat the restricted
-                      pointer the same as an ordinary pointer.  If we
-                      were to make the type pointed to by the
-                      restricted pointer a subset of the pointed-to
-                      type, then we would believe that other subsets
-                      of the pointed-to type (such as fields of that
-                      type) do not conflict with the type pointed to
-                      by the restricted pointer.  */
-                   DECL_POINTER_ALIAS_SET (decl)
-                     = pointed_to_alias_set;
-                 else
-                   {
-                     DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
-                     record_alias_subset (pointed_to_alias_set,
-                                          DECL_POINTER_ALIAS_SET (decl));
-                   }
-               }
-
-             /* We use the alias set indicated in the declaration.  */
-             return DECL_POINTER_ALIAS_SET (decl);
-           }
-
-         /* 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.  */
-         else if (TREE_CODE (TREE_TYPE (inner)) == VOID_TYPE
-                  || (TYPE_REF_CAN_ALIAS_ALL
-                      (TREE_TYPE (TREE_OPERAND (inner, 0)))))
-           return 0;
+         set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0));
+         if (set != -1)
+           return set;
        }
 
       /* Otherwise, pick up the outermost object that we could have a pointer
@@ -1438,15 +1477,16 @@ find_base_term (rtx x)
          return x;
       return 0;
 
+    case LO_SUM:
+      /* The standard form is (lo_sum reg sym) so look only at the
+         second operand.  */
+      return find_base_term (XEXP (x, 1));
+
     case CONST:
       x = XEXP (x, 0);
       if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
        return 0;
       /* Fall through.  */
-    case LO_SUM:
-      /* The standard form is (lo_sum reg sym) so look only at the
-         second operand.  */
-      return find_base_term (XEXP (x, 1));
     case PLUS:
     case MINUS:
       {
@@ -2250,14 +2290,13 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
    Variant of true_dependence which assumes MEM has already been
    canonicalized (hence we no longer do that here).
    The mem_addr argument has been added, since true_dependence computed
-   this value prior to canonicalizing.  */
+   this value prior to canonicalizing.
+   If x_addr is non-NULL, it is used in preference of XEXP (x, 0).  */
 
 int
 canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
-                      const_rtx x, bool (*varies) (const_rtx, bool))
+                      const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool))
 {
-  rtx x_addr;
-
   if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
     return 1;
 
@@ -2283,7 +2322,8 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
   if (nonoverlapping_memrefs_p (x, mem))
     return 0;
 
-  x_addr = get_addr (XEXP (x, 0));
+  if (! x_addr)
+    x_addr = get_addr (XEXP (x, 0));
 
   if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
     return 0;