PR rtl-optimization/40667
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Jul 2009 17:40:29 +0000 (17:40 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 11 Jul 2009 17:40:29 +0000 (17:40 +0000)
* defaults.h (MINIMUM_ALIGNMENT): Define if not defined.
* doc/tm.texi (MINIMUM_ALIGNMENT): Document it.
* config/i386/i386.h (MINIMUM_ALIGNMENT): Define.
* config/i386/i386.c (ix86_minimum_alignment): New function.
* config/i386/i386-protos.h (ix86_minimum_alignment): New prototype.
* cfgexpand.c (expand_one_var): Use MINIMIM_ALIGNMENT.
* emit-rtl.c (gen_reg_rtx): Likewise.
* function.c (assign_parms): Likewise.  If nominal_type needs
bigger alignment than FUNCTION_ARG_BOUNDARY, use its alignment
rather than passed_type's alignment.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149513 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgexpand.c
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/emit-rtl.c
gcc/function.c

index 17bb0cd..f3d298e 100644 (file)
@@ -1,5 +1,17 @@
 2009-07-11  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/40667
+       * defaults.h (MINIMUM_ALIGNMENT): Define if not defined.
+       * doc/tm.texi (MINIMUM_ALIGNMENT): Document it.
+       * config/i386/i386.h (MINIMUM_ALIGNMENT): Define.
+       * config/i386/i386.c (ix86_minimum_alignment): New function.
+       * config/i386/i386-protos.h (ix86_minimum_alignment): New prototype.
+       * cfgexpand.c (expand_one_var): Use MINIMIM_ALIGNMENT.
+       * emit-rtl.c (gen_reg_rtx): Likewise.
+       * function.c (assign_parms): Likewise.  If nominal_type needs
+       bigger alignment than FUNCTION_ARG_BOUNDARY, use its alignment
+       rather than passed_type's alignment.
+
        PR target/40668
        * function.c (assign_parm_setup_stack): Adjust
        MEM_OFFSET (data->stack_parm) if promoted_mode is different
index 62b5c45..c8d19fb 100644 (file)
@@ -1164,9 +1164,11 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
         variables, which won't be on stack, we collect alignment of
         type and ignore user specified alignment.  */
       if (TREE_STATIC (var) || DECL_EXTERNAL (var))
-       align = TYPE_ALIGN (TREE_TYPE (var));
+       align = MINIMUM_ALIGNMENT (TREE_TYPE (var),
+                                  TYPE_MODE (TREE_TYPE (var)),
+                                  TYPE_ALIGN (TREE_TYPE (var)));
       else
-       align = DECL_ALIGN (var);
+       align = MINIMUM_ALIGNMENT (var, DECL_MODE (var), DECL_ALIGN (var));
 
       if (crtl->stack_alignment_estimated < align)
         {
index d1d601a..2e92219 100644 (file)
@@ -199,6 +199,8 @@ extern int ix86_return_pops_args (tree, tree, int);
 extern int ix86_data_alignment (tree, int);
 extern unsigned int ix86_local_alignment (tree, enum machine_mode,
                                          unsigned int);
+extern unsigned int ix86_minimum_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 6844031..f05eb5c 100644 (file)
@@ -20087,6 +20087,41 @@ ix86_local_alignment (tree exp, enum machine_mode mode,
     }
   return align;
 }
+
+/* Compute the minimum required alignment for dynamic stack realignment
+   purposes for a local variable, parameter or a stack slot.  EXP is
+   the data type or decl itself, MODE is its mode and ALIGN is the
+   alignment that the object would ordinarily have.  */
+
+unsigned int
+ix86_minimum_alignment (tree exp, enum machine_mode mode,
+                       unsigned int align)
+{
+  tree type, decl;
+
+  if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
+    return align;
+
+  if (exp && DECL_P (exp))
+    {
+      type = TREE_TYPE (exp);
+      decl = exp;
+    }
+  else
+    {
+      type = exp;
+      decl = NULL;
+    }
+
+  /* Don't do dynamic stack realignment for long long objects with
+     -mpreferred-stack-boundary=2.  */
+  if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
+      && (!type || !TYPE_USER_ALIGN (type))
+      && (!decl || !DECL_USER_ALIGN (decl)))
+    return 32;
+
+  return align;
+}
 \f
 /* Emit RTL insns to initialize the variable parts of a trampoline.
    FNADDR is an RTX for the address of the function's pure code.
index 97483b7..f9b9dd1 100644 (file)
@@ -831,6 +831,15 @@ enum target_cpu_default
 #define LOCAL_DECL_ALIGNMENT(DECL) \
   ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL))
 
+/* If defined, a C expression to compute the minimum required alignment
+   for dynamic stack realignment purposes for EXP (a TYPE or DECL),
+   MODE, assuming normal alignment ALIGN.
+
+   If this macro is not defined, then (ALIGN) will be used.  */
+
+#define MINIMUM_ALIGNMENT(EXP, MODE, ALIGN) \
+  ix86_minimum_alignment (EXP, 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 11873a8..b6cec4b 100644 (file)
@@ -1138,6 +1138,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   LOCAL_ALIGNMENT (TREE_TYPE (DECL), DECL_ALIGN (DECL))
 #endif
 
+#ifndef MINIMUM_ALIGNMENT
+#define MINIMUM_ALIGNMENT(EXP,MODE,ALIGN) (ALIGN)
+#endif
+
 /* Alignment value for attribute ((aligned)).  */
 #ifndef ATTRIBUTE_ALIGNED_VALUE
 #define ATTRIBUTE_ALIGNED_VALUE BIGGEST_ALIGNMENT
index e328210..41ed031 100644 (file)
@@ -1227,6 +1227,14 @@ 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 MINIMUM_ALIGNMENT (@var{exp}, @var{mode}, @var{align})
+If defined, a C expression to compute the minimum required alignment
+for dynamic stack realignment purposes for @var{exp} (a type or decl),
+@var{mode}, assuming normal alignment @var{align}.
+
+If this macro is not defined, then @var{align} will be used.
+@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;}.
index df2b4b7..d20f2b5 100644 (file)
@@ -869,7 +869,11 @@ gen_reg_rtx (enum machine_mode mode)
   if (SUPPORTS_STACK_ALIGNMENT 
       && crtl->stack_alignment_estimated < align
       && !crtl->stack_realign_processed)
-    crtl->stack_alignment_estimated = align;
+    {
+      unsigned int min_align = MINIMUM_ALIGNMENT (NULL, mode, align);
+      if (crtl->stack_alignment_estimated < min_align)
+       crtl->stack_alignment_estimated = min_align;
+    }
 
   if (generating_concat_p
       && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
index 258f594..e31c12a 100644 (file)
@@ -3146,8 +3146,12 @@ assign_parms (tree fndecl)
         {
           unsigned int align = FUNCTION_ARG_BOUNDARY (data.promoted_mode,
                                                      data.passed_type);
+         align = MINIMUM_ALIGNMENT (data.passed_type, data.promoted_mode,
+                                    align);
          if (TYPE_ALIGN (data.nominal_type) > align)
-           align = TYPE_ALIGN (data.passed_type);
+           align = MINIMUM_ALIGNMENT (data.nominal_type,
+                                      TYPE_MODE (data.nominal_type),
+                                      TYPE_ALIGN (data.nominal_type));
          if (crtl->stack_alignment_estimated < align)
            {
              gcc_assert (!crtl->stack_realign_processed);