This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: optimization/902: x86 optimization bug with sibling call and -fomit-frame-pointer
- To: nobody at gcc dot gnu dot org
- Subject: Re: optimization/902: x86 optimization bug with sibling call and -fomit-frame-pointer
- From: Richard Henderson <rth at redhat dot com>
- Date: 29 Nov 2000 00:26:00 -0000
- Cc: gcc-prs at gcc dot gnu dot org,
- Reply-To: Richard Henderson <rth at redhat dot com>
The following reply was made to PR optimization/902; it has been noted by GNATS.
From: Richard Henderson <rth@redhat.com>
To: Fergus Henderson <fjh@cs.mu.oz.au>
Cc: gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: optimization/902: x86 optimization bug with sibling call and -fomit-frame-pointer
Date: Tue, 28 Nov 2000 16:19:23 -0800
On Mon, Nov 27, 2000 at 10:06:43PM +1100, Fergus Henderson wrote:
> static void empty(void)
> {
> }
>
> static void foo (int a, int * b, int c, int * d)
> {
> malloc(20);
> empty();
> }
We recognize that empty does nothing and mark it CONST. This leads us to
/* 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 (flags & (ECF_CONST | ECF_PURE))
NO_DEFER_POP;
For some reason, do_pending_stack_adjust does nothing if NO_DEFER_POP
is active. I found this highly confusing, but didn't have the guts to
change it, since it has been that way since before egcs forked in '97.
The simple fix is to move this code fragment down 10 lines.
Bootstrapped on i686 with -O2 -fomit-frame-pointer.
r~
* calls.c (expand_call): Defer const/pure NO_DEFER_POP until
after sibcall do_pending_stack_adjust.
Index: calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.166
diff -c -p -d -r1.166 calls.c
*** calls.c 2000/11/28 19:34:59 1.166
--- calls.c 2000/11/28 23:15:49
*************** expand_call (exp, target, ignore)
*** 2657,2667 ****
expand_start_target_temps ();
}
- /* 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 (flags & (ECF_CONST | ECF_PURE))
- 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 or if we are expanding a sibling
--- 2657,2662 ----
*************** expand_call (exp, target, ignore)
*** 2670,2675 ****
--- 2665,2675 ----
|| (pending_stack_adjust > 0 && (flags & ECF_MAY_BE_ALLOCA))
|| pass == 0)
do_pending_stack_adjust ();
+
+ /* 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 (flags & (ECF_CONST | ECF_PURE))
+ NO_DEFER_POP;
/* Push the temporary stack slot level so that we can free any
temporaries we make. */