Ejemplo n.º 1
0
// visitCallInst - This converts all LLVM call instructions into invoke
// instructions. The except part of the invoke goes to the "LongJmpBlkPre"
// that grabs the exception and proceeds to determine if it's a longjmp
// exception or not.
void LowerSetJmp::visitCallInst(CallInst& CI)
{
  if (CI.getCalledFunction())
    if (!IsTransformableFunction(CI.getCalledFunction()->getName()) ||
        CI.getCalledFunction()->isIntrinsic()) return;

  BasicBlock* OldBB = CI.getParent();

  // If not reachable from a setjmp call, don't transform.
  if (!DFSBlocks.count(OldBB)) return;

  BasicBlock* NewBB = OldBB->splitBasicBlock(CI);
  assert(NewBB && "Couldn't split BB of \"call\" instruction!!");
  DFSBlocks.insert(NewBB);
  NewBB->setName("Call2Invoke");

  Function* Func = OldBB->getParent();

  // Construct the new "invoke" instruction.
  TerminatorInst* Term = OldBB->getTerminator();
  std::vector<Value*> Params(CI.op_begin() + 1, CI.op_end());
  InvokeInst* II =
    InvokeInst::Create(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
                       Params.begin(), Params.end(), CI.getName(), Term);
  II->setCallingConv(CI.getCallingConv());
  II->setAttributes(CI.getAttributes());

  // Replace the old call inst with the invoke inst and remove the call.
  CI.replaceAllUsesWith(II);
  CI.eraseFromParent();

  // The old terminator is useless now that we have the invoke inst.
  Term->eraseFromParent();
  ++CallsTransformed;
}
Instruction* TripCountGenerator::generateReplaceIfEqual
		(Value* Op, Value* ValueToTest, Value* ValueToReplace,
				Instruction* InsertBefore){

	BasicBlock* startBB = InsertBefore->getParent();
	BasicBlock* endBB = InsertBefore->getParent()->splitBasicBlock(InsertBefore);

	TerminatorInst* T = startBB->getTerminator();

	IRBuilder<> Builder(T);

	BasicBlock* EQ = BasicBlock::Create(*context, "", InsertBefore->getParent()->getParent(), endBB);

	Value* cmp;
	cmp = Builder.CreateICmpEQ(Op,ValueToTest,"");
	Builder.CreateCondBr(cmp, EQ, endBB, NULL);
	T->eraseFromParent();

	Builder.SetInsertPoint(EQ);
	Builder.CreateBr(endBB);

	Builder.SetInsertPoint(InsertBefore);
	PHINode* phi = Builder.CreatePHI(Op->getType(), 2, "");
	phi->addIncoming(ValueToReplace, EQ);
	phi->addIncoming(Op, startBB);

	return phi;

}
Ejemplo n.º 3
0
/// \brief Remove phi values from all successors and then remove the terminator.
void StructurizeCFG::killTerminator(BasicBlock *BB) {
  TerminatorInst *Term = BB->getTerminator();
  if (!Term)
    return;

  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
       SI != SE; ++SI)
    delPhiValues(BB, *SI);

  Term->eraseFromParent();
}
Ejemplo n.º 4
0
// Cleanly removes a terminator instruction.
void GNUstep::removeTerminator(BasicBlock *BB) {
    TerminatorInst *BBTerm = BB->getTerminator();

    // Remove the BB as a predecessor from all of  successors
    for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) {
        BBTerm->getSuccessor(i)->removePredecessor(BB);
    }

    BBTerm->replaceAllUsesWith(UndefValue::get(BBTerm->getType()));
    // Remove the terminator instruction itself.
    BBTerm->eraseFromParent();
}
Ejemplo n.º 5
0
/// LowerUnwinds - Turn unwind instructions into calls to _Unwind_Resume,
/// rethrowing any previously caught exception.  This will crash horribly
/// at runtime if there is no such exception: using unwind to throw a new
/// exception is currently not supported.
bool DwarfEHPrepare::LowerUnwinds() {
  SmallVector<TerminatorInst*, 16> UnwindInsts;

  for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
    TerminatorInst *TI = I->getTerminator();
    if (isa<UnwindInst>(TI))
      UnwindInsts.push_back(TI);
  }

  if (UnwindInsts.empty()) return false;

  // Find the rewind function if we didn't already.
  if (!RewindFunction) {
    LLVMContext &Ctx = UnwindInsts[0]->getContext();
    std::vector<const Type*>
      Params(1, Type::getInt8PtrTy(Ctx));
    FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
                                          Params, false);
    const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME);
    RewindFunction = F->getParent()->getOrInsertFunction(RewindName, FTy);
  }

  bool Changed = false;

  for (SmallVectorImpl<TerminatorInst*>::iterator
         I = UnwindInsts.begin(), E = UnwindInsts.end(); I != E; ++I) {
    TerminatorInst *TI = *I;

    // Replace the unwind instruction with a call to _Unwind_Resume (or the
    // appropriate target equivalent) followed by an UnreachableInst.

    // Create the call...
    CallInst *CI = CallInst::Create(RewindFunction,
                                    CreateReadOfExceptionValue(TI->getParent()),
                                    "", TI);
    CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));
    // ...followed by an UnreachableInst.
    new UnreachableInst(TI->getContext(), TI);

    // Nuke the unwind instruction.
    TI->eraseFromParent();
    ++NumUnwindsLowered;
    Changed = true;
  }

  return Changed;
}
void ForwardControlFlowIntegrity::rewriteFunctionPointer(
    Module &M, Instruction *I, Value *FunPtr, Constant *JumpTableStart,
    Constant *JumpTableMask, Constant *JumpTableSize) {
  IRBuilder<> TempBuilder(I);

  Type *OrigFunType = FunPtr->getType();

  BasicBlock *CurBB = cast<BasicBlock>(I->getParent());
  Function *CurF = cast<Function>(CurBB->getParent());
  Type *Int64Ty = Type::getInt64Ty(M.getContext());

  Value *TI = TempBuilder.CreatePtrToInt(FunPtr, Int64Ty);
  Value *TStartInt = TempBuilder.CreatePtrToInt(JumpTableStart, Int64Ty);

  Value *NewFunPtr = nullptr;
  Value *Check = nullptr;
  switch (CFIType) {
  case CFIntegrity::Sub: {
    // This is the subtract, mask, and add version.
    // Subtract from the base.
    Value *Sub = TempBuilder.CreateSub(TI, TStartInt);

    // Mask the difference to force this to be a table offset.
    Value *And = TempBuilder.CreateAnd(Sub, JumpTableMask);

    // Add it back to the base.
    Value *Result = TempBuilder.CreateAdd(And, TStartInt);

    // Convert it back into a function pointer that we can call.
    NewFunPtr = TempBuilder.CreateIntToPtr(Result, OrigFunType);
    break;
  }
  case CFIntegrity::Ror: {
    // This is the subtract and rotate version.
    // Rotate right by the alignment value. The optimizer should recognize
    // this sequence as a rotation.

    // This cast is safe, since unsigned is always a subset of uint64_t.
    uint64_t LogByteAlignment64 = static_cast<uint64_t>(LogByteAlignment);
    Constant *RightShift = ConstantInt::get(Int64Ty, LogByteAlignment64);
    Constant *LeftShift = ConstantInt::get(Int64Ty, 64 - LogByteAlignment64);

    // Subtract from the base.
    Value *Sub = TempBuilder.CreateSub(TI, TStartInt);

    // Create the equivalent of a rotate-right instruction.
    Value *Shr = TempBuilder.CreateLShr(Sub, RightShift);
    Value *Shl = TempBuilder.CreateShl(Sub, LeftShift);
    Value *Or = TempBuilder.CreateOr(Shr, Shl);

    // Perform unsigned comparison to check for inclusion in the table.
    Check = TempBuilder.CreateICmpULT(Or, JumpTableSize);
    NewFunPtr = FunPtr;
    break;
  }
  case CFIntegrity::Add: {
    // This is the mask and add version.
    // Mask the function pointer to turn it into an offset into the table.
    Value *And = TempBuilder.CreateAnd(TI, JumpTableMask);

    // Then or this offset to the base and get the pointer value.
    Value *Result = TempBuilder.CreateAdd(And, TStartInt);

    // Convert it back into a function pointer that we can call.
    NewFunPtr = TempBuilder.CreateIntToPtr(Result, OrigFunType);
    break;
  }
  }

  if (!CFIEnforcing) {
    // If a check hasn't been added (in the rotation version), then check to see
    // if it's the same as the original function. This check determines whether
    // or not we call the CFI failure function.
    if (!Check)
      Check = TempBuilder.CreateICmpEQ(NewFunPtr, FunPtr);
    BasicBlock *InvalidPtrBlock =
        BasicBlock::Create(M.getContext(), "invalid.ptr", CurF, 0);
    BasicBlock *ContinuationBB = CurBB->splitBasicBlock(I);

    // Remove the unconditional branch that connects the two blocks.
    TerminatorInst *TermInst = CurBB->getTerminator();
    TermInst->eraseFromParent();

    // Add a conditional branch that depends on the Check above.
    BranchInst::Create(ContinuationBB, InvalidPtrBlock, Check, CurBB);

    // Call the warning function for this pointer, then continue.
    Instruction *BI = BranchInst::Create(ContinuationBB, InvalidPtrBlock);
    insertWarning(M, InvalidPtrBlock, BI, FunPtr);
  } else {
    // Modify the instruction to call this value.
    CallSite CS(I);
    CS.setCalledFunction(NewFunPtr);
  }
}
Value* TripCountGenerator::generatePericlesEstimatedTripCount(BasicBlock* header, BasicBlock* entryBlock, Value* Op1, Value* Op2, CmpInst* CI){

	bool isSigned = CI->isSigned();

	BasicBlock* GT = BasicBlock::Create(*context, "", header->getParent(), header);
	BasicBlock* LE = BasicBlock::Create(*context, "", header->getParent(), header);
	BasicBlock* PHI = BasicBlock::Create(*context, "", header->getParent(), header);

	TerminatorInst* T = entryBlock->getTerminator();

	IRBuilder<> Builder(T);


	//Make sure the two operands have the same type
	if (Op1->getType() != Op2->getType()) {

		if (Op1->getType()->getIntegerBitWidth() > Op2->getType()->getIntegerBitWidth() ) {
			//expand op2
			if (isSigned) Op2 = Builder.CreateSExt(Op2, Op1->getType(), "");
			else Op2 = Builder.CreateZExt(Op2, Op1->getType(), "");

		} else {
			//expand op1
			if (isSigned) Op1 = Builder.CreateSExt(Op1, Op2->getType(), "");
			else Op1 = Builder.CreateZExt(Op1, Op2->getType(), "");

		}

	}

	assert(Op1->getType() == Op2->getType() && "Operands with different data types, even after adjust!");


	Value* cmp;

	if (isSigned)
		cmp = Builder.CreateICmpSGT(Op1,Op2,"");
	else
		cmp = Builder.CreateICmpUGT(Op1,Op2,"");

	Builder.CreateCondBr(cmp, GT, LE, NULL);
	T->eraseFromParent();

	/*
	 * estimatedTripCount = |Op1 - Op2|
	 *
	 * We will create the same sub in both GT and in LE blocks, but
	 * with inverted operand order. Thus, the result of the subtraction
	 * will be always positive.
	 */

	Builder.SetInsertPoint(GT);
	Value* sub1;
	if (isSigned) {
		//We create a signed sub
		sub1 = Builder.CreateNSWSub(Op1, Op2);
	} else {
		//We create an unsigned sub
		sub1 = Builder.CreateNUWSub(Op1, Op2);
	}
	Builder.CreateBr(PHI);

	Builder.SetInsertPoint(LE);
	Value* sub2;
	if (isSigned) {
		//We create a signed sub
		sub2 = Builder.CreateNSWSub(Op2, Op1);
	} else {
		//We create an unsigned sub
		sub2 = Builder.CreateNUWSub(Op2, Op1);
	}
	Builder.CreateBr(PHI);

	Builder.SetInsertPoint(PHI);
	PHINode* sub = Builder.CreatePHI(sub2->getType(), 2, "");
	sub->addIncoming(sub1, GT);
	sub->addIncoming(sub2, LE);

	Value* EstimatedTripCount;
	if (isSigned) 	EstimatedTripCount = Builder.CreateSExtOrBitCast(sub, Type::getInt64Ty(*context), "EstimatedTripCount");
	else			EstimatedTripCount = Builder.CreateZExtOrBitCast(sub, Type::getInt64Ty(*context), "EstimatedTripCount");

	switch(CI->getPredicate()){
		case CmpInst::ICMP_UGE:
		case CmpInst::ICMP_ULE:
		case CmpInst::ICMP_SGE:
		case CmpInst::ICMP_SLE:
			{
				Constant* One = ConstantInt::get(EstimatedTripCount->getType(), 1);
				EstimatedTripCount = Builder.CreateAdd(EstimatedTripCount, One);
				break;
			}
		default:
			break;
	}

	//Insert a metadata to identify the instruction as the EstimatedTripCount
	Instruction* i = dyn_cast<Instruction>(EstimatedTripCount);
	MarkAsTripCount(*i);

	Builder.CreateBr(header);

	//Adjust the PHINodes of the loop header accordingly
	for (BasicBlock::iterator it = header->begin(); it != header->end(); it++){
		Instruction* tmp = it;

		if (PHINode* I = dyn_cast<PHINode>(tmp)){
			int i = I->getBasicBlockIndex(entryBlock);
			if (i >= 0){
				I->setIncomingBlock(i,PHI);
			}
		}

	}



	return EstimatedTripCount;
}
Instruction* llvm::TripCountGenerator::generateModuleOfSubtraction
		(Value* Op1, Value* Op2, bool isSigned, Instruction* InsertBefore){

	BasicBlock* startBB = InsertBefore->getParent();
	BasicBlock* endBB = InsertBefore->getParent()->splitBasicBlock(InsertBefore);

	TerminatorInst* T = startBB->getTerminator();

	IRBuilder<> Builder(T);

	//Make sure the two operands have the same type
	equalizeTypes(Op1, Op2, isSigned, Builder);
	assert(Op1->getType() == Op2->getType() && "Operands with different data types, even after adjust!");


	BasicBlock* GT = BasicBlock::Create(*context, "", InsertBefore->getParent()->getParent(), endBB);
	BasicBlock* LE = BasicBlock::Create(*context, "", InsertBefore->getParent()->getParent(), endBB);

	Value* cmp;

	if (isSigned)
		cmp = Builder.CreateICmpSGT(Op1,Op2,"");
	else
		cmp = Builder.CreateICmpUGT(Op1,Op2,"");

	Builder.CreateCondBr(cmp, GT, LE, NULL);
	T->eraseFromParent();

	/*
	 * ModuleOfSubtraction = |Op1 - Op2|
	 *
	 * We will create the same sub in both GT and in LE blocks, but
	 * with inverted operand order. Thus, the result of the subtraction
	 * will be always positive.
	 */

	Builder.SetInsertPoint(GT);
	Value* sub1;
	if (isSigned) {
		//We create a signed sub
		sub1 = Builder.CreateNSWSub(Op1, Op2, "diff");
	} else {
		//We create an unsigned sub
		sub1 = Builder.CreateNUWSub(Op1, Op2, "diff");
	}
	Builder.CreateBr(endBB);


	Builder.SetInsertPoint(LE);
	Value* sub2;
	if (isSigned) {
		//We create a signed sub
		sub2 = Builder.CreateNSWSub(Op2, Op1, "diff");
	} else {
		//We create an unsigned sub
		sub2 = Builder.CreateNUWSub(Op2, Op1, "diff");
	}
	Builder.CreateBr(endBB);

	Builder.SetInsertPoint(InsertBefore);
	PHINode* sub = Builder.CreatePHI(sub2->getType(), 2, "");
	sub->addIncoming(sub1, GT);
	sub->addIncoming(sub2, LE);

	return sub;
}
Ejemplo n.º 9
0
/// Rotate loop LP. Return true if the loop is rotated.
bool LoopRotate::rotateLoop(Loop *L) {
  // If the loop has only one block then there is not much to rotate.
  if (L->getBlocks().size() == 1)
    return false;
  
  BasicBlock *OrigHeader = L->getHeader();
  
  BranchInst *BI = dyn_cast<BranchInst>(OrigHeader->getTerminator());
  if (BI == 0 || BI->isUnconditional())
    return false;
  
  // If the loop header is not one of the loop exiting blocks then
  // either this loop is already rotated or it is not
  // suitable for loop rotation transformations.
  if (!L->isLoopExiting(OrigHeader))
    return false;

  // Updating PHInodes in loops with multiple exits adds complexity. 
  // Keep it simple, and restrict loop rotation to loops with one exit only.
  // In future, lift this restriction and support for multiple exits if
  // required.
  SmallVector<BasicBlock*, 8> ExitBlocks;
  L->getExitBlocks(ExitBlocks);
  if (ExitBlocks.size() > 1)
    return false;

  // Check size of original header and reject loop if it is very big.
  {
    CodeMetrics Metrics;
    Metrics.analyzeBasicBlock(OrigHeader);
    if (Metrics.NumInsts > MAX_HEADER_SIZE)
      return false;
  }

  // Now, this loop is suitable for rotation.
  BasicBlock *OrigPreheader = L->getLoopPreheader();
  BasicBlock *OrigLatch = L->getLoopLatch();
  
  // If the loop could not be converted to canonical form, it must have an
  // indirectbr in it, just give up.
  if (OrigPreheader == 0 || OrigLatch == 0)
    return false;

  // Anything ScalarEvolution may know about this loop or the PHI nodes
  // in its header will soon be invalidated.
  if (ScalarEvolution *SE = getAnalysisIfAvailable<ScalarEvolution>())
    SE->forgetLoop(L);

  // Find new Loop header. NewHeader is a Header's one and only successor
  // that is inside loop.  Header's other successor is outside the
  // loop.  Otherwise loop is not suitable for rotation.
  BasicBlock *Exit = BI->getSuccessor(0);
  BasicBlock *NewHeader = BI->getSuccessor(1);
  if (L->contains(Exit))
    std::swap(Exit, NewHeader);
  assert(NewHeader && "Unable to determine new loop header");
  assert(L->contains(NewHeader) && !L->contains(Exit) && 
         "Unable to determine loop header and exit blocks");
  
  // This code assumes that the new header has exactly one predecessor.
  // Remove any single-entry PHI nodes in it.
  assert(NewHeader->getSinglePredecessor() &&
         "New header doesn't have one pred!");
  FoldSingleEntryPHINodes(NewHeader);

  // Begin by walking OrigHeader and populating ValueMap with an entry for
  // each Instruction.
  BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end();
  ValueToValueMapTy ValueMap;

  // For PHI nodes, the value available in OldPreHeader is just the
  // incoming value from OldPreHeader.
  for (; PHINode *PN = dyn_cast<PHINode>(I); ++I)
    ValueMap[PN] = PN->getIncomingValue(PN->getBasicBlockIndex(OrigPreheader));

  // For the rest of the instructions, either hoist to the OrigPreheader if
  // possible or create a clone in the OldPreHeader if not.
  TerminatorInst *LoopEntryBranch = OrigPreheader->getTerminator();
  while (I != E) {
    Instruction *Inst = I++;
    
    // If the instruction's operands are invariant and it doesn't read or write
    // memory, then it is safe to hoist.  Doing this doesn't change the order of
    // execution in the preheader, but does prevent the instruction from
    // executing in each iteration of the loop.  This means it is safe to hoist
    // something that might trap, but isn't safe to hoist something that reads
    // memory (without proving that the loop doesn't write).
    if (L->hasLoopInvariantOperands(Inst) &&
        !Inst->mayReadFromMemory() && !Inst->mayWriteToMemory() &&
        !isa<TerminatorInst>(Inst) && !isa<DbgInfoIntrinsic>(Inst)) {
      Inst->moveBefore(LoopEntryBranch);
      continue;
    }
    
    // Otherwise, create a duplicate of the instruction.
    Instruction *C = Inst->clone();
    
    // Eagerly remap the operands of the instruction.
    RemapInstruction(C, ValueMap,
                     RF_NoModuleLevelChanges|RF_IgnoreMissingEntries);
    
    // With the operands remapped, see if the instruction constant folds or is
    // otherwise simplifyable.  This commonly occurs because the entry from PHI
    // nodes allows icmps and other instructions to fold.
    Value *V = SimplifyInstruction(C);
    if (V && LI->replacementPreservesLCSSAForm(C, V)) {
      // If so, then delete the temporary instruction and stick the folded value
      // in the map.
      delete C;
      ValueMap[Inst] = V;
    } else {
      // Otherwise, stick the new instruction into the new block!
      C->setName(Inst->getName());
      C->insertBefore(LoopEntryBranch);
      ValueMap[Inst] = C;
    }
  }

  // Along with all the other instructions, we just cloned OrigHeader's
  // terminator into OrigPreHeader. Fix up the PHI nodes in each of OrigHeader's
  // successors by duplicating their incoming values for OrigHeader.
  TerminatorInst *TI = OrigHeader->getTerminator();
  for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
    for (BasicBlock::iterator BI = TI->getSuccessor(i)->begin();
         PHINode *PN = dyn_cast<PHINode>(BI); ++BI)
      PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreheader);

  // Now that OrigPreHeader has a clone of OrigHeader's terminator, remove
  // OrigPreHeader's old terminator (the original branch into the loop), and
  // remove the corresponding incoming values from the PHI nodes in OrigHeader.
  LoopEntryBranch->eraseFromParent();

  // If there were any uses of instructions in the duplicated block outside the
  // loop, update them, inserting PHI nodes as required
  RewriteUsesOfClonedInstructions(OrigHeader, OrigPreheader, ValueMap);

  // NewHeader is now the header of the loop.
  L->moveToHeader(NewHeader);
  assert(L->getHeader() == NewHeader && "Latch block is our new header");

  
  // At this point, we've finished our major CFG changes.  As part of cloning
  // the loop into the preheader we've simplified instructions and the
  // duplicated conditional branch may now be branching on a constant.  If it is
  // branching on a constant and if that constant means that we enter the loop,
  // then we fold away the cond branch to an uncond branch.  This simplifies the
  // loop in cases important for nested loops, and it also means we don't have
  // to split as many edges.
  BranchInst *PHBI = cast<BranchInst>(OrigPreheader->getTerminator());
  assert(PHBI->isConditional() && "Should be clone of BI condbr!");
  if (!isa<ConstantInt>(PHBI->getCondition()) ||
      PHBI->getSuccessor(cast<ConstantInt>(PHBI->getCondition())->isZero())
          != NewHeader) {
    // The conditional branch can't be folded, handle the general case.
    // Update DominatorTree to reflect the CFG change we just made.  Then split
    // edges as necessary to preserve LoopSimplify form.
    if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>()) {
      // Since OrigPreheader now has the conditional branch to Exit block, it is
      // the dominator of Exit.
      DT->changeImmediateDominator(Exit, OrigPreheader);
      DT->changeImmediateDominator(NewHeader, OrigPreheader);
      
      // Update OrigHeader to be dominated by the new header block.
      DT->changeImmediateDominator(OrigHeader, OrigLatch);
    }
    
    // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
    // thus is not a preheader anymore.  Split the edge to form a real preheader.
    BasicBlock *NewPH = SplitCriticalEdge(OrigPreheader, NewHeader, this);
    NewPH->setName(NewHeader->getName() + ".lr.ph");
    
    // Preserve canonical loop form, which means that 'Exit' should have only one
    // predecessor.
    BasicBlock *ExitSplit = SplitCriticalEdge(L->getLoopLatch(), Exit, this);
    ExitSplit->moveBefore(Exit);
  } else {
    // We can fold the conditional branch in the preheader, this makes things
    // simpler. The first step is to remove the extra edge to the Exit block.
    Exit->removePredecessor(OrigPreheader, true /*preserve LCSSA*/);
    BranchInst::Create(NewHeader, PHBI);
    PHBI->eraseFromParent();
    
    // With our CFG finalized, update DomTree if it is available.
    if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>()) {
      // Update OrigHeader to be dominated by the new header block.
      DT->changeImmediateDominator(NewHeader, OrigPreheader);
      DT->changeImmediateDominator(OrigHeader, OrigLatch);
    }
  }
  
  assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
  assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");

  // Now that the CFG and DomTree are in a consistent state again, try to merge
  // the OrigHeader block into OrigLatch.  This will succeed if they are
  // connected by an unconditional branch.  This is just a cleanup so the
  // emitted code isn't too gross in this common case.
  MergeBlockIntoPredecessor(OrigHeader, this);
  
  ++NumRotated;
  return true;
}
Ejemplo n.º 10
0
	virtual bool runOnModule(Module &M) {

		LLVMContext &C = M.getContext();
		Function *printError_func = (Function*)M.getOrInsertFunction("printErrorMessage", Type::getVoidTy(C), NULL);

		BasicBlock* entryBlock = BasicBlock::Create(C, "", printError_func);
		IRBuilder<> builder(entryBlock);

		Constant *msg = ConstantArray::get(C, "ERROR!  Array Index Out of Bounds", true);

		Constant *zero_32 = Constant::getNullValue(IntegerType::getInt32Ty(C));
		Constant *gep_params[] = {zero_32, zero_32};


		GlobalVariable *errorMsg = new GlobalVariable(M, msg->getType(), true, GlobalValue::InternalLinkage, msg, "errorMsg");
		Function *puts_func = (Function*)(M.getOrInsertFunction("puts", IntegerType::getInt32Ty(C), PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL));
		Constant *msgptr = ConstantExpr::getGetElementPtr(errorMsg, gep_params);

		Value *puts_params[] = {msgptr};

		CallInst *puts_call = builder.CreateCall(puts_func, puts_params);
		puts_call->setTailCall(false);

		Function *exit_func = cast<Function>(M.getOrInsertFunction("exit", IntegerType::getVoidTy(C), Type::getInt32Ty(C),NULL));

		Value *exit_val = ConstantInt::get(IntegerType::getInt32Ty(C), 1);
		
		//create exit block.  This block prints the error and calls exit system function
		BasicBlock* exitBlock = BasicBlock::Create(C, "exitBlock", printError_func);
		builder.CreateBr(exitBlock);
		builder.SetInsertPoint(exitBlock);


		builder.CreateCall(exit_func,exit_val);
		builder.CreateBr(exitBlock);

		int checksInserted = 0;

		for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
		{
			//leave func defs alone
			if (!MI->isDeclaration()) 
			{
				for (inst_iterator I = inst_begin(*MI), E = inst_end(*MI); I != E; ++I)
				{
					Instruction *inst = &*I;
					
					if(GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(inst))
					{
						if (const ArrayType *ar = dyn_cast<ArrayType>(gep->getPointerOperandType()->getElementType()))
						{           
							//increment checks inserted counter
							checksInserted++;
	
							//create split in basic block for function call insertion (branch)
							Instruction* next = inst->getNextNode();
							BasicBlock* oldBlock = inst->getParent();
							BasicBlock* newBlock = SplitBlock(oldBlock, next, this);

							//get upper limit and index used
							unsigned upperLim = ar->getNumElements();
							int index = gep->getNumOperands() - 1;
							Value *vIndexUsed = gep->getOperand(index);
							Value *vUpperLimit = ConstantInt::get(vIndexUsed->getType(), upperLim);

							BasicBlock* checkUpperBlock = BasicBlock::Create(C, "checkUpperBlock", MI, newBlock);
							BasicBlock* checkLowerBlock = BasicBlock::Create(C, "checkLowerBlock", MI, checkUpperBlock);
							
							builder.SetInsertPoint(oldBlock);
							
							//remove old terminator
							TerminatorInst* term = oldBlock->getTerminator();
							term->eraseFromParent();
							//insert new one
							builder.CreateBr(checkUpperBlock);
							
							//configure uppper bound test
							builder.SetInsertPoint(checkUpperBlock);
							Value* condUpperInst = builder.CreateICmpSLT(vIndexUsed, vUpperLimit, "checkUpperBounds");
							BasicBlock* errorBlock = BasicBlock::Create(C, "errorBlock", MI, newBlock);
							builder.CreateCondBr(condUpperInst, checkLowerBlock, errorBlock);

							//configure lower bound test
							builder.SetInsertPoint(checkLowerBlock);
							Value *vLowerLimit = ConstantInt::get(vIndexUsed->getType(), -1);
							Value *condLowerInst = builder.CreateICmpSGT(vIndexUsed, vLowerLimit, "checkLowerBounds");
							builder.CreateCondBr(condLowerInst, newBlock, errorBlock);

							//setup error block.  All this block does is call func to print error and exit
							builder.SetInsertPoint(errorBlock);
							builder.CreateCall(printError_func);
							builder.CreateBr(errorBlock);
						}
					}				
				}
			}
		}
		errs() << "This pass has inserted " << checksInserted << " checks\n";
      return true;
	}