X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FUtils%2FCloneTrace.cpp;h=07111393e2757a638fd52af0028e4bdec61380f0;hb=280a6e607d8eb7401749a92db624a82de47da777;hp=9d995464bf8dc48ccd08304971b60ebbfcf10e2e;hpb=b576c94c15af9a440f69d9d03c2afead7971118c;p=oota-llvm.git diff --git a/lib/Transforms/Utils/CloneTrace.cpp b/lib/Transforms/Utils/CloneTrace.cpp index 9d995464bf8..07111393e27 100644 --- a/lib/Transforms/Utils/CloneTrace.cpp +++ b/lib/Transforms/Utils/CloneTrace.cpp @@ -1,88 +1,119 @@ //===- 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 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. +// 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/Analysis/Trace.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/iPHINode.h" +#include "llvm/Instructions.h" #include "llvm/Function.h" - +#include "llvm/Transforms/Utils/ValueMapper.h" +using namespace llvm; //Clones the trace (a vector of basic blocks) -std::vector CloneTrace(const std::vector &origTrace) { - +std::vector +llvm::CloneTrace(const std::vector &origTrace) { std::vector clonedTrace; - std::map ValueMap; - + DenseMap 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::const_iterator T = origTrace.begin(), - End = origTrace.end(); T != End; ++T) { + for (std::vector::const_iterator T = origTrace.begin(), + End = origTrace.end(); T != End; ++T) { //Clone Basic Block - BasicBlock *clonedBlock = CloneBasicBlock(*T, ValueMap); - + 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; - //Add this cloned BB to the old BB's function - (*T)->getParent()->getBasicBlockList().push_back(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()) { + if (T != origTrace.begin()) { for (BasicBlock::iterator I = clonedBlock->begin(); - PHINode *PN = dyn_cast(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); + isa(I); ++I) { + PHINode *PN = cast(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::const_iterator BB = clonedTrace.begin(), - BE = clonedTrace.end(); BB != BE; ++BB) { - for(BasicBlock::iterator I = (*BB)->begin(); I != (*BB)->end(); ++I) { - + for (std::vector::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); + 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; } + +/// CloneTraceInto - Clone T into NewFunc. Original<->clone mapping is +/// saved in ValueMap. +/// +void llvm::CloneTraceInto(Function *NewFunc, Trace &T, + DenseMap &ValueMap, + const char *NameSuffix) { + assert(NameSuffix && "NameSuffix cannot be null!"); + + // Loop over all of the basic blocks in the trace, cloning them as + // appropriate. + // + for (Trace::const_iterator BI = T.begin(), BE = T.end(); BI != BE; ++BI) { + const BasicBlock *BB = *BI; + + // Create a new basic block and copy instructions into it! + BasicBlock *CBB = CloneBasicBlock(BB, ValueMap, NameSuffix, NewFunc); + ValueMap[BB] = CBB; // Add basic block mapping. + } + + // Loop over all of the instructions in the new function, fixing up operand + // references as we go. This uses ValueMap to do all the hard work. + // + for (Function::iterator BB = + cast(ValueMap[T.getEntryBasicBlock()]), + BE = NewFunc->end(); BB != BE; ++BB) + // Loop over all instructions, fixing each one as we find it... + for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) + RemapInstruction(II, ValueMap); +} +