LLVM 22.0.0git
MemoryBuiltins.h
Go to the documentation of this file.
1//==- llvm/Analysis/MemoryBuiltins.h - Calls to memory builtins --*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This family of functions identifies calls to builtin functions that allocate
10// or free memory.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
15#define LLVM_ANALYSIS_MEMORYBUILTINS_H
16
17#include "llvm/ADT/APInt.h"
18#include "llvm/ADT/DenseMap.h"
21#include "llvm/IR/IRBuilder.h"
22#include "llvm/IR/InstVisitor.h"
23#include "llvm/IR/ValueHandle.h"
25#include <cstdint>
26#include <optional>
27#include <utility>
28
29namespace llvm {
30
31class AllocaInst;
32class AAResults;
33class Argument;
34class ConstantPointerNull;
35class DataLayout;
36class ExtractElementInst;
37class ExtractValueInst;
38class GEPOperator;
39class GlobalAlias;
40class GlobalVariable;
41class Instruction;
42class IntegerType;
43class IntrinsicInst;
44class IntToPtrInst;
45class LLVMContext;
46class LoadInst;
47class PHINode;
48class SelectInst;
49class Type;
50class UndefValue;
51class Value;
52
53/// Tests if a value is a call or invoke to a library function that
54/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
55/// like).
56LLVM_ABI bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI);
57LLVM_ABI bool
58isAllocationFn(const Value *V,
59 function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
60
61/// Tests if a value is a call or invoke to a library function that
62/// allocates memory via new.
63LLVM_ABI bool isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI);
64
65/// Tests if a value is a call or invoke to a library function that
66/// allocates memory similar to malloc or calloc.
67LLVM_ABI bool isMallocOrCallocLikeFn(const Value *V,
68 const TargetLibraryInfo *TLI);
69
70/// Tests if a value is a call or invoke to a library function that
71/// allocates memory (either malloc, calloc, or strdup like).
72LLVM_ABI bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
73
74/// Tests if a function is a call or invoke to a library function that
75/// reallocates memory (e.g., realloc).
76LLVM_ABI bool isReallocLikeFn(const Function *F);
77
78/// If this is a call to a realloc function, return the reallocated operand.
79LLVM_ABI Value *getReallocatedOperand(const CallBase *CB);
80
81//===----------------------------------------------------------------------===//
82// free Call Utility Functions.
83//
84
85/// isLibFreeFunction - Returns true if the function is a builtin free()
86LLVM_ABI bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
87
88/// If this if a call to a free function, return the freed operand.
89LLVM_ABI Value *getFreedOperand(const CallBase *CB,
90 const TargetLibraryInfo *TLI);
91
92//===----------------------------------------------------------------------===//
93// Properties of allocation functions
94//
95
96/// Return true if this is a call to an allocation function that does not have
97/// side effects that we are required to preserve beyond the effect of
98/// allocating a new object.
99/// Ex: If our allocation routine has a counter for the number of objects
100/// allocated, and the program prints it on exit, can the value change due
101/// to optimization? Answer is highly language dependent.
102/// Note: *Removable* really does mean removable; it does not mean observable.
103/// A language (e.g. C++) can allow removing allocations without allowing
104/// insertion or speculative execution of allocation routines.
105LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI);
106
107/// Gets the alignment argument for an aligned_alloc-like function, using either
108/// built-in knowledge based on fuction names/signatures or allocalign
109/// attributes. Note: the Value returned may not indicate a valid alignment, per
110/// the definition of the allocalign attribute.
111LLVM_ABI Value *getAllocAlignment(const CallBase *V,
112 const TargetLibraryInfo *TLI);
113
114/// Return the size of the requested allocation. With a trivial mapper, this is
115/// similar to calling getObjectSize(..., Exact), but without looking through
116/// calls that return their argument. A mapper function can be used to replace
117/// one Value* (operand to the allocation) with another. This is useful when
118/// doing abstract interpretation.
119LLVM_ABI std::optional<APInt> getAllocSize(
120 const CallBase *CB, const TargetLibraryInfo *TLI,
121 function_ref<const Value *(const Value *)> Mapper = [](const Value *V) {
122 return V;
123 });
124
125/// If this is a call to an allocation function that initializes memory to a
126/// fixed value, return said value in the requested type. Otherwise, return
127/// nullptr.
129 const TargetLibraryInfo *TLI,
130 Type *Ty);
131
132/// If a function is part of an allocation family (e.g.
133/// malloc/realloc/calloc/free), return the identifier for its family
134/// of functions.
135LLVM_ABI std::optional<StringRef>
136getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI);
137
138//===----------------------------------------------------------------------===//
139// Utility functions to compute size of objects.
140//
141
142/// Various options to control the behavior of getObjectSize.
144 /// Controls how we handle conditional statements with unknown conditions.
145 enum class Mode : uint8_t {
146 /// All branches must be known and have the same size, starting from the
147 /// offset, to be merged.
149 /// All branches must be known and have the same underlying size and offset
150 /// to be merged.
152 /// Evaluate all branches of an unknown condition. If all evaluations
153 /// succeed, pick the minimum size.
154 Min,
155 /// Same as Min, except we pick the maximum size of all of the branches.
156 Max,
157 };
158
159 /// How we want to evaluate this object's size.
161 /// Whether to round the result up to the alignment of allocas, byval
162 /// arguments, and global variables.
163 bool RoundToAlign = false;
164 /// If this is true, null pointers in address space 0 will be treated as
165 /// though they can't be evaluated. Otherwise, null is always considered to
166 /// point to a 0 byte region of memory.
167 bool NullIsUnknownSize = false;
168 /// If set, used for more accurate evaluation
169 AAResults *AA = nullptr;
170};
171
172/// Compute the size of the object pointed by Ptr. Returns true and the
173/// object size in Size if successful, and false otherwise. In this context, by
174/// object we mean the region of memory starting at Ptr to the end of the
175/// underlying object pointed to by Ptr.
176///
177/// WARNING: The object size returned is the allocation size. This does not
178/// imply dereferenceability at site of use since the object may be freeed in
179/// between.
181 const DataLayout &DL, const TargetLibraryInfo *TLI,
182 ObjectSizeOpts Opts = {});
183
184/// Try to turn a call to \@llvm.objectsize into an integer value of the given
185/// Type. Returns null on failure. If MustSucceed is true, this function will
186/// not return null, and may return conservative values governed by the second
187/// argument of the call to objectsize.
188LLVM_ABI Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize,
189 const DataLayout &DL,
190 const TargetLibraryInfo *TLI,
191 bool MustSucceed);
193 IntrinsicInst *ObjectSize, const DataLayout &DL,
194 const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
195 SmallVectorImpl<Instruction *> *InsertedInstructions = nullptr);
196
197/// SizeOffsetType - A base template class for the object size visitors. Used
198/// here as a self-documenting way to handle the values rather than using a
199/// \p std::pair.
200template <typename T, class C> struct SizeOffsetType {
201public:
204
205 SizeOffsetType() = default;
207 : Size(std::move(Size)), Offset(std::move(Offset)) {}
208
209 bool knownSize() const { return C::known(Size); }
210 bool knownOffset() const { return C::known(Offset); }
211 bool anyKnown() const { return knownSize() || knownOffset(); }
212 bool bothKnown() const { return knownSize() && knownOffset(); }
213
215 return Size == RHS.Size && Offset == RHS.Offset;
216 }
218 return !(*this == RHS);
219 }
220};
221
222/// SizeOffsetAPInt - Used by \p ObjectSizeOffsetVisitor, which works with
223/// \p APInts.
224struct SizeOffsetAPInt : public SizeOffsetType<APInt, SizeOffsetAPInt> {
225 SizeOffsetAPInt() = default;
228
229 static bool known(const APInt &V) { return V.getBitWidth() > 1; }
230};
231
232/// OffsetSpan - Used internally by \p ObjectSizeOffsetVisitor. Represents a
233/// point in memory as a pair of allocated bytes before and after it.
234///
235/// \c Before and \c After fields are signed values. It makes it possible to
236/// represent out-of-bound access, e.g. as a result of a GEP, at the expense of
237/// not being able to represent very large allocation.
239 APInt Before; /// Number of allocated bytes before this point.
240 APInt After; /// Number of allocated bytes after this point.
241
242 OffsetSpan() = default;
244
245 bool knownBefore() const { return known(Before); }
246 bool knownAfter() const { return known(After); }
247 bool anyKnown() const { return knownBefore() || knownAfter(); }
248 bool bothKnown() const { return knownBefore() && knownAfter(); }
249
250 bool operator==(const OffsetSpan &RHS) const {
251 return Before == RHS.Before && After == RHS.After;
252 }
253 bool operator!=(const OffsetSpan &RHS) const { return !(*this == RHS); }
254
255 static bool known(const APInt &V) { return V.getBitWidth() > 1; }
256};
257
258/// Evaluate the size and offset of an object pointed to by a Value*
259/// statically. Fails if size or offset are not known at compile time.
261 : public InstVisitor<ObjectSizeOffsetVisitor, OffsetSpan> {
262 const DataLayout &DL;
263 const TargetLibraryInfo *TLI;
264 ObjectSizeOpts Options;
265 unsigned IntTyBits;
266 APInt Zero;
268 unsigned InstructionsVisited;
269
271
272 static OffsetSpan unknown() { return OffsetSpan(); }
273
274public:
276 const TargetLibraryInfo *TLI,
278 ObjectSizeOpts Options = {});
279
281
282 // These are "private", except they can't actually be made private. Only
283 // compute() should be used by external users.
298
299private:
301 findLoadOffsetRange(LoadInst &LoadFrom, BasicBlock &BB,
304 unsigned &ScannedInstCount);
305 OffsetSpan combineOffsetRange(OffsetSpan LHS, OffsetSpan RHS);
306 OffsetSpan computeImpl(Value *V);
307 OffsetSpan computeValue(Value *V);
308 bool CheckedZextOrTrunc(APInt &I);
309};
310
311/// SizeOffsetValue - Used by \p ObjectSizeOffsetEvaluator, which works with
312/// \p Values.
314struct SizeOffsetValue : public SizeOffsetType<Value *, SizeOffsetValue> {
315 SizeOffsetValue() : SizeOffsetType(nullptr, nullptr) {}
318
319 static bool known(Value *V) { return V != nullptr; }
320};
321
322/// SizeOffsetWeakTrackingVH - Used by \p ObjectSizeOffsetEvaluator in a
323/// \p DenseMap.
325 : public SizeOffsetType<WeakTrackingVH, SizeOffsetWeakTrackingVH> {
330 : SizeOffsetType(SOV.Size, SOV.Offset) {}
331
332 static bool known(WeakTrackingVH V) { return V.pointsToAliveValue(); }
333};
334
335/// Evaluate the size and offset of an object pointed to by a Value*.
336/// May create code to compute the result at run-time.
338 : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetValue> {
343
344 const DataLayout &DL;
345 const TargetLibraryInfo *TLI;
346 LLVMContext &Context;
347 BuilderTy Builder;
348 IntegerType *IntTy;
349 Value *Zero;
350 CacheMapTy CacheMap;
351 PtrSetTy SeenVals;
352 ObjectSizeOpts EvalOpts;
353 SmallPtrSet<Instruction *, 8> InsertedInstructions;
354
355 SizeOffsetValue compute_(Value *V);
356
357public:
359 const TargetLibraryInfo *TLI,
361 ObjectSizeOpts EvalOpts = {});
362
364
366
367 // The individual instruction visitors should be treated as private.
378};
379
380} // end namespace llvm
381
382#endif // LLVM_ANALYSIS_MEMORYBUILTINS_H
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
RelocType Type
Definition: COFFYAML.cpp:410
#define LLVM_ABI
Definition: Compiler.h:213
This file defines the DenseMap class.
uint64_t Size
Hexagon Common GEP
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file defines the SmallPtrSet class.
Value * RHS
Value * LHS
A private abstract base class describing the concept of an individual alias analysis implementation.
Class for arbitrary precision integers.
Definition: APInt.h:78
an instruction to allocate memory on the stack
Definition: Instructions.h:64
This class represents an incoming formal argument to a Function.
Definition: Argument.h:32
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:170
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
A constant pointer value that points to null.
Definition: Constants.h:558
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
Base class for instruction visitors.
Definition: InstVisitor.h:78
This class represents a cast from an integer to a pointer.
Class to represent integer types.
Definition: DerivedTypes.h:42
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
An instruction for reading from memory.
Definition: Instructions.h:180
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 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 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)
This class represents the LLVM 'select' instruction.
Provides information about what library functions are available for the current target.
'undef' values are things that do not have specified contents.
Definition: Constants.h:1420
LLVM Value Representation.
Definition: Value.h:75
Value handle that is nullable, but tries to track the Value.
Definition: ValueHandle.h:205
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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...
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 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....
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
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 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.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
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.
OffsetSpan()=default
Number of allocated bytes after this point.
bool knownBefore() const
APInt After
Number of allocated bytes before this point.
bool anyKnown() const
bool knownAfter() const
static bool known(const APInt &V)
bool operator!=(const OffsetSpan &RHS) const
bool operator==(const OffsetSpan &RHS) const
OffsetSpan(APInt Before, APInt After)
bool bothKnown() const
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.
static bool known(const APInt &V)
SizeOffsetAPInt(APInt Size, APInt Offset)
SizeOffsetType - A base template class for the object size visitors.
bool operator!=(const SizeOffsetType< T, C > &RHS) const
bool operator==(const SizeOffsetType< T, C > &RHS) const
SizeOffsetType()=default
SizeOffsetType(T Size, T Offset)
bool knownOffset() const
bool knownSize() const
bool bothKnown() const
SizeOffsetValue(Value *Size, Value *Offset)
static bool known(Value *V)
SizeOffsetWeakTrackingVH - Used by ObjectSizeOffsetEvaluator in a DenseMap.
SizeOffsetWeakTrackingVH(const SizeOffsetValue &SOV)
static bool known(WeakTrackingVH V)
SizeOffsetWeakTrackingVH(Value *Size, Value *Offset)