//===- CloneLoop.cpp - Clone loop nest ------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the CloneLoop interface which makes a copy of a loop. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/BasicBlock.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/DominanceFrontier.h" using namespace llvm; /// CloneDominatorInfo - Clone basicblock's dominator tree and, if available, /// dominance info. It is expected that basic block is already cloned. static void CloneDominatorInfo(BasicBlock *BB, ValueToValueMapTy &VMap, DominatorTree *DT, DominanceFrontier *DF) { assert (DT && "DominatorTree is not available"); ValueToValueMapTy::iterator BI = VMap.find(BB); assert (BI != VMap.end() && "BasicBlock clone is missing"); BasicBlock *NewBB = cast(BI->second); // NewBB already got dominator info. if (DT->getNode(NewBB)) return; assert (DT->getNode(BB) && "BasicBlock does not have dominator info"); // Entry block is not expected here. Infinite loops are not to cloned. assert (DT->getNode(BB)->getIDom() && "BasicBlock does not have immediate dominator"); BasicBlock *BBDom = DT->getNode(BB)->getIDom()->getBlock(); // NewBB's dominator is either BB's dominator or BB's dominator's clone. BasicBlock *NewBBDom = BBDom; ValueToValueMapTy::iterator BBDomI = VMap.find(BBDom); if (BBDomI != VMap.end()) { NewBBDom = cast(BBDomI->second); if (!DT->getNode(NewBBDom)) CloneDominatorInfo(BBDom, VMap, DT, DF); } DT->addNewBlock(NewBB, NewBBDom); // Copy cloned dominance frontiner set if (DF) { DominanceFrontier::DomSetType NewDFSet; DominanceFrontier::iterator DFI = DF->find(BB); if ( DFI != DF->end()) { DominanceFrontier::DomSetType S = DFI->second; for (DominanceFrontier::DomSetType::iterator I = S.begin(), E = S.end(); I != E; ++I) { BasicBlock *DB = *I; ValueToValueMapTy::iterator IDM = VMap.find(DB); if (IDM != VMap.end()) NewDFSet.insert(cast(IDM->second)); else NewDFSet.insert(DB); } } DF->addBasicBlock(NewBB, NewDFSet); } } /// CloneLoop - Clone Loop. Clone dominator info. Populate VMap /// using old blocks to new blocks mapping. Loop *llvm::CloneLoop(Loop *OrigL, LPPassManager *LPM, LoopInfo *LI, ValueToValueMapTy &VMap, Pass *P) { DominatorTree *DT = NULL; DominanceFrontier *DF = NULL; if (P) { DT = P->getAnalysisIfAvailable(); DF = P->getAnalysisIfAvailable(); } SmallVector NewBlocks; // Populate loop nest. SmallVector LoopNest; LoopNest.push_back(OrigL); Loop *NewParentLoop = NULL; do { Loop *L = LoopNest.pop_back_val(); Loop *NewLoop = new Loop(); if (!NewParentLoop) NewParentLoop = NewLoop; LPM->insertLoop(NewLoop, L->getParentLoop()); // Clone Basic Blocks. for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BasicBlock *BB = *I; BasicBlock *NewBB = CloneBasicBlock(BB, VMap, ".clone"); VMap[BB] = NewBB; if (P) LPM->cloneBasicBlockSimpleAnalysis(BB, NewBB, L); NewLoop->addBasicBlockToLoop(NewBB, LI->getBase()); NewBlocks.push_back(NewBB); } // Clone dominator info. if (DT) for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BasicBlock *BB = *I; CloneDominatorInfo(BB, VMap, DT, DF); } // Process sub loops for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) LoopNest.push_back(*I); } while (!LoopNest.empty()); // Remap instructions to reference operands from VMap. for(SmallVector::iterator NBItr = NewBlocks.begin(), NBE = NewBlocks.end(); NBItr != NBE; ++NBItr) { BasicBlock *NB = *NBItr; for(BasicBlock::iterator BI = NB->begin(), BE = NB->end(); BI != BE; ++BI) { Instruction *Insn = BI; for (unsigned index = 0, num_ops = Insn->getNumOperands(); index != num_ops; ++index) { Value *Op = Insn->getOperand(index); ValueToValueMapTy::iterator OpItr = VMap.find(Op); if (OpItr != VMap.end()) Insn->setOperand(index, OpItr->second); } } } BasicBlock *Latch = OrigL->getLoopLatch(); Function *F = Latch->getParent(); F->getBasicBlockList().insert(OrigL->getHeader(), NewBlocks.begin(), NewBlocks.end()); return NewParentLoop; }