OSDN Git Service

* intrinsic.texi: Various minor cleanups.
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index 7ba93a6..efa1a39 100644 (file)
@@ -888,16 +888,8 @@ reload (rtx first, int global)
     {
       int something_changed;
       int did_spill;
-
       HOST_WIDE_INT starting_frame_size;
 
-      /* Round size of stack frame to stack_alignment_needed.  This must be done
-        here because the stack size may be a part of the offset computation
-        for register elimination, and there might have been new stack slots
-        created in the last iteration of this loop.  */
-      if (cfun->stack_alignment_needed)
-        assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
-
       starting_frame_size = get_frame_size ();
 
       set_initial_elim_offsets ();
@@ -964,6 +956,20 @@ reload (rtx first, int global)
       /* If we allocated another stack slot, redo elimination bookkeeping.  */
       if (starting_frame_size != get_frame_size ())
        continue;
+      if (starting_frame_size && cfun->stack_alignment_needed)
+       {
+         /* If we have a stack frame, we must align it now.  The
+            stack size may be a part of the offset computation for
+            register elimination.  So if this changes the stack size,
+            then repeat the elimination bookkeeping.  We don't
+            realign when there is no stack, as that will cause a
+            stack frame when none is needed should
+            STARTING_FRAME_OFFSET not be already aligned to
+            STACK_BOUNDARY.  */
+         assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
+         if (starting_frame_size != get_frame_size ())
+           continue;
+       }
 
       if (caller_save_needed)
        {
@@ -3098,12 +3104,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
            if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
              to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)),
                                    to_rtx);
-           /* If we have a nonzero offset, and the source is already
-              a simple REG, the following transformation would
-              increase the cost of the insn by replacing a simple REG
-              with (plus (reg sp) CST).  So try only when we already
-              had a PLUS before.  */
-           if (offset == 0 || plus_src)
+           if (offset == 0)
              {
                int num_clobbers;
                /* We assume here that if we need a PARALLEL with
@@ -3112,7 +3113,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
                   There's not much we can do if that doesn't work.  */
                PATTERN (insn) = gen_rtx_SET (VOIDmode,
                                              SET_DEST (old_set),
-                                             plus_constant (to_rtx, offset));
+                                             to_rtx);
                num_clobbers = 0;
                INSN_CODE (insn) = recog (PATTERN (insn), insn, &num_clobbers);
                if (num_clobbers)
@@ -3125,6 +3126,26 @@ eliminate_regs_in_insn (rtx insn, int replace)
                  }
                gcc_assert (INSN_CODE (insn) >= 0);
              }
+           /* If we have a nonzero offset, and the source is already
+              a simple REG, the following transformation would
+              increase the cost of the insn by replacing a simple REG
+              with (plus (reg sp) CST).  So try only when we already
+              had a PLUS before.  */
+           else if (plus_src)
+             {
+               new_body = old_body;
+               if (! replace)
+                 {
+                   new_body = copy_insn (old_body);
+                   if (REG_NOTES (insn))
+                     REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
+                 }
+               PATTERN (insn) = new_body;
+               old_set = single_set (insn);
+
+               XEXP (SET_SRC (old_set), 0) = to_rtx;
+               XEXP (SET_SRC (old_set), 1) = GEN_INT (offset);
+             }
            else
              break;