[llvm] r364310 - Expand cloneLoopWithPreheader() to support cloning loop nest
Whitney Tsang via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 25 06:23:13 PDT 2019
Author: whitneyt
Date: Tue Jun 25 06:23:13 2019
New Revision: 364310
URL: http://llvm.org/viewvc/llvm-project?rev=364310&view=rev
Log:
Expand cloneLoopWithPreheader() to support cloning loop nest
Summary: cloneLoopWithPreheader() currently only support innermost loop,
and assert otherwise.
Reviewers: Meinersbur, fhahn, kbarton
Reviewed By: Meinersbur
Subscribers: hiraditya, jsji, llvm-commits
Tag: LLVM
Differential Revision: https://reviews.llvm.org/D63446
Modified:
llvm/trunk/include/llvm/Analysis/LoopInfo.h
llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h
llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=364310&r1=364309&r2=364310&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Tue Jun 25 06:23:13 2019
@@ -311,6 +311,40 @@ public:
LoopLatches.push_back(Pred);
}
+ /// Return all inner loops in the loop nest rooted by the loop in preorder,
+ /// with siblings in forward program order.
+ template <class Type>
+ static void getInnerLoopsInPreorder(const LoopT &L,
+ SmallVectorImpl<Type> &PreOrderLoops) {
+ SmallVector<LoopT *, 4> PreOrderWorklist;
+ PreOrderWorklist.append(L.rbegin(), L.rend());
+
+ while (!PreOrderWorklist.empty()) {
+ LoopT *L = PreOrderWorklist.pop_back_val();
+ // Sub-loops are stored in forward program order, but will process the
+ // worklist backwards so append them in reverse order.
+ PreOrderWorklist.append(L->rbegin(), L->rend());
+ PreOrderLoops.push_back(L);
+ }
+ }
+
+ /// Return all loops in the loop nest rooted by the loop in preorder, with
+ /// siblings in forward program order.
+ SmallVector<const LoopT *, 4> getLoopsInPreorder() const {
+ SmallVector<const LoopT *, 4> PreOrderLoops;
+ const LoopT *CurLoop = static_cast<const LoopT *>(this);
+ PreOrderLoops.push_back(CurLoop);
+ getInnerLoopsInPreorder(*CurLoop, PreOrderLoops);
+ return PreOrderLoops;
+ }
+ SmallVector<LoopT *, 4> getLoopsInPreorder() {
+ SmallVector<LoopT *, 4> PreOrderLoops;
+ LoopT *CurLoop = static_cast<LoopT *>(this);
+ PreOrderLoops.push_back(CurLoop);
+ getInnerLoopsInPreorder(*CurLoop, PreOrderLoops);
+ return PreOrderLoops;
+ }
+
//===--------------------------------------------------------------------===//
// APIs for updating loop information after changing the CFG
//
Modified: llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h?rev=364310&r1=364309&r2=364310&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopInfoImpl.h Tue Jun 25 06:23:13 2019
@@ -587,16 +587,9 @@ SmallVector<LoopT *, 4> LoopInfoBase<Blo
// FIXME: If we change the order of LoopInfo we will want to remove the
// reverse here.
for (LoopT *RootL : reverse(*this)) {
- assert(PreOrderWorklist.empty() &&
- "Must start with an empty preorder walk worklist.");
- PreOrderWorklist.push_back(RootL);
- do {
- LoopT *L = PreOrderWorklist.pop_back_val();
- // Sub-loops are stored in forward program order, but will process the
- // worklist backwards so append them in reverse order.
- PreOrderWorklist.append(L->rbegin(), L->rend());
- PreOrderLoops.push_back(L);
- } while (!PreOrderWorklist.empty());
+ auto PreOrderLoopsInRootL = RootL->getLoopsInPreorder();
+ PreOrderLoops.append(PreOrderLoopsInRootL.begin(),
+ PreOrderLoopsInRootL.end());
}
return PreOrderLoops;
Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=364310&r1=364309&r2=364310&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Tue Jun 25 06:23:13 2019
@@ -739,12 +739,12 @@ Loop *llvm::cloneLoopWithPreheader(Basic
const Twine &NameSuffix, LoopInfo *LI,
DominatorTree *DT,
SmallVectorImpl<BasicBlock *> &Blocks) {
- assert(OrigLoop->getSubLoops().empty() &&
- "Loop to be cloned cannot have inner loop");
Function *F = OrigLoop->getHeader()->getParent();
Loop *ParentLoop = OrigLoop->getParentLoop();
+ DenseMap<Loop *, Loop *> LMap;
Loop *NewLoop = LI->AllocateLoop();
+ LMap[OrigLoop] = NewLoop;
if (ParentLoop)
ParentLoop->addChildLoop(NewLoop);
else
@@ -764,17 +764,38 @@ Loop *llvm::cloneLoopWithPreheader(Basic
// Update DominatorTree.
DT->addNewBlock(NewPH, LoopDomBB);
- for (BasicBlock *BB : OrigLoop->getBlocks()) {
- BasicBlock *NewBB = CloneBasicBlock(BB, VMap, NameSuffix, F);
- VMap[BB] = NewBB;
-
- // Update LoopInfo.
- NewLoop->addBasicBlockToLoop(NewBB, *LI);
-
- // Add DominatorTree node. After seeing all blocks, update to correct IDom.
- DT->addNewBlock(NewBB, NewPH);
+ for (Loop *CurLoop : OrigLoop->getLoopsInPreorder()) {
+ for (BasicBlock *BB : CurLoop->getBlocks()) {
+ if (CurLoop != LI->getLoopFor(BB))
+ continue;
+
+ Loop *&NewLoop = LMap[CurLoop];
+ if (!NewLoop) {
+ NewLoop = LI->AllocateLoop();
+
+ // Establish the parent/child relationship.
+ Loop *OrigParent = CurLoop->getParentLoop();
+ assert(OrigParent && "Could not find the original parent loop");
+ Loop *NewParentLoop = LMap[OrigParent];
+ assert(NewParentLoop && "Could not find the new parent loop");
+
+ NewParentLoop->addChildLoop(NewLoop);
+ }
+
+ BasicBlock *NewBB = CloneBasicBlock(BB, VMap, NameSuffix, F);
+ VMap[BB] = NewBB;
+
+ // Update LoopInfo.
+ NewLoop->addBasicBlockToLoop(NewBB, *LI);
+ if (BB == CurLoop->getHeader())
+ NewLoop->moveToHeader(NewBB);
+
+ // Add DominatorTree node. After seeing all blocks, update to correct
+ // IDom.
+ DT->addNewBlock(NewBB, NewPH);
- Blocks.push_back(NewBB);
+ Blocks.push_back(NewBB);
+ }
}
for (BasicBlock *BB : OrigLoop->getBlocks()) {
More information about the llvm-commits
mailing list