Fix for "Too restrictive sanity check"

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Wed Apr 19 04:06:00 GMT 2000


Hi
Interestingly this testcase exhibits two unrelated bugs.  First one is in
my sanity checking.  It is done for sibbling calls too, where it is incorrect
since my last calls.c patch (it did before).

Second is stack missalignment, that don't show actually in the code (since
another sequence is choosed by sibcall), but the purpose is obvious:
first compute_argument_block_size is used to caluculate size of argument
block to get proper alignment once they are pused and then precompute_arguments
is called that expands another call resulting in missaligning stack (and
adjusting stack_pointer_delta).

The fix is to call compute_argument_block_size later.  There are two
uses of args_size in between.  First one is in precompute_arguments.
I have patch approved to avoid this, since it is useless. Second is in
finalize_must_preallocate.  I've did same change for this code in my home
tree.  The rationale is, that finalize_must_preallocate use args_size to
decide whether it is better to precompute arguments (and direct structures
to it) or not precompute (and require pushing).  Ratio of structs over
args size is calculated and when it exceeds 50%, preallocation is done.

Author had unadjusted args size in mind here, so in fact this is third
bug fixed by this patch.

Alexandre: this obsolettes you patch, but please try to get approval for
the testcase, it is definitly interesting from the calls.c point of
view. Thank you for pointing this out.

Honza

Wed Apr 19 12:54:31 MET DST 2000  Jan Hubicka  <jh@suse.cz>
	* calls.c (expand_call): Call compute_argument_block_size right
	before allocating the block; update comment; don't do alignment
	sanity checking for sibbling call; use args_size instead of
	unadjusted_args_size before args_size is adjusted.

Index: egcs/gcc//calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.121
diff -c -3 -p -r1.121 calls.c
*** calls.c	2000/04/13 13:58:59	1.121
--- calls.c	2000/04/19 10:58:44
*************** expand_call (exp, target, ignore)
*** 2444,2462 ****
  	  sibcall_failure = 1;
  	}
  
-       /* Compute the actual size of the argument block required.  The variable
- 	 and constant sizes must be combined, the size may have to be rounded,
- 	 and there may be a minimum required size.  When generating a sibcall
- 	 pattern, do not round up, since we'll be re-using whatever space our
- 	 caller provided.  */
-       unadjusted_args_size
- 	= compute_argument_block_size (reg_parm_stack_space, &args_size,
- 				       (pass == 0 ? 0
- 					: preferred_stack_boundary));
- 
        /* If the callee pops its own arguments, then it must pop exactly
  	 the same number of arguments as the current function.  */
!       if (RETURN_POPS_ARGS (fndecl, funtype, unadjusted_args_size)
  	  != RETURN_POPS_ARGS (current_function_decl,
  			       TREE_TYPE (current_function_decl),
  			       current_function_args_size))
--- 2444,2452 ----
  	  sibcall_failure = 1;
  	}
  
        /* If the callee pops its own arguments, then it must pop exactly
  	 the same number of arguments as the current function.  */
!       if (RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
  	  != RETURN_POPS_ARGS (current_function_decl,
  			       TREE_TYPE (current_function_decl),
  			       current_function_args_size))
*************** expand_call (exp, target, ignore)
*** 2610,2615 ****
--- 2600,2615 ----
  		}
  	    }
  	}
+       /* Compute the actual size of the argument block required.  The variable
+ 	 and constant sizes must be combined, the size may have to be rounded,
+ 	 and there may be a minimum required size.  When generating a sibcall
+ 	 pattern, do not round up, since we'll be re-using whatever space our
+ 	 caller provided.  */
+       unadjusted_args_size
+ 	= compute_argument_block_size (reg_parm_stack_space, &args_size,
+ 				       (pass == 0 ? 0
+ 					: preferred_stack_boundary));
+ 
  
        /* The argument block when performing a sibling call is the
  	 incoming argument block.  */
*************** expand_call (exp, target, ignore)
*** 2817,2824 ****
  	 now!  */
  
  #ifdef PREFERRED_STACK_BOUNDARY
!       /* Stack must to be properly aligned now.  */
!       if (stack_pointer_delta & (preferred_stack_boundary / BITS_PER_UNIT - 1))
  	abort();
  #endif
  
--- 2817,2826 ----
  	 now!  */
  
  #ifdef PREFERRED_STACK_BOUNDARY
!       /* Stack must be properly aligned now.  */
!       if (pass &&
! 	  (stack_pointer_delta
! 	   & (preferred_stack_boundary / BITS_PER_UNIT - 1)))
  	abort();
  #endif
  
*************** emit_library_call_value_1 (retval, orgfu
*** 3722,3728 ****
  	    ? hard_libcall_value (outmode) : NULL_RTX);
  
  #ifdef PREFERRED_STACK_BOUNDARY
!   /* Stack must to be properly aligned now.  */
    if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))
      abort();
  #endif
--- 3724,3730 ----
  	    ? hard_libcall_value (outmode) : NULL_RTX);
  
  #ifdef PREFERRED_STACK_BOUNDARY
!   /* Stack must be properly aligned now.  */
    if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))
      abort();
  #endif


More information about the Gcc-patches mailing list