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