From 17b9cb181775e47fb986dae45e2e2a38b84e33cf Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Thu, 19 Aug 2021 11:41:09 -0700 Subject: [runtimeunroll] Support multiple exits to latch exit w/prolog loop This patch extends the runtime unrolling infrastructure to support unrolling a loop with multiple exiting blocks branching to the same exit block used by the latch. It intentionally does not include a cost model change to enable this functionality unless appropriate force flags are used. This is the prolog companion to D107381. Since this was LGTMed, a problem with DT updating was reported against that patch. I roled in the analogous fix here as it seemed obvious, and not worth re-review. As an aside, our prolog form leaves a lot of potential value on the floor when there is an invariant load or invariant condition in the loop being runtime unrolled. We should probably consider a "required prolog" heuristic. (Alternatively, maybe we should be peeling these cases more aggressively?) Differential Revision: https://reviews.llvm.org/D108262 --- llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp') diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index cd86552..84feb44 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -167,8 +167,11 @@ static void ConnectProlog(Loop *L, Value *BECount, unsigned Count, // Add the branch to the exit block (around the unrolled loop) B.CreateCondBr(BrLoopExit, OriginalLoopLatchExit, NewPreHeader); InsertPt->eraseFromParent(); - if (DT) - DT->changeImmediateDominator(OriginalLoopLatchExit, PrologExit); + if (DT) { + auto *NewDom = DT->findNearestCommonDominator(OriginalLoopLatchExit, + PrologExit); + DT->changeImmediateDominator(OriginalLoopLatchExit, NewDom); + } } /// Connect the unrolling epilog code to the original loop. @@ -445,14 +448,6 @@ static bool canSafelyUnrollMultiExitLoop(Loop *L, BasicBlock *LatchExit, if (!PreserveLCSSA) return false; - // TODO: Support multiple exiting blocks jumping to the `LatchExit` when - // using a prolog loop. - if (!UseEpilogRemainder && !LatchExit->getSinglePredecessor()) { - LLVM_DEBUG( - dbgs() << "Bailout for multi-exit handling when latch exit has >1 " - "predecessor.\n"); - return false; - } // FIXME: We bail out of multi-exit unrolling when epilog loop is generated // and L is an inner loop. This is because in presence of multiple exits, the // outer loop is incorrect: we do not add the EpilogPreheader and exit to the -- cgit v1.1