Ejemplo n.º 1
0
// reuseOrInsertFastDiv - Reuses previously computed dividend or remainder if
// operands and operation are identical. Otherwise call insertFastDiv to perform
// the optimization and cache the resulting dividend and remainder.
static bool reuseOrInsertFastDiv(Function &F,
                                 Function::iterator &I,
                                 BasicBlock::iterator &J,
                                 IntegerType *BypassType,
                                 bool UseDivOp,
                                 bool UseSignedOp,
                                 DivCacheTy &PerBBDivCache) {
  // Get instruction operands
  Instruction *Instr = J;
  DivOpInfo Key(UseSignedOp, Instr->getOperand(0), Instr->getOperand(1));
  DivCacheTy::iterator CacheI = PerBBDivCache.find(Key);

  if (CacheI == PerBBDivCache.end()) {
    // If previous instance does not exist, insert fast div
    return insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp,
                         PerBBDivCache);
  }

  // Replace operation value with previously generated phi node
  DivPhiNodes &Value = CacheI->second;
  if (UseDivOp) {
    // Replace all uses of div instruction with quotient phi node
    J->replaceAllUsesWith(Value.Quotient);
  } else {
    // Replace all uses of rem instruction with remainder phi node
    J->replaceAllUsesWith(Value.Remainder);
  }

  // Advance to next operation
  ++J;

  // Remove redundant operation
  Instr->eraseFromParent();
  return true;
}
Ejemplo n.º 2
0
/// ChangeToUnreachable - Insert an unreachable instruction before the specified
/// instruction, making it and the rest of the code in the block dead.
static void ChangeToUnreachable(Instruction *I, bool UseLLVMTrap) {
  BasicBlock *BB = I->getParent();
  // Loop over all of the successors, removing BB's entry from any PHI
  // nodes.
  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
    (*SI)->removePredecessor(BB);
  
  // Insert a call to llvm.trap right before this.  This turns the undefined
  // behavior into a hard fail instead of falling through into random code.
  if (UseLLVMTrap) {
    Function *TrapFn =
      Intrinsic::getDeclaration(BB->getParent()->getParent(), Intrinsic::trap);
    CallInst *CallTrap = CallInst::Create(TrapFn, "", I);
    CallTrap->setDebugLoc(I->getDebugLoc());
  }
  new UnreachableInst(I->getContext(), I);
  
  // All instructions after this are dead.
  BasicBlock::iterator BBI = I, BBE = BB->end();
  while (BBI != BBE) {
    if (!BBI->use_empty())
      BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
    BB->getInstList().erase(BBI++);
  }
}
Ejemplo n.º 3
0
 virtual bool runOnFunction(Function& f)
 {
   CurrentFile::set(__FILE__);
   bool changed = false;
   // Make sure this is a function that we can use
   if (f.isDeclaration() /*|| !f.isDFFunction()*/ )
   {
     return changed ;
   }
   for(Function::iterator BB = f.begin(); BB != f.end(); ++BB)
   {
     begin:
     for(BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II)
     {
       if( !dynamic_cast<TerminatorInst*>(&*II) )
       {
         II->replaceAllUsesWith(UndefValue::get(II->getType()));
         II->eraseFromParent();
         goto begin;
       }
     }
   }
   changed = true;
   return changed;
 }
/// DeleteBasicBlock - remove the specified basic block from the program,
/// updating the callgraph to reflect any now-obsolete edges due to calls that
/// exist in the BB.
void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
  assert(pred_begin(BB) == pred_end(BB) && "BB is not dead!");
  CallGraph &CG = getAnalysis<CallGraph>();

  CallGraphNode *CGN = CG[BB->getParent()];
  for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) {
    --I;
    if (CallInst *CI = dyn_cast<CallInst>(I)) {
      if (Function *Callee = CI->getCalledFunction())
        CGN->removeCallEdgeTo(CG[Callee]);
    } else if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
      if (Function *Callee = II->getCalledFunction())
        CGN->removeCallEdgeTo(CG[Callee]);
    }
    if (!I->use_empty())
      I->replaceAllUsesWith(UndefValue::get(I->getType()));
  }

  // Get the list of successors of this block.
  std::vector<BasicBlock*> Succs(succ_begin(BB), succ_end(BB));

  for (unsigned i = 0, e = Succs.size(); i != e; ++i)
    Succs[i]->removePredecessor(BB);

  BB->eraseFromParent();
}
Ejemplo n.º 5
0
/// doConstantPropagation - If an instruction references constants, try to fold
/// them together...
///
bool llvm::doConstantPropagation(BasicBlock::iterator &II) {
  if (Constant *C = ConstantFoldInstruction(II)) {
    // Replaces all of the uses of a variable with uses of the constant.
    II->replaceAllUsesWith(C);
    
    // Remove the instruction from the basic block...
    II = II->getParent()->getInstList().erase(II);
    return true;
  }

  return false;
}
Ejemplo n.º 6
0
/// ChangeToUnreachable - Insert an unreachable instruction before the specified
/// instruction, making it and the rest of the code in the block dead.
static void ChangeToUnreachable(Instruction *I) {
    BasicBlock *BB = I->getParent();
    // Loop over all of the successors, removing BB's entry from any PHI
    // nodes.
    for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
        (*SI)->removePredecessor(BB);

    new UnreachableInst(I);

    // All instructions after this are dead.
    BasicBlock::iterator BBI = I, BBE = BB->end();
    while (BBI != BBE) {
        if (!BBI->use_empty())
            BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
        BB->getInstList().erase(BBI++);
    }
}
Ejemplo n.º 7
0
/// DeleteBasicBlock - remove the specified basic block from the program,
/// updating the callgraph to reflect any now-obsolete edges due to calls that
/// exist in the BB.
void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
  assert(pred_empty(BB) && "BB is not dead!");
  CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();

  Instruction *TokenInst = nullptr;

  CallGraphNode *CGN = CG[BB->getParent()];
  for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) {
    --I;

    if (I->getType()->isTokenTy()) {
      TokenInst = &*I;
      break;
    }

    if (auto CS = CallSite (&*I)) {
      const Function *Callee = CS.getCalledFunction();
      if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID()))
        CGN->removeCallEdgeFor(CS);
      else if (!Callee->isIntrinsic())
        CGN->removeCallEdgeFor(CS);
    }

    if (!I->use_empty())
      I->replaceAllUsesWith(UndefValue::get(I->getType()));
  }

  if (TokenInst) {
    if (!isa<TerminatorInst>(TokenInst))
      changeToUnreachable(TokenInst->getNextNode(), /*UseLLVMTrap=*/false);
  } else {
    // Get the list of successors of this block.
    std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB));

    for (unsigned i = 0, e = Succs.size(); i != e; ++i)
      Succs[i]->removePredecessor(BB);

    BB->eraseFromParent();
  }
}
Ejemplo n.º 8
0
/// RemoveBlockIfDead - If the specified block is dead, remove it, update loop
/// information, and remove any dead successors it has.
///
void LoopUnswitch::RemoveBlockIfDead(BasicBlock *BB,
                                     std::vector<Instruction*> &Worklist,
                                     Loop *L) {
  if (pred_begin(BB) != pred_end(BB)) {
    // This block isn't dead, since an edge to BB was just removed, see if there
    // are any easy simplifications we can do now.
    if (BasicBlock *Pred = BB->getSinglePredecessor()) {
      // If it has one pred, fold phi nodes in BB.
      while (isa<PHINode>(BB->begin()))
        ReplaceUsesOfWith(BB->begin(), 
                          cast<PHINode>(BB->begin())->getIncomingValue(0), 
                          Worklist, L, LPM);
      
      // If this is the header of a loop and the only pred is the latch, we now
      // have an unreachable loop.
      if (Loop *L = LI->getLoopFor(BB))
        if (loopHeader == BB && L->contains(Pred)) {
          // Remove the branch from the latch to the header block, this makes
          // the header dead, which will make the latch dead (because the header
          // dominates the latch).
          LPM->deleteSimpleAnalysisValue(Pred->getTerminator(), L);
          Pred->getTerminator()->eraseFromParent();
          new UnreachableInst(BB->getContext(), Pred);
          
          // The loop is now broken, remove it from LI.
          RemoveLoopFromHierarchy(L);
          
          // Reprocess the header, which now IS dead.
          RemoveBlockIfDead(BB, Worklist, L);
          return;
        }
      
      // If pred ends in a uncond branch, add uncond branch to worklist so that
      // the two blocks will get merged.
      if (BranchInst *BI = dyn_cast<BranchInst>(Pred->getTerminator()))
        if (BI->isUnconditional())
          Worklist.push_back(BI);
    }
    return;
  }

  DEBUG(dbgs() << "Nuking dead block: " << *BB);
  
  // Remove the instructions in the basic block from the worklist.
  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
    RemoveFromWorklist(I, Worklist);
    
    // Anything that uses the instructions in this basic block should have their
    // uses replaced with undefs.
    // If I is not void type then replaceAllUsesWith undef.
    // This allows ValueHandlers and custom metadata to adjust itself.
    if (!I->getType()->isVoidTy())
      I->replaceAllUsesWith(UndefValue::get(I->getType()));
  }
  
  // If this is the edge to the header block for a loop, remove the loop and
  // promote all subloops.
  if (Loop *BBLoop = LI->getLoopFor(BB)) {
    if (BBLoop->getLoopLatch() == BB)
      RemoveLoopFromHierarchy(BBLoop);
  }

  // Remove the block from the loop info, which removes it from any loops it
  // was in.
  LI->removeBlock(BB);
  
  
  // Remove phi node entries in successors for this block.
  TerminatorInst *TI = BB->getTerminator();
  SmallVector<BasicBlock*, 4> Succs;
  for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) {
    Succs.push_back(TI->getSuccessor(i));
    TI->getSuccessor(i)->removePredecessor(BB);
  }
  
  // Unique the successors, remove anything with multiple uses.
  array_pod_sort(Succs.begin(), Succs.end());
  Succs.erase(std::unique(Succs.begin(), Succs.end()), Succs.end());
  
  // Remove the basic block, including all of the instructions contained in it.
  LPM->deleteSimpleAnalysisValue(BB, L);  
  BB->eraseFromParent();
  // Remove successor blocks here that are not dead, so that we know we only
  // have dead blocks in this list.  Nondead blocks have a way of becoming dead,
  // then getting removed before we revisit them, which is badness.
  //
  for (unsigned i = 0; i != Succs.size(); ++i)
    if (pred_begin(Succs[i]) != pred_end(Succs[i])) {
      // One exception is loop headers.  If this block was the preheader for a
      // loop, then we DO want to visit the loop so the loop gets deleted.
      // We know that if the successor is a loop header, that this loop had to
      // be the preheader: the case where this was the latch block was handled
      // above and headers can only have two predecessors.
      if (!LI->isLoopHeader(Succs[i])) {
        Succs.erase(Succs.begin()+i);
        --i;
      }
    }
  
  for (unsigned i = 0, e = Succs.size(); i != e; ++i)
    RemoveBlockIfDead(Succs[i], Worklist, L);
}
Ejemplo n.º 9
0
void HeterotbbTransform::edit_template_function (Module &M,Function* F,Function* new_join,GlobalVariable *old_gb,Value *gb) {

    SmallVector<Value*, 16> Args; // Argument lists to the new call
    vector<Instruction *> toDelete;
    //	old_gb->dump();
    //	gb->dump();
    Constant *Ids[2];

    for (Function::iterator BI=F->begin(),BE = F->end(); BI != BE; ++BI) {
        for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE; ++II) {
            GetElementPtrInst *GEP;
            GlobalVariable *op;
            if (isa<CallInst>(II) || isa<InvokeInst>(II)) {
                CallSite CI(cast<Instruction>(II));
                //replace dummy reduce with new reduce
                if(CI.getCalledFunction()->getName().equals("__join_reduce_hetero")) {
                    Args.clear();
                    CastInst *newarg1 = CastInst::Create(Instruction::BitCast, CI.getArgument(0), new_join->arg_begin()->getType(), "arg1",CI.getInstruction());
                    Args.push_back(newarg1);
                    CastInst *newarg2 = CastInst::Create(Instruction::BitCast, CI.getArgument(1), new_join->arg_begin()->getType(), "arg2", CI.getInstruction());
                    Args.push_back(newarg2);

                    //no need to set attributes
                    Instruction *NewCall = CallInst::Create(new_join, Args, "", CI.getInstruction());
                    cast<CallInst>(NewCall)->setCallingConv(CI.getCallingConv());
                    toDelete.push_back(CI.getInstruction());
                    DEBUG(dbgs()<<"Joins Replaced\n");
                }
            }

            /*
            %arrayidx18 = getelementptr inbounds i32 addrspace(3)* getelementptr
            inbounds ([192 x i32] addrspace(3)* @opencl_kernel_join_name_local_arr, i32 0, i32 0),
            i64 %idxprom1
            */
            if((GEP = dyn_cast<GetElementPtrInst>(II)) /*&&
													   (op = dyn_cast<GlobalVariable>(GEP->getOperand(0)))*/ /*&&
													   (op->getName().equals("opencl_kernel_join_name_local_arr"))*/) {
                //II->dump();
                Value *val= II->getOperand(0);
                if(Constant *op=dyn_cast<ConstantExpr>(val)) {
                    //II->dump();
                    //II->getOperand(1)->dump();

                    /*Ids[0]=cast<Constant>(op->getOperand(1));
                    Ids[1]=cast<Constant>(op->getOperand(1));
                    Constant *new_op = ConstantExpr::getInBoundsGetElementPtr(cast<Constant>(gb),Ids,2);
                    new_op->dump();
                    Instruction *inst = GetElementPtrInst::CreateInBounds(new_op, II->getOperand(1), II->getName()+"_temp",II);
                    Value *Elts[] = {MDString::get(M.getContext(), "local_access")};
                    MDNode *Node = MDNode::get(M.getContext(), Elts);
                    inst->setMetadata("local_access",Node);
                    inst->dump();
                    II->replaceAllUsesWith(inst);
                    toDelete.push_back(II);
                    */

                    Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(M.getContext()), 0),
                                      ConstantInt::get(Type::getInt32Ty(M.getContext()), 0)
                                     };
                    //gb->getType()->dump();
                    //gb->dump();
                    Instruction *inst_= GetElementPtrInst::CreateInBounds(gb, Idxs, /*Idxs+2,*/ II->getName()+"_temp_",II);
                    //inst_->dump();
                    Instruction *inst= GetElementPtrInst::CreateInBounds(inst_, II->getOperand(1), II->getName()+"_temp",II);
                    Value *Elts[] = {MDString::get(M.getContext(), inst->getName())};
                    MDNode *Node = MDNode::get(M.getContext(), Elts);
                    inst->setMetadata("local_access",Node);

                    //inst->dump();
                    II->replaceAllUsesWith(inst);
                    toDelete.push_back(II);

                }
            }
        }
    }
    while(!toDelete.empty()) {
        Instruction *g = toDelete.back();
        toDelete.pop_back();

        g->eraseFromParent();
    }

}
Ejemplo n.º 10
0
void ArrayObfs::ArrObfuscate ( Function *F )
{

	// Iterate the whole Function
	Function *f = F;
	for ( Function::iterator bb = f->begin(); bb != f->end(); ++bb )
	{
		for ( BasicBlock::iterator inst = bb->begin(); inst != bb->end(); )
		{
			if ( inst->getOpcode() == 29 )		// getelementptr
			{
				//errs() << "INST : " << *inst << "\n";

				GetElementPtrInst *Ary = dyn_cast<GetElementPtrInst>(&*inst);
				Value *ptrVal = Ary->getOperand(0);
				Type *type = ptrVal->getType();

				unsigned numOfOprand = Ary->getNumOperands();
				unsigned lastOprand = numOfOprand - 1;

				// Check Type Array

				if ( PointerType *ptrType = dyn_cast<PointerType>( type ) )
				{
					Type *elementType = ptrType->getElementType();
					if ( elementType->isArrayTy() )
					{
						// Skip if Index is a Variable
						if ( dyn_cast<ConstantInt>( Ary->getOperand( lastOprand ) ) )
						{

				//////////////////////////////////////////////////////////////////////////////

				// Do Real Stuff
				Value *oprand = Ary->getOperand( lastOprand );
				Value *basePtr = Ary->getOperand( 0 );
				APInt offset = dyn_cast<ConstantInt>(oprand)->getValue();
				Value *prevPtr = basePtr;

				// Enter a Loop to Perform Random Obfuscation
				unsigned cnt = 100;

				// Prelog : Clone the Original Inst
				unsigned ObfsIdx =  cryptoutils->get_uint64_t() & 0xffff;
				Value *newOprand = ConstantInt::get( oprand->getType(), ObfsIdx );
				Instruction *gep = inst->clone();
				gep->setOperand( lastOprand, newOprand );
				gep->setOperand( 0, prevPtr );
				gep->insertBefore( inst );
				prevPtr = gep;
				offset = offset - ObfsIdx;

				// Create a Global Variable to Avoid Optimization
				Module *M = f->getParent();
				Constant *initGV = ConstantInt::get( prevPtr->getType(), 0 );
				GlobalVariable *gv = new GlobalVariable( *M, prevPtr->getType(), false, GlobalValue::CommonLinkage, initGV );

				while ( cnt-- )
				{
					// Iteratively Generate Obfuscated Code
					switch( cryptoutils->get_uint64_t() & 7 )
					{
					// Random Indexing Obfuscation
					case 0 :
					case 1 :
					case 2 :
						{
						//errs() << "=> Random Index \n";

						// Create New Instruction
						//   Create Obfuscated New Oprand in ConstantInt Type
						unsigned ObfsIdx =  cryptoutils->get_uint64_t() & 0xffff;
						Value *newOprand = ConstantInt::get( oprand->getType(), ObfsIdx );

						//   Create GetElementPtrInst Instruction
						GetElementPtrInst *gep = GetElementPtrInst::Create( prevPtr, newOprand, "", inst );

						//Set prevPtr
						prevPtr = gep;

						//errs() << "Created : " << *prevPtr << "\n";

						offset = offset - ObfsIdx;
						break;
						}

					// Ptr Dereference
					case 3 :
					case 4 :
						{
						//errs() << "=> Ptr Dereference \n";

						Module *M = f->getParent();
						Value *ONE = ConstantInt::get( Type::getInt32Ty( M->getContext() ), 1 );
						Value *tmp = new AllocaInst( prevPtr->getType(), ONE, "", inst );

						new StoreInst( prevPtr, tmp, inst );

						prevPtr = new LoadInst( tmp, "", inst );

						break;
						}

					// Ptr Value Transform
					case 5 :
					case 6 :
					case 7 :
						{
						//errs() << "=> Ptr Value Trans \n";

						unsigned RandNum =  cryptoutils->get_uint64_t();
						Value *ObfsVal = ConstantInt::get( prevPtr->getType(), RandNum );

						BinaryOperator *op = BinaryOperator::Create( Instruction::FAdd, prevPtr, ObfsVal, "", inst );
						new StoreInst( prevPtr, gv, inst );
						BinaryOperator::Create( Instruction::FSub, gv, ObfsVal, "", inst );
						prevPtr = new LoadInst( gv, "", inst );

						break;
						}
					}
				}

				// Postlog : Fix the Original Indexing
				{
				Value *fixOprand = ConstantInt::get( oprand->getType(), offset );
				// Refine the Last Instruction
				GetElementPtrInst *gep = GetElementPtrInst::Create( prevPtr, fixOprand, "", inst );

				// Fix the Relationship
				inst->replaceAllUsesWith( gep );

				// Finally : Unlink This Instruction From Parent
				Instruction *DI = inst++;
				//errs() << "user_back : " << *(DI->user_back()) << "\n";
				DI->removeFromParent();
				}

				//////////////////////////////////////////////////////////////////////////////

						// End : Variable Index
						} else { inst++; }
					// End : Check Array Type
					} else { inst++; }
				// End : Check Pointer Type
				} else { inst++; }
			// End : Check Opcode GetElementPtr
			} else { inst++; }
		}
	}
	++ArrayMod;
}
Ejemplo n.º 11
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();
}
Ejemplo n.º 12
0
    virtual bool runOnFunction(Function &F) {
      DEBUG(errs() << "Running on " << F.getName() << "\n");
      DEBUG(F.dump());
      Changed = false;
      BaseMap.clear();
      BoundsMap.clear();
      AbrtBB = 0;
      valid = true;

      if (!rootNode) {
        rootNode = getAnalysis<CallGraph>().getRoot();
        // No recursive functions for now.
        // In the future we may insert runtime checks for stack depth.
        for (scc_iterator<CallGraphNode*> SCCI = scc_begin(rootNode),
             E = scc_end(rootNode); SCCI != E; ++SCCI) {
          const std::vector<CallGraphNode*> &nextSCC = *SCCI;
          if (nextSCC.size() > 1 || SCCI.hasLoop()) {
            errs() << "INVALID: Recursion detected, callgraph SCC components: ";
            for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(),
                 E = nextSCC.end(); I != E; ++I) {
              Function *FF = (*I)->getFunction();
              if (FF) {
                errs() << FF->getName() << ", ";
                badFunctions.insert(FF);
              }
            }
            if (SCCI.hasLoop())
              errs() << "(self-loop)";
            errs() << "\n";
          }
          // we could also have recursion via function pointers, but we don't
          // allow calls to unknown functions, see runOnFunction() below
        }
      }

      BasicBlock::iterator It = F.getEntryBlock().begin();
      while (isa<AllocaInst>(It) || isa<PHINode>(It)) ++It;
      EP = &*It;

      TD = &getAnalysis<TargetData>();
      SE = &getAnalysis<ScalarEvolution>();
      PT = &getAnalysis<PointerTracking>();
      DT = &getAnalysis<DominatorTree>();

      std::vector<Instruction*> insns;

      BasicBlock *LastBB = 0;
      bool skip = false;
      for (inst_iterator I=inst_begin(F),E=inst_end(F); I != E;++I) {
        Instruction *II = &*I;
	if (II->getParent() != LastBB) {
	    LastBB = II->getParent();
	    skip = DT->getNode(LastBB) == 0;
	}
	if (skip)
	    continue;
        if (isa<LoadInst>(II) || isa<StoreInst>(II) || isa<MemIntrinsic>(II))
          insns.push_back(II);
        if (CallInst *CI = dyn_cast<CallInst>(II)) {
          Value *V = CI->getCalledValue()->stripPointerCasts();
          Function *F = dyn_cast<Function>(V);
          if (!F) {
            printLocation(CI, true);
            errs() << "Could not determine call target\n";
            valid = 0;
            continue;
          }
          if (!F->isDeclaration())
            continue;
          insns.push_back(CI);
        }
      }
      while (!insns.empty()) {
        Instruction *II = insns.back();
        insns.pop_back();
        DEBUG(dbgs() << "checking " << *II << "\n");
        if (LoadInst *LI = dyn_cast<LoadInst>(II)) {
          const Type *Ty = LI->getType();
          valid &= validateAccess(LI->getPointerOperand(),
                                  TD->getTypeAllocSize(Ty), LI);
        } else if (StoreInst *SI = dyn_cast<StoreInst>(II)) {
          const Type *Ty = SI->getOperand(0)->getType();
          valid &= validateAccess(SI->getPointerOperand(),
                                  TD->getTypeAllocSize(Ty), SI);
        } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(II)) {
          valid &= validateAccess(MI->getDest(), MI->getLength(), MI);
          if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) {
            valid &= validateAccess(MTI->getSource(), MI->getLength(), MI);
          }
        } else if (CallInst *CI = dyn_cast<CallInst>(II)) {
          Value *V = CI->getCalledValue()->stripPointerCasts();
          Function *F = cast<Function>(V);
          const FunctionType *FTy = F->getFunctionType();
	  CallSite CS(CI);

          if (F->getName().equals("memcmp") && FTy->getNumParams() == 3) {
            valid &= validateAccess(CS.getArgument(0), CS.getArgument(2), CI);
            valid &= validateAccess(CS.getArgument(1), CS.getArgument(2), CI);
            continue;
          }
	  unsigned i;
#ifdef CLAMBC_COMPILER
	  i = 0;
#else
	  i = 1;// skip hidden ctx*
#endif
          for (;i<FTy->getNumParams();i++) {
            if (isa<PointerType>(FTy->getParamType(i))) {
              Value *Ptr = CS.getArgument(i);
              if (i+1 >= FTy->getNumParams()) {
                printLocation(CI, false);
                errs() << "Call to external function with pointer parameter last cannot be analyzed\n";
                errs() << *CI << "\n";
                valid = 0;
                break;
              }
              Value *Size = CS.getArgument(i+1);
              if (!Size->getType()->isIntegerTy()) {
                printLocation(CI, false);
                errs() << "Pointer argument must be followed by integer argument representing its size\n";
                errs() << *CI << "\n";
                valid = 0;
                break;
              }
              valid &= validateAccess(Ptr, Size, CI);
            }
          }
        }
      }
      if (badFunctions.count(&F))
        valid = 0;

      if (!valid) {
	DEBUG(F.dump());
        ClamBCModule::stop("Verification found errors!", &F);
	// replace function with call to abort
        std::vector<const Type*>args;
        FunctionType* abrtTy = FunctionType::get(
          Type::getVoidTy(F.getContext()),args,false);
        Constant *func_abort =
          F.getParent()->getOrInsertFunction("abort", abrtTy);

	BasicBlock *BB = &F.getEntryBlock();
	Instruction *I = &*BB->begin();
	Instruction *UI = new UnreachableInst(F.getContext(), I);
	CallInst *AbrtC = CallInst::Create(func_abort, "", UI);
        AbrtC->setCallingConv(CallingConv::C);
        AbrtC->setTailCall(true);
        AbrtC->setDoesNotReturn(true);
        AbrtC->setDoesNotThrow(true);
	// remove all instructions from entry
	BasicBlock::iterator BBI = I, BBE=BB->end();
	while (BBI != BBE) {
	    if (!BBI->use_empty())
		BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
	    BB->getInstList().erase(BBI++);
	}
      }
      return Changed;
    }
Ejemplo n.º 13
0
    bool ModuloSchedulerDriverPass::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) {
      
        subscripts subs(IncomingLoop);

        if (!loop_is_ms_able(IncomingLoop) ) return false; 

        // The header before the parallelized loop will be placed here
        BasicBlock* preheader = IncomingLoop->getLoopPreheader();
        assert(preheader && "Unable to get a hold of the preheader");

        // Balance all BasicBlocks in this loop
        for (Loop::block_iterator it=IncomingLoop->block_begin(); it!=IncomingLoop->block_end();++it) {
            duplicateValuesWithMultipleUses(*it,subs.getInductionVar());
        }

        // For each BB in loop
        for (Loop::block_iterator it=IncomingLoop->block_begin(); it!=IncomingLoop->block_end();++it) {
            instructionPriority  ip(*it);
            (*it)->setName("PipelinedLoop");
            
            // ++++++++ Preheader part +++++++++
            // Make a copy of the body for each instruction. Place a pointer to the 
            // parallel cloned instruction in the map below. Later on we will replace it 
            // with a PHINode.
            DenseMap<const Value *, Value *>  InstToPreheader;

            // For each Instruction in body of the loop, clone, store, etc.
            for (BasicBlock::iterator ib = (*it)->begin(), eb = (*it)->end(); ib!=eb; ++ib) {
                // If this is NOT a phi node
                if (!dyn_cast<PHINode>(ib)) {
                    // Get the priority of the instruction
                    unsigned int p = ip.getPriority(ib);
                    // This is the header version of each variable that goes into a PHI node.
                    // The other edge needs to come from the 'prev' iteration
                    // We subtract -1 because this is one iteration before 
                    // Store the result into the map of the cloned
                    InstToPreheader[ib] = copyLoopBodyToHeader(ib, subs.getInductionVar(), preheader, p-1);
                }
            }

            // ++++++++ Loop body part +++++++++
            // For each of the cloned increment the indexs if needed and place the PHINode.
            for (BasicBlock::iterator ib = (*it)->begin(), eb = (*it)->end(); ib!=eb; ++ib) {
                // If this is NOT a phi node
                if (!dyn_cast<PHINode>(ib)) {
                    unsigned int p = ip.getPriority(ib);

                    // If this variable is not dependent on i (not i:=i+1)
                    // then we need to replace each i to i+5 ...
                    // We also do not need to create a PHI node, etc.
                    if (!subs.isUsedByInductionVariable(ib)) {
                        
                        incrementInductionVarIfUsed(ib,subs.getInductionVar(),p);

                        // Create the new PHI Node to replace the node
                        if (!dyn_cast<StoreInst>(ib) && !ib->isTerminator()) {
                            std::string newname = "glue" + (*it)->getName();

                            //PHINode* np = PHINode::Create(ib->getType(), "glue", *it);
                            PHINode* np = PHINode::Create(ib->getType(), newname, *it);
                            ib->replaceAllUsesWith(np);
                            np->reserveOperandSpace(2);
                            np->addIncoming(InstToPreheader[ib], preheader);
                            np->addIncoming(ib, *it);
                            np->moveBefore((*it)->begin());
                        }

                    }// end of if this is not an IV node (i:=i+1) 
                }
            }
        }

        eliminateDuplicatedLoads(preheader);
        for (Loop::block_iterator it=IncomingLoop->block_begin(); it!=IncomingLoop->block_end();++it) {
            eliminateDuplicatedLoads(*it);
            for (BasicBlock::iterator in = (*it)->begin(); in != (*it)->end(); ++in) {
                foldAddInstructions(in);
            }
        }
        return true;
    }