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

--- Comment #6 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
This looks like a class of problems we could easily get if we wanted.  The
pattern is:

PREHEADER
    |
    |
    V
  HEADER --> LOOPEXIT
    |
    |
    V
   SUCC
    |  \
    |   \
   DEAD  \
     |   /
     |  /
     | v
   XXXXXX

On the PREHEADER->HEADER->SUCC path we want to know if the edge out of SUCC can
be statically determined.  The threader can't do this for a number of reasons. 
First, we'd be essentially peeling an iteration.  Second, IIUC, we'd be
rotating the loop.

However, there's no reason we can't catch this in a loop optimizer like we did
with the loopch pass.  This is the exact type of problem that is trivially
handled by the path solver, which is quite cheap when you don't have to do full
path discovery like the threader has to do.

Something like:

gimple *control = gimple_outgoing_range_stmt_p (succ);
if (control) {
  auto_vec<basic_block> bbs (3);
  bbs.quick_push (preheader);
  bbs.quick_push (header);
  bbs.quick_push (succ);

  int_range<2> r;
  path_range_query query;
  query.compute_ranges (bbs);
  query.range_of_stmt (r, control);
  if (r == desired_static_value...)
    peel();
...
}

If "dead code on the first iteration" is something we want to handle, I could
help with the ranger bits if someone gives me a hand with the loop bits.

Reply via email to