[PATCH] Fix DECL_ALIGN during expand with dynamic stack realignment (PR target/44542)

Jakub Jelinek jakub@redhat.com
Thu Jun 17 12:39:00 GMT 2010


Hi!

As discussed in the PR, with dynamic stack realignment (== x86_64/i686
right now) expand_one_stack_var_at sometimes sets DECL_ALIGN to a too high
value, bigger than what the stack will be actually aligned.

The purpose of the expand_one_stack_var_at munging of DECL_ALIGN is likely
that if a decl with small requested alignment is given some very nicely
aligned offset  we shouldn't hide that fact from the expanders.
The alignment is computed just from the offset though, so say for
offset 64 it sets DECL_ALIGN to 512 bits.  It needs to
take into account alignment of the stack as well though, the decl
is only aligned to 512 bits in that case if the base is at least that much
aligned.  Without dynamic stack realignment we should know that already
(and, the patch shouldn't change anything for those), with dynamic stack
realignment we unfortunately don't know the final alignment yet, but we should
know some lower boundary for it.

The last hunk is just to make sure the so computed DECL_ALIGN isn't later on
considered again for stack realignment purposes.  On the 4.4 branch
expand_one_var could be called for the same variable more than once, on the
trunk it is unclear whether that can happen and is just a latent issue.
I'm aware that Michael suggested doing the adjustments only for
!really_expand, but we never call it with !really_expand at -O0 and for -O1+
we call it too early (during inlining etc.), rather than right before the
actual expansion.

Bootstrapped/regtested on x86_64-linux and i686-linux.  Ok for trunk?

2010-06-17  Jakub Jelinek  <jakub@redhat.com>

	PR target/44542
	* cfgexpand.c (expand_one_stack_var_at): Limit align to maximum
	of max_used_stack_slot_alignment and PREFERRED_STACK_BOUNDARY
	instead of MAX_SUPPORTED_STACK_ALIGNMENT.
	(expand_one_var): Don't consider DECL_ALIGN for variables for
	which expand_one_stack_var_at has been already called.

--- gcc/cfgexpand.c.jj	2010-06-17 08:16:56.000000000 +0200
+++ gcc/cfgexpand.c	2010-06-17 10:16:35.000000000 +0200
@@ -706,7 +706,7 @@ static void
 expand_one_stack_var_at (tree decl, HOST_WIDE_INT offset)
 {
   /* Alignment is unsigned.   */
-  unsigned HOST_WIDE_INT align;
+  unsigned HOST_WIDE_INT align, max_align;
   rtx x;
 
   /* If this fails, we've overflowed the stack frame.  Error nicely?  */
@@ -723,10 +723,12 @@ expand_one_stack_var_at (tree decl, HOST
       offset -= frame_phase;
       align = offset & -offset;
       align *= BITS_PER_UNIT;
+      max_align = MAX (crtl->max_used_stack_slot_alignment,
+		       PREFERRED_STACK_BOUNDARY);
       if (align == 0)
 	align = STACK_BOUNDARY;
-      else if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
-	align = MAX_SUPPORTED_STACK_ALIGNMENT;
+      else if (align > max_align)
+	align = max_align;
 
       DECL_ALIGN (decl) = align;
       DECL_USER_ALIGN (decl) = 0;
@@ -931,6 +933,19 @@ expand_one_var (tree var, bool toplevel,
 	align = MINIMUM_ALIGNMENT (TREE_TYPE (var),
 				   TYPE_MODE (TREE_TYPE (var)),
 				   TYPE_ALIGN (TREE_TYPE (var)));
+      else if (DECL_HAS_VALUE_EXPR_P (var)
+	       || (DECL_RTL_SET_P (var)
+		   && MEM_P (DECL_RTL (var))
+		   && (XEXP (DECL_RTL (var), 0) == virtual_stack_vars_rtx
+		       || (GET_CODE (XEXP (DECL_RTL (var), 0)) == PLUS
+			   && XEXP (XEXP (DECL_RTL (var), 0), 0)
+			      == virtual_stack_vars_rtx
+			   && CONST_INT_P (XEXP (XEXP (DECL_RTL (var), 0), 1))))))
+	/* Don't consider debug only variables with DECL_HAS_VALUE_EXPR_P set
+	   or variables which were assigned a stack slot already by
+	   expand_one_stack_var_at - in the latter case DECL_ALIGN has been
+	   changed from the offset chosen to it.  */
+	align = crtl->stack_alignment_estimated;
       else
 	align = MINIMUM_ALIGNMENT (var, DECL_MODE (var), DECL_ALIGN (var));
 

	Jakub



More information about the Gcc-patches mailing list