PREFERRED_STACK_BOUNDARY/function calling code fix

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Fri Mar 3 06:03:00 GMT 2000


> Note that even with this patch, stack alignment is broken in some cases.
> This was not caused by your patch, but I noticed it while tracking down the
> recent breakage.  For the testcase
> 
> void *f (void *p, int i) { return p; }
> int g (int i, int j, int k) { return i; }
> 
> int main ()
> {
>   f (f (0, 1), g (2, 3, 4));
> }
Hi
Here is patch attempting to fix problems with yor fix I am aware of.
Now the arg_space_so_far is getting updater propertly in emit_library_call
and emit_library_call_value.  I've also added bit of sanity checking and
updating code on the stack adjustements after parm space.
Now the sanity  checks pass testsuite on i386 as I just verified.
Since the calling code is quite weird, I am affraid of bootstraps
on other platforms.
I am not sure, if the sanity checking will pass on machines
with parm_space, since stack adjustments necesary for parm_space are made
there and it is not completely clear to me how this does this work.


Fri Mar  3 14:52:56 MET 2000  Jan Hubicka  <jh@suse.cz>
	* calls.c (expand_call): Do sanity checking on arg_space_so_far.
	Update arg_space_so_far on stack adjustments.
	(emit_library_call, emit_library_call_value): Likewise; take into
	account arg_space_so_far and pending_stack_adjust when calculcating
	the boundary.

Index: egcs/gcc/calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.89
diff -c -3 -p -r1.89 calls.c
*** calls.c	2000/03/03 09:19:42	1.89
--- calls.c	2000/03/03 13:51:23
*************** expand_call (exp, target, ignore)
*** 1699,1704 ****
--- 1699,1705 ----
    rtx old_stack_level = 0;
    int old_pending_adj = 0;
    int old_inhibit_defer_pop = inhibit_defer_pop;
+   int old_arg_space_so_far = arg_space_so_far;
    rtx call_fusage = 0;
    register tree p;
    register int i;
*************** expand_call (exp, target, ignore)
*** 2369,2375 ****
    /* If we pushed args in forward order, perform stack alignment
       after pushing the last arg.  */
    if (argblock == 0)
!     anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size));
  #endif
  #endif
  
--- 2370,2379 ----
    /* If we pushed args in forward order, perform stack alignment
       after pushing the last arg.  */
    if (argblock == 0)
!     {
!       anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size));
!       arg_space_so_far += args_size.constant - unadjusted_args_size;
!     }
  #endif
  #endif
  
*************** expand_call (exp, target, ignore)
*** 2421,2426 ****
--- 2425,2434 ----
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       valreg, old_inhibit_defer_pop, call_fusage, is_const);
  
+   /* Stack pointer ought to be restored to the value before call.  */
+   if (old_arg_space_so_far != arg_space_so_far)
+     abort();
+ 
    /* If call is cse'able, make appropriate pair of reg-notes around it.
       Test valreg so we don't crash; may safely ignore `const'
       if return type is void.  Disable for PARALLEL return values, because
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2713,2718 ****
--- 2721,2727 ----
  	       struct args_size offset; struct args_size size; rtx save_area; };
    struct arg *argvec;
    int old_inhibit_defer_pop = inhibit_defer_pop;
+   int old_arg_space_so_far = arg_space_so_far;
    rtx call_fusage = 0;
    int reg_parm_stack_space = 0;
  #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2853,2860 ****
  
    original_args_size = args_size;
  #ifdef PREFERRED_STACK_BOUNDARY
!   args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
! 			 / STACK_BYTES) * STACK_BYTES);
  #endif
  
    args_size.constant = MAX (args_size.constant,
--- 2862,2875 ----
  
    original_args_size = args_size;
  #ifdef PREFERRED_STACK_BOUNDARY
!   args_size.constant = (((args_size.constant
! 			  + arg_space_so_far
! 			  + pending_stack_adjust
! 			  + STACK_BYTES - 1)
! 			 / STACK_BYTES
! 			 * STACK_BYTES)
! 			- arg_space_so_far
! 			- pending_stack_adjust);
  #endif
  
    args_size.constant = MAX (args_size.constant,
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2924,2931 ****
    /* If we push args individually in reverse order, perform stack alignment
       before the first push (the last arg).  */
    if (argblock == 0)
!     anti_adjust_stack (GEN_INT (args_size.constant
! 				- original_args_size.constant));
  #endif
  #endif
  
--- 2939,2949 ----
    /* If we push args individually in reverse order, perform stack alignment
       before the first push (the last arg).  */
    if (argblock == 0)
!     {
!       anti_adjust_stack (GEN_INT (args_size.constant
! 				  - original_args_size.constant));
!       arg_space_so_far += args_size.constant - original_args_size.constant;
!     }
  #endif
  #endif
  
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 3056,3061 ****
--- 3075,3081 ----
  	  emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
  			  argblock, GEN_INT (argvec[argnum].offset.constant),
  			  reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
+ 	  arg_space_so_far += argvec[argnum].size.constant;
  
  #ifdef ACCUMULATE_OUTGOING_ARGS
  	  /* Now mark the segment we just used.  */
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 3072,3079 ****
    /* If we pushed args in forward order, perform stack alignment
       after pushing the last arg.  */
    if (argblock == 0)
!     anti_adjust_stack (GEN_INT (args_size.constant
! 				- original_args_size.constant));
  #endif
  #endif
  
--- 3092,3102 ----
    /* If we pushed args in forward order, perform stack alignment
       after pushing the last arg.  */
    if (argblock == 0)
!     {
!       anti_adjust_stack (GEN_INT (args_size.constant
! 				  - original_args_size.constant));
!       arg_space_so_far += args_size.constant - original_args_size.constant;
!     }
  #endif
  #endif
  
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 3144,3149 ****
--- 3167,3176 ----
  
    pop_temp_slots ();
  
+   /* Stack pointer ought to be restored to the value before call.  */
+   if (old_arg_space_so_far != arg_space_so_far)
+     abort();
+ 
    /* Now restore inhibit_defer_pop to its actual original value.  */
    OK_DEFER_POP;
  
*************** emit_library_call_value VPARAMS((rtx org
*** 3229,3234 ****
--- 3256,3262 ----
  	       struct args_size offset; struct args_size size; rtx save_area; };
    struct arg *argvec;
    int old_inhibit_defer_pop = inhibit_defer_pop;
+   int old_arg_space_so_far = arg_space_so_far;
    rtx call_fusage = 0;
    rtx mem_value = 0;
    int pcc_struct_value = 0;
*************** emit_library_call_value VPARAMS((rtx org
*** 3441,3448 ****
  
    original_args_size = args_size;
  #ifdef PREFERRED_STACK_BOUNDARY
!   args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
! 			 / STACK_BYTES) * STACK_BYTES);
  #endif
  
    args_size.constant = MAX (args_size.constant,
--- 3469,3482 ----
  
    original_args_size = args_size;
  #ifdef PREFERRED_STACK_BOUNDARY
!   args_size.constant = (((args_size.constant
! 			  + arg_space_so_far
! 			  + pending_stack_adjust
! 			  + STACK_BYTES - 1)
! 			 / STACK_BYTES
! 			 * STACK_BYTES)
! 			- arg_space_so_far
! 			- pending_stack_adjust);
  #endif
  
    args_size.constant = MAX (args_size.constant,
*************** emit_library_call_value VPARAMS((rtx org
*** 3512,3519 ****
    /* If we push args individually in reverse order, perform stack alignment
       before the first push (the last arg).  */
    if (argblock == 0)
!     anti_adjust_stack (GEN_INT (args_size.constant
! 				- original_args_size.constant));
  #endif
  #endif
  
--- 3546,3556 ----
    /* If we push args individually in reverse order, perform stack alignment
       before the first push (the last arg).  */
    if (argblock == 0)
!     {
!       anti_adjust_stack (GEN_INT (args_size.constant
! 				  - original_args_size.constant));
!       arg_space_so_far += args_size.constant - original_args_size.constant;
!     }
  #endif
  #endif
  
*************** emit_library_call_value VPARAMS((rtx org
*** 3644,3649 ****
--- 3681,3687 ----
  	  emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
  			  argblock, GEN_INT (argvec[argnum].offset.constant),
  			  reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
+ 	  arg_space_so_far += argvec[argnum].size.constant;
  
  #ifdef ACCUMULATE_OUTGOING_ARGS
  	  /* Now mark the segment we just used.  */
*************** emit_library_call_value VPARAMS((rtx org
*** 3660,3667 ****
    /* If we pushed args in forward order, perform stack alignment
       after pushing the last arg.  */
    if (argblock == 0)
!     anti_adjust_stack (GEN_INT (args_size.constant
! 				- original_args_size.constant));
  #endif
  #endif
  
--- 3698,3708 ----
    /* If we pushed args in forward order, perform stack alignment
       after pushing the last arg.  */
    if (argblock == 0)
!     {
!       anti_adjust_stack (GEN_INT (args_size.constant
! 				  - original_args_size.constant));
!       arg_space_so_far += args_size.constant - unadjusted_args_size;
!     }
  #endif
  #endif
  
*************** emit_library_call_value VPARAMS((rtx org
*** 3744,3749 ****
--- 3785,3794 ----
    OK_DEFER_POP;
  
    pop_temp_slots ();
+ 
+   /* Stack pointer ought to be restored to the value before call.  */
+   if (old_arg_space_so_far != arg_space_so_far)
+     abort();
  
    /* Copy the value to the right place.  */
    if (outmode != VOIDmode)


More information about the Gcc-patches mailing list