Example #1
0
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();

}
Example #2
0
/// eliminateUnconditionalBranch - Clone the instructions from the destination
/// block into the source block, eliminating the specified unconditional branch.
/// If the destination block defines values used by successors of the dest
/// block, we may need to insert PHI nodes.
///
void TailDup::eliminateUnconditionalBranch(BranchInst *Branch) {
  BasicBlock *SourceBlock = Branch->getParent();
  BasicBlock *DestBlock = Branch->getSuccessor(0);
  assert(SourceBlock != DestBlock && "Our predicate is broken!");

  DEBUG(errs() << "TailDuplication[" << SourceBlock->getParent()->getName()
        << "]: Eliminating branch: " << *Branch);

  // See if we can avoid duplicating code by moving it up to a dominator of both
  // blocks.
  if (BasicBlock *DomBlock = FindObviousSharedDomOf(SourceBlock, DestBlock)) {
    DEBUG(errs() << "Found shared dominator: " << DomBlock->getName() << "\n");

    // If there are non-phi instructions in DestBlock that have no operands
    // defined in DestBlock, and if the instruction has no side effects, we can
    // move the instruction to DomBlock instead of duplicating it.
    BasicBlock::iterator BBI = DestBlock->getFirstNonPHI();
    while (!isa<TerminatorInst>(BBI)) {
      Instruction *I = BBI++;

      bool CanHoist = I->isSafeToSpeculativelyExecute() &&
                      !I->mayReadFromMemory();
      if (CanHoist) {
        for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op)
          if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(op)))
            if (OpI->getParent() == DestBlock ||
                (isa<InvokeInst>(OpI) && OpI->getParent() == DomBlock)) {
              CanHoist = false;
              break;
            }
        if (CanHoist) {
          // Remove from DestBlock, move right before the term in DomBlock.
          DestBlock->getInstList().remove(I);
          DomBlock->getInstList().insert(DomBlock->getTerminator(), I);
          DEBUG(errs() << "Hoisted: " << *I);
        }
      }
    }
  }

  // Tail duplication can not update SSA properties correctly if the values
  // defined in the duplicated tail are used outside of the tail itself.  For
  // this reason, we spill all values that are used outside of the tail to the
  // stack.
  for (BasicBlock::iterator I = DestBlock->begin(); I != DestBlock->end(); ++I)
    if (I->isUsedOutsideOfBlock(DestBlock)) {
      // We found a use outside of the tail.  Create a new stack slot to
      // break this inter-block usage pattern.
      DemoteRegToStack(*I);
    }

  // We are going to have to map operands from the original block B to the new
  // copy of the block B'.  If there are PHI nodes in the DestBlock, these PHI
  // nodes also define part of this mapping.  Loop over these PHI nodes, adding
  // them to our mapping.
  //
  std::map<Value*, Value*> ValueMapping;

  BasicBlock::iterator BI = DestBlock->begin();
  bool HadPHINodes = isa<PHINode>(BI);
  for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI)
    ValueMapping[PN] = PN->getIncomingValueForBlock(SourceBlock);

  // Clone the non-phi instructions of the dest block into the source block,
  // keeping track of the mapping...
  //
  for (; BI != DestBlock->end(); ++BI) {
    Instruction *New = BI->clone();
    New->setName(BI->getName());
    SourceBlock->getInstList().push_back(New);
    ValueMapping[BI] = New;
  }

  // Now that we have built the mapping information and cloned all of the
  // instructions (giving us a new terminator, among other things), walk the new
  // instructions, rewriting references of old instructions to use new
  // instructions.
  //
  BI = Branch; ++BI;  // Get an iterator to the first new instruction
  for (; BI != SourceBlock->end(); ++BI)
    for (unsigned i = 0, e = BI->getNumOperands(); i != e; ++i) {
      std::map<Value*, Value*>::const_iterator I =
        ValueMapping.find(BI->getOperand(i));
      if (I != ValueMapping.end())
        BI->setOperand(i, I->second);
    }

  // Next we check to see if any of the successors of DestBlock had PHI nodes.
  // If so, we need to add entries to the PHI nodes for SourceBlock now.
  for (succ_iterator SI = succ_begin(DestBlock), SE = succ_end(DestBlock);
       SI != SE; ++SI) {
    BasicBlock *Succ = *SI;
    for (BasicBlock::iterator PNI = Succ->begin(); isa<PHINode>(PNI); ++PNI) {
      PHINode *PN = cast<PHINode>(PNI);
      // Ok, we have a PHI node.  Figure out what the incoming value was for the
      // DestBlock.
      Value *IV = PN->getIncomingValueForBlock(DestBlock);

      // Remap the value if necessary...
      std::map<Value*, Value*>::const_iterator I = ValueMapping.find(IV);
      if (I != ValueMapping.end())
        IV = I->second;
      PN->addIncoming(IV, SourceBlock);
    }
  }

  // Next, remove the old branch instruction, and any PHI node entries that we
  // had.
  BI = Branch; ++BI;  // Get an iterator to the first new instruction
  DestBlock->removePredecessor(SourceBlock); // Remove entries in PHI nodes...
  SourceBlock->getInstList().erase(Branch);  // Destroy the uncond branch...

  // Final step: now that we have finished everything up, walk the cloned
  // instructions one last time, constant propagating and DCE'ing them, because
  // they may not be needed anymore.
  //
  if (HadPHINodes) {
    while (BI != SourceBlock->end()) {
      Instruction *Inst = BI++;
      if (isInstructionTriviallyDead(Inst))
        Inst->eraseFromParent();
      else if (Constant *C = ConstantFoldInstruction(Inst)) {
        Inst->replaceAllUsesWith(C);
        Inst->eraseFromParent();
      }
    }
  }

  ++NumEliminated;  // We just killed a branch!
}
Example #3
0
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
}
Example #4
0
bool GenericToNVVM::runOnModule(Module &M) {
  // Create a clone of each global variable that has the default address space.
  // The clone is created with the global address space  specifier, and the pair
  // of original global variable and its clone is placed in the GVMap for later
  // use.

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E;) {
    GlobalVariable *GV = &*I++;
    if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
        !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
        !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
      GlobalVariable *NewGV = new GlobalVariable(
          M, GV->getValueType(), GV->isConstant(),
          GV->getLinkage(),
          GV->hasInitializer() ? GV->getInitializer() : nullptr,
          "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
      NewGV->copyAttributesFrom(GV);
      GVMap[GV] = NewGV;
    }
  }

  // Return immediately, if every global variable has a specific address space
  // specifier.
  if (GVMap.empty()) {
    return false;
  }

  // Walk through the instructions in function defitinions, and replace any use
  // of original global variables in GVMap with a use of the corresponding
  // copies in GVMap.  If necessary, promote constants to instructions.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (I->isDeclaration()) {
      continue;
    }
    IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
    for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
         ++BBI) {
      for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
           ++II) {
        for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
          Value *Operand = II->getOperand(i);
          if (isa<Constant>(Operand)) {
            II->setOperand(
                i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
          }
        }
      }
    }
    ConstantToValueMap.clear();
  }

  // Copy GVMap over to a standard value map.
  ValueToValueMapTy VM;
  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
    VM[I->first] = I->second;

  // Walk through the metadata section and update the debug information
  // associated with the global variables in the default address space.
  for (NamedMDNode &I : M.named_metadata()) {
    remapNamedMDNode(VM, &I);
  }

  // Walk through the global variable  initializers, and replace any use of
  // original global variables in GVMap with a use of the corresponding copies
  // in GVMap.  The copies need to be bitcast to the original global variable
  // types, as we cannot use cvta in global variable initializers.
  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
    GlobalVariable *GV = I->first;
    GlobalVariable *NewGV = I->second;

    // Remove GV from the map so that it can be RAUWed.  Note that
    // DenseMap::erase() won't invalidate any iterators but this one.
    auto Next = std::next(I);
    GVMap.erase(I);
    I = Next;

    Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
    // At this point, the remaining uses of GV should be found only in global
    // variable initializers, as other uses have been already been removed
    // while walking through the instructions in function definitions.
    GV->replaceAllUsesWith(BitCastNewGV);
    std::string Name = GV->getName();
    GV->eraseFromParent();
    NewGV->setName(Name);
  }
  assert(GVMap.empty() && "Expected it to be empty by now");

  return true;
}
Example #5
0
void SuperBlock::fixSideEntrances() {
    // due to merging of BBs, some superblocks may have 1 BB remaining
    list<map<BasicBlock*, list<BasicBlock*> >::iterator > delSuperBlocks;

    for (map<BasicBlock*, list<BasicBlock*> >::iterator sp = superBlocks.begin(),
            sp_e = superBlocks.end();  sp != sp_e; ++sp) {
        // we need to keep track of the predecessor of the current basic block
        // being checked
        BasicBlock* prev = sp->first;

        // don't clone basic blocks if the code size threshold is achieved
        if (currCodeSize/originalCodeSize > CODE_EXPANSION_THRESHOLD) {
            break;
        }

        // the first basic block for a superblock need not be duplicated
        for (list<BasicBlock*>::iterator bb = sp->second.begin(),
                bb_e = sp->second.end(); bb != bb_e; ++bb) {
            // first, collect all predecessors for this BB
            // (note: we could not just iterate through as the predecessor set may
            // change
            list<BasicBlock*> predBBs;
            for (pred_iterator pred = pred_begin(*bb), pred_e = pred_end(*bb);
                    pred != pred_e; ++pred) {
                predBBs.push_back(*pred);
            }

            // now, walk through all predecessors of this current basic block
            BasicBlock* clonedBB = NULL;
            for (list<BasicBlock*>::iterator pred = predBBs.begin(),
                    pred_e = predBBs.end(); pred != pred_e; ++pred) {
                // if it is not the predecessor of this current basic block present in
                // the superblock, duplicate!
                if (*pred != prev) {
                    // there is no need to clone this BB multiple times
                    if (clonedBB == NULL) {
                        ValueToValueMapTy vmap;

                        // clone this basic block, and place the corresponding code after
                        // the last BB of this superblock
                        clonedBB = CloneBasicBlock(*bb, vmap, ".cloned",
                                                   (*bb)->getParent());
                        vmap[*bb] = clonedBB;

                        /*
                        errs() << "@@ BEFORE: " << *clonedBB << "\n";
                        // fix phi nodes in the cloned BB
                        for (BasicBlock::iterator I = clonedBB->begin(); isa<PHINode>(I); ++I) {
                          PHINode* PN = dyn_cast<PHINode>(I);
                          int bbIdx = PN->getBasicBlockIndex(prev);
                          if (bbIdx != -1) {
                            PN->removeIncomingValue(bbIdx, false);
                          }
                        }
                        */

                        // add size of duplicated BBs to total code size count
                        currCodeSize += clonedBB->size();

                        // modify operands in this basic block
                        for (BasicBlock::iterator instr = clonedBB->begin(),
                                instr_e = clonedBB->end(); instr != instr_e; ++instr) {
                            for (unsigned idx = 0, num_ops = instr->getNumOperands();
                                    idx < num_ops; ++idx) {
                                Value* op = instr->getOperand(idx);
                                ValueToValueMapTy::iterator op_it = vmap.find(op);
                                if (op_it != vmap.end()) {
                                    instr->setOperand(idx, op_it->second);
                                }
                            }
                        }
                    }

                    // remove phi nodes into this BB in the trace
                    /*
                    for (BasicBlock::iterator I = (*bb)->begin(); isa<PHINode>(I); ++I) {
                      PHINode* PN = dyn_cast<PHINode>(I);
                      int bbIdx = PN->getBasicBlockIndex(*pred);
                      if (bbIdx != -1) {
                        PN->removeIncomingValue(bbIdx, false);
                      }
                    }
                    */

                    // modify the branch instruction of the predecessor not in the superblock to
                    // branch to the cloned basic block
                    Instruction* br_instr = (*pred)->getTerminator();
                    br_instr->replaceUsesOfWith((Value*)*bb, (Value*)clonedBB);
                }
            }

            // determine if we can merge the BB (definitely can be merged), and its clone
            // with theirpredecessors
            if (clonedBB != NULL) {
                if (MergeBlockIntoPredecessor(*bb, this)) {
                    // since we have merged this BB, delete from our superblock mappings
                    partOfSuperBlock.erase(*bb);
                    bb = sp->second.erase(bb);
                    --bb;

                    if (sp->second.empty()) {
                        delSuperBlocks.push_back(sp);
                    }
                }

                MergeBlockIntoPredecessor(clonedBB, this);
            }

            prev = *bb;
        }
    }

    // erase some superblocks (which only have 1 BB remaining)
    for (list<map<BasicBlock*, list<BasicBlock*> >::iterator >::iterator del =
                delSuperBlocks.begin(), del_e = delSuperBlocks.end(); del != del_e;
            ++del) {
        superBlocks.erase(*del);
    }
}
Example #6
0
/**
 * 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){ 
					string called_func_name = CI.getCalledFunction()->getName();
					if (called_func_name == OMP_GET_NUM_THREADS_NAME && CI.arg_size() == 0) {
						II->replaceAllUsesWith(ValueMap[max_threads]);
						toDelete.push_back(II);
					}
					else if (called_func_name == OMP_GET_THREAD_NUM_NAME && CI.arg_size() == 0) {
						II->replaceAllUsesWith(num_iters);
						toDelete.push_back(II);
					}
				}
			}
		}
	}


	/* Delete the last branch instruction of the first basic block -- Assuming it is safe */
	Function::iterator nfBB = NF->begin();
	TerminatorInst *lastI = nfBB->getTerminator();
	BranchInst *bI;
	BasicBlock *returnBlock;
	if ((bI = dyn_cast<BranchInst>(lastI)) && bI->isConditional() && 
		(returnBlock = bI->getSuccessor(1)) && 
		(returnBlock->getName() == "return")) {
		/* modify to a unconditional branch to next basic block and not return */
		Instruction *bbI = BranchInst::Create(bI->getSuccessor(0),lastI);
		bbI->dump();
		toDelete.push_back(lastI);
	}

	//NF->dump();
	while(!toDelete.empty()) {
		Instruction *g = toDelete.back();
		//g->replaceAllUsesWith(UndefValue::get(g->getType()));
		toDelete.pop_back();
		g->eraseFromParent();
	}

	//NF->dump();
}
bool ReplaceNopCastsAndByteSwaps::processBasicBlock(BasicBlock& BB)
{
	bool Changed = false;
	
	/**
	 * First pass: replace nopCasts with bitcasts and bswap intrinsics with logic operations
	
	 */
	for ( BasicBlock::iterator it = BB.begin(); it != BB.end(); )
	{
		Instruction * Inst = it++;
		
		if (isNopCast(Inst) )
		{
			assert( isa<CallInst>(Inst) );
			
			CallInst * call = cast<CallInst>(Inst);
			
			if ( TypeSupport::isClientType( call->getType()) )
			{
				llvm::errs() << "Cast of client type: " << *call << "\n";
				continue;
			}
			if ( TypeSupport::isClientType( call->getArgOperand(0)->getType()) )
			{
				llvm::errs() << "Cast of client type: " << *call->getArgOperand(0) << "\n";
				continue;
			}

			ReplaceInstWithInst( call,  BitCastInst::Create( Instruction::CastOps::BitCast, call->getArgOperand(0), call->getType() ) );

			Changed = true;
		}
		else if( IntrinsicInst* II = dyn_cast<IntrinsicInst>(Inst) )
		{
			if(II->getIntrinsicID() == Intrinsic::bswap)
			{
				IL->LowerIntrinsicCall(II);
				Changed = true;
			}
			else if(II->getIntrinsicID() == Intrinsic::cheerp_deallocate)
			{
				II->eraseFromParent();
				Changed = true;
			}
		}
	}
	
	/**
	 * Second pass: collapse bitcasts of bitcasts.
	 * 
	 * Note: this might leave some dead instruction around, but we don't care since bitcasts are inlined anyway
	 */
	for ( BasicBlock::iterator it = BB.begin(); it != BB.end(); ++it )
	{
		if ( isa<BitCastInst>(it) ) 
		{
			while ( BitCastInst * src = dyn_cast<BitCastInst>(it->getOperand(0) ) )
			{
				it->setOperand(0, src->getOperand(0) );
				Changed = true;
			}
		}
	}

	return Changed;
}