diff options
| author | Florian Hahn <florian.hahn@arm.com> | 2018-09-26 19:34:25 +0000 |
|---|---|---|
| committer | Florian Hahn <florian.hahn@arm.com> | 2018-09-26 19:34:25 +0000 |
| commit | 6feb637124e5bf5a3bb45c1b2106d622b93e7c28 (patch) | |
| tree | ca308325099cf164a112bd309bfdf4bd7d41e347 /llvm/lib/Transforms | |
| parent | 79c88c31056fc52f8414c497f2d6e2e53749c48b (diff) | |
| download | bcm5719-llvm-6feb637124e5bf5a3bb45c1b2106d622b93e7c28.tar.gz bcm5719-llvm-6feb637124e5bf5a3bb45c1b2106d622b93e7c28.zip | |
[LoopInterchange] Preserve LCSSA.
This patch extends LoopInterchange to move LCSSA to the right place
after interchanging. This is required for LoopInterchange to become a
function pass.
An alternative to the manual moving of the PHIs, we could also re-form
the LCSSA phis for a set of interchanged loops, but that's more
expensive.
Reviewers: efriedma, mcrosier, davide
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D52154
llvm-svn: 343132
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index 38c9396b954..3be41646741 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -411,8 +411,6 @@ private: bool adjustLoopLinks(); void adjustLoopPreheaders(); bool adjustLoopBranches(); - void updateIncomingBlock(BasicBlock *CurrBlock, BasicBlock *OldPred, - BasicBlock *NewPred); Loop *OuterLoop; Loop *InnerLoop; @@ -455,6 +453,7 @@ struct LoopInterchange : public FunctionPass { AU.addPreserved<DominatorTreeWrapperPass>(); AU.addPreserved<LoopInfoWrapperPass>(); AU.addPreserved<ScalarEvolutionWrapperPass>(); + AU.addPreservedID(LCSSAID); } bool runOnFunction(Function &F) override { @@ -1297,9 +1296,8 @@ static void moveBBContents(BasicBlock *FromBB, Instruction *InsertBefore) { FromBB->getTerminator()->getIterator()); } -void LoopInterchangeTransform::updateIncomingBlock(BasicBlock *CurrBlock, - BasicBlock *OldPred, - BasicBlock *NewPred) { +static void updateIncomingBlock(BasicBlock *CurrBlock, BasicBlock *OldPred, + BasicBlock *NewPred) { for (PHINode &PHI : CurrBlock->phis()) { unsigned Num = PHI.getNumIncomingValues(); for (unsigned i = 0; i < Num; ++i) { @@ -1330,6 +1328,52 @@ static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB, } } +// Move Lcssa PHIs to the right place. +static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerLatch, + BasicBlock *OuterLatch) { + SmallVector<PHINode *, 8> LcssaInnerExit; + for (PHINode &P : InnerExit->phis()) + LcssaInnerExit.push_back(&P); + + SmallVector<PHINode *, 8> LcssaInnerLatch; + for (PHINode &P : InnerLatch->phis()) + LcssaInnerLatch.push_back(&P); + + // Lcssa PHIs for values used outside the inner loop are in InnerExit. + // If a PHI node has users outside of InnerExit, it has a use outside the + // interchanged loop and we have to preserve it. We move these to + // InnerLatch, which will become the new exit block for the innermost + // loop after interchanging. For PHIs only used in InnerExit, we can just + // replace them with the incoming value. + for (PHINode *P : LcssaInnerExit) { + bool hasUsersOutside = false; + for (auto UI = P->use_begin(), E = P->use_end(); UI != E;) { + Use &U = *UI; + ++UI; + auto *Usr = cast<Instruction>(U.getUser()); + if (Usr->getParent() != InnerExit) { + hasUsersOutside = true; + continue; + } + U.set(P->getIncomingValueForBlock(InnerLatch)); + } + if (hasUsersOutside) + P->moveBefore(InnerLatch->getFirstNonPHI()); + else + P->eraseFromParent(); + } + + // If the inner loop latch contains LCSSA PHIs, those come from a child loop + // and we have to move them to the new inner latch. + for (PHINode *P : LcssaInnerLatch) + P->moveBefore(InnerExit->getFirstNonPHI()); + + // Now adjust the incoming blocks for the LCSSA PHIs. + // For PHIs moved from Inner's exit block, we need to replace Inner's latch + // with the new latch. + updateIncomingBlock(InnerLatch, InnerLatch, OuterLatch); +} + bool LoopInterchangeTransform::adjustLoopBranches() { LLVM_DEBUG(dbgs() << "adjustLoopBranches called\n"); std::vector<DominatorTree::UpdateType> DTUpdates; @@ -1409,17 +1453,6 @@ bool LoopInterchangeTransform::adjustLoopBranches() { updateSuccessor(InnerLoopLatchPredecessorBI, InnerLoopLatch, InnerLoopLatchSuccessor, DTUpdates); - // Adjust PHI nodes in InnerLoopLatchSuccessor. Update all uses of PHI with - // the value and remove this PHI node from inner loop. - SmallVector<PHINode *, 8> LcssaVec; - for (PHINode &P : InnerLoopLatchSuccessor->phis()) - LcssaVec.push_back(&P); - - for (PHINode *P : LcssaVec) { - Value *Incoming = P->getIncomingValueForBlock(InnerLoopLatch); - P->replaceAllUsesWith(Incoming); - P->eraseFromParent(); - } if (OuterLoopLatchBI->getSuccessor(0) == OuterLoopHeader) OuterLoopLatchSuccessor = OuterLoopLatchBI->getSuccessor(1); @@ -1431,12 +1464,15 @@ bool LoopInterchangeTransform::adjustLoopBranches() { updateSuccessor(OuterLoopLatchBI, OuterLoopLatchSuccessor, InnerLoopLatch, DTUpdates); - updateIncomingBlock(OuterLoopLatchSuccessor, OuterLoopLatch, InnerLoopLatch); - DT->applyUpdates(DTUpdates); restructureLoops(OuterLoop, InnerLoop, InnerLoopPreHeader, OuterLoopPreHeader); + moveLCSSAPhis(InnerLoopLatchSuccessor, InnerLoopLatch, OuterLoopLatch); + // For PHIs in the exit block of the outer loop, outer's latch has been + // replaced by Inners'. + updateIncomingBlock(OuterLoopLatchSuccessor, OuterLoopLatch, InnerLoopLatch); + // Now update the reduction PHIs in the inner and outer loop headers. SmallVector<PHINode *, 4> InnerLoopPHIs, OuterLoopPHIs; for (PHINode &PHI : drop_begin(InnerLoopHeader->phis(), 1)) |

