public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* c++/10528: Unexpected loop un-optimization when removing a field of a class
@ 2003-04-28 22:06 have
  0 siblings, 0 replies; only message in thread
From: have @ 2003-04-28 22:06 UTC (permalink / raw)
  To: gcc-gnats


>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)   #  <variable>._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:


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-04-28 22:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-28 22:06 c++/10528: Unexpected loop un-optimization when removing a field of a class have

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