freebsd-dev/contrib/llvm/lib/Transforms/Utils/CloneLoop.cpp
Ed Schouten ffd1746d03 Upgrade our Clang in base to r108428.
This commit merges the latest LLVM sources from the vendor space. It
also updates the build glue to match the new sources. Clang's version
number is changed to match LLVM's, which means /usr/include/clang/2.0
has been renamed to /usr/include/clang/2.8.

Obtained from:	projects/clangbsd
2010-07-20 17:16:57 +00:00

152 lines
5.0 KiB
C++

//===- 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/Dominators.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,
ValueMap<const Value *, Value *> &VMap,
DominatorTree *DT,
DominanceFrontier *DF) {
assert (DT && "DominatorTree is not available");
ValueMap<const Value *, Value*>::iterator BI = VMap.find(BB);
assert (BI != VMap.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;
ValueMap<const Value *, Value*>::iterator BBDomI = VMap.find(BBDom);
if (BBDomI != VMap.end()) {
NewBBDom = cast<BasicBlock>(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;
ValueMap<const Value*, Value*>::iterator IDM = VMap.find(DB);
if (IDM != VMap.end())
NewDFSet.insert(cast<BasicBlock>(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,
ValueMap<const Value *, Value *> &VMap, Pass *P) {
DominatorTree *DT = NULL;
DominanceFrontier *DF = NULL;
if (P) {
DT = P->getAnalysisIfAvailable<DominatorTree>();
DF = P->getAnalysisIfAvailable<DominanceFrontier>();
}
SmallVector<BasicBlock *, 16> NewBlocks;
// Populate loop nest.
SmallVector<Loop *, 8> 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<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);
ValueMap<const Value *, Value *>::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;
}