From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27988 invoked by alias); 28 Apr 2003 22:06:01 -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 27968 invoked by uid 71); 28 Apr 2003 22:06:01 -0000 Resent-Date: 28 Apr 2003 22:06:01 -0000 Resent-Message-ID: <20030428220601.27967.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, have@ann.jussieu.fr Received: (qmail 25920 invoked by uid 48); 28 Apr 2003 21:59:54 -0000 Message-Id: <20030428215954.25919.qmail@sources.redhat.com> Date: Mon, 28 Apr 2003 22:06:00 -0000 From: have@ann.jussieu.fr Reply-To: have@ann.jussieu.fr To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: c++/10528: Unexpected loop un-optimization when removing a field of a class X-SW-Source: 2003-04/txt/msg01280.txt.bz2 List-Id: >Number: 10528 >Category: c++ >Synopsis: Unexpected loop un-optimization when removing a field of a class >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Mon Apr 28 22:06:01 UTC 2003 >Closed-Date: >Last-Modified: >Originator: have@ann.jussieu.fr >Release: 3.3 >Organization: >Environment: Linux i686 >Description: Removing a field of a class implies a loop un-optimization [2 useless mov in asm code] Asm code of main loop of go1 function, with 'optimize' field .L5: cmpl %ecx, %eax je .L21 addl (%eax), %ebx # c addl $4, %eax jmp .L5 Asm code without 'optimize' field .L5: movl 4(%ebx), %eax cmpl %edx, %eax je .L20 addl (%eax), %ecx # c addl $4, %eax movl %eax, 4(%ebx) # ._M_current jmp .L5 We can see that 2 movl operations slow down the code. Previous release of g++ never optimize this part [same (slow) code with or without the field] >How-To-Repeat: No flag about alignement, loop or reg moves optimizations change this behaviour. Compile the following piece of code (extracted from STL vector by removing unused code and templates) and look at asm code. Removing comment on 'optimize' field (WI class) optimizes go1 function loop. [go2 function is given as reference] -----------%<----------------------------- class const_iterator { protected: typedef const int * _Iterator; typedef const int & _Reference; _Iterator _M_current; public: const_iterator () : _M_current(0) { } const_iterator (const _Iterator& __i) : _M_current(__i) { } _Reference operator*() const { return *_M_current; } const_iterator & operator++() { ++_M_current; return *this; } const _Iterator& base() const { return _M_current; } }; inline bool operator==(const const_iterator & __lhs, const const_iterator & __rhs) { return __lhs.base() == __rhs.base(); } inline bool operator!=(const const_iterator & __lhs, const const_iterator & __rhs) { return __lhs.base() != __rhs.base(); } class vector { protected: int* _M_start; int* _M_finish; int* _M_end_of_storage; public: typedef int value_type; public: const_iterator begin() const { return const_iterator (_M_start); } const_iterator end() const { return const_iterator (_M_finish); } explicit vector(unsigned __n) { _M_start = new int[__n]; _M_finish = _M_start; } }; class WI { private: const vector & object; const_iterator _iterator; // int optimize; public: WI(const vector &in) : object(in), _iterator(in.begin()) { } inline void operator++() { ++_iterator; } inline int operator*() const { return *_iterator; } inline bool end() const { return _iterator == object.end(); } }; int go1(const vector & v1) { int c = 0; for(WI i(v1);!i.end();++i) c += *i; return c; } int go2(const vector & v2) { int c = 0; for(const_iterator i = v2.begin();i != v2.end();++i) c += *i; return c; } int main(void) { vector v(10); go1(v); go2(v); } >Fix: >Release-Note: >Audit-Trail: >Unformatted: