52#define DEBUG_TYPE "memory-builtins"
55 "object-size-offset-visitor-max-visit-instructions",
56 cl::desc(
"Maximum number of instructions for ObjectSizeOffsetVisitor to "
88 return "_ZnwmSt11align_val_t";
92 return "_ZnamSt11align_val_t";
94 return "??2@YAPAXI@Z";
96 return "??_U@YAPAXI@Z";
100 return "__kmpc_alloc_shared";
163 if (isa<IntrinsicInst>(V))
166 const auto *CB = dyn_cast<CallBase>(V);
170 IsNoBuiltin = CB->isNoBuiltin();
172 if (
const Function *Callee = CB->getCalledFunction())
179static std::optional<AllocFnsTy>
184 if (!Callee->getReturnType()->isPointerTy())
189 if (!TLI || !TLI->
getLibFunc(*Callee, TLIFn) || !TLI->
has(TLIFn))
194 return P.first == TLIFn;
209 if (FTy->getReturnType()->isPointerTy() &&
210 FTy->getNumParams() == FnData->
NumParams &&
212 (FTy->getParamType(FstParam)->isIntegerTy(32) ||
213 FTy->getParamType(FstParam)->isIntegerTy(64))) &&
215 FTy->getParamType(SndParam)->isIntegerTy(32) ||
216 FTy->getParamType(SndParam)->isIntegerTy(64)))
221static std::optional<AllocFnsTy>
224 bool IsNoBuiltinCall;
226 if (!IsNoBuiltinCall)
231static std::optional<AllocFnsTy>
234 bool IsNoBuiltinCall;
236 if (!IsNoBuiltinCall)
238 Callee, AllocTy, &GetTLI(
const_cast<Function &
>(*Callee)));
242static std::optional<AllocFnsTy>
244 bool IsNoBuiltinCall;
252 if (!IsNoBuiltinCall)
253 if (std::optional<AllocFnsTy> Data =
257 Attribute Attr = Callee->getFnAttribute(Attribute::AllocSize);
261 std::pair<unsigned, std::optional<unsigned>> Args = Attr.
getAllocSizeArgs();
267 Result.NumParams = Callee->getNumOperands();
268 Result.FstParam = Args.first;
269 Result.SndParam = Args.second.value_or(-1);
271 Result.AlignParam = -1;
276 if (
const auto *CB = dyn_cast<CallBase>(V)) {
277 Attribute Attr = CB->getFnAttr(Attribute::AllocKind);
281 return AllocFnKind::Unknown;
285 return F->getAttributes().getAllocKind();
356 if (FnData && FnData->AlignParam >= 0) {
357 return V->getOperand(FnData->AlignParam);
359 return V->getArgOperandWithAttribute(Attribute::AllocAlign);
371 if (
I.getBitWidth() > IntTyBits &&
I.getActiveBits() > IntTyBits)
373 if (
I.getBitWidth() != IntTyBits)
374 I =
I.zextOrTrunc(IntTyBits);
390 const unsigned IntTyBits =
DL.getIndexTypeSizeInBits(CB->
getType());
399 if (FnData->FstParam > 0) {
401 dyn_cast<ConstantInt>(Mapper(CB->
getArgOperand(FnData->FstParam)));
406 if (
Size.ugt(MaxSize))
413 dyn_cast<ConstantInt>(Mapper(CB->
getArgOperand(FnData->FstParam)));
422 if (FnData->SndParam < 0)
425 Arg = dyn_cast<ConstantInt>(Mapper(CB->
getArgOperand(FnData->SndParam)));
434 Size =
Size.umul_ov(NumElems, Overflow);
443 auto *Alloc = dyn_cast<CallBase>(V);
452 if ((AK & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
454 if ((AK & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
504 return P.first == TLIFn;
511std::optional<StringRef>
515 if (Callee ==
nullptr || IsNoBuiltin)
519 if (TLI && TLI->
getLibFunc(*Callee, TLIFn) && TLI->
has(TLIFn)) {
530 AllocFnKind::Realloc)) {
531 Attribute Attr = cast<CallBase>(
I)->getFnAttr(
"alloc-family");
559 bool IsNoBuiltinCall;
561 if (Callee ==
nullptr || IsNoBuiltinCall)
565 if (TLI && TLI->
getLibFunc(*Callee, TLIFn) && TLI->
has(TLIFn) &&
581 if (Data.second.isNegative() || Data.first.ult(Data.second))
582 return APInt(Data.first.getBitWidth(), 0);
583 return Data.first - Data.second;
614 "ObjectSize must be a call to llvm.objectsize!");
616 bool MaxVal = cast<ConstantInt>(ObjectSize->
getArgOperand(1))->isZero();
624 MaxVal ? ObjectSizeOpts::Mode::Max : ObjectSizeOpts::Mode::Min;
626 EvalOptions.
EvalMode = ObjectSizeOpts::Mode::ExactSizeFromOffset;
631 auto *ResultType = cast<IntegerType>(ObjectSize->
getType());
632 bool StaticOnly = cast<ConstantInt>(ObjectSize->
getArgOperand(3))->isZero();
649 if (InsertedInstructions)
657 Builder.
CreateSub(SizeOffsetPair.first, SizeOffsetPair.second);
659 Builder.
CreateICmpULT(SizeOffsetPair.first, SizeOffsetPair.second);
665 if (!isa<Constant>(SizeOffsetPair.first) ||
666 !isa<Constant>(SizeOffsetPair.second))
681 "Number of arguments with unsolved size and offset");
683 "Number of load instructions with unsolved size and offset");
701 InstructionsVisited = 0;
702 return computeImpl(V);
714 V = V->stripAndAccumulateConstantOffsets(
724 bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
725 if (!IndexTypeSizeChanged &&
Offset.isZero())
731 if (IndexTypeSizeChanged) {
732 if (
knownSize(SOT) && !::CheckedZextOrTrunc(SOT.first, InitialIntTyBits))
734 if (
knownOffset(SOT) && !::CheckedZextOrTrunc(SOT.second, InitialIntTyBits))
735 SOT.second =
APInt();
739 SOT.second.getBitWidth() > 1 ? SOT.second +
Offset : SOT.second};
746 auto P = SeenInsts.try_emplace(
I, unknown());
748 return P.first->second;
749 ++InstructionsVisited;
769 LLVM_DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor::compute() unhandled value: "
774bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(
APInt &
I) {
775 return ::CheckedZextOrTrunc(
I, IntTyBits);
783 if (!
I.isArrayAllocation())
784 return std::make_pair(align(
Size,
I.getAlign()), Zero);
786 Value *ArraySize =
I.getArraySize();
787 if (
const ConstantInt *
C = dyn_cast<ConstantInt>(ArraySize)) {
788 APInt NumElems =
C->getValue();
789 if (!CheckedZextOrTrunc(NumElems))
793 Size =
Size.umul_ov(NumElems, Overflow);
794 return Overflow ? unknown()
795 : std::make_pair(align(
Size,
I.getAlign()), Zero);
801 Type *MemoryTy =
A.getPointeeInMemoryValueType();
803 if (!MemoryTy|| !MemoryTy->
isSized()) {
804 ++ObjectVisitorArgument;
809 return std::make_pair(align(
Size,
A.getParamAlign()), Zero);
814 return std::make_pair(*
Size, Zero);
829 return std::make_pair(Zero, Zero);
856 return std::make_pair(align(
Size, GV.
getAlign()), Zero);
867 unsigned &ScannedInstCount) {
868 constexpr unsigned MaxInstsToScan = 128;
870 auto Where = VisitedBlocks.
find(&BB);
871 if (Where != VisitedBlocks.
end())
872 return Where->second;
874 auto Unknown = [
this, &BB, &VisitedBlocks]() {
875 return VisitedBlocks[&BB] = unknown();
878 return VisitedBlocks[&BB] = SO;
884 if (
I.isDebugOrPseudoInst())
887 if (++ScannedInstCount > MaxInstsToScan)
890 if (!
I.mayWriteToMemory())
893 if (
auto *SI = dyn_cast<StoreInst>(&
I)) {
895 Options.
AA->
alias(
SI->getPointerOperand(),
Load.getPointerOperand());
900 if (
SI->getValueOperand()->getType()->isPointerTy())
901 return Known(computeImpl(
SI->getValueOperand()));
909 if (
auto *CB = dyn_cast<CallBase>(&
I)) {
921 if (TLIFn != LibFunc_posix_memalign)
940 if (!Checked || !*Checked)
944 auto *
C = dyn_cast<ConstantInt>(
Size);
948 return Known({
C->getValue(),
APInt(
C->getValue().getBitWidth(), 0)});
956 PredecessorSizeOffsets.
push_back(findLoadSizeOffset(
958 VisitedBlocks, ScannedInstCount));
963 if (PredecessorSizeOffsets.
empty())
966 return Known(std::accumulate(PredecessorSizeOffsets.
begin() + 1,
967 PredecessorSizeOffsets.
end(),
968 PredecessorSizeOffsets.
front(),
970 return combineSizeOffset(LHS, RHS);
981 unsigned ScannedInstCount = 0;
984 VisitedBlocks, ScannedInstCount);
1013 return std::accumulate(IncomingValues.begin() + 1, IncomingValues.end(),
1014 computeImpl(*IncomingValues.begin()),
1016 return combineSizeOffset(LHS, computeImpl(VRHS));
1021 return combineSizeOffset(computeImpl(
I.getTrueValue()),
1022 computeImpl(
I.getFalseValue()));
1026 return std::make_pair(Zero, Zero);
1030 LLVM_DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor unknown instruction:" <<
I
1042 EvalOpts(EvalOpts) {
1049 IntTy = cast<IntegerType>(DL.
getIndexType(V->getType()));
1058 for (
const Value *SeenVal : SeenVals) {
1061 if (CacheIt != CacheMap.
end() &&
anyKnown(CacheIt->second))
1062 CacheMap.
erase(CacheIt);
1068 I->eraseFromParent();
1073 InsertedInstructions.clear();
1080 if (Visitor.bothKnown(Const))
1084 V = V->stripPointerCasts();
1088 if (CacheIt != CacheMap.
end())
1089 return CacheIt->second;
1103 if (!SeenVals.
insert(V).second) {
1107 }
else if (
Instruction *
I = dyn_cast<Instruction>(V)) {
1109 }
else if (isa<Argument>(V) ||
1110 (isa<ConstantExpr>(V) &&
1111 cast<ConstantExpr>(V)->
getOpcode() == Instruction::IntToPtr) ||
1112 isa<GlobalAlias>(V) ||
1113 isa<GlobalVariable>(V)) {
1118 dbgs() <<
"ObjectSizeOffsetEvaluator::compute() unhandled value: " << *V
1129 if (!
I.getAllocatedType()->isSized())
1133 assert(
I.isArrayAllocation());
1141 "Expected zero constant to have pointer index type");
1146 return std::make_pair(
Size, Zero);
1162 if (FnData->SndParam < 0)
1163 return std::make_pair(FirstArg, Zero);
1168 return std::make_pair(
Size, Zero);
1189 return std::make_pair(PtrData.first,
Offset);
1207 CacheMap[&
PHI] = std::make_pair(SizePHI, OffsetPHI);
1210 for (
unsigned i = 0, e =
PHI.getNumIncomingValues(); i != e; ++i) {
1218 InsertedInstructions.erase(OffsetPHI);
1221 InsertedInstructions.erase(SizePHI);
1224 SizePHI->
addIncoming(EdgeData.first, IncomingBlock);
1225 OffsetPHI->
addIncoming(EdgeData.second, IncomingBlock);
1233 InsertedInstructions.erase(SizePHI);
1239 InsertedInstructions.erase(OffsetPHI);
1250 if (TrueSide == FalseSide)
1261 LLVM_DEBUG(
dbgs() <<
"ObjectSizeOffsetEvaluator unknown instruction:" <<
I
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements a class to represent arbitrary precision integral constant values and operations...
This file contains the simple types necessary to represent the attributes associated with functions a...
BlockVerifier::State From
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static AllocFnKind getAllocFnKind(const Value *V)
static APInt getSizeWithOverflow(const SizeOffsetType &Data)
static std::optional< AllocFnsTy > getAllocationDataForFunction(const Function *Callee, AllocType AllocTy, const TargetLibraryInfo *TLI)
Returns the allocation data for the given value if it's a call to a known allocation function.
static std::optional< AllocFnsTy > getAllocationData(const Value *V, AllocType AllocTy, const TargetLibraryInfo *TLI)
std::optional< FreeFnsTy > getFreeFunctionDataForFunction(const Function *Callee, const LibFunc TLIFn)
static std::optional< AllocFnsTy > getAllocationSize(const Value *V, const TargetLibraryInfo *TLI)
static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted)
StringRef mangledNameForMallocFamily(const MallocFamily &Family)
static bool CheckedZextOrTrunc(APInt &I, unsigned IntTyBits)
When we're compiling N-bit code, and the user uses parameters that are greater than N bits (e....
static const std::pair< LibFunc, FreeFnsTy > FreeFnData[]
static cl::opt< unsigned > ObjectSizeOffsetVisitorMaxVisitInstructions("object-size-offset-visitor-max-visit-instructions", cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to " "look at"), cl::init(100))
static const std::pair< LibFunc, AllocFnsTy > AllocationFnData[]
static const Function * getCalledFunction(const Value *V, bool &IsNoBuiltin)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
Class for arbitrary precision integers.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
The possible results of an alias query.
@ NoAlias
The two locations do not alias at all.
@ MustAlias
The two locations precisely alias each other.
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
InstListType::iterator iterator
Instruction iterators...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
Value * getArgOperandWithAttribute(Attribute::AttrKind Kind) const
If one of the arguments has the specified attribute, returns its operand value.
This is the shared class of boolean and integer constants.
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.
const APInt & getValue() const
Return the constant as an APInt value reference.
A constant pointer value that points to null.
PointerType * getType() const
Specialize the getType() method to always return an PointerType, which reduces the amount of casting ...
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
unsigned getIndexTypeSizeInBits(Type *Ty) const
Layout size of the index used in GEP calculation.
unsigned getAllocaAddrSpace() const
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Class to represent function types.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Type * getParamType(unsigned i) const
Parameter type accessors.
Type * getReturnType() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
const Constant * getAliasee() const
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
bool hasExternalWeakLinkage() const
bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
Type * getValueType() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateAssumption(Value *Cond, ArrayRef< OperandBundleDef > OpBundles=std::nullopt)
Create an assume intrinsic call that allows the optimizer to assume that the provided condition will ...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void visit(Iterator Start, Iterator End)
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
const Function * getFunction() const
Return the function this instruction belongs to.
This class represents a cast from an integer to a pointer.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Evaluate the size and offset of an object pointed to by a Value*.
SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I)
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I)
SizeOffsetEvalType visitPHINode(PHINode &PHI)
SizeOffsetEvalType visitSelectInst(SelectInst &I)
static SizeOffsetEvalType unknown()
SizeOffsetEvalType compute(Value *V)
bool anyKnown(SizeOffsetEvalType SizeOffset)
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts EvalOpts={})
SizeOffsetEvalType visitCallBase(CallBase &CB)
SizeOffsetEvalType visitInstruction(Instruction &I)
SizeOffsetEvalType visitAllocaInst(AllocaInst &I)
bool bothKnown(SizeOffsetEvalType SizeOffset)
SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst &)
SizeOffsetEvalType visitLoadInst(LoadInst &I)
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP)
Evaluate the size and offset of an object pointed to by a Value* statically.
SizeOffsetType visitAllocaInst(AllocaInst &I)
SizeOffsetType visitArgument(Argument &A)
SizeOffsetType visitGlobalVariable(GlobalVariable &GV)
SizeOffsetType visitSelectInst(SelectInst &I)
ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts Options={})
SizeOffsetType visitCallBase(CallBase &CB)
SizeOffsetType visitExtractValueInst(ExtractValueInst &I)
SizeOffsetType visitConstantPointerNull(ConstantPointerNull &)
SizeOffsetType visitExtractElementInst(ExtractElementInst &I)
static bool bothKnown(const SizeOffsetType &SizeOffset)
SizeOffsetType visitUndefValue(UndefValue &)
SizeOffsetType visitGlobalAlias(GlobalAlias &GA)
SizeOffsetType visitIntToPtrInst(IntToPtrInst &)
static bool knownSize(const SizeOffsetType &SizeOffset)
SizeOffsetType visitLoadInst(LoadInst &I)
static bool knownOffset(const SizeOffsetType &SizeOffset)
SizeOffsetType visitInstruction(Instruction &I)
SizeOffsetType compute(Value *V)
SizeOffsetType visitPHINode(PHINode &)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
Value * hasConstantValue() const
If the specified PHI node always merges together the same value, return the value,...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This class represents the LLVM 'select' instruction.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetFolder - Create constants with target dependent folding.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isVoidTy() const
Return true if this is 'void'.
'undef' values are things that do not have specified contents.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
std::pair< APInt, APInt > SizeOffsetType
bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
std::optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)
If a function is part of an allocation family (e.g.
Value * lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL, const TargetLibraryInfo *TLI, bool MustSucceed)
Try to turn a call to @llvm.objectsize into an integer value of the given Type.
Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
std::pair< Value *, Value * > SizeOffsetEvalType
bool isLibFreeFunction(const Function *F, const LibFunc TLIFn)
isLibFreeFunction - Returns true if the function is a builtin free()
Value * getReallocatedOperand(const CallBase *CB)
If this is a call to a realloc function, return the reallocated operand.
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory (either malloc,...
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t GetStringLength(const Value *V, unsigned CharSize=8)
If we can compute the length of the string pointed to by the specified pointer, return 'len+1'.
bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory similar to malloc or...
bool isReallocLikeFn(const Function *F)
Tests if a function is a call or invoke to a library function that reallocates memory (e....
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
auto predecessors(const MachineBasicBlock *BB)
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates or reallocates memory (eith...
std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
std::optional< bool > isImpliedByDomCondition(const Value *Cond, const Instruction *ContextI, const DataLayout &DL)
Return the boolean condition value in the context of the given instruction if it is known based on do...
bool isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI)
Tests if a value is a call or invoke to a library function that allocates memory via new.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
Mode EvalMode
How we want to evaluate this object's size.
AAResults * AA
If set, used for more accurate evaluation.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
@ ExactUnderlyingSizeAndOffset
All branches must be known and have the same underlying size and offset to be merged.
@ Max
Same as Min, except we pick the maximum size of all of the branches.
@ Min
Evaluate all branches of an unknown condition.
@ ExactSizeFromOffset
All branches must be known and have the same size, starting from the offset, to be merged.