i386 compute_frame_size cleanups

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Wed Feb 9 07:43:00 GMT 2000


Hi
This patch cleanups the compute_stack_frame_size, avoids now unnecesary
optimizations that are handled by generic code and adds some of sanity
checking, because this code is easy to break.

The sanity checking spotted two problems. First one of over-active propagation
of alignemnt in expand_inline_function. The stack_alignment_needed is updated
correctly (in fact incorrectly, because the alignment used is BIGGEST_ALIGNMENT
instead of stack_alignment_needed of inlined function, but I will correct this
later) when the stack frame is allocated. This is not always the case, since
function may have only stack frame references that have been optimized out.

Second problem was trigered by following testcase:

x(){int y[]={};}

It forces alignment even when framesize is still 0.  My current approach to
avoid this alignment is to check for this speccase in assign_temp and allocate
NULL such arrays at NULL pointer, but I am not sure, if this is OK for
standards.

Wed Feb  9 16:38:43 MET 2000  Jan Hubicka  <jh@suse.cz>
	* function.c (assign_temp): Allocate zero-sized arrays at NULL pointer.
	* integrate.c (expand_inline_function): Do not update stack_alignment_needed
	* i386.c (compute_frame_size): Remove #ifdef PREFERRED_FRAME_BOUNDARY, add some
	sanity checking, remove optimization for function with 0 frame size.

Index: egcs/gcc/function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.158
diff -c -3 -p -r1.158 function.c
*** function.c	2000/02/08 16:32:20	1.158
--- function.c	2000/02/09 15:33:48
*************** assign_temp (type, keep, memory_required
*** 837,842 ****
--- 837,851 ----
        HOST_WIDE_INT size = int_size_in_bytes (type);
        rtx tmp;
  
+       /* Zero sized arrays can be allocated at NULL.  We need to avoid assk_stack
+ 	 machinery in order to avoid useless stack frame alignments.  */
+       if (size == 0)
+ 	{
+ 	  tmp = gen_rtx_MEM (mode, const0_rtx);
+ 	  MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
+ 	  return tmp;
+ 	}
+ 
        /* Unfortunately, we don't yet know how to allocate variable-sized
  	 temporaries.  However, sometimes we have a fixed upper limit on
  	 the size (which is stored in TYPE_ARRAY_MAX_SIZE) and can use that
Index: egcs/gcc/integrate.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/integrate.c,v
retrieving revision 1.90
diff -c -3 -p -r1.90 integrate.c
*** integrate.c	2000/02/07 17:39:40	1.90
--- integrate.c	2000/02/09 15:33:50
*************** expand_inline_function (fndecl, parms, t
*** 605,613 ****
    if (cfun->preferred_stack_boundary < inl_f->preferred_stack_boundary)
      cfun->preferred_stack_boundary = inl_f->preferred_stack_boundary;
  
-   if (cfun->stack_alignment_needed < inl_f->stack_alignment_needed)
-     cfun->stack_alignment_needed = inl_f->stack_alignment_needed;
- 
    /* Check that the parms type match and that sufficient arguments were
       passed.  Since the appropriate conversions or default promotions have
       already been applied, the machine modes should match exactly.  */
--- 605,610 ----
Index: egcs/gcc/config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.137
diff -c -3 -p -r1.137 i386.c
*** i386.c	2000/02/07 17:39:40	1.137
--- i386.c	2000/02/09 15:33:59
*************** ix86_compute_frame_size (size, nregs_on_
*** 1769,1812 ****
    int padding2 = 0;
    HOST_WIDE_INT total_size;
    int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
  
    nregs = ix86_nsaved_regs ();
    total_size = size;
  
! #ifdef PREFERRED_STACK_BOUNDARY
!   {
!     int offset;
!     int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
! 
!     offset = frame_pointer_needed ? 8 : 4;
! 
!     /* When frame is not empty we ought to have recorded the alignment.  */
!     if (size && !stack_alignment_needed)
!       abort ();
! 
!     if (stack_alignment_needed < 4)
!       stack_alignment_needed = 4;
! 
!     if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
!       abort ();
! 
!     offset += nregs * UNITS_PER_WORD;
! 
!     total_size += offset;
! 
!     /* Align start of frame for local function.  */
!     if (size > 0)
!       {
!         padding1 = ((offset + stack_alignment_needed - 1)
! 		    & -stack_alignment_needed) - offset;
!         total_size += padding1;
!       }
! 
!     /* Align stack boundary. */
!     padding2 = ((total_size + preferred_alignment - 1)
! 		& -preferred_alignment) - total_size;
!   }
! #endif
  
    if (nregs_on_stack)
      *nregs_on_stack = nregs;
--- 1769,1811 ----
    int padding2 = 0;
    HOST_WIDE_INT total_size;
    int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
+   int offset;
+   int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
  
    nregs = ix86_nsaved_regs ();
    total_size = size;
  
!   offset = frame_pointer_needed ? 8 : 4;
! 
!   /* Do some sanity checking of stack_alignment_needed and preferred_alignment,
!      since i386 port is the only using those features that may break easilly.  */
! 
!   if (size && !stack_alignment_needed)
!     abort ();
!   if (!size && stack_alignment_needed)
!     abort ();
!   if (preferred_alignment < STACK_BOUNDARY / BITS_PER_UNIT)
!     abort ();
!   if (preferred_alignment > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
!     abort ();
!   if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
!     abort ();
! 
!   if (stack_alignment_needed < 4)
!     stack_alignment_needed = 4;
! 
!   offset += nregs * UNITS_PER_WORD;
! 
!   total_size += offset;
! 
!   /* Align start of frame for local function.  */
!   padding1 = ((offset + stack_alignment_needed - 1)
! 	      & -stack_alignment_needed) - offset;
!   total_size += padding1;
! 
!   /* Align stack boundary. */
!   padding2 = ((total_size + preferred_alignment - 1)
! 	      & -preferred_alignment) - total_size;
  
    if (nregs_on_stack)
      *nregs_on_stack = nregs;


More information about the Gcc-patches mailing list