|  | //===- 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/Analysis/Trace.h" | 
|  | #include "llvm/Transforms/Utils/Cloning.h" | 
|  | #include "llvm/Instructions.h" | 
|  | #include "llvm/Function.h" | 
|  | #include "ValueMapper.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; | 
|  | DenseMap<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(); | 
|  | isa<PHINode>(I); ++I) { | 
|  | PHINode *PN = cast<PHINode>(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; | 
|  | } | 
|  |  | 
|  | /// CloneTraceInto - Clone T into NewFunc. Original<->clone mapping is | 
|  | /// saved in ValueMap. | 
|  | /// | 
|  | void llvm::CloneTraceInto(Function *NewFunc, Trace &T, | 
|  | DenseMap<const Value*, Value*> &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<BasicBlock>(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); | 
|  | } | 
|  |  |