This is the mail archive of the gcc-bugs@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]

bad interaction between inlining and sibcall optimization?


Attached below is a small test program that demonstrates what appears
to be a bad interaction between inlining and the "sibcall"
optimization.  Specifically, if I compile the program with the gcc 3.0
branch configured for IA-64 using the command "gcc -O3 fac.c", then
fac1() gets inlined into fac() as expected, but the inlined recursive
call to fac() is not being treated as a "sibcall".  In contrast, if I
drop the optimization level to -O2, both fac() and fac1() are sibcall
optimized, but of course no inlining is done that way.

Is this something that can be fixed with a reasonable amount of
effort?  For the toy program below, doing both inlining and sibcall
optimization makes a difference of more than 50% (I measured this by
manually tweaking the assembly code generated by gcc).

On a related note, it appears to me that the following code in sibcall.c:

	  /* We must be careful with stack slots which are live at
	     potential optimization sites.

	     ?!? This test is overly conservative and will be replaced.  */
	  if (frame_offset)
	    goto failure;

prevents this optimization from being used whenever the callee needs a
stack frame.  I suspect this prevents many cases where this
optimization could be used profitably.  Especially in latency
sensitive code, reducing the amount of stack memory being touched can
make a big difference performance-wise.  So I'm wondering whether it
would be possible to change this code so it wouldn't be quite so
conservative.

I should say that I'm very happy that the sibcall optimization has
made its way into gcc.  Thanks for implementing it!

	--david

<-- fac.c --><-- fac.c --><-- fac.c --><-- fac.c --><-- fac.c -->
#include <stdio.h>

static double fac (double factor, double n);

double
fac1 (double factor, double n)
{
  if (n == 0.0)
    return factor;

  factor *= n;
  return fac (factor, n - 1.0);
}

double
fac (double factor, double n)
{
  if (n == 0.0)
    return factor;

  factor *= n;
  return fac1 (factor, n - 1.0);
}

int
main (int argc, char **argv)
{
  return fac (1.0, 170.0);
}


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