PR 34548
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Aug 2012 20:41:16 +0000 (20:41 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Aug 2012 20:41:16 +0000 (20:41 +0000)
* 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.

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

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

index 9b2019f..ea98416 100644 (file)
@@ -1,5 +1,14 @@
 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.
        (NUM_MODE_VECTOR_INT, NUM_MODE_IP_INT, NUM_MODE_IPV_INT): New.
        (struct expmed_op_cheap): Size one array on NUM_MODE_IPV_INT.
index 96c2e2e..1f16534 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 1cfe93b..c7581b0 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 f1e0b2d..827f687 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 3d3313f..ed6fcb1 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