This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Const/libcall function calling tweeks
- To: egcs-patches at egcs dot cygnus dot com, rth at cygnus dot com
- Subject: Const/libcall function calling tweeks
- From: Jan Hubicka <hubicka at atrey dot karlin dot mff dot cuni dot cz>
- Date: Tue, 7 Mar 2000 15:07:08 +0100
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 ();