Drop excess size used for run time allocated stack variables.

* get_dynamic_stack_size is passed a SIZE of a data block (which is
  allocated elsewhere), the SIZE_ALIGN of the SIZE (i.e. the alignment
  of the underlying memory units (e.g. 32 bytes split into 4 times 8
  bytes = 64 bit alignment) and the REQUIRED_ALIGN of the data portion
  of the allocated memory.

* Assuming the function is called with SIZE = 2, SIZE_ALIGN = 8 and
  REQUIRED_ALIGN = 64 it first adds 7 bytes to SIZE -> 9.  This is
  what is needed to have two bytes 8-byte-aligned at some memory
  location without any known alignment.

* Finally round_push is called to round up SIZE to a multiple of the
  stack slot size.

The key to understanding this is that the function assumes that
STACK_DYNMAIC_OFFSET is completely unknown at the time its called
and therefore it does not make assumptions about the alignment of
STACKPOINTER + STACK_DYNMAIC_OFFSET.  The latest patch simply
hard-codes that SP + SDO is supposed to be aligned to at least
stack slot size (and does that in a very complicated way).  Since
there is no guarantee that this is the case on all targets, the
patch is broken.  It may miscalculate a SIZE that is too small in
some cases.

However, on many targets there is some guarantee about the
alignment of SP + SDO even if the actual value of SDO is unknown.
On s390x it's always 8-byte-aligned (stack slot size).  So the
right fix should be to add knowledge about the target's guaranteed
alignment of SP + SDO to the function.  I'm right now testing a
much simpler patch that uses
REGNO_POINTER_ALIGN(VIRTUAL_STACK_DYNAMIC_REGNUM) as the
alignment.


gcc/ChangeLog:

2016-08-23  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	* explow.c (get_dynamic_stack_size): Take known alignment of stack
	pointer + STACK_DYNAMIC_OFFSET into account when calculating the
	size needed.  Correct a typo in a comment.

From-SVN: r239688
This commit is contained in:
Dominik Vogt 2016-08-23 09:20:15 +00:00 committed by Andreas Krebbel
parent 7e11f46f12
commit 1135a1330c
2 changed files with 17 additions and 4 deletions

View file

@ -1,3 +1,10 @@
2016-08-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* explow.c (get_dynamic_stack_size): Take known alignment of stack
pointer + STACK_DYNAMIC_OFFSET into account when calculating the size
needed.
Correct a typo in a comment.
2016-08-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* config/s390/s390.md ("*andc_split"): New splitter for and with

View file

@ -1224,9 +1224,15 @@ 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);
unsigned known_align = REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM);
if (known_align == 0)
known_align = BITS_PER_UNIT;
if (required_align > known_align)
{
extra = (required_align - known_align) / 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;
@ -1235,7 +1241,7 @@ get_dynamic_stack_size (rtx *psize, unsigned size_align,
size_align = BITS_PER_UNIT;
/* 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