This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)  \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]