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]

little epilogue optimization


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   `------------------------


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