15 #define DEBUG_TYPE "bounds-checking"
32 cl::desc(
"Use one trap block per function"));
34 STATISTIC(ChecksAdded,
"Bounds checks added");
35 STATISTIC(ChecksSkipped,
"Bounds checks skipped");
36 STATISTIC(ChecksUnable,
"Bounds checks unable to add");
64 void emitBranchToTrap(
Value *Cmp = 0);
85 Builder->SetInsertPoint(TrapBB);
88 CallInst *TrapCall = Builder->CreateCall(F);
90 TrapCall->setDoesNotThrow();
91 TrapCall->setDebugLoc(Inst->getDebugLoc());
92 Builder->CreateUnreachable();
100 void BoundsChecking::emitBranchToTrap(
Value *Cmp) {
129 bool BoundsChecking::instrument(
Value *Ptr,
Value *InstVal) {
130 uint64_t NeededSize =
TD->getTypeStoreSize(InstVal->
getType());
131 DEBUG(
dbgs() <<
"Instrument " << *Ptr <<
" for " <<
Twine(NeededSize)
136 if (!ObjSizeEval->bothKnown(SizeOffset)) {
141 Value *Size = SizeOffset.first;
142 Value *Offset = SizeOffset.second;
155 Value *ObjSize = Builder->CreateSub(Size, Offset);
156 Value *Cmp2 = Builder->CreateICmpULT(Size, Offset);
157 Value *Cmp3 = Builder->CreateICmpULT(ObjSize, NeededSizeVal);
158 Value *
Or = Builder->CreateOr(Cmp2, Cmp3);
161 Or = Builder->CreateOr(Cmp1, Or);
163 emitBranchToTrap(Or);
168 bool BoundsChecking::runOnFunction(
Function &
F) {
169 TD = &getAnalysis<DataLayout>();
170 TLI = &getAnalysis<TargetLibraryInfo>();
174 Builder = &TheBuilder;
177 ObjSizeEval = &TheObjSizeEval;
181 std::vector<Instruction*> WorkList;
184 if (isa<LoadInst>(I) || isa<StoreInst>(
I) || isa<AtomicCmpXchgInst>(I) ||
185 isa<AtomicRMWInst>(
I))
186 WorkList.push_back(I);
189 bool MadeChange =
false;
190 for (std::vector<Instruction*>::iterator i = WorkList.begin(),
191 e = WorkList.end(); i != e; ++i) {
194 Builder->SetInsertPoint(Inst);
195 if (
LoadInst *
LI = dyn_cast<LoadInst>(Inst)) {
196 MadeChange |= instrument(
LI->getPointerOperand(),
LI);
197 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
198 MadeChange |= instrument(SI->getPointerOperand(), SI->getValueOperand());
200 MadeChange |= instrument(AI->getPointerOperand(),AI->getCompareOperand());
201 }
else if (
AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(Inst)) {
202 MadeChange |= instrument(AI->getPointerOperand(), AI->getValOperand());
211 return new BoundsChecking();
static PassRegistry * getPassRegistry()
LLVMContext & getContext() const
FunctionPass * createBoundsCheckingPass()
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
LoopInfoBase< BlockT, LoopT > * LI
AnalysisUsage & addRequired()
inst_iterator inst_begin(Function *F)
const APInt & getValue() const
Return the constant's value.
#define llvm_unreachable(msg)
static cl::opt< bool > SingleTrapBB("bounds-checking-single-trap", cl::desc("Use one trap block per function"))
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
ID
LLVM Calling Convention Representation.
uint64_t getZExtValue() const
Return the zero extended value.
Evaluate the size and offset of an object pointed to by a Value*. May create code to compute the resu...
TargetFolder - Create constants with target dependent folding.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
LLVM Basic Block Representation.
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
STATISTIC(ChecksAdded,"Bounds checks added")
INITIALIZE_PASS(BoundsChecking,"bounds-checking","Run-time bounds checking", false, false) BasicBlock *BoundsChecking
Class for constant integers.
bool slt(const APInt &RHS) const
Signed less than comparison.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Class for arbitrary precision integers.
std::pair< Value *, Value * > SizeOffsetEvalType
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
LLVM Value Representation.
inst_iterator inst_end(Function *F)
IRBuilder< true, TargetFolder > BuilderTy
const BasicBlock * getParent() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
void initializeBoundsCheckingPass(PassRegistry &)