[NFC] [LoopPeel] Update IDoms of non-loop blocks dominated by the loop
authorMax Kazantsev <mkazantsev@azul.com>
Tue, 26 Oct 2021 06:09:07 +0000 (13:09 +0700)
committerMax Kazantsev <mkazantsev@azul.com>
Tue, 26 Oct 2021 06:09:07 +0000 (13:09 +0700)
commitd4c74cd4e8f321a63154fb7fc442399b38a69935
tree9ec32074798e9c6859946d04854bbfa229a6f162
parentb43a2aee4ee946d8897880e824f4b09fe4c46143
[NFC] [LoopPeel] Update IDoms of non-loop blocks dominated by the loop

When peeling a loop, we assume that the latch has a `br` terminator and that
all loop exits are either terminated with an `unreachable` or have a terminating
deoptimize call. So when we peel off the 1st iteration, we change the IDom of
all loop exits to the peeled copy of `NCD(IDom(Exit), Latch)`. This works now,
but if we add logic to support loops with exits that are followed by a block
with an `unreachable` or a terminating deoptimize call, changing the exit's idom
wouldn't be enough and DT would be broken.

For example, let `Exit1` and `Exit2` are loop exits, and each of them
unconditionally branches to the same `unreachable` terminated block. So neither
of the exits dominates this unreachable block. If we change the IDoms of the
exits to some peeled loop block, we don't update the dominators of the unreachable
block. Currently we just don't get to the peeling logic, saying that we can't peel
such loops.

Previously we stored exits' IDoms in a map before peeling a loop and then, after
peeling off one iteration, we changed their IDoms.
Now we use the same logic not only for exits but for all non-loop blocks dominated
by the loop.
So when we add logic to support peeling loops with exits which branch, for example,
to an unreachable-terminated block, we would update the IDoms not only for exits,
but for their successors.

Patch by Dmitry Makogon!

Differential Revision: https://reviews.llvm.org/D111611
Reviewed By: mkazantsev, nikic
llvm/lib/Transforms/Utils/LoopPeel.cpp