calls.c cleanup 1 and better d30v crash fix

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Sat Apr 8 06:46:00 GMT 2000


Hi
The precompute_arguments take as an argument args_size and precompute alloca
(and other calls) only when args_size is nonzero, this is actually
not necesary, since only case to have parameter and args_size is 0
is to pass it in register and such parameter will get precalculated
anyway in precompute_register_arguments, so I've removed the test.

Also precompute_arguments is quite overactive on !ACCUMULATE_OUTGOING_ARGS
machines. When BLK mode operand gets passed such as:

struct a {int i[40];};
void blb(struct a);
struct a pablb(void)
main()
{
   blb(pablb());
}

finalize_must_preallocate decides to preallocate in order to make possible
evaulate pablb call directly to the blb operand. This gets disabled by
precompute_arguments since it precomputes all calls when must_precompute
is set.
I believe this was intended for ACCUMULATE_OUTGOING_ARGS only, where
arguments of nested calls conflicts (and even on such machines stack_map
code is present to guard such cases). I've checked all other purposes
for setting must_preallocate and they seems to be OK. It bootstraps
in i386, improves code somehow (especially f771 binarry by 10%)
and fixes crash on Richard's testcase, since alloca gets precomputed soon.

In the next step I would like to merge precompute_register_parameters into
precompute_arguments. Both these changes are actually part of
larger revamp of call code I have in my local tree, but I would like to use
small steps for such functionality changes. After recent fiascos with my
calls.c changes I am now trying to be curefull.


Sat Apr  8 15:40:39 MET DST 2000  Jan Hubicka  <jh@suse.cz>
	* calls.c (precompute_arguments): Remove must_preallocate and
	args_size calls.
	(expand_call): Update call of precompute_arguments.

Index: egcs/gcc/calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.115
diff -c -3 -p -r1.115 calls.c
*** calls.c	2000/04/05 01:52:54	1.115
--- calls.c	2000/04/08 13:28:13
*************** static void store_unaligned_arguments_in
*** 182,190 ****
  static int finalize_must_preallocate		PARAMS ((int, int,
  							 struct arg_data *,
  							 struct args_size *));
! static void precompute_arguments 		PARAMS ((int, int, int,
! 							 struct arg_data *,
! 							 struct args_size *));
  static int compute_argument_block_size		PARAMS ((int, 
  							 struct args_size *,
  							 int));
--- 182,189 ----
  static int finalize_must_preallocate		PARAMS ((int, int,
  							 struct arg_data *,
  							 struct args_size *));
! static void precompute_arguments 		PARAMS ((int, int,
! 							 struct arg_data *));
  static int compute_argument_block_size		PARAMS ((int, 
  							 struct args_size *,
  							 int));
*************** compute_argument_block_size (reg_parm_st
*** 1401,1423 ****
  
     FLAGS is mask of ECF_* constants.
  
-    MUST_PREALLOCATE indicates that we must preallocate stack space for
-    any stack arguments.
- 
     NUM_ACTUALS is the number of arguments.
  
     ARGS is an array containing information for each argument; this routine
!    fills in the INITIAL_VALUE and VALUE fields for each precomputed argument.
! 
!    ARGS_SIZE contains information about the size of the arg list.  */
  
  static void
! precompute_arguments (flags, must_preallocate, num_actuals, args, args_size)
       int flags;
-      int must_preallocate;
       int num_actuals;
       struct arg_data *args;
-      struct args_size *args_size;
  {
    int i;
  
--- 1400,1416 ----
  
     FLAGS is mask of ECF_* constants.
  
     NUM_ACTUALS is the number of arguments.
  
     ARGS is an array containing information for each argument; this routine
!    fills in the INITIAL_VALUE and VALUE fields for each precomputed argument.  
!    */
  
  static void
! precompute_arguments (flags, num_actuals, args)
       int flags;
       int num_actuals;
       struct arg_data *args;
  {
    int i;
  
*************** precompute_arguments (flags, must_preall
*** 1428,1446 ****
       If a parameter contains a call to alloca and this function uses the
       stack, precompute the parameter.  */
  
!   /* If we preallocated the stack space, and some arguments must be passed
       on the stack, then we must precompute any parameter which contains a
       function call which will store arguments on the stack.
       Otherwise, evaluating the parameter may clobber previous parameters
!      which have already been stored into the stack.  */
  
    for (i = 0; i < num_actuals; i++)
      if ((flags & ECF_CONST)
! 	|| ((args_size->var != 0 || args_size->constant != 0)
! 	    && calls_function (args[i].tree_value, 1))
! 	|| (must_preallocate
! 	    && (args_size->var != 0 || args_size->constant != 0)
! 	    && calls_function (args[i].tree_value, 0)))
        {
  	/* If this is an addressable type, we cannot pre-evaluate it.  */
  	if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
--- 1421,1437 ----
       If a parameter contains a call to alloca and this function uses the
       stack, precompute the parameter.  */
  
!   /* If we accumulate outgoing args and some arguments must be passed
       on the stack, then we must precompute any parameter which contains a
       function call which will store arguments on the stack.
       Otherwise, evaluating the parameter may clobber previous parameters
!      which have already been stored into the stack.  (we have code to avoid
!      such case by saving the ougoing stack arguments, but it results in
!      worse code)  */
  
    for (i = 0; i < num_actuals; i++)
      if ((flags & ECF_CONST)
! 	|| calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS))
        {
  	/* If this is an addressable type, we cannot pre-evaluate it.  */
  	if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
*************** expand_call (exp, target, ignore)
*** 2463,2470 ****
  	structure_value_addr = copy_to_reg (structure_value_addr);
  
        /* Precompute any arguments as needed.  */
!       precompute_arguments (flags, must_preallocate, num_actuals,
! 			    args, &args_size);
  
        /* Now we are about to start emitting insns that can be deleted
  	 if a libcall is deleted.  */
--- 2454,2460 ----
  	structure_value_addr = copy_to_reg (structure_value_addr);
  
        /* Precompute any arguments as needed.  */
!       precompute_arguments (flags, num_actuals, args);
  
        /* Now we are about to start emitting insns that can be deleted
  	 if a libcall is deleted.  */


More information about the Gcc-patches mailing list