本文整理汇总了C++中basicblock::iterator::op_end方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::op_end方法的具体用法?C++ iterator::op_end怎么用?C++ iterator::op_end使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类basicblock::iterator
的用法示例。
在下文中一共展示了iterator::op_end方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: generateIdentityMapping
ValueToValueMapTy* MCJITHelper::generateIdentityMapping(Function* F) {
ValueToValueMapTy* VMap = new ValueToValueMapTy();
// arguments
for (Function::arg_iterator argIt = F->arg_begin(), argEnd = F->arg_end(); argIt != argEnd; ++argIt) {
(*VMap)[argIt] = argIt;
}
// TODO: metadata (also in the body?)
for (Function::iterator bbIt = F->begin(), bbEnd = F->end(); bbIt != bbEnd; ++bbIt) {
// basic blocks
(*VMap)[bbIt] = bbIt;
// TODO: BB.hasAddressTaken() ?
for (BasicBlock::iterator insIt = bbIt->begin(), insEnd = bbIt->end(); insIt != insEnd; ++insIt) {
// instructions
(*VMap)[insIt] = insIt;
/** Code adapted from MapValue() called by RemapInstruction() **/
// operators
for (User::op_iterator opIt = insIt->op_begin(), opEnd = insIt->op_end(); opIt != opEnd; ++opIt) {
Value* v = *opIt;
ValueToValueMapTy::iterator I = VMap->find(v);
if (I != VMap->end() && I->second) continue; // value already exists in VMap
(*VMap)[v] = v;
}
}
}
return VMap;
}
示例2: copy_function
void HeterotbbTransform::copy_function (Function* NF, Function* F) {
DenseMap<const Value*, Value *> ValueMap;
// Get the names of the parameters for old function
for(Function::arg_iterator FI = F->arg_begin(), FE=F->arg_end(), DI=NF->arg_begin(); FE!=FI; ++FI,++DI) {
DI->setName(FI->getName());
ValueMap[FI]=DI;
}
for (Function::const_iterator BI=F->begin(),BE = F->end(); BI != BE; ++BI) {
const BasicBlock &FBB = *BI;
BasicBlock *NFBB = BasicBlock::Create(FBB.getContext(), "", NF);
ValueMap[&FBB] = NFBB;
if (FBB.hasName()) {
NFBB->setName(FBB.getName());
//DEBUG(dbgs()<<NFBB->getName()<<"\n");
}
for (BasicBlock::const_iterator II = FBB.begin(), IE = FBB.end(); II != IE; ++II) {
Instruction *NFInst = II->clone(/*F->getContext()*/);
if (II->hasName()) NFInst->setName(II->getName());
const Instruction *FInst = &(*II);
rewrite_instruction((Instruction *)FInst, NFInst, ValueMap);
NFBB->getInstList().push_back(NFInst);
ValueMap[II] = NFInst;
}
}
// Remap the instructions again to take care of forward jumps
for (Function::iterator BB = NF->begin(), BE=NF->end(); BB != BE; ++ BB) {
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) {
int opIdx = 0;
//DEBUG(dbgs()<<*II<<"\n");
for (User::op_iterator i = II->op_begin(), e = II->op_end(); i != e; ++i, opIdx++) {
Value *V = *i;
if (ValueMap[V] != NULL) {
II->setOperand(opIdx, ValueMap[V]);
}
}
}
}
//NF->dump();
}
示例3: gen_opt_code_per_f
void HeterotbbTransform::gen_opt_code_per_f (Function* NF, Function* F) {
// Get the names of the parameters for old function
Function::arg_iterator FI = F->arg_begin();
Argument *classname = &*FI;
FI++;
Argument *numiters = &*FI;
// Set the names of the parameters for new function
Function::arg_iterator DestI = NF->arg_begin();
DestI->setName(classname->getName());
Argument *class_name = &(*DestI);
//second argument
DestI++;
DestI->setName(numiters->getName());
Argument *num_iters = &(*DestI);
#ifdef EXPLICIT_REWRITE
DenseMap<const Value*, Value *> ValueMap;
#else
ValueToValueMapTy ValueMap;
#endif
#if EXPLICIT_REWRITE
//get the old basic block and create a new one
Function::const_iterator BI = F->begin();
const BasicBlock &FB = *BI;
BasicBlock *NFBB = BasicBlock::Create(FB.getContext(), "", NF);
if (FB.hasName()) {
NFBB->setName(FB.getName());
//DEBUG(dbgs()<<FB.getName()<<"\n");
}
ValueMap[&FB] = NFBB;
ValueMap[numiters] = num_iters;
//must create a new instruction which casts i32* back to the class name
CastInst *StrucRevCast = CastInst::Create(Instruction::BitCast, class_name,
classname->getType(), classname->getName(), NFBB);
ValueMap[classname] = StrucRevCast;
for (BasicBlock::const_iterator II = FB.begin(), IE = FB.end(); II != IE; ++II) {
Instruction *NFInst = II->clone(/*F->getContext()*/);
// DEBUG(dbgs()<<*II<<"\n");
if (II->hasName()) NFInst->setName(II->getName());
const Instruction *FInst = &(*II);
rewrite_instruction((Instruction *)FInst, NFInst, ValueMap);
NFBB->getInstList().push_back(NFInst);
ValueMap[II] = NFInst;
}
BI++;
for (Function::const_iterator /*BI=F->begin(),*/BE = F->end(); BI != BE; ++BI) {
const BasicBlock &FBB = *BI;
BasicBlock *NFBB = BasicBlock::Create(FBB.getContext(), "", NF);
ValueMap[&FBB] = NFBB;
if (FBB.hasName()) {
NFBB->setName(FBB.getName());
//DEBUG(dbgs()<<NFBB->getName()<<"\n");
}
for (BasicBlock::const_iterator II = FBB.begin(), IE = FBB.end(); II != IE; ++II) {
Instruction *NFInst = II->clone(/*F->getContext()*/);
if (II->hasName()) NFInst->setName(II->getName());
const Instruction *FInst = &(*II);
rewrite_instruction((Instruction *)FInst, NFInst, ValueMap);
NFBB->getInstList().push_back(NFInst);
ValueMap[II] = NFInst;
}
}
// Remap the instructions again to take care of forward jumps
for (Function::iterator BB = NF->begin(), BE=NF->end(); BB != BE; ++ BB) {
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) {
int opIdx = 0;
//DEBUG(dbgs()<<*II<<"\n");
for (User::op_iterator i = II->op_begin(), e = II->op_end(); i != e; ++i, opIdx++) {
Value *V = *i;
if (ValueMap[V] != NULL) {
II->setOperand(opIdx, ValueMap[V]);
}
}
}
}
#else
Function::const_iterator BI = F->begin();
const BasicBlock &FB = *BI;
BasicBlock *NFBB = BasicBlock::Create(FB.getContext(), "", NF);
if (FB.hasName()) {
NFBB->setName(FB.getName());
}
ValueMap[&FB] = NFBB;
CastInst *StrucRevCast = CastInst::Create(Instruction::BitCast, class_name,
classname->getType(), classname->getName(), NFBB);
ValueMap[classname] = StrucRevCast;
ValueMap[numiters] = num_iters;
CloneFunctionWithExistingBBInto(NF, NFBB, F, ValueMap, "");
#endif
}
示例4: runOnFunction
bool CopyMinimizationPass::runOnFunction(Function& f)
{
CurrentFile::set(__FILE__);
bool changed = false ;
if (f.isDeclaration() || f.getDFFunction() == NULL)
{
return changed ;
}
std::vector<Node<DFBasicBlock*>*> graph;
//We need to start with an acyclic graph to do retiming on -
//the analyzeCopyPass conveniently provides a function that returns the
//blocks reachable by the sink. These are the same blocks that the
//detectLoopsPass goes through, so they should be acyclical.
std::map<DFBasicBlock*, bool> pipeBlocks = getPipelineBlocks(f);
std::map<DFBasicBlock*,Node<DFBasicBlock*>*> nodeMap;
//for each block in the DFG, create a Node for it.
//this means we need to provide a weight for the block,
//and we also want to save it in a map for later
for(std::map<DFBasicBlock*, bool>::iterator BB = pipeBlocks.begin(); BB != pipeBlocks.end(); ++BB)
{
if( BB->second == false )
continue;
Node<DFBasicBlock*>* node = new Node<DFBasicBlock*>(BB->first, BB->first->getPipelineLevel(), BB->first->getDelay());
nodeMap[BB->first] = node;
graph.push_back(node);
}
//for each edge in the DFG, we need to create an Edge in the graph
for(std::map<DFBasicBlock*, bool>::iterator BB = pipeBlocks.begin(); BB != pipeBlocks.end(); ++BB)
{
if( BB->second == false )
continue;
CallInst* CI = dynamic_cast<CallInst*>(BB->first->getFirstNonPHI());
if( isROCCCFunctionCall(CI, ROCCCNames::LoadPrevious) )
continue;
for(pred_iterator pred = pred_begin(BB->first); pred != pred_end(BB->first); ++pred)
{
assert( (*pred)->getDFBasicBlock() );
std::map<DFBasicBlock*,Node<DFBasicBlock*>*>::iterator predNode = nodeMap.find((*pred)->getDFBasicBlock());
if( predNode != nodeMap.end() )
{
assert( nodeMap[BB->first] );
int weight = 0;
std::map<llvm::Value*,bool> valsUsed;
for(BasicBlock::iterator II = BB->first->begin(); II != BB->first->end(); ++II)
{
for(User::op_iterator OP = II->op_begin(); OP != II->op_end(); ++OP)
{
valsUsed[*OP] = true;
}
}
for(BasicBlock::iterator PII = (*pred)->begin(); PII != (*pred)->end(); ++PII)
{
for(std::map<llvm::Value*,bool>::iterator VUI = valsUsed.begin(); VUI != valsUsed.end(); ++VUI)
{
if( isDefinition(PII, VUI->first) )
{
weight += getSizeInBits(VUI->first);
}
}
}
predNode->second->flowsInto(*nodeMap[BB->first], weight);
}
else
{
INTERNAL_WARNING((*pred)->getName() << " was not found!\n");
}
}
}
int minimum_copies = getTotalCopiedBits(graph);
int num_original_copied_bits = minimum_copies;
std::vector< Node<DFBasicBlock*>* > min_graph = createCopyOfGraph(graph);
int iterationCount = 0;
int minIterationCount = 0;
LOG_MESSAGE2("Pipelining", "Register Minimization", "Bit registers needed to pipeline original graph, including both copies and pipeline boundaries: " << minimum_copies << ".\n");
while(maxTripCount(graph) < 10)
{
//cout << iterationCount << " - " << maxTripCount(graph) << "\n";
++iterationCount;
//display(graph);
Edge< Node<DFBasicBlock*> >* largest = selectEdgeWithLargestWeight(graph);
if( largest )
{
//LOG_MESSAGE2("Pipelining", "Register Minimization", "Edge with most bit registers needed: " << largest->source->getData() << " -> " << largest->sink->getData() << "\n");
tightenEdge(largest);
largest->tripCount++;
}
else
{
LOG_MESSAGE2("Pipelining", "Register Minimization", "Completely reduced.\n");
break;
}
//LOG_MESSAGE2("Pipelining", "Register Minimization", "Iteration " << iterationCount << " - total number of bits registers needed: " << getTotalCopiedBits(graph) << ".\n");
if( getTotalCopiedBits(graph) < minimum_copies )
{
min_graph = createCopyOfGraph(graph);
minimum_copies = getTotalCopiedBits(graph);
++minIterationCount;
}
//.........这里部分代码省略.........
示例5: SimplifyDivRemOfSelect
/// SimplifyDivRemOfSelect - Try to fold a divide or remainder of a select
/// instruction.
bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) {
SelectInst *SI = cast<SelectInst>(I.getOperand(1));
// div/rem X, (Cond ? 0 : Y) -> div/rem X, Y
int NonNullOperand = -1;
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
if (ST->isNullValue())
NonNullOperand = 2;
// div/rem X, (Cond ? Y : 0) -> div/rem X, Y
if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
if (ST->isNullValue())
NonNullOperand = 1;
if (NonNullOperand == -1)
return false;
Value *SelectCond = SI->getOperand(0);
// Change the div/rem to use 'Y' instead of the select.
I.setOperand(1, SI->getOperand(NonNullOperand));
// Okay, we know we replace the operand of the div/rem with 'Y' with no
// problem. However, the select, or the condition of the select may have
// multiple uses. Based on our knowledge that the operand must be non-zero,
// propagate the known value for the select into other uses of it, and
// propagate a known value of the condition into its other users.
// If the select and condition only have a single use, don't bother with this,
// early exit.
if (SI->use_empty() && SelectCond->hasOneUse())
return true;
// Scan the current block backward, looking for other uses of SI.
BasicBlock::iterator BBI = &I, BBFront = I.getParent()->begin();
while (BBI != BBFront) {
--BBI;
// If we found a call to a function, we can't assume it will return, so
// information from below it cannot be propagated above it.
if (isa<CallInst>(BBI) && !isa<IntrinsicInst>(BBI))
break;
// Replace uses of the select or its condition with the known values.
for (Instruction::op_iterator I = BBI->op_begin(), E = BBI->op_end();
I != E; ++I) {
if (*I == SI) {
*I = SI->getOperand(NonNullOperand);
Worklist.Add(BBI);
} else if (*I == SelectCond) {
*I = NonNullOperand == 1 ? ConstantInt::getTrue(BBI->getContext()) :
ConstantInt::getFalse(BBI->getContext());
Worklist.Add(BBI);
}
}
// If we past the instruction, quit looking for it.
if (&*BBI == SI)
SI = 0;
if (&*BBI == SelectCond)
SelectCond = 0;
// If we ran out of things to eliminate, break out of the loop.
if (SelectCond == 0 && SI == 0)
break;
}
return true;
}
示例6: gen_code_per_f
/**
* Generate code for
*/
void HeteroOMPTransform::gen_code_per_f (Function* NF, Function* F, Instruction *max_threads){
Function::arg_iterator FI = F->arg_begin();
Argument *ctxname = &*FI;
Function::arg_iterator DestI = NF->arg_begin();
DestI->setName(ctxname->getName());
Argument *ctx_name = &(*DestI);
DestI++;
DestI->setName("tid");
Argument *num_iters = &(*DestI);
#ifdef EXPLICIT_REWRITE
DenseMap<const Value*, Value *> ValueMap;
#else
ValueToValueMapTy ValueMap;
#endif
//get the old basic block and create a new one
Function::const_iterator BI = F->begin();
const BasicBlock &FB = *BI;
BasicBlock *NFBB = BasicBlock::Create(FB.getContext(), "", NF);
if (FB.hasName()){
NFBB->setName(FB.getName());
}
ValueMap[&FB] = NFBB;
//ValueMap[numiters] = num_iters;
ValueMap[ctxname] = ctx_name;
#if EXPLICIT_REWRITE
for (BasicBlock::const_iterator II = FB.begin(), IE = FB.end(); II != IE; ++II) {
Instruction *NFInst = II->clone(/*F->getContext()*/);
// DEBUG(dbgs()<<*II<<"\n");
if (II->hasName()) NFInst->setName(II->getName());
const Instruction *FInst = &(*II);
rewrite_instruction((Instruction *)FInst, NFInst, ValueMap);
NFBB->getInstList().push_back(NFInst);
ValueMap[II] = NFInst;
}
BI++;
for (Function::const_iterator /*BI=F->begin(),*/BE = F->end();BI != BE; ++BI) {
const BasicBlock &FBB = *BI;
BasicBlock *NFBB = BasicBlock::Create(FBB.getContext(), "", NF);
ValueMap[&FBB] = NFBB;
if (FBB.hasName()){
NFBB->setName(FBB.getName());
//DEBUG(dbgs()<<NFBB->getName()<<"\n");
}
for (BasicBlock::const_iterator II = FBB.begin(), IE = FBB.end(); II != IE; ++II) {
Instruction *NFInst = II->clone(/*F->getContext()*/);
if (II->hasName()) NFInst->setName(II->getName());
const Instruction *FInst = &(*II);
rewrite_instruction((Instruction *)FInst, NFInst, ValueMap);
NFBB->getInstList().push_back(NFInst);
ValueMap[II] = NFInst;
}
}
// Remap the instructions again to take care of forward jumps
for (Function::iterator BB = NF->begin(), BE=NF->end(); BB != BE; ++ BB) {
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II){
int opIdx = 0;
//DEBUG(dbgs()<<*II<<"\n");
for (User::op_iterator i = II->op_begin(), e = II->op_end(); i != e; ++i, opIdx++) {
Value *V = *i;
if (ValueMap[V] != NULL) {
II->setOperand(opIdx, ValueMap[V]);
}
}
}
}
#else
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
CloneFunctionInto(NF, F, ValueMap, false, Returns, "");
#endif
//max_threads->dump();
/* Remap openmp omp_num_threads() and omp_thread_num() */
/*
* define internal void @_Z20initialize_variablesiPfS_.omp_fn.4(i8* nocapture %.omp_data_i) nounwind ssp {
* entry:
* %0 = bitcast i8* %.omp_data_i to i32* ; <i32*> [#uses=1]
* %1 = load i32* %0, align 8 ; <i32> [#uses=2]
* %2 = tail call i32 @omp_get_num_threads() nounwind readnone ; <i32> [#uses=2]
* %3 = tail call i32 @omp_get_thread_num() nounwind readnone ; <i32> [#uses=2]
%4 = sdiv i32 %1, %2
%5 = mul nsw i32 %4, %2
%6 = icmp ne i32 %5, %1
%7 = zext i1 %6 to i32
*/
vector<Instruction *> toDelete;
for (Function::iterator BB = NF->begin(), BE=NF->end(); BB != BE; ++ BB) {
for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II){
if (isa<CallInst>(II)) {
CallSite CI(cast<Instruction>(II));
if (CI.getCalledFunction() != NULL){
//.........这里部分代码省略.........
示例7: findInputsOutputs
void RegionExtractor::findInputsOutputs(ValueSet &Inputs,
ValueSet &Outputs) const {
for (SetVector<BasicBlock *>::const_iterator I = Blocks.begin(),
E = Blocks.end();
I != E; ++I) {
BasicBlock *BB = *I;
// If a used value is defined outside the region, it's an input. If an
// instruction is used outside the region, it's an output.
for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
II != IE; ++II) {
for (User::op_iterator OI = II->op_begin(), OE = II->op_end();
OI != OE; ++OI)
if (definedInCaller(Blocks, *OI))
Inputs.insert(*OI);
#if LLVM_VERSION_MINOR == 5
for (User *U : II->users())
if (!definedInRegion(Blocks, U)) {
#else
for (Value::use_iterator UI = II->use_begin(), UE = II->use_end();
UI != UE; ++UI)
if (!definedInRegion(Blocks, *UI)) {
#endif
Outputs.insert(II);
break;
}
}
}
}
/// severSplitPHINodes - If a PHI node has multiple inputs from outside of the
/// region, we need to split the entry block of the region so that the PHI node
/// is easier to deal with.
void RegionExtractor::severSplitPHINodes(BasicBlock *&Header) {
unsigned NumPredsFromRegion = 0;
unsigned NumPredsOutsideRegion = 0;
if (Header != &Header->getParent()->getEntryBlock()) {
PHINode *PN = dyn_cast<PHINode>(Header->begin());
if (!PN) return; // No PHI nodes.
// If the header node contains any PHI nodes, check to see if there is more
// than one entry from outside the region. If so, we need to sever the
// header block into two.
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (Blocks.count(PN->getIncomingBlock(i)))
++NumPredsFromRegion;
else
++NumPredsOutsideRegion;
// If there is one (or fewer) predecessor from outside the region, we don't
// need to do anything special.
if (NumPredsOutsideRegion <= 1) return;
}
// Otherwise, we need to split the header block into two pieces: one
// containing PHI nodes merging values from outside of the region, and a
// second that contains all of the code for the block and merges back any
// incoming values from inside of the region.
BasicBlock::iterator AfterPHIs = Header->getFirstNonPHI();
BasicBlock *NewBB = Header->splitBasicBlock(AfterPHIs,
Header->getName()+".ce");
// We only want to code extract the second block now, and it becomes the new
// header of the region.
BasicBlock *OldPred = Header;
Blocks.remove(OldPred);
Blocks.insert(NewBB);
Header = NewBB;
// Okay, update dominator sets. The blocks that dominate the new one are the
// blocks that dominate TIBB plus the new block itself.
if (DT)
DT->splitBlock(NewBB);
// Okay, now we need to adjust the PHI nodes and any branches from within the
// region to go to the new header block instead of the old header block.
if (NumPredsFromRegion) {
PHINode *PN = cast<PHINode>(OldPred->begin());
// Loop over all of the predecessors of OldPred that are in the region,
// changing them to branch to NewBB instead.
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (Blocks.count(PN->getIncomingBlock(i))) {
TerminatorInst *TI = PN->getIncomingBlock(i)->getTerminator();
TI->replaceUsesOfWith(OldPred, NewBB);
}
// Okay, everything within the region is now branching to the right block, we
// just have to update the PHI nodes now, inserting PHI nodes into NewBB.
for (AfterPHIs = OldPred->begin(); isa<PHINode>(AfterPHIs); ++AfterPHIs) {
PHINode *PN = cast<PHINode>(AfterPHIs);
// Create a new PHI node in the new region, which has an incoming value
// from OldPred of PN.
PHINode *NewPN = PHINode::Create(PN->getType(), 1 + NumPredsFromRegion,
PN->getName()+".ce", NewBB->begin());
NewPN->addIncoming(PN, OldPred);
// Loop over all of the incoming value in PN, moving them to NewPN if they
// are from the extracted region.
for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) {
//.........这里部分代码省略.........
示例8: runOnLoop
bool partition::runOnLoop(Loop* L, LPPassManager &LPM) {
errs() << "*************************** Loop encountered: ************************" << '\n' << L->getHeader()->getName() << '\n';
if (function->getName() != "main")
return false;
IntegerType* int32Ty = Type::getInt32Ty(*context);
IntegerType* int64Ty = Type::getInt64Ty(*context);
PointerType* voidPtrTy = Type::getInt8PtrTy(*context);
FunctionType* funcTy = FunctionType::get(int32Ty, false);
Constant* func1_c;
Function* func1;
func1_c = module->getOrInsertFunction("func1", funcTy);
func1 = cast<Function>(func1_c);
Function* pro = module->getFunction("produce");
Function* con = module->getFunction("consume");
BasicBlock* func1EntryBlock = BasicBlock::Create(*context, "entry.func1", func1);
AllocaInst* i_var = new AllocaInst(int32Ty, NULL, 4, "i", func1EntryBlock);
Value* liveIn;
BasicBlock *forCond, *forBody, *forInc;
ValueToValueMapTy VMap;
std::map<BasicBlock *, BasicBlock *> BlockMap;
for (Loop::block_iterator BB = L->block_begin(), BBe = L->block_end(); BB != BBe; ++BB) {
BasicBlock* func1Block = CloneBasicBlock(*BB, VMap, ".func1", func1);
BlockMap[*BB] = func1Block;
if ((*BB)->getName() == "for.cond")
forCond = func1Block;
if ((*BB)->getName() == "for.body")
forBody = func1Block;
if ((*BB)->getName() == "for.inc")
forInc = func1Block;
for (BasicBlock::iterator it = func1Block->begin(), ite = func1Block->end(); it != ite; ++it) {
for (User::op_iterator oit = it->op_begin(), oite = it->op_end(); oit != oite; ++oit) {
if (VMap[*oit] != NULL) {
*oit = VMap[*oit];
} else {
Constant* cons = dyn_cast<Constant>(*oit);
BranchInst* br = dyn_cast<BranchInst>(it);
if (cons == NULL && br == NULL) {
liveIn = *oit;
*oit = i_var;
}
}
}
}
if ((*BB)->getName() == "for.body") {
Instruction* term = (*BB)->getTerminator();
term->removeFromParent();
for (int i = 0; i < 7; i++) {
(*BB)->back().eraseFromParent();
}
term->insertAfter(&(*BB)->back());
(*BB)->front().eraseFromParent();
LoadInst* load = new LoadInst(liveIn, "", false, 4, term);
std::vector<Value *> produce_args;
CastInst* cast = CastInst::CreateIntegerCast(load, int64Ty, true);
cast->insertAfter(load);
produce_args.push_back(cast);
ConstantInt* val = ConstantInt::get(int32Ty, (uint32_t) 3);
produce_args.push_back(val);
CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", term);
produce_args.pop_back();
val = ConstantInt::get(int32Ty, (uint32_t) 2);
produce_args.push_back(val);
CallInst::Create(pro, ArrayRef<Value*>(produce_args), "", term);
}
}
// set branch instructions to restructure the CFG in created function
BasicBlock* func1EndBlock = BasicBlock::Create(*context, "if.end.func1", func1);
BasicBlock* garbageBB = BasicBlock::Create(*context, "garbage", func1);
ConstantInt* retVal_g = ConstantInt::get(int32Ty, (uint32_t) 0);
ReturnInst* ret_g = ReturnInst::Create(*context, retVal_g, garbageBB);
for (Function::iterator fit = func1->begin(), fite = func1->end(); fit != fite; ++fit) {
if (fit->getTerminator() == NULL || fit->getName() == "garbage")
continue;
BranchInst* br = dyn_cast<BranchInst>(fit->getTerminator());
int numSuccessors = br->getNumSuccessors();
for (int i = 0; i < numSuccessors; i++) {
//.........这里部分代码省略.........