https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89134

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-02-01
     Ever confirmed|0                           |1

--- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> ---
The optimized dump of the following function:

  void f (std::map<int, int> m)
  {
    for (auto it = m.begin (); it != m.end (); ++it);
  }

shows the following loop:

  <bb 3> [local count: 955630224]:
  # it_14 = PHI <_4(2), _7(3)>
  _7 = std::_Rb_tree_increment (it_14);
  if (_7 != _11)
    goto <bb 3>; [89.00%]
  else
    goto <bb 4>; [11.00%]

The _Rb_tree_increment() function that implements the iterator increment is
declared pure in libstdc++-v3/include/bits/stl_tree.h:

   __attribute__ ((__pure__)) _Rb_tree_node_base*
    _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();

and defined in libstdc++-v3/src/c++98/tree.cc, so GCC should be able to make
use of the pure attribute to eliminate the loop since pure functions cannot
change the observable state of the program.  (This works when
_Rb_tree_increment() is defined in the test case above so that GCC sees that
its definition does, in fact, meet the requirements of a pure function.)

So I can confirm that GCC doesn't eliminate the empty loop.  Once the loop
contains calls to functions that aren't pure (like do_something() in comment
#0) the same optimization would no longer be valid.

Reply via email to