public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* 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

* 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

* 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

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 10:56 c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided niemayer
2002-12-05 11:34 bangerth
2003-05-02 12:06 Giovanni Bajo

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).