OSDN Git Service

* config/i386/i386.c (override_options): Define c3-2 as a 686 with SSE.
[pf3gnuchains/gcc-fork.git] / gcc / alias.c
index ca560b6..23f4134 100644 (file)
@@ -1,5 +1,6 @@
 /* Alias analysis for GNU C
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
    Contributed by John Carr (jfc@mit.edu).
 
 This file is part of GCC.
@@ -21,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "rtl.h"
 #include "tree.h"
 #include "tm_p.h"
@@ -61,7 +64,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
    To see whether two alias sets can point to the same memory, we must
    see if either alias set is a subset of the other. We need not trace
-   past immediate descendents, however, since we propagate all
+   past immediate descendants, however, since we propagate all
    grandchildren up one level.
 
    Alias set zero is implicitly a superset of all other alias sets.
@@ -74,7 +77,7 @@ typedef struct alias_set_entry
   HOST_WIDE_INT alias_set;
 
   /* The children of the alias set.  These are not just the immediate
-     children, but, in fact, all descendents.  So, if we have:
+     children, but, in fact, all descendants.  So, if we have:
 
        struct T { struct S s; float f; }
 
@@ -116,6 +119,7 @@ static int nonlocal_referenced_p_1      PARAMS ((rtx *, void *));
 static int nonlocal_referenced_p        PARAMS ((rtx));
 static int nonlocal_set_p_1             PARAMS ((rtx *, void *));
 static int nonlocal_set_p               PARAMS ((rtx));
+static void memory_modified_1          PARAMS ((rtx, rtx, void *));
 
 /* Set up all info needed to perform alias analysis on memory references.  */
 
@@ -199,7 +203,7 @@ char *reg_known_equiv_p;
 
 /* True when scanning insns from the start of the rtl to the
    NOTE_INSN_FUNCTION_BEG note.  */
-static int copying_arguments;
+static bool copying_arguments;
 
 /* The splay-tree used to store the various alias set entries.  */
 static splay_tree alias_sets;
@@ -781,9 +785,17 @@ find_base_value (src)
         The test above is not sufficient because the scheduler may move
         a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN.  */
       if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
-         && regno < reg_base_value_size
-         && reg_base_value[regno])
-       return reg_base_value[regno];
+         && regno < reg_base_value_size)
+       {
+         /* If we're inside init_alias_analysis, use new_reg_base_value
+            to reduce the number of relaxation iterations.  */
+         if (new_reg_base_value && new_reg_base_value[regno]
+             && REG_N_SETS (regno) == 1)
+           return new_reg_base_value[regno];
+
+         if (reg_base_value[regno])
+           return reg_base_value[regno];
+       }
 
       return src;
 
@@ -923,6 +935,7 @@ record_set (dest, set, data)
 {
   unsigned regno;
   rtx src;
+  int n;
 
   if (GET_CODE (dest) != REG)
     return;
@@ -932,6 +945,22 @@ record_set (dest, set, data)
   if (regno >= reg_base_value_size)
     abort ();
 
+  /* If this spans multiple hard registers, then we must indicate that every
+     register has an unusable value.  */
+  if (regno < FIRST_PSEUDO_REGISTER)
+    n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+  else
+    n = 1;
+  if (n != 1)
+    {
+      while (--n >= 0)
+       {
+         reg_seen[regno + n] = 1;
+         new_reg_base_value[regno + n] = 0;
+       }
+      return;
+    }
+
   if (set)
     {
       /* A CLOBBER wipes out any old value but does not prevent a previously
@@ -1924,7 +1953,7 @@ adjust_offset_for_component_ref (x, offset)
   return GEN_INT (ioffset);
 }
 
-/* Return nonzero if we can deterimine the exprs corresponding to memrefs
+/* Return nonzero if we can determine the exprs corresponding to memrefs
    X and Y and they do not overlap.  */
 
 static int
@@ -2675,6 +2704,35 @@ init_alias_once ()
   alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
 }
 
+/* Set MEMORY_MODIFIED when X modifies DATA (that is assumed
+   to be memory reference.  */
+static bool memory_modified;
+static void
+memory_modified_1 (x, pat, data)
+       rtx x, pat ATTRIBUTE_UNUSED;
+       void *data;
+{
+  if (GET_CODE (x) == MEM)
+    {
+      if (anti_dependence (x, (rtx)data) || output_dependence (x, (rtx)data))
+       memory_modified = true;
+    }
+}
+
+
+/* Return true when INSN possibly modify memory contents of MEM
+   (ie address can be modified).  */
+bool
+memory_modified_in_insn_p (mem, insn)
+     rtx mem, insn;
+{
+  if (!INSN_P (insn))
+    return false;
+  memory_modified = false;
+  note_stores (PATTERN (insn), memory_modified_1, mem);
+  return memory_modified;
+}
+
 /* Initialize the aliasing machinery.  Initialize the REG_KNOWN_VALUE
    array.  */
 
@@ -2744,7 +2802,7 @@ init_alias_analysis ()
 
       /* We're at the start of the function each iteration through the
         loop, so we're copying arguments.  */
-      copying_arguments = 1;
+      copying_arguments = true;
 
       /* Wipe the potential alias information clean for this pass.  */
       memset ((char *) new_reg_base_value, 0, reg_base_value_size * sizeof (rtx));
@@ -2834,7 +2892,7 @@ init_alias_analysis ()
            }
          else if (GET_CODE (insn) == NOTE
                   && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
-           copying_arguments = 0;
+           copying_arguments = false;
        }
 
       /* Now propagate values from new_reg_base_value to reg_base_value.  */