diff options
author | Whitney Tsang <whitney.uwaterloo@gmail.com> | 2019-06-25 13:23:13 +0000 |
---|---|---|
committer | Whitney Tsang <whitney.uwaterloo@gmail.com> | 2019-06-25 13:23:13 +0000 |
commit | 7c1deeff4a67296654823a871fea5c1a2aef3b8a (patch) | |
tree | fd020bc08ee4acee322d1d6510186aa93c8fb328 /llvm/lib/Transforms/Utils/CloneFunction.cpp | |
parent | dcd8b72e1a7ee9ad8a9d435eb540757ce735979f (diff) | |
download | bcm5719-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.cpp | 41 |
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()) { |