1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00
llvm-mirror/lib/Transforms/Utils/CloneTrace.cpp
Chris Lattner aa44b4de3e Give CloneBasicBlock an optional function argument to specify which function
to add the cloned block to.  This allows the block to be added to the function
immediately, and all of the instructions to be immediately added to the function
symbol table, which speeds up the inliner from 3.7 -> 3.38s on the PR209.

llvm-svn: 11107
2004-02-04 01:19:43 +00:00

87 lines
2.9 KiB
C++

//===- CloneTrace.cpp - Clone a trace -------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the CloneTrace interface, which is used when writing
// runtime optimizations. It takes a vector of basic blocks clones the basic
// blocks, removes internal phi nodes, adds it to the same function as the
// original (although there is no jump to it) and returns the new vector of
// basic blocks.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/iPHINode.h"
#include "llvm/Function.h"
using namespace llvm;
//Clones the trace (a vector of basic blocks)
std::vector<BasicBlock *>
llvm::CloneTrace(const std::vector<BasicBlock*> &origTrace) {
std::vector<BasicBlock *> clonedTrace;
std::map<const Value*, Value*> ValueMap;
//First, loop over all the Basic Blocks in the trace and copy
//them using CloneBasicBlock. Also fix the phi nodes during
//this loop. To fix the phi nodes, we delete incoming branches
//that are not in the trace.
for(std::vector<BasicBlock *>::const_iterator T = origTrace.begin(),
End = origTrace.end(); T != End; ++T) {
//Clone Basic Block
BasicBlock *clonedBlock =
CloneBasicBlock(*T, ValueMap, ".tr", (*T)->getParent());
//Add it to our new trace
clonedTrace.push_back(clonedBlock);
//Add this new mapping to our Value Map
ValueMap[*T] = clonedBlock;
//Loop over the phi instructions and delete operands
//that are from blocks not in the trace
//only do this if we are NOT the first block
if(T != origTrace.begin()) {
for (BasicBlock::iterator I = clonedBlock->begin();
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
//get incoming value for the previous BB
Value *V = PN->getIncomingValueForBlock(*(T-1));
assert(V && "No incoming value from a BasicBlock in our trace!");
//remap our phi node to point to incoming value
ValueMap[*&I] = V;
//remove phi node
clonedBlock->getInstList().erase(PN);
}
}
}
//Second loop to do the remapping
for(std::vector<BasicBlock *>::const_iterator BB = clonedTrace.begin(),
BE = clonedTrace.end(); BB != BE; ++BB) {
for(BasicBlock::iterator I = (*BB)->begin(); I != (*BB)->end(); ++I) {
//Loop over all the operands of the instruction
for(unsigned op=0, E = I->getNumOperands(); op != E; ++op) {
const Value *Op = I->getOperand(op);
//Get it out of the value map
Value *V = ValueMap[Op];
//If not in the value map, then its outside our trace so ignore
if(V != 0)
I->setOperand(op,V);
}
}
}
//return new vector of basic blocks
return clonedTrace;
}