Improve alloca alignment
authorWilco Dijkstra <wdijkstr@arm.com>
Tue, 5 Sep 2017 13:27:58 +0000 (13:27 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Tue, 5 Sep 2017 13:27:58 +0000 (13:27 +0000)
This patch improves alloca alignment.  Currently alloca reserves
too much space as it aligns twice, and generates unnecessary stack
alignment code.

When the requested alignment is lower than the stack alignment, no
extra alignment is needed.  If the requested alignment is higher,
we need to increase the size by the difference of the requested
alignment and the stack alignment.  As a result, the alloca alignment
is exactly as expected:

alloca (16):
sub sp, sp, #16
mov x1, sp

alloca (x):
add x0, x0, 15
and x0, x0, -16
sub sp, sp, x0
mov x0, sp

__builtin_alloca_with_align (x, 512):
add x0, x0, 63
and x0, x0, -16
sub sp, sp, x0
add x0, sp, 63
and x0, x0, -64

    gcc/
* explow.c (get_dynamic_stack_size): Improve dynamic alignment.

From-SVN: r251713

gcc/ChangeLog
gcc/explow.c

index 7f5b384bca4bd160ca11e20bce60131dbd15ed1a..58d162972ba9de64dc5d002be2fb4c51ad78d380 100644 (file)
@@ -1,3 +1,7 @@
+2017-09-05  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * explow.c (get_dynamic_stack_size): Improve dynamic alignment.
+
 2017-09-05  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82084
index 13736a586d88965e442d0cc265607f9c3d06b803..638dc5f8f0fcadb4c71aa2727b4ad0a3a4a3209e 100644 (file)
@@ -1240,15 +1240,20 @@ get_dynamic_stack_size (rtx *psize, unsigned size_align,
      example), so we must preventively align the value.  We leave space
      in SIZE for the hole that might result from the alignment operation.  */
 
-  extra = (required_align - BITS_PER_UNIT) / BITS_PER_UNIT;
-  size = plus_constant (Pmode, size, extra);
-  size = force_operand (size, NULL_RTX);
-
-  if (flag_stack_usage_info && pstack_usage_size)
-    *pstack_usage_size += extra;
+  /* Since the stack is presumed to be aligned before this allocation,
+     we only need to increase the size of the allocation if the required
+     alignment is more than the stack alignment.  */
+  if (required_align > STACK_BOUNDARY)
+    {
+      extra = (required_align - STACK_BOUNDARY) / BITS_PER_UNIT;
+      size = plus_constant (Pmode, size, extra);
+      size = force_operand (size, NULL_RTX);
+      if (size_align > STACK_BOUNDARY)
+       size_align = STACK_BOUNDARY;
 
-  if (extra && size_align > BITS_PER_UNIT)
-    size_align = BITS_PER_UNIT;
+      if (flag_stack_usage_info && pstack_usage_size)
+       *pstack_usage_size += extra;
+    }
 
   /* Round the size to a multiple of the required stack alignment.
      Since the stack is presumed to be rounded before this allocation,