reload1.c (alter_reg): Require the alignment of the stack slot to be at least reg_max...
authorRichard Sandiford <richard@codesourcery.com>
Wed, 27 Sep 2006 15:27:38 +0000 (15:27 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 27 Sep 2006 15:27:38 +0000 (15:27 +0000)
gcc/
* reload1.c (alter_reg): Require the alignment of the stack slot to
be at least reg_max_ref_width bytes.
(scan_paradoxical_subregs): Record the largest width in
reg_max_ref_width.

From-SVN: r117252

gcc/ChangeLog
gcc/reload1.c

index 4a167dd..584f6de 100644 (file)
@@ -1,3 +1,10 @@
+2006-09-27  Richard Sandiford  <richard@codesourcery.com>
+
+       * reload1.c (alter_reg): Require the alignment of the stack slot to
+       be at least reg_max_ref_width bytes.
+       (scan_paradoxical_subregs): Record the largest width in
+       reg_max_ref_width.
+
 2006-09-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/25261
index 58f77cb..4244b29 100644 (file)
@@ -1996,8 +1996,11 @@ alter_reg (int i, int from_reg)
       && reg_equiv_memory_loc[i] == 0)
     {
       rtx x;
+      enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
       unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
+      unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
       unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
+      unsigned int min_align = reg_max_ref_width[i] * BITS_PER_UNIT;
       int adjust = 0;
 
       /* Each pseudo reg has an inherent size which comes from its own mode,
@@ -2011,8 +2014,9 @@ alter_reg (int i, int from_reg)
       if (from_reg == -1)
        {
          /* No known place to spill from => no slot to reuse.  */
-         x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size,
-                                 inherent_size == total_size ? 0 : -1);
+         x = assign_stack_local (mode, total_size,
+                                 min_align > inherent_align
+                                 || total_size > inherent_size ? -1 : 0);
          if (BYTES_BIG_ENDIAN)
            /* Cancel the  big-endian correction done in assign_stack_local.
               Get the address of the beginning of the slot.
@@ -2028,7 +2032,8 @@ alter_reg (int i, int from_reg)
       else if (spill_stack_slot[from_reg] != 0
               && spill_stack_slot_width[from_reg] >= total_size
               && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
-                  >= inherent_size))
+                  >= inherent_size)
+              && MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align)
        x = spill_stack_slot[from_reg];
 
       /* Allocate a bigger slot.  */
@@ -2036,7 +2041,6 @@ alter_reg (int i, int from_reg)
        {
          /* Compute maximum size needed, both for inherent size
             and for total size.  */
-         enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
          rtx stack_slot;
 
          if (spill_stack_slot[from_reg])
@@ -2046,11 +2050,14 @@ alter_reg (int i, int from_reg)
                mode = GET_MODE (spill_stack_slot[from_reg]);
              if (spill_stack_slot_width[from_reg] > total_size)
                total_size = spill_stack_slot_width[from_reg];
+             if (MEM_ALIGN (spill_stack_slot[from_reg]) > min_align)
+               min_align = MEM_ALIGN (spill_stack_slot[from_reg]);
            }
 
          /* Make a slot with that size.  */
          x = assign_stack_local (mode, total_size,
-                                 inherent_size == total_size ? 0 : -1);
+                                 min_align > inherent_align
+                                 || total_size > inherent_size ? -1 : 0);
          stack_slot = x;
 
          /* All pseudos mapped to this slot can alias each other.  */
@@ -3828,7 +3835,8 @@ scan_paradoxical_subregs (rtx x)
 
     case SUBREG:
       if (REG_P (SUBREG_REG (x))
-         && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && (GET_MODE_SIZE (GET_MODE (x))
+             > reg_max_ref_width[REGNO (SUBREG_REG (x))]))
        reg_max_ref_width[REGNO (SUBREG_REG (x))]
          = GET_MODE_SIZE (GET_MODE (x));
       return;