From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26790 invoked by alias); 5 Dec 2002 18:56:02 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 26726 invoked by uid 71); 5 Dec 2002 18:56:02 -0000 Resent-Date: 5 Dec 2002 18:56:02 -0000 Resent-Message-ID: <20021205185602.26717.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, niemayer@isg.de Received: (qmail 22788 invoked by uid 61); 5 Dec 2002 18:53:04 -0000 Message-Id: <20021205185304.22787.qmail@sources.redhat.com> Date: Thu, 05 Dec 2002 10:56:00 -0000 From: niemayer@isg.de Reply-To: niemayer@isg.de To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: c++/8826: "a >> b" differs from "a.operator>>(b)" in that virtual function calls are not avoided X-SW-Source: 2002-12/txt/msg00288.txt.bz2 List-Id: >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: