diff options
author | David Green <david.green@arm.com> | 2018-04-01 12:48:24 +0000 |
---|---|---|
committer | David Green <david.green@arm.com> | 2018-04-01 12:48:24 +0000 |
commit | f80ebc8d214115c1887854aa37965fb799c8b6ef (patch) | |
tree | 43c781ebdf68b4c02a0fe2a4526454a5b6be15a2 /llvm/lib/Transforms/Utils/LoopRotationUtils.cpp | |
parent | c16815ca8abc496778d34e7acb6aa25bb0f29176 (diff) | |
download | llvm-f80ebc8d214115c1887854aa37965fb799c8b6ef.zip llvm-f80ebc8d214115c1887854aa37965fb799c8b6ef.tar.gz llvm-f80ebc8d214115c1887854aa37965fb799c8b6ef.tar.bz2 |
[LoopRotate] Rotate loops with loop exiting latches
If a loop has a loop exiting latch, it can be profitable
to rotate the loop if it leads to the simplification of
a phi node. Perform rotation in these cases even if loop
rotate itself didnt simplify the loop to get there.
Differential Revision: https://reviews.llvm.org/D44199
llvm-svn: 328933
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopRotationUtils.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopRotationUtils.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 0853826..529a0ec 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -163,6 +163,27 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader, } } +// Look for a phi which is only used outside the loop (via a LCSSA phi) +// in the exit from the header. This means that rotating the loop can +// remove the phi. +static bool shouldRotateLoopExitingLatch(Loop *L) { + BasicBlock *Header = L->getHeader(); + BasicBlock *HeaderExit = Header->getTerminator()->getSuccessor(0); + if (L->contains(HeaderExit)) + HeaderExit = Header->getTerminator()->getSuccessor(1); + + for (auto &Phi : Header->phis()) { + // Look for uses of this phi in the loop/via exits other than the header. + if (llvm::any_of(Phi.users(), [HeaderExit](const User *U) { + return cast<Instruction>(U)->getParent() != HeaderExit; + })) + continue; + return true; + } + + return false; +} + /// Rotate loop LP. Return true if the loop is rotated. /// /// \param SimplifiedLatch is true if the latch was just folded into the final @@ -197,8 +218,9 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { return false; // Rotate if either the loop latch does *not* exit the loop, or if the loop - // latch was just simplified. - if (L->isLoopExiting(OrigLatch) && !SimplifiedLatch) + // latch was just simplified. Or if we think it will be profitable. + if (L->isLoopExiting(OrigLatch) && !SimplifiedLatch && + !shouldRotateLoopExitingLatch(L)) return false; // Check size of original header and reject loop if it is very big or we can't |