This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Const/libcall function calling tweeks



Hi
The expand_call calls NO_DEFER_POP for the const functions.  I don't see any
purpose for doing that, since this only affects the nested function calls in
the arguments.  These appear outside the libcall sequence at top-level call (in
order to allow removing of the libcall easilly), so the only result is, that
the pending stack adjustments are not combined there. The testcase is:

int a(int,int) __attribute__ ((const))
;
main()
{
a(b(1),b(2));
}

The calls to functions b are emited suboptimally.  Second problem I found in
the emit_library_call functions.  These don't use the pending_stack_adjust even
for non-const functions. I expect this is artefact from times when
emit_library_call was used only for const functions.  The scheme used by
emit_library_call is quite weird. It does call NO_DEFER_POP right before
emit_call_1 and then use tricky way to restore old value.  Only effect of this
seems to be pesimization of nonconstant calls (try memset/memcpy builtins).

So I've changed emit_library_call to synchronize with emit_call.
I am getting no new testsuite failures and I can bootstrap.

Tue Mar  7 13:04:20 CET 2000  Jan Hubicka  <jh@suse.cz>
	* calls.c (expand_call): Do not do NO_DEFER_POP for const functions,
	do not flush pending stack adjustments for const functions.
	(emit_library_call): Flush pending stack adjustments for no-const
	functions; combine stack adjustments; allow using of pending_stack_adjust
	optimization.
	(emit_library_call_value): Likewise.

*** calls.c.old	Tue Mar  7 00:56:21 2000
--- calls.c	Tue Mar  7 13:03:49 2000
*************** expand_call (exp, target, ignore)
*** 1957,1972 ****
      abort ();
    funtype = TREE_TYPE (funtype);
  
-   /* When calling a const function, we must pop the stack args right away,
-      so that the pop is deleted or moved with the call.  */
-   if (is_const)
-     NO_DEFER_POP;
- 
    /* Don't let pending stack adjusts add up to too much.
       Also, do all pending adjustments now
       if there is any chance this might be a call to alloca.  */
  
!   if (pending_stack_adjust >= 32
        || (pending_stack_adjust > 0 && may_be_alloca))
      do_pending_stack_adjust ();
  
--- 1957,1967 ----
      abort ();
    funtype = TREE_TYPE (funtype);
  
    /* Don't let pending stack adjusts add up to too much.
       Also, do all pending adjustments now
       if there is any chance this might be a call to alloca.  */
  
!   if ((pending_stack_adjust >= 32 && !is_const)
        || (pending_stack_adjust > 0 && may_be_alloca))
      do_pending_stack_adjust ();
  
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2735,2740 ****
--- 2730,2742 ----
    nargs = va_arg (p, int);
  #endif
  
+   /* Don't let pending stack adjusts add up to too much.
+      Also, do all pending adjustments now
+      if there is any chance this might be a call to alloca.  */
+ 
+   if (pending_stack_adjust >= 32 && !no_queue)
+     do_pending_stack_adjust ();
+ 
    fun = orgfun;
  
    /* Copy all the libcall-arguments out of the varargs data
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2913,2921 ****
  #ifdef PREFERRED_STACK_BOUNDARY
    /* 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
  
--- 2915,2936 ----
  #ifdef PREFERRED_STACK_BOUNDARY
    /* If we push args individually in reverse order, perform stack alignment
       before the first push (the last arg).  */
!   if (args_size.constant != original_args_size.constant && argblock == 0)
!     {
!       /* When the stack adjustment is pending,
! 	 we get better code by combining the adjustments.  */
!       if (pending_stack_adjust && !no_queue && !inhibit_defer_pop)
! 	{
! 	  args_size.constant = (original_args_size.constant
! 			        + ((pending_stack_adjust + args_size.constant
! 				    - original_args_size.constant)
! 			           % (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)));
! 	  pending_stack_adjust -= args_size.constant - original_args_size.constant;
! 	  do_pending_stack_adjust ();
! 	}
!       else if (argblock == 0)
! 	anti_adjust_stack (GEN_INT (args_size.constant - original_args_size.constant));
!     }
  #endif
  #endif
  
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 3099,3110 ****
      if (argvec[count].reg != 0)
         use_reg (&call_fusage, argvec[count].reg);
  
-   /* Don't allow popping to be deferred, since then
-      cse'ing of library calls could delete a call and leave the pop.  */
-   NO_DEFER_POP;
- 
-   /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
-      will set inhibit_defer_pop to that value.  */
  
    /* The return type is needed to decide how many bytes the function pops.
       Signedness plays no role in that, so for simplicity, we pretend it's
--- 3114,3119 ----
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 3118,3130 ****
  	       original_args_size.constant, args_size.constant, 0,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop + 1, call_fusage, no_queue);
  
    pop_temp_slots ();
  
-   /* Now restore inhibit_defer_pop to its actual original value.  */
-   OK_DEFER_POP;
- 
  #ifdef ACCUMULATE_OUTGOING_ARGS
  #ifdef REG_PARM_STACK_SPACE
    if (save_area)
--- 3127,3136 ----
  	       original_args_size.constant, args_size.constant, 0,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop, call_fusage, no_queue);
  
    pop_temp_slots ();
  
  #ifdef ACCUMULATE_OUTGOING_ARGS
  #ifdef REG_PARM_STACK_SPACE
    if (save_area)
*************** emit_library_call_value VPARAMS((rtx org
*** 3248,3253 ****
--- 3254,3266 ----
    nargs = va_arg (p, int);
  #endif
  
+   /* Don't let pending stack adjusts add up to too much.
+      Also, do all pending adjustments now
+      if there is any chance this might be a call to alloca.  */
+ 
+   if (pending_stack_adjust >= 32 && !no_queue)
+     do_pending_stack_adjust ();
+ 
    is_const = no_queue;
    fun = orgfun;
  
*************** emit_library_call_value VPARAMS((rtx org
*** 3490,3498 ****
  #ifdef PREFERRED_STACK_BOUNDARY
    /* 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
  
--- 3503,3524 ----
  #ifdef PREFERRED_STACK_BOUNDARY
    /* If we push args individually in reverse order, perform stack alignment
       before the first push (the last arg).  */
!   if (args_size.constant != original_args_size.constant && argblock == 0)
!     {
!       /* When the stack adjustment is pending,
! 	 we get better code by combining the adjustments.  */
!       if (pending_stack_adjust && !is_const && !inhibit_defer_pop)
! 	{
! 	  args_size.constant = (original_args_size.constant
! 			        + ((pending_stack_adjust + args_size.constant
! 				    - original_args_size.constant)
! 			           % (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)));
! 	  pending_stack_adjust -= args_size.constant - original_args_size.constant;
! 	  do_pending_stack_adjust ();
! 	}
!       else if (argblock == 0)
! 	anti_adjust_stack (GEN_INT (args_size.constant - original_args_size.constant));
!     }
  #endif
  #endif
  
*************** emit_library_call_value VPARAMS((rtx org
*** 3689,3700 ****
  	  use_reg (&call_fusage, struct_value_rtx);
      }
  
-   /* Don't allow popping to be deferred, since then
-      cse'ing of library calls could delete a call and leave the pop.  */
-   NO_DEFER_POP;
- 
-   /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
-      will set inhibit_defer_pop to that value.  */
    /* See the comment in emit_library_call about the function type we build
       and pass here.  */
  
--- 3715,3720 ----
*************** emit_library_call_value VPARAMS((rtx org
*** 3705,3714 ****
  	       struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       mem_value == 0 ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop + 1, call_fusage, is_const);
! 
!   /* Now restore inhibit_defer_pop to its actual original value.  */
!   OK_DEFER_POP;
  
    pop_temp_slots ();
  
--- 3725,3731 ----
  	       struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       mem_value == 0 ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop, call_fusage, is_const);
  
    pop_temp_slots ();
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]