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

            Bug ID: 89713
           Summary: Optimize away an empty loop whose finiteness can not
                    be analytically determined
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fxue at os dot amperecomputing.com
  Target Milestone: ---

C++ stl container-based loop is very common, but its low representation looks
like irregular, not standard form of [index, step], there is no way to estimate
iteration, or even check whether it is finite or infinite only via static
analysis. Current gcc can not optimize away an empty stl loop as the following
(case in bug 89134,comment 6), although we know a vector/map must be a finite
set.

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

Gimple dump is:

  <bb 2> [local count: 118111600]:
  # VUSE <.MEM_2(D)>
  _4 = MEM[(struct _Rb_tree_node_base * *)m_3(D) + 24B];
  _11 = &MEM[(struct _Rb_tree *)m_3(D)]._M_impl.D.34825._M_header;
  if (_4 != _11)
    goto <bb 3>; [89.00%]
  else
    goto <bb 4>; [11.00%]

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

  <bb 4> [local count: 118111601]:

The iteration variable is re-assigned by std::_Rb_tree_increment(), a pure
function, more than a simple add/dec instruction.

As mentioned in bug 82776, comment 8, we might assume it is a finite empty loop
covered by implementation suggestion of C++ spec.

"[intro.progress]
The implementation may assume that any thread will eventually do one of the
following:
(1.1) — terminate,
(1.2) — make a call to a library I/O function,
(1.3) — perform an access through a volatile glvalue, or
(1.4) — perform a synchronization operation or an atomic operation.
[ Note: This is intended to allow compiler transformations such as removal of
empty loops, even when termination cannot be proven. — end note ]"

We may do something on this. A rough thought is to introduce a flag(such as
-fno-infinite-loop, or whatever name) to tell gcc characteristic of being
compiled source, like -fstrict-aliasing. This flag is disabled by default,
enabled explicitly, and could be correlated with
-faggressive-loop-optimization. And invoke a dce optimization dedicated to
this, late in gcc passes, in hope of not impacting true infinite loop.

Reply via email to