[llvm-commits] [llvm] r40997 - in /llvm/trunk: include/llvm/Transforms/Utils/Cloning.h lib/Transforms/Utils/CloneLoop.cpp
Devang Patel
dpatel at apple.com
Fri Aug 10 10:59:48 PDT 2007
Author: dpatel
Date: Fri Aug 10 12:59:47 2007
New Revision: 40997
URL: http://llvm.org/viewvc/llvm-project?rev=40997&view=rev
Log:
Add utility to clone loops.
Added:
llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp
Modified:
llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=40997&r1=40996&r2=40997&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Fri Aug 10 12:59:47 2007
@@ -25,6 +25,10 @@
class Module;
class Function;
+class Loop;
+class LoopInfo;
+class Pass;
+class LPPassManager;
class BasicBlock;
class Value;
class CallInst;
@@ -99,6 +103,11 @@
ClonedCodeInfo *CodeInfo = 0);
+/// CloneLoop - Clone Loop. Clone dominator info for loop insiders. Populate ValueMap
+/// using old blocks to new blocks mapping.
+Loop *CloneLoop(Loop *L, LPPassManager *LPM, LoopInfo *LI,
+ DenseMap<const Value *, Value *> &ValueMap, Pass *P);
+
/// CloneFunction - Return a copy of the specified function, but without
/// embedding the function into another module. Also, any references specified
/// in the ValueMap are changed to refer to their mapped value instead of the
Added: llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp?rev=40997&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp (added)
+++ llvm/trunk/lib/Transforms/Utils/CloneLoop.cpp Fri Aug 10 12:59:47 2007
@@ -0,0 +1,149 @@
+//===- CloneLoop.cpp - Clone loop nest ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and 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/Dominators.h"
+#include "llvm/ADT/DenseMap.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,
+ DenseMap<const Value *, Value *> &ValueMap,
+ DominatorTree *DT,
+ DominanceFrontier *DF) {
+
+ assert (DT && "DominatorTree is not available");
+ DenseMap<const Value *, Value*>::iterator BI = ValueMap.find(BB);
+ assert (BI != ValueMap.end() && "BasicBlock clone is missing");
+ BasicBlock *NewBB = cast<BasicBlock>(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;
+ DenseMap<const Value *, Value*>::iterator BBDomI = ValueMap.find(BBDom);
+ if (BBDomI != ValueMap.end()) {
+ NewBBDom = cast<BasicBlock>(BBDomI->second);
+ if (!DT->getNode(NewBBDom))
+ CloneDominatorInfo(BBDom, ValueMap, 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;
+ DenseMap<const Value*, Value*>::iterator IDM = ValueMap.find(DB);
+ if (IDM != ValueMap.end())
+ NewDFSet.insert(cast<BasicBlock>(IDM->second));
+ else
+ NewDFSet.insert(DB);
+ }
+ }
+ DF->addBasicBlock(NewBB, NewDFSet);
+ }
+}
+
+/// CloneLoop - Clone Loop. Clone dominator info. Populate ValueMap
+/// using old blocks to new blocks mapping.
+Loop *llvm::CloneLoop(Loop *OrigL, LPPassManager *LPM, LoopInfo *LI,
+ DenseMap<const Value *, Value *> &ValueMap, Pass *P) {
+
+ DominatorTree *DT = NULL;
+ DominanceFrontier *DF = NULL;
+ if (P) {
+ DT = P->getAnalysisToUpdate<DominatorTree>();
+ DF = P->getAnalysisToUpdate<DominanceFrontier>();
+ }
+
+ SmallVector<BasicBlock *, 16> NewBlocks;
+ SmallVector<std::pair<Loop *, Loop::iterator>, 8> LoopNest;
+ LoopNest.push_back(std::make_pair(OrigL, OrigL->begin()));
+
+ Loop *NewLoop = NULL;
+ while (!LoopNest.empty()) {
+ Loop *L = LoopNest.back().first;
+ Loop::iterator SubLoop = LoopNest.back().second;
+
+ // Handle sub loops.
+ if (SubLoop != L->end()) {
+ Loop *SL = *SubLoop;
+ LoopNest.push_back(std::make_pair(SL, SL->begin()));
+ }
+
+ LoopNest.pop_back();
+ NewLoop = new Loop();
+ 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, ValueMap, ".clone");
+ ValueMap[BB] = NewBB;
+ if (P)
+ LPM->cloneBasicBlockSimpleAnalysis(BB, NewBB, L);
+ NewLoop->addBasicBlockToLoop(NewBB, *LI);
+ 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, ValueMap, DT, DF);
+ }
+
+ }
+
+ // Remap instructions to reference operands from ValueMap.
+ for(SmallVector<BasicBlock *, 16>::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);
+ DenseMap<const Value *, Value *>::iterator OpItr = ValueMap.find(Op);
+ if (OpItr != ValueMap.end())
+ Insn->setOperand(index, OpItr->second);
+ }
+ }
+ }
+
+ BasicBlock *Latch = OrigL->getLoopLatch();
+ Function *F = Latch->getParent();
+ F->getBasicBlockList().insert(Latch, NewBlocks.begin(), NewBlocks.end());
+
+ return NewLoop;
+}
More information about the llvm-commits
mailing list