https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78468

--- Comment #18 from Dominik Vogt <vogt at linux dot vnet.ibm.com> ---
Another approach may be to make the middleend ask the backend for the actual
value of REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM).  Since on Sparc
the address is always 4 mod 8, we'd get an additional gap for *each* alloca()
if the size is still required to be a multiple of STACK_BOUNDARY.

To prevent this it would also be necessary to adapt the logic in
explow.c:get_dynamic_stack_size().  Since a recent patch this function also
uses REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) as the alignment of the
beginning of that block, but still rounds the size up to a multiple of
STACK_BOUNDARY (explow.c:round_push()):

-- get_dynamic_stack_size() --
  /* Round the size to a multiple of the required stack alignment. 
     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 
     SIZE from the stack pointer and then aligning the stack pointer. 
     The problem with this is that the stack pointer may be unaligned 
     between the execution of the subtraction and alignment insns and 
     some machines do not allow this.  Even on those that do, some 
     signal handlers malfunction if a signal should occur between those 
     insns.  Since this is an extremely rare event, we have no reliable 
     way of knowing which systems have this problem.  So we avoid even 
     momentarily mis-aligning the stack.  */ 
  if (size_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0) 
    { 
      size = round_push (size); 
-- END --

-- round_push() --
/* Round the size of a block to be pushed up to the boundary required 
   by this machine.  SIZE is the desired size, which need not be constant.  */ 

static rtx 
round_push (rtx size) 
{ 
  rtx align_rtx, alignm1_rtx; 

  if (!SUPPORTS_STACK_ALIGNMENT 
      || crtl->preferred_stack_boundary == MAX_SUPPORTED_STACK_ALIGNMENT) 
    { 
      int align = crtl->preferred_stack_boundary / BITS_PER_UNIT; 

      if (align == 1) 
        return size; 

      if (CONST_INT_P (size)) 
        ...

      align_rtx = GEN_INT (align); 
      alignm1_rtx = GEN_INT (align - 1); 

-- END --

It looks quite tricky to change this code to deal with preferred_stack_boundary
and REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) at the same time.  What
if REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) is maller than
STACK_BOUNDARY and preferred_stack_boundary is larger than STACK_BOUNDARY?

In the end, both approaches result in the same amount of memory being
allocated.

Reply via email to