51#define DEBUG_TYPE "memory-builtins"
54 "object-size-offset-visitor-max-visit-instructions",
55 cl::desc(
"Maximum number of instructions for ObjectSizeOffsetVisitor to "
87 return "_ZnwmSt11align_val_t";
91 return "_ZnamSt11align_val_t";
93 return "??2@YAPAXI@Z";
95 return "??_U@YAPAXI@Z";
99 return "__kmpc_alloc_shared";
161 if (isa<IntrinsicInst>(V))
164 const auto *CB = dyn_cast<CallBase>(V);
168 if (CB->isNoBuiltin())
171 return CB->getCalledFunction();
176static std::optional<AllocFnsTy>
181 if (!Callee->getReturnType()->isPointerTy())
186 if (!TLI || !TLI->
getLibFunc(*Callee, TLIFn) || !TLI->
has(TLIFn))
191 return P.first == TLIFn;
206 if (FTy->getReturnType()->isPointerTy() &&
207 FTy->getNumParams() == FnData->
NumParams &&
209 (FTy->getParamType(FstParam)->isIntegerTy(32) ||
210 FTy->getParamType(FstParam)->isIntegerTy(64))) &&
212 FTy->getParamType(SndParam)->isIntegerTy(32) ||
213 FTy->getParamType(SndParam)->isIntegerTy(64)))
218static std::optional<AllocFnsTy>
226static std::optional<AllocFnsTy>
231 Callee, AllocTy, &GetTLI(
const_cast<Function &
>(*Callee)));
235static std::optional<AllocFnsTy>
240 if (std::optional<AllocFnsTy> Data =
249 std::pair<unsigned, std::optional<unsigned>> Args = Attr.
getAllocSizeArgs();
256 Result.FstParam = Args.first;
257 Result.SndParam = Args.second.value_or(-1);
259 Result.AlignParam = -1;
264 if (
const auto *CB = dyn_cast<CallBase>(V)) {
265 Attribute Attr = CB->getFnAttr(Attribute::AllocKind);
269 return AllocFnKind::Unknown;
273 return F->getAttributes().getAllocKind();
344 if (FnData && FnData->AlignParam >= 0) {
345 return V->getOperand(FnData->AlignParam);
347 return V->getArgOperandWithAttribute(Attribute::AllocAlign);
359 if (
I.getBitWidth() > IntTyBits &&
I.getActiveBits() > IntTyBits)
361 if (
I.getBitWidth() != IntTyBits)
362 I =
I.zextOrTrunc(IntTyBits);
378 const unsigned IntTyBits =
DL.getIndexTypeSizeInBits(CB->
getType());
387 if (FnData->FstParam > 0) {
389 dyn_cast<ConstantInt>(Mapper(CB->
getArgOperand(FnData->FstParam)));
394 if (
Size.ugt(MaxSize))
401 dyn_cast<ConstantInt>(Mapper(CB->
getArgOperand(FnData->FstParam)));
410 if (FnData->SndParam < 0)
413 Arg = dyn_cast<ConstantInt>(Mapper(CB->
getArgOperand(FnData->SndParam)));
422 Size =
Size.umul_ov(NumElems, Overflow);
431 if (isa<AllocaInst>(V))
434 auto *Alloc = dyn_cast<CallBase>(V);
443 if ((AK & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
445 if ((AK & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
495 return P.first == TLIFn;
502std::optional<StringRef>
506 if (TLI && TLI->
getLibFunc(*Callee, TLIFn) && TLI->
has(TLIFn)) {
508 const auto AllocData =
520 AllocFnKind::Realloc)) {
521 Attribute Attr = cast<CallBase>(
I)->getFnAttr(
"alloc-family");
551 if (TLI && TLI->
getLibFunc(*Callee, TLIFn) && TLI->
has(TLIFn) &&
585 if (!Data.bothKnown())
605 "ObjectSize must be a call to llvm.objectsize!");
607 bool MaxVal = cast<ConstantInt>(ObjectSize->
getArgOperand(1))->isZero();
615 MaxVal ? ObjectSizeOpts::Mode::Max : ObjectSizeOpts::Mode::Min;
617 EvalOptions.
EvalMode = ObjectSizeOpts::Mode::ExactSizeFromOffset;
622 auto *ResultType = cast<IntegerType>(ObjectSize->
getType());
623 bool StaticOnly = cast<ConstantInt>(ObjectSize->
getArgOperand(3))->isZero();
630 return ConstantInt::get(ResultType,
Size);
639 if (InsertedInstructions)
653 UseZero, ConstantInt::get(ResultType, 0), ResultSize);
656 if (!isa<Constant>(
Size) || !isa<Constant>(
Offset))
658 Builder.
CreateICmpNE(Ret, ConstantInt::get(ResultType, -1)));
672 "Number of arguments with unsolved size and offset");
674 "Number of load instructions with unsolved size and offset");
676static std::optional<APInt>
678 std::optional<APInt> RHS,
682 if (EvalMode == ObjectSizeOpts::Mode::Max)
690 constexpr unsigned maxRecursionDepth = 4;
691 if (recursionDepth == maxRecursionDepth)
694 if (
const auto *CI = dyn_cast<ConstantInt>(V)) {
695 return CI->getValue();
696 }
else if (
const auto *SI = dyn_cast<SelectInst>(V)) {
703 }
else if (
const auto *PN = dyn_cast<PHINode>(V)) {
704 unsigned Count = PN->getNumIncomingValues();
708 PN->getIncomingValue(0), EvalMode, recursionDepth + 1);
709 for (
unsigned I = 1; Acc &&
I < Count; ++
I) {
711 PN->getIncomingValue(
I), EvalMode, recursionDepth + 1);
720static std::optional<APInt>
722 if (
auto *CI = dyn_cast<ConstantInt>(V))
723 return CI->getValue();
725 if (EvalMode != ObjectSizeOpts::Mode::Min &&
726 EvalMode != ObjectSizeOpts::Mode::Max)
755 InstructionsVisited = 0;
779 V = V->stripAndAccumulateConstantOffsets(
787 isa<GEPOperator>(V)) {
795 if (
auto PossibleOffset =
803 V =
V->stripAndAccumulateConstantOffsets(
805 OffsetRangeAnalysis);
814 bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
815 if (!IndexTypeSizeChanged &&
Offset.isZero())
821 if (IndexTypeSizeChanged) {
823 !::CheckedZextOrTrunc(ORT.
Before, InitialIntTyBits))
825 if (ORT.
knownAfter() && !::CheckedZextOrTrunc(ORT.
After, InitialIntTyBits))
851 return ObjectSizeOffsetVisitor::unknown();
862 auto P = SeenInsts.try_emplace(
I, ObjectSizeOffsetVisitor::unknown());
864 return P.first->second;
865 ++InstructionsVisited;
867 return ObjectSizeOffsetVisitor::unknown();
885 LLVM_DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor::compute() unhandled value: "
887 return ObjectSizeOffsetVisitor::unknown();
890bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(
APInt &
I) {
891 return ::CheckedZextOrTrunc(
I, IntTyBits);
897 return ObjectSizeOffsetVisitor::unknown();
899 return ObjectSizeOffsetVisitor::unknown();
902 if (!
I.isArrayAllocation())
905 Value *ArraySize =
I.getArraySize();
906 if (
auto PossibleSize =
908 APInt NumElems = *PossibleSize;
909 if (!CheckedZextOrTrunc(NumElems))
910 return ObjectSizeOffsetVisitor::unknown();
913 Size =
Size.umul_ov(NumElems, Overflow);
915 return Overflow ? ObjectSizeOffsetVisitor::unknown()
918 return ObjectSizeOffsetVisitor::unknown();
922 Type *MemoryTy =
A.getPointeeInMemoryValueType();
924 if (!MemoryTy|| !MemoryTy->
isSized()) {
925 ++ObjectVisitorArgument;
926 return ObjectSizeOffsetVisitor::unknown();
934 auto Mapper = [
this](
const Value *V) ->
const Value * {
935 if (!V->getType()->isIntegerTy())
938 if (
auto PossibleBound =
940 return ConstantInt::get(V->getType(), *PossibleBound);
947 if (
Size->isNegative())
948 return ObjectSizeOffsetVisitor::unknown();
951 return ObjectSizeOffsetVisitor::unknown();
964 return ObjectSizeOffsetVisitor::unknown();
970 return ObjectSizeOffsetVisitor::unknown();
975 return ObjectSizeOffsetVisitor::unknown();
980 return ObjectSizeOffsetVisitor::unknown();
988 return ObjectSizeOffsetVisitor::unknown();
996 return ObjectSizeOffsetVisitor::unknown();
999OffsetSpan ObjectSizeOffsetVisitor::findLoadOffsetRange(
1002 unsigned &ScannedInstCount) {
1003 constexpr unsigned MaxInstsToScan = 128;
1005 auto Where = VisitedBlocks.
find(&BB);
1006 if (Where != VisitedBlocks.
end())
1007 return Where->second;
1009 auto Unknown = [&BB, &VisitedBlocks]() {
1010 return VisitedBlocks[&BB] = ObjectSizeOffsetVisitor::unknown();
1012 auto Known = [&BB, &VisitedBlocks](
OffsetSpan SO) {
1013 return VisitedBlocks[&BB] = SO;
1019 if (
I.isDebugOrPseudoInst())
1022 if (++ScannedInstCount > MaxInstsToScan)
1025 if (!
I.mayWriteToMemory())
1028 if (
auto *SI = dyn_cast<StoreInst>(&
I)) {
1030 Options.
AA->
alias(
SI->getPointerOperand(),
Load.getPointerOperand());
1035 if (
SI->getValueOperand()->getType()->isPointerTy())
1036 return Known(computeImpl(
SI->getValueOperand()));
1044 if (
auto *CB = dyn_cast<CallBase>(&
I)) {
1056 if (TLIFn != LibFunc_posix_memalign)
1075 if (!Checked || !*Checked)
1079 auto *
C = dyn_cast<ConstantInt>(
Size);
1083 APInt CSize =
C->getValue();
1095 PredecessorSizeOffsets.
push_back(findLoadOffsetRange(
1097 VisitedBlocks, ScannedInstCount));
1098 if (!PredecessorSizeOffsets.
back().bothKnown())
1102 if (PredecessorSizeOffsets.
empty())
1105 return Known(std::accumulate(
1106 PredecessorSizeOffsets.
begin() + 1, PredecessorSizeOffsets.
end(),
1108 return combineOffsetRange(LHS, RHS);
1114 ++ObjectVisitorLoad;
1115 return ObjectSizeOffsetVisitor::unknown();
1119 unsigned ScannedInstCount = 0;
1122 VisitedBlocks, ScannedInstCount);
1124 ++ObjectVisitorLoad;
1130 if (!
LHS.bothKnown() || !
RHS.bothKnown())
1131 return ObjectSizeOffsetVisitor::unknown();
1135 return {
LHS.Before.slt(
RHS.Before) ?
LHS.Before :
RHS.Before,
1138 return {
LHS.Before.sgt(
RHS.Before) ?
LHS.Before :
RHS.Before,
1145 return (LHS == RHS) ?
LHS : ObjectSizeOffsetVisitor::unknown();
1152 return ObjectSizeOffsetVisitor::unknown();
1154 return std::accumulate(IncomingValues.begin() + 1, IncomingValues.end(),
1155 computeImpl(*IncomingValues.begin()),
1157 return combineOffsetRange(LHS, computeImpl(VRHS));
1162 return combineOffsetRange(computeImpl(
I.getTrueValue()),
1163 computeImpl(
I.getFalseValue()));
1171 LLVM_DEBUG(
dbgs() <<
"ObjectSizeOffsetVisitor unknown instruction:" <<
I
1173 return ObjectSizeOffsetVisitor::unknown();
1187 EvalOpts(EvalOpts) {
1194 IntTy = cast<IntegerType>(DL.
getIndexType(V->getType()));
1195 Zero = ConstantInt::get(IntTy, 0);
1199 if (!Result.bothKnown()) {
1203 for (
const Value *SeenVal : SeenVals) {
1206 if (CacheIt != CacheMap.
end() && CacheIt->second.anyKnown())
1207 CacheMap.
erase(CacheIt);
1213 I->eraseFromParent();
1218 InsertedInstructions.clear();
1231 if (Const.bothKnown())
1233 ConstantInt::get(Context, Const.Offset));
1235 V = V->stripPointerCasts();
1239 if (CacheIt != CacheMap.
end())
1240 return CacheIt->second;
1254 if (!SeenVals.
insert(V).second) {
1258 }
else if (
Instruction *
I = dyn_cast<Instruction>(V)) {
1260 }
else if (isa<Argument>(V) ||
1261 (isa<ConstantExpr>(V) &&
1262 cast<ConstantExpr>(V)->
getOpcode() == Instruction::IntToPtr) ||
1263 isa<GlobalAlias>(V) ||
1264 isa<GlobalVariable>(V)) {
1269 dbgs() <<
"ObjectSizeOffsetEvaluator::compute() unhandled value: " << *V
1280 if (!
I.getAllocatedType()->isSized())
1284 assert(
I.isArrayAllocation() ||
I.getAllocatedType()->isScalableTy());
1292 "Expected zero constant to have pointer index type");
1313 if (FnData->SndParam < 0)
1360 for (
unsigned i = 0, e =
PHI.getNumIncomingValues(); i != e; ++i) {
1368 InsertedInstructions.erase(OffsetPHI);
1371 InsertedInstructions.erase(SizePHI);
1383 InsertedInstructions.erase(SizePHI);
1389 InsertedInstructions.erase(OffsetPHI);
1400 if (TrueSide == FalseSide)
1411 LLVM_DEBUG(
dbgs() <<
"ObjectSizeOffsetEvaluator unknown instruction:" <<
I
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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 std::optional< APInt > combinePossibleConstantValues(std::optional< APInt > LHS, std::optional< APInt > RHS, ObjectSizeOpts::Mode EvalMode)
static AllocFnKind getAllocFnKind(const Value *V)
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 bool checkFnAllocKind(const Value *V, AllocFnKind Wanted)
StringRef mangledNameForMallocFamily(const MallocFamily &Family)
static std::optional< AllocFnsTy > getAllocationSize(const CallBase *CB, const TargetLibraryInfo *TLI)
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 const Function * getCalledFunction(const Value *V)
static std::optional< APInt > aggregatePossibleConstantValues(const Value *V, ObjectSizeOpts::Mode EvalMode)
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 std::optional< APInt > aggregatePossibleConstantValuesImpl(const Value *V, ObjectSizeOpts::Mode EvalMode, unsigned recursionDepth)
static const std::pair< LibFunc, AllocFnsTy > AllocationFnData[]
static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data)
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.
A private abstract base class describing the concept of an individual alias analysis implementation.
LLVM_ABI AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const
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.
LLVM_ABI uint64_t getValueAsInt() const
Return the attribute's value as an integer.
LLVM_ABI std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
LLVM_ABI 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.
LLVM_ABI 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...
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
Value * getArgOperand(unsigned i) const
LLVM_ABI Value * getArgOperandWithAttribute(Attribute::AttrKind Kind) const
If one of the arguments has the specified attribute, returns its operand value.
unsigned arg_size() const
This is the shared class of boolean and integer constants.
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 LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI 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.
LLVM_ABI unsigned getIndexTypeSizeInBits(Type *Ty) const
The size in bits of the index used in GEP calculation for this type.
unsigned getAllocaAddrSpace() const
LLVM_ABI 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
bool hasExternalWeakLinkage() const
LLVM_ABI 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.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
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.
LLVM_ABI CallInst * CreateAssumption(Value *Cond, ArrayRef< OperandBundleDef > OpBundles={})
Create an assume intrinsic call that allows the optimizer to assume that the provided condition will ...
LLVM_ABI 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)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
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)
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module 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.
Evaluate the size and offset of an object pointed to by a Value*.
LLVM_ABI SizeOffsetValue visitExtractValueInst(ExtractValueInst &I)
LLVM_ABI SizeOffsetValue visitExtractElementInst(ExtractElementInst &I)
LLVM_ABI SizeOffsetValue compute(Value *V)
LLVM_ABI SizeOffsetValue visitInstruction(Instruction &I)
LLVM_ABI ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts EvalOpts={})
LLVM_ABI SizeOffsetValue visitLoadInst(LoadInst &I)
LLVM_ABI SizeOffsetValue visitGEPOperator(GEPOperator &GEP)
LLVM_ABI SizeOffsetValue visitIntToPtrInst(IntToPtrInst &)
LLVM_ABI SizeOffsetValue visitPHINode(PHINode &PHI)
LLVM_ABI SizeOffsetValue visitCallBase(CallBase &CB)
LLVM_ABI SizeOffsetValue visitSelectInst(SelectInst &I)
LLVM_ABI SizeOffsetValue visitAllocaInst(AllocaInst &I)
static SizeOffsetValue unknown()
Evaluate the size and offset of an object pointed to by a Value* statically.
LLVM_ABI OffsetSpan visitSelectInst(SelectInst &I)
LLVM_ABI OffsetSpan visitExtractValueInst(ExtractValueInst &I)
LLVM_ABI OffsetSpan visitConstantPointerNull(ConstantPointerNull &)
LLVM_ABI OffsetSpan visitExtractElementInst(ExtractElementInst &I)
LLVM_ABI OffsetSpan visitGlobalVariable(GlobalVariable &GV)
LLVM_ABI OffsetSpan visitCallBase(CallBase &CB)
LLVM_ABI OffsetSpan visitIntToPtrInst(IntToPtrInst &)
LLVM_ABI OffsetSpan visitAllocaInst(AllocaInst &I)
LLVM_ABI ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts Options={})
LLVM_ABI OffsetSpan visitLoadInst(LoadInst &I)
LLVM_ABI OffsetSpan visitPHINode(PHINode &)
LLVM_ABI OffsetSpan visitGlobalAlias(GlobalAlias &GA)
LLVM_ABI OffsetSpan visitInstruction(Instruction &I)
LLVM_ABI SizeOffsetAPInt compute(Value *V)
LLVM_ABI OffsetSpan visitUndefValue(UndefValue &)
LLVM_ABI OffsetSpan visitArgument(Argument &A)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
op_range incoming_values()
LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI 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.
LLVM_ABI 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.
const ParentTy * getParent() const
#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.
LLVM_ABI 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,...
LLVM_ABI 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...
LLVM_ABI std::optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)
If a function is part of an allocation family (e.g.
LLVM_ABI 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.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI bool isLibFreeFunction(const Function *F, const LibFunc TLIFn)
isLibFreeFunction - Returns true if the function is a builtin free()
LLVM_ABI Value * getReallocatedOperand(const CallBase *CB)
If this is a call to a realloc function, return the reallocated operand.
LLVM_ABI 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,...
LLVM_ABI 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.
LLVM_ABI 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...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI 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'.
LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI 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)
LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI 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...
LLVM_ABI 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.
Mode
Controls how we handle conditional statements with unknown conditions.
@ 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.
OffsetSpan - Used internally by ObjectSizeOffsetVisitor.
APInt After
Number of allocated bytes before this point.
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.
SizeOffsetType - A base template class for the object size visitors.
SizeOffsetWeakTrackingVH - Used by ObjectSizeOffsetEvaluator in a DenseMap.