OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index 31407b3..06df026 100644 (file)
@@ -268,7 +268,7 @@ enum insn_code reload_out_optab[NUM_MACHINE_MODES];
 /* This obstack is used for allocation of rtl during register elimination.
    The allocated storage can be freed once find_reloads has processed the
    insn.  */
-struct obstack reload_obstack;
+static struct obstack reload_obstack;
 
 /* Points to the beginning of the reload_obstack.  All insn_chain structures
    are allocated first.  */
@@ -740,8 +740,20 @@ reload (rtx first, int global)
                     that is not a legitimate memory operand.  As later
                     stages of reload assume that all addresses found
                     in the reg_equiv_* arrays were originally legitimate,
-                    we ignore such REG_EQUIV notes.  */
-                 if (memory_operand (x, VOIDmode))
+
+                    It can also happen that a REG_EQUIV note contains a
+                    readonly memory location.  If the destination pseudo
+                    is set from some other value (typically a different
+                    pseudo), and the destination pseudo does not get a
+                    hard reg, then reload will replace the destination
+                    pseudo with its equivalent memory location.  This
+                    is horribly bad as it creates a store to a readonly
+                    memory location and a runtime segfault.  To avoid
+                    this problem we reject readonly memory locations
+                    for equivalences.  This is overly conservative as
+                    we could find all sets of the destination pseudo
+                    and remove them as they should be redundant.  */
+                 if (memory_operand (x, VOIDmode) && ! MEM_READONLY_P (x))
                    {
                      /* Always unshare the equivalence, so we can
                         substitute into this insn without touching the
@@ -1078,8 +1090,8 @@ reload (rtx first, int global)
       CLEAR_REGNO_REG_SET (bb->global_live_at_start,
                           HARD_FRAME_POINTER_REGNUM);
 
-  /* Come here (with failure set nonzero) if we can't get enough spill regs
-     and we decide not to abort about it.  */
+  /* Come here (with failure set nonzero) if we can't get enough spill
+     regs.  */
  failed:
 
   CLEAR_REG_SET (&spilled_pseudos);
@@ -1174,6 +1186,19 @@ reload (rtx first, int global)
          replace_pseudos_in (& XEXP (PATTERN (insn), 0),
                              VOIDmode, PATTERN (insn));
 
+       /* Discard obvious no-ops, even without -O.  This optimization
+          is fast and doesn't interfere with debugging.  */
+       if (NONJUMP_INSN_P (insn)
+           && GET_CODE (PATTERN (insn)) == SET
+           && REG_P (SET_SRC (PATTERN (insn)))
+           && REG_P (SET_DEST (PATTERN (insn)))
+           && (REGNO (SET_SRC (PATTERN (insn)))
+               == REGNO (SET_DEST (PATTERN (insn)))))
+         {
+           delete_insn (insn);
+           continue;
+         }
+
        pnote = &REG_NOTES (insn);
        while (*pnote != 0)
          {
@@ -1208,10 +1233,10 @@ reload (rtx first, int global)
 
       if (size > STACK_CHECK_MAX_FRAME_SIZE)
        {
-         warning ("frame size too large for reliable stack checking");
+         warning (0, "frame size too large for reliable stack checking");
          if (! verbose_warned)
            {
-             warning ("try reducing the number of local variables");
+             warning (0, "try reducing the number of local variables");
              verbose_warned = 1;
            }
        }
@@ -4034,7 +4059,7 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
   unsigned int nr;
 
   /* note_stores does give us subregs of hard regs,
-     subreg_regno_offset will abort if it is not a hard reg.  */
+     subreg_regno_offset requires a hard reg.  */
   while (GET_CODE (x) == SUBREG)
     {
       /* We ignore the subreg offset when calculating the regno,
@@ -4938,11 +4963,11 @@ free_for_value_p (int regno, enum machine_mode mode, int opnum,
 }
 
 /* Return nonzero if the rtx X is invariant over the current function.  */
-/* ??? Actually, the places where we use this expect exactly what
* is tested here, and not everything that is function invariant.  In
* particular, the frame pointer and arg pointer are special cased;
- * pic_offset_table_rtx is not, and this will cause aborts when we
*             go to spill these things to memory.  */
+/* ??? Actually, the places where we use this expect exactly what is
  tested here, and not everything that is function invariant.  In
  particular, the frame pointer and arg pointer are special cased;
+   pic_offset_table_rtx is not, and we must not spill these things to
  memory.  */
 
 static int
 function_invariant_p (rtx x)
@@ -6062,10 +6087,10 @@ merge_assigned_reloads (rtx insn)
                        || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
                       ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
 
-                 /* Check to see if we accidentally converted two reloads
-                    that use the same reload register with different inputs
-                    to the same type.  If so, the resulting code won't work,
-                    so abort.  */
+                 /* Check to see if we accidentally converted two
+                    reloads that use the same reload register with
+                    different inputs to the same type.  If so, the
+                    resulting code won't work.  */
                  if (rld[j].reg_rtx)
                    for (k = 0; k < j; k++)
                      gcc_assert (rld[k].in == 0 || rld[k].reg_rtx == 0