OSDN Git Service

* pt.c (can_complete_type_without_circularity): Add static to
[pf3gnuchains/gcc-fork.git] / gcc / alias.c
index 140e58a..2e6a2b0 100644 (file)
@@ -36,6 +36,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "splay-tree.h"
 #include "ggc.h"
 #include "langhooks.h"
+#include "target.h"
 
 /* The alias sets assigned to MEMs assist the back-end in determining
    which MEMs can alias which other MEMs.  In general, two MEMs in
@@ -151,10 +152,14 @@ static int nonlocal_set_p               PARAMS ((rtx));
    current function performs nonlocal memory memory references for the
    purposes of marking the function as a constant function.  */
 
-static rtx *reg_base_value;
+static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
 static rtx *new_reg_base_value;
 static unsigned int reg_base_value_size; /* size of reg_base_value array */
 
+/* Static hunks of RTL used by the aliasing code; these are initialized
+   once per function to avoid unnecessary RTL allocations.  */
+static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
+
 #define REG_BASE_VALUE(X) \
   (REGNO (X) < reg_base_value_size \
    ? reg_base_value[REGNO (X)] : 0)
@@ -570,6 +575,14 @@ get_alias_set (t)
      and references to functions, but that's different.)  */
   else if (TREE_CODE (t) == FUNCTION_TYPE)
     set = 0;
+
+  /* Unless the language specifies otherwise, let vector types alias
+     their components.  This avoids some nasty type punning issues in
+     normal usage.  And indeed lets vectors be treated more like an
+     array slice.  */
+  else if (TREE_CODE (t) == VECTOR_TYPE)
+    set = get_alias_set (TREE_TYPE (t));
+
   else
     /* Otherwise make a new alias set for this type.  */
     set = new_alias_set ();
@@ -2021,7 +2034,7 @@ nonoverlapping_memrefs_p (x, y)
 
   /* If we don't know the size of the lower-offset value, we can't tell
      if they conflict.  Otherwise, we do the test.  */
-  return sizex >= 0 && offsety > offsetx + sizex;
+  return sizex >= 0 && offsety >= offsetx + sizex;
 }
 
 /* True dependence: X is read after store in MEM takes place.  */
@@ -2572,12 +2585,12 @@ mark_constant_function ()
   rtx insn;
   int nonlocal_memory_referenced;
 
-  if (TREE_PUBLIC (current_function_decl)
-      || TREE_READONLY (current_function_decl)
+  if (TREE_READONLY (current_function_decl)
       || DECL_IS_PURE (current_function_decl)
       || TREE_THIS_VOLATILE (current_function_decl)
       || TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode
-      || current_function_has_nonlocal_goto)
+      || current_function_has_nonlocal_goto
+      || !(*targetm.binds_local_p) (current_function_decl))
     return;
 
   /* A loop might not return which counts as a side effect.  */
@@ -2616,8 +2629,6 @@ mark_constant_function ()
 }
 \f
 
-static HARD_REG_SET argument_registers;
-
 void
 init_alias_once ()
 {
@@ -2632,7 +2643,19 @@ init_alias_once ()
        numbers, so translate if necessary due to register windows.  */
     if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
        && HARD_REGNO_MODE_OK (i, Pmode))
-      SET_HARD_REG_BIT (argument_registers, i);
+      static_reg_base_value[i]
+       = gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));
+
+  static_reg_base_value[STACK_POINTER_REGNUM]
+    = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
+  static_reg_base_value[ARG_POINTER_REGNUM]
+    = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
+  static_reg_base_value[FRAME_POINTER_REGNUM]
+    = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
+#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+  static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
+    = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
+#endif
 
   alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
 }
@@ -2662,8 +2685,8 @@ init_alias_analysis ()
      optimization.  Loop unrolling can create a large number of
      registers.  */
   reg_base_value_size = maxreg * 2;
-  reg_base_value = (rtx *) xcalloc (reg_base_value_size, sizeof (rtx));
-  ggc_add_rtx_root (reg_base_value, reg_base_value_size);
+  reg_base_value = (rtx *) ggc_alloc_cleared (reg_base_value_size
+                                             * sizeof (rtx));
 
   new_reg_base_value = (rtx *) xmalloc (reg_base_value_size * sizeof (rtx));
   reg_seen = (char *) xmalloc (reg_base_value_size);
@@ -2722,21 +2745,8 @@ init_alias_analysis ()
         The address expression is VOIDmode for an argument and
         Pmode for other registers.  */
 
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-       if (TEST_HARD_REG_BIT (argument_registers, i))
-         new_reg_base_value[i] = gen_rtx_ADDRESS (VOIDmode,
-                                                  gen_rtx_REG (Pmode, i));
-
-      new_reg_base_value[STACK_POINTER_REGNUM]
-       = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
-      new_reg_base_value[ARG_POINTER_REGNUM]
-       = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
-      new_reg_base_value[FRAME_POINTER_REGNUM]
-       = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-      new_reg_base_value[HARD_FRAME_POINTER_REGNUM]
-       = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
-#endif
+      memcpy (new_reg_base_value, static_reg_base_value,
+             FIRST_PSEUDO_REGISTER * sizeof (rtx));
 
       /* Walk the insns adding values to the new_reg_base_value array.  */
       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -2877,12 +2887,7 @@ end_alias_analysis ()
   reg_known_value_size = 0;
   free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
   reg_known_equiv_p = 0;
-  if (reg_base_value)
-    {
-      ggc_del_root (reg_base_value);
-      free (reg_base_value);
-      reg_base_value = 0;
-    }
+  reg_base_value = 0;
   reg_base_value_size = 0;
   if (alias_invariant)
     {
@@ -2890,3 +2895,5 @@ end_alias_analysis ()
       alias_invariant = 0;
     }
 }
+
+#include "gt-alias.h"