]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/34548 (GCC generates too many alignment adds for alloca)
authorRichard Henderson <rth@redhat.com>
Wed, 1 Aug 2012 20:41:16 +0000 (13:41 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 1 Aug 2012 20:41:16 +0000 (13:41 -0700)
PR 34548

* function.h (struct rtl_data): Add max_dynamic_stack_alignment.
* cfgexpand.c (gimple_expand_cfg): Initialise it.
* explow.c (allocate_dynamic_stack_space): Set it.  Simplify
alignment requirements given the known alignment of dynamic_offset.
* function.c (instantiate_virtual_regs): Align dtnamic_offset.

From-SVN: r190051

gcc/ChangeLog
gcc/cfgexpand.c
gcc/explow.c
gcc/function.c
gcc/function.h

index 9b2019fc4c1961a5559139cad9f75cd730dcd393..ea98416a494c7061959019ff8f22f6322c9f5df5 100644 (file)
@@ -1,3 +1,12 @@
+2012-08-01  Richard Henderson  <rth@redhat.com>
+
+       PR middle-end/34548
+       * function.h (struct rtl_data): Add max_dynamic_stack_alignment.
+       * cfgexpand.c (gimple_expand_cfg): Initialise it.
+       * explow.c (allocate_dynamic_stack_space): Set it.  Simplify
+       alignment requirements given the known alignment of dynamic_offset.
+       * function.c (instantiate_virtual_regs): Align dtnamic_offset.
+
 2012-08-01  Richard Henderson  <rth@redhat.com>
 
        * expmed.h (NUM_MODE_PARTIAL_INT): New.
index 96c2e2ed8a2079ee148e7279c147db6ff7a1e01a..1f165343b305568cc4c2fb16e6760144ccab160a 100644 (file)
@@ -4363,6 +4363,7 @@ gimple_expand_cfg (void)
   crtl->max_used_stack_slot_alignment = STACK_BOUNDARY;
   crtl->stack_alignment_estimated = 0;
   crtl->preferred_stack_boundary = STACK_BOUNDARY;
+  crtl->max_dynamic_stack_alignment = 0;
   cfun->cfg->max_jumptable_ents = 0;
 
   /* Resovle the function section.  Some targets, like ARM EABI rely on knowledge
index 1cfe93bc7dbd73088ca4f82ff91f15300e7e0022..c7581b0661662a141f8be46e682c182be301d8c4 100644 (file)
@@ -1173,7 +1173,6 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
 {
   HOST_WIDE_INT stack_usage_size = -1;
   rtx final_label, final_target, target;
-  unsigned extra_align = 0;
   bool must_align;
 
   /* If we're asking for zero bytes, it doesn't matter what we point
@@ -1237,58 +1236,40 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
   else if (size_align < BITS_PER_UNIT)
     size_align = BITS_PER_UNIT;
 
-  /* We can't attempt to minimize alignment necessary, because we don't
-     know the final value of preferred_stack_boundary yet while executing
-     this code.  */
-  if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
-    crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
-
   /* We will need to ensure that the address we return is aligned to
-     REQUIRED_ALIGN.  If STACK_DYNAMIC_OFFSET is defined, we don't
-     always know its final value at this point in the compilation (it
-     might depend on the size of the outgoing parameter lists, for
-     example), so we must align the value to be returned in that case.
-     (Note that STACK_DYNAMIC_OFFSET will have a default nonzero value if
-     STACK_POINTER_OFFSET or ACCUMULATE_OUTGOING_ARGS are defined).
-     We must also do an alignment operation on the returned value if
-     the stack pointer alignment is less strict than REQUIRED_ALIGN.
-
-     If we have to align, we must leave space in SIZE for the hole
-     that might result from the alignment operation.  */
-
-  must_align = (crtl->preferred_stack_boundary < required_align);
-  if (must_align)
+     REQUIRED_ALIGN.  If that alignment is no larger than
+     PREFERRED_STACK_BOUNDARY, we can handle everything without an
+     explicit alignment.  */
+  if (required_align <= PREFERRED_STACK_BOUNDARY)
     {
-      if (required_align > PREFERRED_STACK_BOUNDARY)
-       extra_align = PREFERRED_STACK_BOUNDARY;
-      else if (required_align > STACK_BOUNDARY)
-       extra_align = STACK_BOUNDARY;
-      else
-       extra_align = BITS_PER_UNIT;
+      if (crtl->preferred_stack_boundary < required_align)
+       crtl->preferred_stack_boundary = required_align;
+      if (crtl->max_dynamic_stack_alignment < required_align)
+       crtl->max_dynamic_stack_alignment = required_align;
+      must_align = false;
     }
+  else
+    {
+      unsigned extra, extra_align;
 
-  /* ??? STACK_POINTER_OFFSET is always defined now.  */
-#if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET)
-  must_align = true;
-  extra_align = BITS_PER_UNIT;
-#endif
+      crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+      crtl->max_dynamic_stack_alignment = PREFERRED_STACK_BOUNDARY;
 
-  if (must_align)
-    {
-      unsigned extra = (required_align - extra_align) / BITS_PER_UNIT;
+      extra_align = PREFERRED_STACK_BOUNDARY;
+      extra = (required_align - extra_align) / BITS_PER_UNIT;
 
       size = plus_constant (Pmode, size, extra);
       size = force_operand (size, NULL_RTX);
 
       if (flag_stack_usage_info)
        stack_usage_size += extra;
-
       if (extra && size_align > extra_align)
        size_align = extra_align;
+      must_align = true;
     }
 
   /* Round the size to a multiple of the required stack alignment.
-     Since the stack if presumed to be rounded before this allocation,
+     Since the stack is presumed to be rounded before this allocation,
      this will maintain the required alignment.
 
      If the stack grows downward, we could save an insn by subtracting
index f1e0b2d3ebac0dec6b86ca4c6ead808bacca7339..827f687f4218c72e76e81794ba0ad536debce12f 100644 (file)
@@ -1892,7 +1892,14 @@ instantiate_virtual_regs (void)
   /* Compute the offsets to use for this function.  */
   in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
   var_offset = STARTING_FRAME_OFFSET;
+
   dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
+  if (crtl->max_dynamic_stack_alignment)
+    {
+      int align = crtl->max_dynamic_stack_alignment / BITS_PER_UNIT;
+      dynamic_offset = (dynamic_offset + align - 1) & -align;
+    }
+
   out_arg_offset = STACK_POINTER_OFFSET;
 #ifdef FRAME_POINTER_CFA_OFFSET
   cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
index 3d3313fc9b3286d8b6e14f5b0bd9bb850bff0150..ed6fcb198d53d79b16f37bcd59433658ccc317f7 100644 (file)
@@ -347,6 +347,10 @@ struct GTY(()) rtl_data {
         local stack.  */
   unsigned int stack_alignment_estimated;
 
+  /* The (capped) maximum alignment of dynamic stack space, and thus the
+     required alignment of STACK_DYNAMIC_OFFSET.  */
+  unsigned int max_dynamic_stack_alignment;
+
   /* For reorg.  */
 
   /* If some insns can be deferred to the delay slots of the epilogue, the