Inlining Improvements

Martin v. Loewis martin@loewis.home.cs.tu-berlin.de
Wed Dec 22 00:35:00 GMT 1999


> The RTL inlining happens too late, after some objects have already been
> assigned to memory.  Thus passing an automatic struct or C++ class to an
> inline function often results in dead stores when the RTL inliner is used.

Given this hint, I would guess that the code

struct A{
  int i;
  int j;
};

inline
int foo(struct A a)
{
  return a.i+a.j;
}

int bar()
{
  struct A a = {1,2};
  return foo(a);
}

should compile better now, right? Compiled with g++ -V2.95.2 -O2
-fomit-frame-pointer, I get

bar__Fv:
.LFB1:
	subl $28,%esp
.LCFI0:
	movl $0,8(%esp)
	movl $1,8(%esp)
	movl 8(%esp),%eax
	movl $0,12(%esp)
	movl $2,12(%esp)
	movl 12(%esp),%edx
	addl %edx,%eax
	addl $28,%esp
.LCFI1:
	ret
.LFE1:

I can clearly see the dead stores you are talking about. Now let's try
2.96 19991221:

bar__Fv:
.LFB1:
	subl	$28, %esp
.LCFI0:
	movl	$1, %eax
	movl	$2, %edx
	movl	%eax, 8(%esp)
	movl	$3, %eax
	movl	%edx, 12(%esp)
	addl	$28, %esp
	ret
.LFE1:

Yes, it does eliminate some of the dead stores. Now compile it as
plain C (with either 2.95, or the new back-end):

bar:
	movl $3,%eax
	ret

So C is still much better than C++. I understand that 2.96 still
stores the final state of "a", because it believes the address of a
was taken, but I'm surprised it can't emit

	movl	$1, 8(%esp)
	movl	$2, 12(%esp)
	movl	$3, %eax
	ret

since the values of %eax and %edx are not used after the store,
anymore. Also, the stack manipulation seems unnecessary. I was blaming
it on exception handling, but -fno-exceptions does not improve the
code.

Regards,
Martin


More information about the Gcc mailing list