aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2006-09-27 15:27:38 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2006-09-27 15:27:38 +0000
commit63a7a62b25dcea2f63b2f50ee7502084ac8991f1 (patch)
treeae805c7684178f9920bbee449d77cb2bf5c4d45b /gcc/reload1.c
parent0d1187867f0c2f92dc4458ed0bffce479b1c11c0 (diff)
downloadgcc-63a7a62b25dcea2f63b2f50ee7502084ac8991f1.zip
gcc-63a7a62b25dcea2f63b2f50ee7502084ac8991f1.tar.gz
gcc-63a7a62b25dcea2f63b2f50ee7502084ac8991f1.tar.bz2
reload1.c (alter_reg): Require the alignment of the stack slot to be at least reg_max_ref_width bytes.
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
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 58f77cb..4244b29 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -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;