public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided
@ 2002-12-05 11:34 bangerth
0 siblings, 0 replies; 3+ messages in thread
From: bangerth @ 2002-12-05 11:34 UTC (permalink / raw)
To: gcc-bugs, gcc-prs, niemayer, nobody
Synopsis: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided
State-Changed-From-To: open->analyzed
State-Changed-By: bangerth
State-Changed-When: Thu Dec 5 11:34:07 2002
State-Changed-Why:
Confirmed. This is a very annoying bug, which would be nice
if someone looked at it soon, since there should really
be no reason why the two calls are treated differently; this
raises the question whether there are more _correctness_
problems lurking somewhere. Note that the code uses
a.operator>>(y)
not
a.A::operator>>(y)
!
In any case, removing the asm labels that only are there to
help reading the asm code, the second function where the
virtual function call is elided is compiled into
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
movl %ebp, %esp
popl %ebp
incl %eax
ret
which is a far cry from optimal. Essentially, the computation
of the function's value has been scheduled after the
epilog, but then pro- and epilog could be merged and
deleted. This is not done.
Things are a little better with -fomit-frame-pointer:
subl $28, %esp
movl 32(%esp), %eax
addl $28, %esp
incl %eax
ret
but still not optimal.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8826
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided
@ 2003-05-02 12:06 Giovanni Bajo
0 siblings, 0 replies; 3+ messages in thread
From: Giovanni Bajo @ 2003-05-02 12:06 UTC (permalink / raw)
To: nobody; +Cc: gcc-prs
The following reply was made to PR c++/8826; it has been noted by GNATS.
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: <gcc-gnats@gcc.gnu.org>,
<gcc-bugs@gcc.gnu.org>,
<nobody@gcc.gnu.org>,
<gcc-prs@gcc.gnu.org>,
<niemayer@isg.de>
Cc:
Subject: Re: c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided
Date: Fri, 2 May 2003 13:56:18 +0200
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8826
Reconfirmed with everything up to current mainline (20030430). I agree this
is a serious performance pessimization and it should be handled as soon as
possible.
I don't think there are any correctness problem though, since the compiler
knows that a is exactly of type A (it's not a reference or a pointer), so
it's always ok to inline the method, even without specifying
a.A::operator>>() explitally.
Giovanni Bajo
^ permalink raw reply [flat|nested] 3+ messages in thread
* c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided
@ 2002-12-05 10:56 niemayer
0 siblings, 0 replies; 3+ messages in thread
From: niemayer @ 2002-12-05 10:56 UTC (permalink / raw)
To: gcc-gnats
>Number: 8826
>Category: c++
>Synopsis: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: pessimizes-code
>Submitter-Id: net
>Arrival-Date: Thu Dec 05 10:56:02 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Peter Niemayer
>Release: gcc-3.x (x < 3)
>Organization:
>Environment:
linux / x86
>Description:
The compiler tries to avoid unneccessary virtual function
calls, which can sometimes cause dramatic performance
improvements, but alas, it fails to do so when one of two
possible (and IMHO equivalent) syntaxes is used when invoking
an operator member function.
This may seem very harmless as the code still works, but
the optimization is missing in a very often used scenario,
for calls that are done very frequently...
>How-To-Repeat:
Compile the following tiny piece of C++ source optimized
into assember, and have a look at the two code sequences
between the "testlabel?" pairs:
class A {
public:
virtual int operator>>(int x) { return x+1; }
};
int testfunc1(int y) {
A a;
asm volatile("testlabel1: ");
int r = a >> y;
asm volatile("testlabel2: ");
return r;
}
int testfunc2(int y) {
A a;
asm volatile("testlabel3: ");
int r = a.operator>>(y);
asm volatile("testlabel4: ");
return r;
}
(use "gcc -S test.cxx -O3" or similar)
You'll see that while the second function body is well
optimized, inlining just the necessary addition, the first
and most often used form is turned into badly optimized
code, doing an unneccessary virtual function call:
...
testlabel1:
#NO_APP
movl %edx, (%esp)
movl 8(%ebp), %eax
movl %eax, 4(%esp)
call *_ZTV1A+8
#APP
testlabel2:
- versus -
testlabel3:
#NO_APP
movl 8(%ebp), %eax
incl %eax
#APP
testlabel4:
>Fix:
The only work-around I've found is to use the awkward
"a.operator>>(b)" syntax, which is not only clumsy to
type but also fails to be valid when the operator function
is a two-argument global function rather than a member
function.
>Release-Note:
>Audit-Trail:
>Unformatted:
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-05-02 12:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-05 11:34 c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided bangerth
-- strict thread matches above, loose matches on Subject: below --
2003-05-02 12:06 Giovanni Bajo
2002-12-05 10:56 niemayer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).