summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/CloneFunction.cpp
diff options
context:
space:
mode:
authorWhitney Tsang <whitney.uwaterloo@gmail.com>2019-06-25 13:23:13 +0000
committerWhitney Tsang <whitney.uwaterloo@gmail.com>2019-06-25 13:23:13 +0000
commit7c1deeff4a67296654823a871fea5c1a2aef3b8a (patch)
treefd020bc08ee4acee322d1d6510186aa93c8fb328 /llvm/lib/Transforms/Utils/CloneFunction.cpp
parentdcd8b72e1a7ee9ad8a9d435eb540757ce735979f (diff)
downloadbcm5719-llvm-7c1deeff4a67296654823a871fea5c1a2aef3b8a.tar.gz
bcm5719-llvm-7c1deeff4a67296654823a871fea5c1a2aef3b8a.zip
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 llvm-svn: 364310
Diffstat (limited to 'llvm/lib/Transforms/Utils/CloneFunction.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp41
1 files changed, 31 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 5dd7a5bd8c7..9e160342c8c 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -739,12 +739,12 @@ Loop *llvm::cloneLoopWithPreheader(BasicBlock *Before, BasicBlock *LoopDomBB,
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(BasicBlock *Before, BasicBlock *LoopDomBB,
// Update DominatorTree.
DT->addNewBlock(NewPH, LoopDomBB);
- for (BasicBlock *BB : OrigLoop->getBlocks()) {
- BasicBlock *NewBB = CloneBasicBlock(BB, VMap, NameSuffix, F);
- VMap[BB] = NewBB;
+ 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();
- // Update LoopInfo.
- NewLoop->addBasicBlockToLoop(NewBB, *LI);
+ // 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);
+ }
- // Add DominatorTree node. After seeing all blocks, update to correct IDom.
- DT->addNewBlock(NewBB, NewPH);
+ BasicBlock *NewBB = CloneBasicBlock(BB, VMap, NameSuffix, F);
+ VMap[BB] = NewBB;
- Blocks.push_back(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);
+ }
}
for (BasicBlock *BB : OrigLoop->getBlocks()) {
OpenPOWER on IntegriCloud