This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR middle-end/36253: Caller-save stack slot may not have proper alignment
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 17 May 2008 08:10:54 -0700
- Subject: PATCH: PR middle-end/36253: Caller-save stack slot may not have proper alignment
setup_save_areas calls assign_stack_local to allocate a stack slot for
a hard register in the widest mode. assign_stack_local has
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 /= BITS_PER_UNIT;
}
For x87, the widest mode is XF, which is 12byte aligned at 4 byte.
So a 12byte stack slot aligned at 4 byte is allocated for an x87
register. For x87, DF is 8 byte aligned at 8 byte. If it turns out
later that we need to save/restore DF instead XF, we load/store the DF
register at 4 byte instead of 8 byte. It won't give us the best x87
performance.
This patch fixes this problem by passing NULL type and mode to
LOCAL_ALIGNMENT so that the backend can provide the largest alignment
for a caller-save stack slot.
This patch moves the duplicated LOCAL_ALIGNMENT definitions in
cfgexpand.c and function.c to defaults.h. It also removed
the duplicated stack slot alignment code.
Is this a right approach?
Thanks.
H.J.
----
2008-05-17 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.
(get_decl_align_unit): Pass VOIDmode to LOCAL_ALIGNMENT.
* defaults.h (LOCAL_ALIGNMENT): New. Provide default.
* 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/bfin/bfin.c (bfin_local_alignment): Updated.
* config/bfin/bfin.h (LOCAL_ALIGNMENT): Likewise.
* config/bfin/bfin-protos.h (bfin_local_alignment): Likewise.
* config/i386/i386.h (LOCAL_ALIGNMENT): Likewise.
* config/i386/i386-protos.h (ix86_local_alignment): Likewise.
* config/mips/mips.h (LOCAL_ALIGNMENT): Likewise.
* config/mmix/mmix.c (mmix_local_alignment): Likewise.
* config/mmix/mmix.h (LOCAL_ALIGNMENT): Likewise.
* config/mmix/mmix-protos.h (mmix_local_alignment): Likewise.
* config/rs6000/rs6000.h (LOCAL_ALIGNMENT): Likewise.
* config/score/score.h (LOCAL_ALIGNMENT): Likewise.
* config/sh/sh.h (LOCAL_ALIGNMENT): Likewise.
* config/sparc/sparc.h (LOCAL_ALIGNMENT): Likewise.
* config/spu/spu.h (LOCAL_ALIGNMENT): Likewise.
* config/i386/i386.c (ix86_local_alignment): Handle caller-save
stack slot in XFmode.
* config/rs6000/rs6000.h (LOCAL_ALIGNMENT_1): New.
* config/sh/sh.h (LOCAL_ALIGNMENT_1): Likewise.
* doc/tm.texi (LOCAL_ALIGNMENT): Add mode.
Index: doc/tm.texi
===================================================================
--- doc/tm.texi (revision 2603)
+++ doc/tm.texi (working copy)
@@ -1160,11 +1160,16 @@ constants to be word aligned so that @co
constants can be done inline.
@end defmac
-@defmac LOCAL_ALIGNMENT (@var{type}, @var{basic-align})
+@defmac LOCAL_ALIGNMENT (@var{type}, @var{mode}, @var{basic-align})
If defined, a C expression to compute the alignment for a variable in
-the local store. @var{type} is the data type, and @var{basic-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.
+the local store. @var{type} is the data type, @var{mode} is the mode,
+and @var{basic-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.
+
+If @var{type} is @code{NULL}, we are allocating a stack slot for
+caller-save register in @var{mode}. If @var{mode} is @code{VOIDmode},
+it is ignored.
If this macro is not defined, then @var{basic-align} is used.
Index: defaults.h
===================================================================
--- defaults.h (revision 2603)
+++ defaults.h (working copy)
@@ -940,4 +940,8 @@ along with GCC; see the file COPYING3.
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 0
#endif
+#ifndef LOCAL_ALIGNMENT
+#define LOCAL_ALIGNMENT(TYPE, MODE, ALIGNMENT) ALIGNMENT
+#endif
+
#endif /* ! GCC_DEFAULTS_H */
Index: caller-save.c
===================================================================
--- caller-save.c (revision 2603)
+++ caller-save.c (working copy)
@@ -704,6 +704,12 @@ insert_restore (struct insn_chain *chain
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. */
+ if (GET_MODE_ALIGNMENT (GET_MODE (mem)) > MEM_ALIGN (mem))
+ gcc_unreachable ();
+
pat = gen_rtx_SET (VOIDmode,
gen_rtx_REG (GET_MODE (mem),
regno), mem);
@@ -776,6 +782,12 @@ insert_save (struct insn_chain *chain, i
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. */
+ if (GET_MODE_ALIGNMENT (GET_MODE (mem)) > MEM_ALIGN (mem))
+ gcc_unreachable ();
+
pat = gen_rtx_SET (VOIDmode, mem,
gen_rtx_REG (GET_MODE (mem),
regno));
Index: function.c
===================================================================
--- function.c (revision 2603)
+++ function.c (working copy)
@@ -69,10 +69,6 @@ along with GCC; see the file COPYING3.
/* 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 off
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);
+
+ alignment = LOCAL_ALIGNMENT (type, mode, alignment);
+ return 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 mo
{
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 mo
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 mo
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
/* 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
Index: cfgexpand.c
===================================================================
--- cfgexpand.c (revision 2603)
+++ cfgexpand.c (working copy)
@@ -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
@@ -160,7 +156,7 @@ get_decl_align_unit (tree decl)
unsigned int align;
align = DECL_ALIGN (decl);
- align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align);
+ align = LOCAL_ALIGNMENT (TREE_TYPE (decl), VOIDmode, align);
if (align > PREFERRED_STACK_BOUNDARY)
align = PREFERRED_STACK_BOUNDARY;
if (crtl->stack_alignment_needed < align)
Index: config/spu/spu.h
===================================================================
--- config/spu/spu.h (revision 2603)
+++ config/spu/spu.h (working copy)
@@ -100,7 +100,8 @@ extern GTY(()) int spu_tune;
unaligned.) */
#define DATA_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
#define CONSTANT_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
-#define LOCAL_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
+#define LOCAL_ALIGNMENT(TYPE,MODE,ALIGN) \
+ ((!(TYPE) || (ALIGN) > 128) ? (ALIGN) : 128)
#define EMPTY_FIELD_BOUNDARY 32
Index: config/sparc/sparc.h
===================================================================
--- config/sparc/sparc.h (revision 2603)
+++ config/sparc/sparc.h (working copy)
@@ -702,7 +702,8 @@ if (TARGET_ARCH64 \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Make local arrays of chars word-aligned for the same reasons. */
-#define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ ((TYPE) ? DATA_ALIGNMENT (TYPE, ALIGN) : (ALIGN))
/* Set this nonzero if move instructions will actually fail to work
when given unaligned data. */
Index: config/i386/i386.h
===================================================================
--- config/i386/i386.h (revision 2603)
+++ config/i386/i386.h (working copy)
@@ -893,16 +893,20 @@ enum target_cpu_default
#define DATA_ALIGNMENT(TYPE, ALIGN) ix86_data_alignment ((TYPE), (ALIGN))
/* If defined, a C expression to 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.
+ variable. TYPE is the data type, MODE is the mode, 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.
+
+ If TYPE is NULL, we are allocating a stack slot for caller-save
+ register. If MODE is VOIDmode, it is ignored.
If this macro is not defined, then ALIGN is used.
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, 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
Index: config/i386/i386-protos.h
===================================================================
--- config/i386/i386-protos.h (revision 2603)
+++ config/i386/i386-protos.h (working copy)
@@ -190,7 +190,8 @@ extern void function_arg_advance (CUMULA
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 *);
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 2603)
+++ config/i386/i386.c (working copy)
@@ -17001,9 +17001,20 @@ ix86_data_alignment (tree type, int alig
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)
Index: config/sh/sh.h
===================================================================
--- config/sh/sh.h (revision 2603)
+++ config/sh/sh.h (working copy)
@@ -849,11 +849,13 @@ do { \
held in a single integer register. SH5 also holds CSImode and SCmode
values in integer registers. This is relevant for argument passing on
SHcompact as we use a stack temp in order to pass CSImode by reference. */
-#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+#define LOCAL_ALIGNMENT_1(TYPE, ALIGN) \
((GET_MODE_CLASS (TYPE_MODE (TYPE)) == MODE_COMPLEX_INT \
|| GET_MODE_CLASS (TYPE_MODE (TYPE)) == MODE_COMPLEX_FLOAT) \
? (unsigned) MIN (BIGGEST_ALIGNMENT, GET_MODE_BITSIZE (TYPE_MODE (TYPE))) \
: (unsigned) DATA_ALIGNMENT(TYPE, ALIGN))
+#define LOCAL_ALIGNMENT(TYPE, MODE, ALIGN) \
+ ((TYPE) ? LOCAL_ALIGNMENT_1 (TYPE, ALIGN) : (ALIGN))
/* Make arrays of chars word-aligned for the same reasons. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
Index: config/rs6000/rs6000.h
===================================================================
--- config/rs6000/rs6000.h (revision 2603)
+++ config/rs6000/rs6000.h (working copy)
@@ -576,9 +576,9 @@ extern enum rs6000_nop_insertion rs6000_
#define BIGGEST_ALIGNMENT 128
/* A C expression to compute the alignment for a variables in the
- local store. TYPE is the data type, and ALIGN is the alignment
- that the object would ordinarily have. */
-#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ local store. TYPE is the data type, MODE is the mode, and ALIGN
+ is the alignment that the object would ordinarily have. */
+#define LOCAL_ALIGNMENT_1(TYPE, ALIGN) \
((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
(TARGET_E500_DOUBLE \
&& (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 : \
@@ -586,6 +586,8 @@ extern enum rs6000_nop_insertion rs6000_
&& SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \
&& TREE_CODE (TYPE) == VECTOR_TYPE \
&& PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) ? 64 : ALIGN)
+#define LOCAL_ALIGNMENT(TYPE, MODE, ALIGN) \
+ ((TYPE) ? LOCAL_ALIGNMENT_1 (TYPE, ALIGN) : (ALIGN))
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 32
Index: config/score/score.h
===================================================================
--- config/score/score.h (revision 2603)
+++ config/score/score.h (working copy)
@@ -172,16 +172,20 @@
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* If defined, a C expression to 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.
+ variable. TYPE is the data type, MODE is the mode, 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.
+
+ If TYPE is NULL, we are allocating a stack slot for caller-save
+ register. If MODE is VOIDmode, it is ignored.
If this macro is not defined, then ALIGN is used.
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) \
- ((TREE_CODE (TYPE) == ARRAY_TYPE \
+#define LOCAL_ALIGNMENT(TYPE, MODE, ALIGN) \
+ (((TYPE) \
+ && TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))
Index: config/mips/mips.h
===================================================================
--- config/mips/mips.h (revision 2603)
+++ config/mips/mips.h (working copy)
@@ -1316,8 +1316,8 @@ enum mips_code_readable_setting {
character arrays to be word-aligned so that `strcpy' calls that copy
constants to character arrays can be done inline, and 'strcmp' can be
optimised to use word loads. */
-#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
- DATA_ALIGNMENT (TYPE, ALIGN)
+#define LOCAL_ALIGNMENT(TYPE, MODE, ALIGN) \
+ ((TYPE) ? DATA_ALIGNMENT ((TYPE), (ALIGN)) : (ALIGN))
#define PAD_VARARGS_DOWN \
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
Index: config/mmix/mmix.h
===================================================================
--- config/mmix/mmix.h (revision 2603)
+++ config/mmix/mmix.h (working copy)
@@ -223,8 +223,8 @@ extern int target_flags;
#define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \
mmix_constant_alignment (CONSTANT, BASIC_ALIGN)
-#define LOCAL_ALIGNMENT(TYPE, BASIC_ALIGN) \
- mmix_local_alignment (TYPE, BASIC_ALIGN)
+#define LOCAL_ALIGNMENT(TYPE, (MODE), BASIC_ALIGN) \
+ mmix_local_alignment (TYPE, (MODE), BASIC_ALIGN)
/* Following other ports, this seems to most commonly be the word-size,
so let's do that here too. */
Index: config/mmix/mmix-protos.h
===================================================================
--- config/mmix/mmix-protos.h (revision 2603)
+++ config/mmix/mmix-protos.h (working copy)
@@ -58,7 +58,8 @@ extern rtx mmix_function_outgoing_value
extern int mmix_function_value_regno_p (int);
extern int mmix_data_alignment (tree, int);
extern int mmix_constant_alignment (tree, int);
-extern int mmix_local_alignment (tree, int);
+extern unsigned int mmix_local_alignment (tree, enum machine_mode mode,
+ unsigned int);
extern void mmix_asm_output_pool_prologue (FILE *, const char *, tree, int);
extern void mmix_asm_output_aligned_common (FILE *, const char *, int, int);
extern void mmix_asm_output_aligned_local (FILE *, const char *, int, int);
Index: config/mmix/mmix.c
===================================================================
--- config/mmix/mmix.c (revision 2603)
+++ config/mmix/mmix.c (working copy)
@@ -271,10 +271,12 @@ mmix_constant_alignment (tree constant A
/* LOCAL_ALIGNMENT. */
-int
-mmix_local_alignment (tree type ATTRIBUTE_UNUSED, int basic_align)
+unsigned int
+mmix_local_alignment (tree type,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int basic_align)
{
- if (basic_align < 32)
+ if (type && basic_align < 32)
return 32;
return basic_align;
Index: config/bfin/bfin-protos.h
===================================================================
--- config/bfin/bfin-protos.h (revision 2603)
+++ config/bfin/bfin-protos.h (working copy)
@@ -119,7 +119,8 @@ extern void override_options (void);
extern void asm_conditional_branch (rtx, rtx *, int, int);
extern rtx bfin_gen_compare (rtx, Mmode);
-extern int bfin_local_alignment (tree, int);
+extern unsigned int bfin_local_alignment (tree, enum machine_mode,
+ unsigned int);
extern void initialize_trampoline (rtx, rtx, rtx);
extern bool bfin_legitimate_address_p (Mmode, rtx, int);
extern rtx bfin_va_arg (tree, tree);
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c (revision 2603)
+++ config/bfin/bfin.c (working copy)
@@ -3353,12 +3353,15 @@ bfin_expand_movmem (rtx dst, rtx src, rt
the object would ordinarily have. The value of this macro is used
instead of that alignment to align the object. */
-int
-bfin_local_alignment (tree type, int align)
+unsigned int
+bfin_local_alignment (tree type,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ unsigned int align)
{
/* Increasing alignment for (relatively) big types allows the builtin
memcpy can use 32 bit loads/stores. */
- if (TYPE_SIZE (type)
+ if (type
+ && TYPE_SIZE (type)
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& (TREE_INT_CST_LOW (TYPE_SIZE (type)) > 8
|| TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 32)
Index: config/bfin/bfin.h
===================================================================
--- config/bfin/bfin.h (revision 2603)
+++ config/bfin/bfin.h (working copy)
@@ -300,16 +300,20 @@ extern const char *bfin_library_id_strin
/*#define DATA_ALIGNMENT(TYPE, BASIC-ALIGN) for arrays.. */
/* If defined, a C expression to 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.
+ variable. TYPE is the data type, MODE is the mode, 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.
+
+ If TYPE is NULL, we are allocating a stack slot for caller-save
+ register. If MODE is VOIDmode, it is ignored.
If this macro is not defined, then ALIGN is used.
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) bfin_local_alignment ((TYPE), (ALIGN))
+#define LOCAL_ALIGNMENT(TYPE, MODE, ALIGN) \
+ bfin_local_alignment ((TYPE), (MODE), (ALIGN))
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \