32 #define DEBUG_TYPE "memory-builtins"
58 {LibFunc::ZnwjRKSt9nothrow_t,
MallocLike, 2, 0, -1},
60 {LibFunc::ZnwmRKSt9nothrow_t,
MallocLike, 2, 0, -1},
62 {LibFunc::ZnajRKSt9nothrow_t,
MallocLike, 2, 0, -1},
64 {LibFunc::ZnamRKSt9nothrow_t,
MallocLike, 2, 0, -1},
75 if (LookThroughBitCast)
95 bool LookThroughBitCast =
false) {
97 if (isa<IntrinsicInst>(V))
107 if (!TLI || !TLI->
getLibFunc(FnName, TLIFn) || !TLI->
has(TLIFn))
152 bool LookThroughBitCast) {
159 bool LookThroughBitCast) {
169 bool LookThroughBitCast) {
176 bool LookThroughBitCast) {
183 bool LookThroughBitCast) {
190 bool LookThroughBitCast) {
197 bool LookThroughBitCast) {
211 bool LookThroughSExt =
false) {
227 Value *Multiple =
nullptr;
242 assert(
isMallocLikeFn(CI, TLI) &&
"getMallocType and not malloc call");
245 unsigned NumOfBitCastUses = 0;
250 if (
const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) {
251 MallocType = cast<PointerType>(BCI->getDestTy());
256 if (NumOfBitCastUses == 1)
260 if (NumOfBitCastUses == 0)
261 return cast<PointerType>(CI->
getType());
285 bool LookThroughSExt) {
286 assert(
isMallocLikeFn(CI, TLI) &&
"getMallocArraySize and not malloc call");
302 if (!CI || isa<IntrinsicInst>(CI))
305 if (Callee ==
nullptr)
310 if (!TLI || !TLI->
getLibFunc(FnName, TLIFn) || !TLI->
has(TLIFn))
313 unsigned ExpectedNumParams;
314 if (TLIFn == LibFunc::free ||
315 TLIFn == LibFunc::ZdlPv ||
316 TLIFn == LibFunc::ZdaPv)
317 ExpectedNumParams = 1;
318 else if (TLIFn == LibFunc::ZdlPvj ||
319 TLIFn == LibFunc::ZdlPvm ||
320 TLIFn == LibFunc::ZdlPvRKSt9nothrow_t ||
321 TLIFn == LibFunc::ZdaPvj ||
322 TLIFn == LibFunc::ZdaPvm ||
323 TLIFn == LibFunc::ZdaPvRKSt9nothrow_t)
324 ExpectedNumParams = 2;
357 if (!Visitor.bothKnown(Data))
360 APInt ObjSize = Data.first, Offset = Data.second;
362 if (Offset.slt(0) || ObjSize.
ult(Offset))
365 Size = (ObjSize - Offset).getZExtValue();
371 "Number of arguments with unsolved size and offset");
373 "Number of load instructions with unsolved size and offset");
377 if (RoundToAlign && Align)
386 : DL(DL), TLI(TLI), RoundToAlign(RoundToAlign) {
399 if (!SeenInsts.insert(
I).second)
417 if (CE->getOpcode() == Instruction::IntToPtr)
419 if (CE->getOpcode() == Instruction::GetElementPtr)
423 DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor::compute() unhandled value: " << *V
434 return std::make_pair(align(Size, I.
getAlignment()), Zero);
437 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(ArraySize)) {
438 Size *=
C->getValue().zextOrSelf(IntTyBits);
439 return std::make_pair(align(Size, I.
getAlignment()), Zero);
447 ++ObjectVisitorArgument;
474 if (Size.
ugt(MaxSize))
477 return std::make_pair(Size, Zero);
487 return std::make_pair(Size, Zero);
494 return std::make_pair(Size, Zero);
507 return std::make_pair(Zero, Zero);
523 APInt Offset(IntTyBits, 0);
527 return std::make_pair(PtrData.first, PtrData.second + Offset);
541 return std::make_pair(align(Size, GV.
getAlignment()), Zero);
568 return std::make_pair(Zero, Zero);
572 DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor unknown instruction:" << I <<
'\n');
579 : DL(DL), TLI(TLI), Context(Context), Builder(Context,
TargetFolder(DL)),
580 RoundToAlign(RoundToAlign) {
599 if (CacheIt != CacheMap.
end() &&
anyKnown(CacheIt->second))
600 CacheMap.
erase(CacheIt);
611 if (Visitor.bothKnown(Const))
619 if (CacheIt != CacheMap.
end())
620 return CacheIt->second;
634 if (!SeenVals.
insert(V).second) {
640 }
else if (isa<Argument>(V) ||
641 (isa<ConstantExpr>(V) &&
642 cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
643 isa<GlobalAlias>(V) ||
644 isa<GlobalVariable>(V)) {
648 DEBUG(
dbgs() <<
"ObjectSizeOffsetEvaluator::compute() unhandled value: "
657 CacheMap[V] = Result;
670 Size = Builder.
CreateMul(Size, ArraySize);
671 return std::make_pair(Size, Zero);
687 FirstArg = Builder.
CreateZExt(FirstArg, IntTy);
689 return std::make_pair(FirstArg, Zero);
692 SecondArg = Builder.
CreateZExt(SecondArg, IntTy);
694 return std::make_pair(Size, Zero);
722 Offset = Builder.
CreateAdd(PtrData.second, Offset);
723 return std::make_pair(PtrData.first, Offset);
741 CacheMap[&
PHI] = std::make_pair(SizePHI, OffsetPHI);
759 Value *Size = SizePHI, *Offset = OffsetPHI, *Tmp;
770 return std::make_pair(Size, Offset);
779 if (TrueSide == FalseSide)
786 return std::make_pair(Size, Offset);
790 DEBUG(
dbgs() <<
"ObjectSizeOffsetEvaluator unknown instruction:" << I <<
'\n');
Value * EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the code necessary to compute th...
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
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...
A parsed version of the target data layout string in and methods for querying it. ...
uint64_t GetStringLength(Value *V)
GetStringLength - If we can compute the length of the string pointed to by the specified pointer...
BasicBlock::iterator GetInsertPoint() const
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLVM Argument representation.
uint64_t getZExtValue() const
Get zero extended value.
STATISTIC(NumFunctions,"Total number of functions")
ValTy * getArgument(unsigned ArgNo) const
unsigned getNumParams() const
getNumParams - Return the number of fixed parameters this function type requires. ...
InstrTy * getInstruction() const
const CallInst * extractCallocCall(const Value *I, const TargetLibraryInfo *TLI)
extractCallocCall - Returns the corresponding CallInst if the instruction is a calloc call...
bool hasByValOrInAllocaAttr() const
Return true if this argument has the byval attribute or inalloca attribute on it in its containing fu...
unsigned getPointerTypeSizeInBits(Type *) const
Layout pointer size, in bits, based on the type.
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.
CallInst - This class represents a function call, abstracting a target machine's calling convention...
SizeOffsetType visitAllocaInst(AllocaInst &I)
LoadInst - an instruction for reading from memory.
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
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
Return a constant reference to the value's name.
bool isArrayAllocation() const
isArrayAllocation - Return true if there is an allocation size parameter to the allocation instructio...
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
SelectInst - This class represents the LLVM 'select' instruction.
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP)
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
SizeOffsetType visitExtractValueInst(ExtractValueInst &I)
SizeOffsetType visitGEPOperator(GEPOperator &GEP)
const APInt & getValue() const
Return the constant as an APInt value reference.
UndefValue - 'undef' values are things that do not have specified contents.
bool has(LibFunc::Func F) const
Tests whether a library function is available.
StructType - Class to represent struct types.
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 &)
bool isSized(SmallPtrSetImpl< const Type * > *Visited=nullptr) const
isSized - Return true if it makes sense to take the size of this type.
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, bool RoundToAlign=false)
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...
ConstantExpr - a constant value that is initialized with an expression using other constant values...
FunctionType - Class to represent function types.
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.
unsigned getAlignment() const
This class represents a no-op cast from one type to another.
TargetFolder - Create constants with target dependent folding.
std::pair< APInt, APInt > SizeOffsetType
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
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...
PointerType - Class to represent pointers.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
Value * getMallocArraySize(CallInst *CI, const DataLayout &DL, const TargetLibraryInfo *TLI, bool LookThroughSExt=false)
getMallocArraySize - Returns the array size of a malloc call.
SizeOffsetType visitGlobalVariable(GlobalVariable &GV)
bool getLibFunc(StringRef funcName, LibFunc::Func &F) const
Searches for a particular function name.
Type * getParamType(unsigned i) const
Parameter type accessors.
bool erase(const KeyT &Val)
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)
Value * hasConstantValue() const
hasConstantValue - If the specified PHI node always merges together the same value, return the value, otherwise return null.
The instances of the Type class are immutable: once they are created, they are never changed...
static bool mayBeOverridden(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time...
This is an important class for using LLVM in a threaded context.
static const AllocFnsTy AllocationFnData[]
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
const CallInst * extractMallocCall(const Value *I, const TargetLibraryInfo *TLI)
extractMallocCall - Returns the corresponding CallInst if the instruction is a malloc call...
const Value * getCondition() const
unsigned getAlignment() const
getAlignment - Return the alignment of the memory that is being allocated by the instruction.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
unsigned getParamAlignment() const
If this is a byval or inalloca argument, return its alignment.
static Value * computeArraySize(const CallInst *CI, const DataLayout &DL, const TargetLibraryInfo *TLI, bool LookThroughSExt=false)
BasicBlock * getIncomingBlock(unsigned i) const
getIncomingBlock - Return incoming basic block number i.
Value * getPointerOperand()
static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast)
This class represents a cast from an integer to a pointer.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
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)
getMallocType - Returns the PointerType resulting from the malloc call.
SizeOffsetType visitSelectInst(SelectInst &I)
SizeOffsetType visitExtractElementInst(ExtractElementInst &I)
SizeOffsetType visitGlobalAlias(GlobalAlias &GA)
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
Returns an integer type with size at least as big as that of a pointer in the given address space...
SizeOffsetEvalType visitInstruction(Instruction &I)
ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, bool RoundToAlign=false)
This is the shared class of boolean and integer constants.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Value * getIncomingValue(unsigned i) const
getIncomingValue - Return incoming value number x
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Evaluate the size and offset of an object pointed to by a Value* statically.
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
SizeOffsetType visitPHINode(PHINode &)
ConstantPointerNull - a constant pointer value that points to null.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
uint64_t getSizeInBytes() const
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
SizeOffsetType visitUndefValue(UndefValue &)
DenseMapIterator< const Value *, WeakEvalType, DenseMapInfo< const Value * >, detail::DenseMapPair< const Value *, WeakEvalType > > iterator
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Function * getCalledFunction() const
getCalledFunction - Return the function called, or null if this is an indirect function invocation...
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
SizeOffsetType compute(Value *V)
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
Class for arbitrary precision integers.
std::pair< Value *, Value * > SizeOffsetEvalType
SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst &)
bool isIntegerTy() const
isIntegerTy - True if this is an instance of IntegerType.
Type * getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI)
getMallocAllocatedType - Returns the Type allocated by malloc call.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="")
SizeOffsetEvalType visitPHINode(PHINode &PHI)
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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 ...
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
SizeOffsetEvalType compute(Value *V)
PointerType * getType() const
Global values are always pointers.
user_iterator_impl< const User > const_user_iterator
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
SizeOffsetEvalType visitLoadInst(LoadInst &I)
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)
ComputeMultiple - This function computes the integer multiple of Base that equals V...
iterator find(const KeyT &Val)
bool anyKnown(SizeOffsetEvalType SizeOffset)
bool bothKnown(SizeOffsetType &SizeOffset)
Type * getReturnType() const
user_iterator user_begin()
LLVM Value Representation.
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I)
const Value * getArraySize() const
getArraySize - Get the number of elements allocated.
const Value * getFalseValue() const
StringRef - Represent a constant reference to a string, i.e.
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.
Type * getAllocatedType() const
getAllocatedType - Return the type that is being allocated by the instruction.
SizeOffsetType visitLoadInst(LoadInst &I)
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'.
AllocaInst - an instruction to allocate memory on the stack.