Quoting Zdenek Dvorak <rakd...@iuuk.mff.cuni.cz>:
+ entered_at_top = loop_preheader_edge (loop)->dest == desc->in_edge->dest;
is equivalent to
+ entered_at_top = loop->header == desc->in_edge->dest;
But, I don't think it will do what you want. Loops are canonicalized so that
their latch blocks have single successors. So, desc->in_edge->dest will be
the latch block, not the header, for the loop entered at the top. I think
+ entered_at_top = (loop->latch == desc->in_edge->dest
+ && forwarder_block_p (loop->latch));
is what you want. Other than that, the patch seems ok to me,
I'm pretty sure that I checked that this did what I wanted it to do when
I wrote the code originally. Alas, that was a few years ago; the
canonicalization probably has come in in the meantime.
So I made up another test and tried it:
int f(int a, int b)
{
while (--b >= 0)
{
a <<= 1;
a += 42;
}
return a;
}
The loop appears to be entered at the top, yet both my original and your test
fail.
Looking what happens with your test in more detail, I find that
loop->latch == desc->in_edge->dest
is true, but forwarder_block_p (loop->latch) fails:
562 if (dest->loop_father->header == dest)
(gdb)
563 return false;
(gdb) p dest
$7 = (basic_block) 0xb7be8198
(gdb) p dest->loop_father->header
$8 = (basic_block) 0xb7be8198
The comment in front of this code says:
/* Protect loop latches, headers and preheaders. */
So, presumably, the loop latch will remain a forwarder block precisely because
forwarder_block_p denies that it is one.
So, may I just write:
entered_at_top = (loop->latch == desc->in_edge->dest);