diff options
author | Philip Reames <listmail@philipreames.com> | 2021-09-02 16:29:20 -0700 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2021-09-02 16:29:20 -0700 |
commit | fa82a3d016c9fb82c1b81834fa18cd4c797735a0 (patch) | |
tree | 3c0cac17cf5f938993c17a674a7ed5a56c00e941 /llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | |
parent | 45c672e20d40be1f6dfc68ff0ee5347c91833d7c (diff) | |
download | llvm-fa82a3d016c9fb82c1b81834fa18cd4c797735a0.zip llvm-fa82a3d016c9fb82c1b81834fa18cd4c797735a0.tar.gz llvm-fa82a3d016c9fb82c1b81834fa18cd4c797735a0.tar.bz2 |
[runtimeunroll] Support epilogue unrolling with a parent loop
This patch adds support for unrolling inner loops using epilogue unrolling. The basic issue is that the original latch exit block of the inner loop could be outside the outer loop. When we clone the inner loop and split the latch exit, the cloned blocks need to be in the outer loop.
Differential Revision: https://reviews.llvm.org/D108476
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 105c628f..be062b4 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -423,14 +423,6 @@ static bool canSafelyUnrollMultiExitLoop(Loop *L, BasicBlock *LatchExit, if (!PreserveLCSSA) 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 - // outer loop. This is automatically handled in the prolog case, so we do not - // have that bug in prolog generation. - if (UseEpilogRemainder && L->getParentLoop()) - return false; - // All constraints have been satisfied. return true; } @@ -456,6 +448,11 @@ static bool canProfitablyUnrollMultiExitLoop( if (!LatchExit->getSinglePredecessor()) return false; + // TODO: We used to bail out for correctness (now fixed). Under what + // circumstances is this case profitable to allow? + if (UseEpilogRemainder && L->getParentLoop()) + return false; + // The main pain point with multi-exit loop unrolling is that once unrolled, // we will not be able to merge all blocks into a straight line code. // There are branches within the unrolled loop that go to the OtherExits. @@ -729,6 +726,21 @@ bool llvm::UnrollRuntimeLoopRemainder( // Split NewExit to insert epilog remainder loop. EpilogPreHeader = SplitBlock(NewExit, NewExitTerminator, DT, LI); EpilogPreHeader->setName(Header->getName() + ".epil.preheader"); + + // If the latch exits from multiple level of nested loops, then + // by assumption there must be another loop exit which branches to the + // outer loop and we must adjust the loop for the newly inserted blocks + // to account for the fact that our epilogue is still in the same outer + // loop. Note that this leaves loopinfo temporarily out of sync with the + // CFG until the actual epilogue loop is inserted. + if (auto *ParentL = L->getParentLoop()) + if (LI->getLoopFor(LatchExit) != ParentL) { + LI->removeBlock(NewExit); + ParentL->addBasicBlockToLoop(NewExit, *LI); + LI->removeBlock(EpilogPreHeader); + ParentL->addBasicBlockToLoop(EpilogPreHeader, *LI); + } + } else { // If prolog remainder // Split the original preheader twice to insert prolog remainder loop |