15 #define DEBUG_TYPE "memory-builtins"
74 if (LookThroughBitCast)
94 bool LookThroughBitCast =
false) {
96 if (isa<IntrinsicInst>(V))
106 if (!TLI || !TLI->
getLibFunc(FnName, TLIFn) || !TLI->
has(TLIFn))
151 bool LookThroughBitCast) {
158 bool LookThroughBitCast) {
168 bool LookThroughBitCast) {
175 bool LookThroughBitCast) {
182 bool LookThroughBitCast) {
189 bool LookThroughBitCast) {
196 bool LookThroughBitCast) {
210 bool LookThroughSExt =
false) {
216 if (!T || !T->
isSized() || !DL)
243 if (
ConstantInt *ConstSize = dyn_cast_or_null<ConstantInt>(ArraySize))
244 if (ConstSize->isOne())
258 assert(
isMallocLikeFn(CI, TLI) &&
"getMallocType and not malloc call");
261 unsigned NumOfBitCastUses = 0;
266 if (
const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) {
267 MallocType = cast<PointerType>(BCI->getDestTy());
272 if (NumOfBitCastUses == 1)
276 if (NumOfBitCastUses == 0)
277 return cast<PointerType>(CI->
getType());
301 bool LookThroughSExt) {
302 assert(
isMallocLikeFn(CI, TLI) &&
"getMallocArraySize and not malloc call");
318 if (!CI || isa<IntrinsicInst>(CI))
326 if (!TLI || !TLI->
getLibFunc(FnName, TLIFn) || !TLI->
has(TLIFn))
329 unsigned ExpectedNumParams;
333 ExpectedNumParams = 1;
336 ExpectedNumParams = 2;
372 if (!Visitor.bothKnown(Data))
375 APInt ObjSize = Data.first, Offset = Data.second;
377 if (Offset.slt(0) || ObjSize.
ult(Offset))
380 Size = (ObjSize - Offset).getZExtValue();
386 "Number of arguments with unsolved size and offset");
388 "Number of load instructions with unsolved size and offset");
392 if (RoundToAlign && Align)
401 : DL(DL), TLI(TLI), RoundToAlign(RoundToAlign) {
412 if (!SeenInsts.insert(
I))
430 if (CE->getOpcode() == Instruction::IntToPtr)
432 if (CE->getOpcode() == Instruction::GetElementPtr)
436 DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor::compute() unhandled value: " << *V
447 return std::make_pair(align(Size, I.
getAlignment()), Zero);
450 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(ArraySize)) {
451 Size *=
C->getValue().zextOrSelf(IntTyBits);
452 return std::make_pair(align(Size, I.
getAlignment()), Zero);
460 ++ObjectVisitorArgument;
487 if (Size.
ugt(MaxSize))
490 return std::make_pair(Size, Zero);
500 return std::make_pair(Size, Zero);
507 return std::make_pair(Size, Zero);
520 return std::make_pair(Zero, Zero);
536 APInt Offset(IntTyBits, 0);
540 return std::make_pair(PtrData.first, PtrData.second + Offset);
554 return std::make_pair(align(Size, GV.
getAlignment()), Zero);
581 return std::make_pair(Zero, Zero);
585 DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor unknown instruction:" << I <<
'\n');
593 : DL(DL), TLI(TLI), Context(Context), Builder(Context,
TargetFolder(DL)),
594 RoundToAlign(RoundToAlign) {
609 if (CacheIt != CacheMap.
end() &&
anyKnown(CacheIt->second))
610 CacheMap.
erase(CacheIt);
621 if (Visitor.bothKnown(Const))
629 if (CacheIt != CacheMap.
end())
630 return CacheIt->second;
644 if (!SeenVals.
insert(V)) {
646 }
else if (
GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
650 }
else if (isa<Argument>(V) ||
651 (isa<ConstantExpr>(V) &&
652 cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
653 isa<GlobalAlias>(V) ||
654 isa<GlobalVariable>(V)) {
658 DEBUG(
dbgs() <<
"ObjectSizeOffsetEvaluator::compute() unhandled value: "
667 CacheMap[V] = Result;
680 Size = Builder.
CreateMul(Size, ArraySize);
681 return std::make_pair(Size, Zero);
697 FirstArg = Builder.
CreateZExt(FirstArg, IntTy);
699 return std::make_pair(FirstArg, Zero);
702 SecondArg = Builder.
CreateZExt(SecondArg, IntTy);
704 return std::make_pair(Size, Zero);
732 Offset = Builder.
CreateAdd(PtrData.second, Offset);
733 return std::make_pair(PtrData.first, Offset);
751 CacheMap[&
PHI] = std::make_pair(SizePHI, OffsetPHI);
769 Value *Size = SizePHI, *Offset = OffsetPHI, *Tmp;
780 return std::make_pair(Size, Offset);
789 if (TrueSide == FalseSide)
796 return std::make_pair(Size, Offset);
800 DEBUG(
dbgs() <<
"ObjectSizeOffsetEvaluator unknown instruction:" << I <<
'\n');
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
ObjectSizeOffsetVisitor(const DataLayout *DL, const TargetLibraryInfo *TLI, LLVMContext &Context, bool RoundToAlign=false)
uint64_t GetStringLength(Value *V)
BasicBlock::iterator GetInsertPoint() const
void addIncoming(Value *V, BasicBlock *BB)
LLVMContext & getContext() const
LLVM Argument representation.
uint64_t getZExtValue() const
Get zero extended value.
STATISTIC(ObjectVisitorArgument,"Number of arguments with unsolved size and offset")
unsigned getNumParams() const
unsigned getAlignment() const
const CallInst * extractCallocCall(const Value *I, const TargetLibraryInfo *TLI)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Value * EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP, bool NoAssumptions=false)
SizeOffsetType visitAllocaInst(AllocaInst &I)
void *reallocf(void *ptr, size_t size);
void *new(unsigned int, nothrow);
void operator delete[](void*, nothrow);
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that reallocates memory (such as realloc)...
SizeOffsetType visitArgument(Argument &A)
const Constant * getAliasee() const
ValTy * getArgument(unsigned ArgNo) const
const CallInst * isFreeCall(const Value *I, const TargetLibraryInfo *TLI)
isFreeCall - Returns non-null if the value is a call to the builtin free()
StringRef getName() const
bool isArrayAllocation() const
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP)
const StructLayout * getStructLayout(StructType *Ty) const
SizeOffsetType visitExtractValueInst(ExtractValueInst &I)
SizeOffsetType visitGEPOperator(GEPOperator &GEP)
const APInt & getValue() const
Return the constant's value.
bool getLibFunc(StringRef funcName, LibFunc::Func &F) const
bool has(LibFunc::Func F) const
bool isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates memory and never returns nu...
SizeOffsetEvalType visitCallSite(CallSite CS)
SizeOffsetType visitIntToPtrInst(IntToPtrInst &)
void operator delete[](void*);
void operator delete(void*);
Type * getAllocatedType() const
void visit(Iterator Start, Iterator End)
bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a function that returns a NoAlias pointer (including malloc/c...
APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrSelf(unsigned width) const
Zero extend or truncate to width.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const
Accumulate the constant address offset of this GEP if possible.
size_t array_lengthof(T(&)[N])
Find the length of an array.
This class represents a no-op cast from one type to another.
TargetFolder - Create constants with target dependent folding.
std::pair< APInt, APInt > SizeOffsetType
char *strndup(const char *s1, size_t n);
bool hasDefinitiveInitializer() const
void replaceAllUsesWith(Value *V)
SizeOffsetType visitInstruction(Instruction &I)
Type * getElementType() const
Considered to not alias after call.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
bool ult(const APInt &RHS) const
Unsigned less than comparison.
void *new[](unsigned int);
unsigned getNumIncomingValues() const
SizeOffsetType visitGlobalVariable(GlobalVariable &GV)
Type * getParamType(unsigned i) const
Parameter type accessors.
static const AllocFnsTy * getAllocationData(const Value *V, AllocType AllocTy, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Returns the allocation data for the given value if it is a call to a known allocation function...
SizeOffsetEvalType visitSelectInst(SelectInst &I)
void *new(unsigned long);
Value * hasConstantValue() const
InstrTy * getInstruction() const
static bool mayBeOverridden(LinkageTypes Linkage)
static const AllocFnsTy AllocationFnData[]
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
const CallInst * extractMallocCall(const Value *I, const TargetLibraryInfo *TLI)
const Value * getCondition() const
unsigned getAlignment() const
unsigned getParamAlignment() const
If this is a byval argument, return its alignment.
void *realloc(void *ptr, size_t size);
BasicBlock * getIncomingBlock(unsigned i) const
void *valloc(size_t size);
Value * getPointerOperand()
void *new[](unsigned int, nothrow);
static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast)
Integer representation type.
This class represents a cast from an integer to a pointer.
ObjectSizeOffsetEvaluator(const DataLayout *DL, const TargetLibraryInfo *TLI, LLVMContext &Context, bool RoundToAlign=false)
void *new[](unsigned long);
void *new[](unsigned long, nothrow);
static UndefValue * get(Type *T)
SizeOffsetType visitCallSite(CallSite CS)
LLVMContext & getContext() const
All values hold a context through their type.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
const Value * getTrueValue() const
PointerType * getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI)
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
SizeOffsetType visitSelectInst(SelectInst &I)
char *strdup(const char *s1);
SizeOffsetType visitExtractElementInst(ExtractElementInst &I)
SizeOffsetType visitGlobalAlias(GlobalAlias &GA)
bool hasByValAttr() const
Return true if this argument has the byval attribute on it in its containing function.
bool ugt(const APInt &RHS) const
Unsigned greather than comparison.
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
SizeOffsetEvalType visitInstruction(Instruction &I)
Class for constant integers.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Value * getIncomingValue(unsigned i) const
uint64_t getTypeAllocSize(Type *Ty) const
Evaluate the size and offset of an object pointed to by a Value* statically. Fails if size or offset ...
SizeOffsetType visitPHINode(PHINode &)
bool erase(const KeyT &Val)
uint64_t getSizeInBytes() const
Value * stripPointerCasts()
Strips off any unneeded pointer casts, all-zero GEPs and aliases from the specified value...
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
SizeOffsetType visitUndefValue(UndefValue &)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
Function * getCalledFunction() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
SizeOffsetType compute(Value *V)
Value * getArgOperand(unsigned i) const
Class for arbitrary precision integers.
std::pair< Value *, Value * > SizeOffsetEvalType
SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst &)
Type * getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI)
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="")
const CallInst * isArrayMalloc(const Value *I, const DataLayout *DL, const TargetLibraryInfo *TLI)
SizeOffsetEvalType visitPHINode(PHINode &PHI)
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates uninitialized memory (such ...
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
Value * getMallocArraySize(CallInst *CI, const DataLayout *DL, const TargetLibraryInfo *TLI, bool LookThroughSExt=false)
SizeOffsetEvalType compute(Value *V)
DenseMapIterator< KeyT, ValueT, KeyInfoT > iterator
PointerType * getType() const
getType - Global values are always pointers.
void *malloc(size_t size);
bool isDeclaration() const
void *new(unsigned long, nothrow);
SizeOffsetEvalType visitLoadInst(LoadInst &I)
bool hasFnAttr(Attribute::AttrKind A) const
Return true if this function has the given attribute.
ImmutableCallSite - establish a view to a call site for examination.
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates zero-filled memory (such as...
FunctionType * getFunctionType() const
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates memory (either malloc...
static Function * getCalledFunction(const Value *V, bool LookThroughBitCast)
bool ComputeMultiple(Value *V, unsigned Base, Value *&Multiple, bool LookThroughSExt=false, unsigned Depth=0)
bool anyKnown(SizeOffsetEvalType SizeOffset)
bool bothKnown(SizeOffsetType &SizeOffset)
Type * getReturnType() const
static Value * computeArraySize(const CallInst *CI, const DataLayout *DL, const TargetLibraryInfo *TLI, bool LookThroughSExt=false)
LLVM Value Representation.
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I)
void operator delete(void*, nothrow);
const Value * getArraySize() const
const Value * getFalseValue() const
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *DL, const TargetLibraryInfo *TLI, bool RoundToAlign=false)
Compute the size of the object pointed by Ptr. Returns true and the object size in Size if successful...
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
static APInt getNullValue(unsigned numBits)
Get the '0' value.
SizeOffsetType visitLoadInst(LoadInst &I)
iterator find(const KeyT &Val)
void *calloc(size_t count, size_t size);
SizeOffsetEvalType visitAllocaInst(AllocaInst &I)
bool bothKnown(SizeOffsetEvalType SizeOffset)
SizeOffsetType visitConstantPointerNull(ConstantPointerNull &)
SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I)
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
FunTy * getCalledFunction() const