mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-23 21:31:54 +08:00
re PR middle-end/36253 (Caller-save stack slot may not have proper alignment)
2008-05-26 H.J. Lu <hongjiu.lu@intel.com> PR middle-end/36253 * caller-save.c (insert_restore): Verify alignment of spill space. (insert_save): Likewise. * cfgexpand.c (LOCAL_ALIGNMENT): Removed. * defaults.h (LOCAL_ALIGNMENT): New. Provide default. (STACK_SLOT_ALIGNMENT): Likewise. * function.c (LOCAL_ALIGNMENT): Removed. (get_stack_local_alignment): New. (assign_stack_local): Use it. Set alignment on stack slot. (assign_stack_temp_for_type): Use get_stack_local_alignment. * config/i386/i386.h (LOCAL_ALIGNMENT): Updated. (STACK_SLOT_ALIGNMENT): New. * config/i386/i386.c (ix86_local_alignment): Handle caller-save stack slot in XFmode. * doc/tm.texi (STACK_SLOT_ALIGNMENT): New. From-SVN: r135927
This commit is contained in:
parent
e94a83856f
commit
76fe54f07a
@ -1,3 +1,28 @@
|
||||
2008-05-26 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR middle-end/36253
|
||||
* caller-save.c (insert_restore): Verify alignment of spill
|
||||
space.
|
||||
(insert_save): Likewise.
|
||||
|
||||
* cfgexpand.c (LOCAL_ALIGNMENT): Removed.
|
||||
|
||||
* defaults.h (LOCAL_ALIGNMENT): New. Provide default.
|
||||
(STACK_SLOT_ALIGNMENT): Likewise.
|
||||
|
||||
* function.c (LOCAL_ALIGNMENT): Removed.
|
||||
(get_stack_local_alignment): New.
|
||||
(assign_stack_local): Use it. Set alignment on stack slot.
|
||||
(assign_stack_temp_for_type): Use get_stack_local_alignment.
|
||||
|
||||
* config/i386/i386.h (LOCAL_ALIGNMENT): Updated.
|
||||
(STACK_SLOT_ALIGNMENT): New.
|
||||
|
||||
* config/i386/i386.c (ix86_local_alignment): Handle caller-save
|
||||
stack slot in XFmode.
|
||||
|
||||
* doc/tm.texi (STACK_SLOT_ALIGNMENT): New.
|
||||
|
||||
2008-05-26 Kai Tietz <kai.tietz@onevision.com>
|
||||
|
||||
PR/36321
|
||||
|
@ -704,6 +704,11 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
|
||||
mem = adjust_address (mem, save_mode[regno], 0);
|
||||
else
|
||||
mem = copy_rtx (mem);
|
||||
|
||||
/* Verify that the alignment of spill space is equal to or greater
|
||||
than required. */
|
||||
gcc_assert (GET_MODE_ALIGNMENT (GET_MODE (mem)) <= MEM_ALIGN (mem));
|
||||
|
||||
pat = gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_REG (GET_MODE (mem),
|
||||
regno), mem);
|
||||
@ -776,6 +781,11 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
|
||||
mem = adjust_address (mem, save_mode[regno], 0);
|
||||
else
|
||||
mem = copy_rtx (mem);
|
||||
|
||||
/* Verify that the alignment of spill space is equal to or greater
|
||||
than required. */
|
||||
gcc_assert (GET_MODE_ALIGNMENT (GET_MODE (mem)) <= MEM_ALIGN (mem));
|
||||
|
||||
pat = gen_rtx_SET (VOIDmode, mem,
|
||||
gen_rtx_REG (GET_MODE (mem),
|
||||
regno));
|
||||
|
@ -86,10 +86,6 @@ failed:
|
||||
}
|
||||
|
||||
|
||||
#ifndef LOCAL_ALIGNMENT
|
||||
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
|
||||
#endif
|
||||
|
||||
#ifndef STACK_ALIGNMENT_NEEDED
|
||||
#define STACK_ALIGNMENT_NEEDED 1
|
||||
#endif
|
||||
|
@ -187,7 +187,8 @@ extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
extern int ix86_return_pops_args (tree, tree, int);
|
||||
|
||||
extern int ix86_data_alignment (tree, int);
|
||||
extern int ix86_local_alignment (tree, int);
|
||||
extern unsigned int ix86_local_alignment (tree, enum machine_mode,
|
||||
unsigned int);
|
||||
extern int ix86_constant_alignment (tree, int);
|
||||
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
|
||||
extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
|
||||
|
@ -16996,14 +16996,25 @@ ix86_data_alignment (tree type, int align)
|
||||
return align;
|
||||
}
|
||||
|
||||
/* Compute the alignment for a local variable.
|
||||
TYPE is the data type, and ALIGN is the alignment that
|
||||
the object would ordinarily have. The value of this macro is used
|
||||
instead of that alignment to align the object. */
|
||||
/* Compute the alignment for a local variable or a stack slot. TYPE is
|
||||
the data type, MODE is the widest mode available and ALIGN is the
|
||||
alignment that the object would ordinarily have. The value of this
|
||||
macro is used instead of that alignment to align the object. */
|
||||
|
||||
int
|
||||
ix86_local_alignment (tree type, int align)
|
||||
unsigned int
|
||||
ix86_local_alignment (tree type, enum machine_mode mode,
|
||||
unsigned int align)
|
||||
{
|
||||
/* If TYPE is NULL, we are allocating a stack slot for caller-save
|
||||
register in MODE. We will return the largest alignment of XF
|
||||
and DF. */
|
||||
if (!type)
|
||||
{
|
||||
if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
|
||||
align = GET_MODE_ALIGNMENT (DFmode);
|
||||
return align;
|
||||
}
|
||||
|
||||
/* x86-64 ABI requires arrays greater than 16 bytes to be aligned
|
||||
to 16byte boundary. */
|
||||
if (TARGET_64BIT)
|
||||
|
@ -902,7 +902,22 @@ enum target_cpu_default
|
||||
One use of this macro is to increase alignment of medium-size
|
||||
data to make it all fit in fewer cache lines. */
|
||||
|
||||
#define LOCAL_ALIGNMENT(TYPE, ALIGN) ix86_local_alignment ((TYPE), (ALIGN))
|
||||
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
|
||||
ix86_local_alignment ((TYPE), VOIDmode, (ALIGN))
|
||||
|
||||
/* If defined, a C expression to compute the alignment for stack slot.
|
||||
TYPE is the data type, MODE is the widest mode available, and ALIGN
|
||||
is the alignment that the slot would ordinarily have. The value of
|
||||
this macro is used instead of that alignment to align the slot.
|
||||
|
||||
If this macro is not defined, then ALIGN is used when TYPE is NULL,
|
||||
Otherwise, LOCAL_ALIGNMENT will be used.
|
||||
|
||||
One use of this macro is to set alignment of stack slot to the
|
||||
maximum alignment of all possible modes which the slot may have. */
|
||||
|
||||
#define STACK_SLOT_ALIGNMENT(TYPE, MODE, ALIGN) \
|
||||
ix86_local_alignment ((TYPE), (MODE), (ALIGN))
|
||||
|
||||
/* If defined, a C expression that gives the alignment boundary, in
|
||||
bits, of an argument with the specified mode and type. If it is
|
||||
|
@ -940,4 +940,13 @@ along with GCC; see the file COPYING3. If not see
|
||||
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 0
|
||||
#endif
|
||||
|
||||
#ifndef LOCAL_ALIGNMENT
|
||||
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
|
||||
#endif
|
||||
|
||||
#ifndef STACK_SLOT_ALIGNMENT
|
||||
#define STACK_SLOT_ALIGNMENT(TYPE,MODE,ALIGN) \
|
||||
((TYPE) ? LOCAL_ALIGNMENT ((TYPE), (ALIGN)) : (ALIGN))
|
||||
#endif
|
||||
|
||||
#endif /* ! GCC_DEFAULTS_H */
|
||||
|
@ -1172,6 +1172,21 @@ One use of this macro is to increase alignment of medium-size data to
|
||||
make it all fit in fewer cache lines.
|
||||
@end defmac
|
||||
|
||||
@defmac STACK_SLOT_ALIGNMENT (@var{type}, @var{mode}, @var{basic-align})
|
||||
If defined, a C expression to compute the alignment for stack slot.
|
||||
@var{type} is the data type, @var{mode} is the widest mode available,
|
||||
and @var{basic-align} is the alignment that the slot would ordinarily
|
||||
have. The value of this macro is used instead of that alignment to
|
||||
align the slot.
|
||||
|
||||
If this macro is not defined, then @var{basic-align} is used when
|
||||
@var{type} is @code{NULL}. Otherwise, @code{LOCAL_ALIGNMENT} will
|
||||
be used.
|
||||
|
||||
This macro is to set alignment of stack slot to the maximum alignment
|
||||
of all possible modes which the slot may have.
|
||||
@end defmac
|
||||
|
||||
@defmac EMPTY_FIELD_BOUNDARY
|
||||
Alignment in bits to be given to a structure bit-field that follows an
|
||||
empty field such as @code{int : 0;}.
|
||||
|
@ -69,10 +69,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
/* So we can assign to cfun in this file. */
|
||||
#undef cfun
|
||||
|
||||
#ifndef LOCAL_ALIGNMENT
|
||||
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
|
||||
#endif
|
||||
|
||||
#ifndef STACK_ALIGNMENT_NEEDED
|
||||
#define STACK_ALIGNMENT_NEEDED 1
|
||||
#endif
|
||||
@ -325,6 +321,26 @@ frame_offset_overflow (HOST_WIDE_INT offset, tree func)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Return stack slot alignment in bits for TYPE and MODE. */
|
||||
|
||||
static unsigned int
|
||||
get_stack_local_alignment (tree type, enum machine_mode mode)
|
||||
{
|
||||
unsigned int alignment;
|
||||
|
||||
if (mode == BLKmode)
|
||||
alignment = BIGGEST_ALIGNMENT;
|
||||
else
|
||||
alignment = GET_MODE_ALIGNMENT (mode);
|
||||
|
||||
/* Allow the frond-end to (possibly) increase the alignment of this
|
||||
stack slot. */
|
||||
if (! type)
|
||||
type = lang_hooks.types.type_for_mode (mode, 0);
|
||||
|
||||
return STACK_SLOT_ALIGNMENT (type, mode, alignment);
|
||||
}
|
||||
|
||||
/* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
|
||||
with machine mode MODE.
|
||||
|
||||
@ -341,24 +357,12 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
|
||||
{
|
||||
rtx x, addr;
|
||||
int bigend_correction = 0;
|
||||
unsigned int alignment;
|
||||
unsigned int alignment, alignment_in_bits;
|
||||
int frame_off, frame_alignment, frame_phase;
|
||||
|
||||
if (align == 0)
|
||||
{
|
||||
tree type;
|
||||
|
||||
if (mode == BLKmode)
|
||||
alignment = BIGGEST_ALIGNMENT;
|
||||
else
|
||||
alignment = GET_MODE_ALIGNMENT (mode);
|
||||
|
||||
/* Allow the target to (possibly) increase the alignment of this
|
||||
stack slot. */
|
||||
type = lang_hooks.types.type_for_mode (mode, 0);
|
||||
if (type)
|
||||
alignment = LOCAL_ALIGNMENT (type, alignment);
|
||||
|
||||
alignment = get_stack_local_alignment (NULL, mode);
|
||||
alignment /= BITS_PER_UNIT;
|
||||
}
|
||||
else if (align == -1)
|
||||
@ -378,8 +382,10 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
|
||||
if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
|
||||
alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
|
||||
if (crtl->stack_alignment_needed < alignment * BITS_PER_UNIT)
|
||||
crtl->stack_alignment_needed = alignment * BITS_PER_UNIT;
|
||||
alignment_in_bits = alignment * BITS_PER_UNIT;
|
||||
|
||||
if (crtl->stack_alignment_needed < alignment_in_bits)
|
||||
crtl->stack_alignment_needed = alignment_in_bits;
|
||||
|
||||
/* Calculate how many bytes the start of local variables is off from
|
||||
stack alignment. */
|
||||
@ -432,6 +438,7 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
|
||||
frame_offset += size;
|
||||
|
||||
x = gen_rtx_MEM (mode, addr);
|
||||
set_mem_align (x, alignment_in_bits);
|
||||
MEM_NOTRAP_P (x) = 1;
|
||||
|
||||
stack_slot_list
|
||||
@ -544,16 +551,7 @@ assign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size,
|
||||
/* These are now unused. */
|
||||
gcc_assert (keep <= 1);
|
||||
|
||||
if (mode == BLKmode)
|
||||
align = BIGGEST_ALIGNMENT;
|
||||
else
|
||||
align = GET_MODE_ALIGNMENT (mode);
|
||||
|
||||
if (! type)
|
||||
type = lang_hooks.types.type_for_mode (mode, 0);
|
||||
|
||||
if (type)
|
||||
align = LOCAL_ALIGNMENT (type, align);
|
||||
align = get_stack_local_alignment (type, mode);
|
||||
|
||||
/* Try to find an available, already-allocated temporary of the proper
|
||||
mode which meets the size and alignment requirements. Choose the
|
||||
|
Loading…
x
Reference in New Issue
Block a user