This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
little epilogue optimization
- To: egcs-patches at cygnus dot com
- Subject: little epilogue optimization
- From: Ulrich Drepper <drepper at cygnus dot com>
- Date: 27 Jun 1998 23:55:27 -0700
- Reply-To: drepper at cygnus dot com (Ulrich Drepper)
The little patch appended adds an optimization suggested in Intel's
docs. Frames of size 4 or 8 should be removed using pop and not add.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Index: i386.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.32
diff -d -u -p -r1.32 i386.c
--- i386.c 1998/06/21 00:26:50 1.32
+++ i386.c 1998/06/28 06:53:37
@@ -2346,14 +2346,52 @@ ix86_epilogue (do_rtl)
else if (tsize)
{
- /* If there is no frame pointer, we must still release the frame. */
- xops[0] = GEN_INT (tsize);
+ /* Intel's docs say that for 4 or 8 bytes of stack frame one should
+ use `pop' and not `add'. */
+ int use_pop = tsize == 4;
- if (do_rtl)
- emit_insn (gen_rtx (SET, VOIDmode, xops[2],
- gen_rtx (PLUS, SImode, xops[2], xops[0])));
+ if (tsize == 8)
+ {
+ rtx retval = current_function_return_rtx;
+
+ xops[1] = gen_rtx_REG (SImode, 1); /* %edx */
+
+ /* This case is a bit more complex. Since we cannot pop into
+ %ecx twice we need a second register. But this is only
+ available if the return value is not of DImode in which
+ case the %edx register is not available. */
+ use_pop = (retval == NULL
+ || ! reg_overlap_mentioned_p (xops[1], retval));
+ }
+
+ if (use_pop)
+ {
+ xops[0] = gen_rtx_REG (SImode, 2); /* %ecx */
+
+ if (do_rtl)
+ {
+ emit_insn (gen_pop (xops[0]));
+ if (tsize == 8)
+ emit_insn (gen_pop (xops[1]));
+ }
+ else
+ {
+ output_asm_insn ("pop%L0 %0", xops);
+ if (tsize == 8)
+ output_asm_insn ("pop%L1 %1", xops);
+ }
+ }
else
- output_asm_insn (AS2 (add%L2,%0,%2), xops);
+ {
+ /* If there is no frame pointer, we must still release the frame. */
+ xops[0] = GEN_INT (tsize);
+
+ if (do_rtl)
+ emit_insn (gen_rtx (SET, VOIDmode, xops[2],
+ gen_rtx (PLUS, SImode, xops[2], xops[0])));
+ else
+ output_asm_insn (AS2 (add%L2,%0,%2), xops);
+ }
}
#ifdef FUNCTION_BLOCK_PROFILER_EXIT
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If somebody can suggest a way that the two generated pops get not
separated it would be perfect.
--
---------------. drepper at gnu.org ,-. 1325 Chesapeake Terrace
Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA
Cygnus Solutions `--' drepper at cygnus.com `------------------------