LLVM 24.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;
35class DataLayout;
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 (either malloc, calloc, or strdup like).
63LLVM_ABI bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
64
65/// Tests if a function is a call or invoke to a library function that
66/// reallocates memory (e.g., realloc).
68
69/// If this is a call to a realloc function, return the reallocated operand.
71
72//===----------------------------------------------------------------------===//
73// free Call Utility Functions.
74//
75
76/// isLibFreeFunction - Returns true if the function is a builtin free()
77LLVM_ABI bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
78
79/// If this if a call to a free function, return the freed operand.
81 const TargetLibraryInfo *TLI);
82
83//===----------------------------------------------------------------------===//
84// Properties of allocation functions
85//
86
87/// Return true if this is a call to an allocation function that does not have
88/// side effects that we are required to preserve beyond the effect of
89/// allocating a new object.
90/// Ex: If our allocation routine has a counter for the number of objects
91/// allocated, and the program prints it on exit, can the value change due
92/// to optimization? Answer is highly language dependent.
93/// Note: *Removable* really does mean removable; it does not mean observable.
94/// A language (e.g. C++) can allow removing allocations without allowing
95/// insertion or speculative execution of allocation routines.
96LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI);
97
98/// Gets the alignment argument for an aligned_alloc-like function, using either
99/// built-in knowledge based on fuction names/signatures or allocalign
100/// attributes. Note: the Value returned may not indicate a valid alignment, per
101/// the definition of the allocalign attribute.
103 const TargetLibraryInfo *TLI);
104
105/// Return the size of the requested allocation. With a trivial mapper, this is
106/// similar to calling getObjectSize(..., Exact), but without looking through
107/// calls that return their argument. A mapper function can be used to replace
108/// one Value* (operand to the allocation) with another. This is useful when
109/// doing abstract interpretation.
110LLVM_ABI std::optional<APInt> getAllocSize(
111 const CallBase *CB, const TargetLibraryInfo *TLI,
112 function_ref<const Value *(const Value *)> Mapper = [](const Value *V) {
113 return V;
114 });
115
116/// If this is a call to an allocation function that initializes memory to a
117/// fixed value, return said value in the requested type. Otherwise, return
118/// nullptr.
120 const TargetLibraryInfo *TLI,
121 Type *Ty);
122
123/// If a function is part of an allocation family (e.g.
124/// malloc/realloc/calloc/free), return the identifier for its family
125/// of functions.
126LLVM_ABI std::optional<StringRef>
127getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI);
128
129//===----------------------------------------------------------------------===//
130// Utility functions to compute size of objects.
131//
132
133/// Various options to control the behavior of getObjectSize.
135 /// Controls how we handle conditional statements with unknown conditions.
136 enum class Mode : uint8_t {
137 /// All branches must be known and have the same size, starting from the
138 /// offset, to be merged.
140 /// All branches must be known and have the same underlying size and offset
141 /// to be merged.
143 /// Evaluate all branches of an unknown condition. If all evaluations
144 /// succeed, pick the minimum size.
146 /// Same as Min, except we pick the maximum size of all of the branches.
148 };
149
150 /// How we want to evaluate this object's size.
152 /// Whether to round the result up to the alignment of allocas, byval
153 /// arguments, and global variables.
154 bool RoundToAlign = false;
155 /// If this is true, null pointers in address space 0 will be treated as
156 /// though they can't be evaluated. Otherwise, null is always considered to
157 /// point to a 0 byte region of memory.
158 bool NullIsUnknownSize = false;
159 /// If set, used for more accurate evaluation
160 AAResults *AA = nullptr;
161};
162
163/// Compute the size of the object pointed by Ptr. Returns true and the
164/// object size in Size if successful, and false otherwise. In this context, by
165/// object we mean the region of memory starting at Ptr to the end of the
166/// underlying object pointed to by Ptr.
167///
168/// WARNING: The object size returned is the allocation size. This does not
169/// imply dereferenceability at site of use since the object may be freeed in
170/// between.
171LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size,
172 const DataLayout &DL, const TargetLibraryInfo *TLI,
173 ObjectSizeOpts Opts = {});
174
175/// Like getObjectSize(), but only returns the size of base objects (like
176/// allocas, global variables and allocator calls) and std::nullopt otherwise.
177/// Requires ExactSizeFromOffset mode.
178LLVM_ABI std::optional<TypeSize> getBaseObjectSize(const Value *Ptr,
179 const DataLayout &DL,
180 const TargetLibraryInfo *TLI,
181 ObjectSizeOpts Opts = {});
182
183/// Try to turn a call to \@llvm.objectsize into an integer value of the given
184/// Type. Returns null on failure. If MustSucceed is true, this function will
185/// not return null, and may return conservative values governed by the second
186/// argument of the call to objectsize.
188 const DataLayout &DL,
189 const TargetLibraryInfo *TLI,
190 bool MustSucceed);
192 IntrinsicInst *ObjectSize, const DataLayout &DL,
193 const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
194 SmallVectorImpl<Instruction *> *InsertedInstructions = nullptr);
195
196/// SizeOffsetType - A base template class for the object size visitors. Used
197/// here as a self-documenting way to handle the values rather than using a
198/// \p std::pair.
199template <typename T, class C> struct SizeOffsetType {
200public:
203
204 SizeOffsetType() = default;
207
208 bool knownSize() const { return C::known(Size); }
209 bool knownOffset() const { return C::known(Offset); }
210 bool anyKnown() const { return knownSize() || knownOffset(); }
211 bool bothKnown() const { return knownSize() && knownOffset(); }
212
214 return Size == RHS.Size && Offset == RHS.Offset;
215 }
217 return !(*this == RHS);
218 }
219};
220
221/// SizeOffsetAPInt - Used by \p ObjectSizeOffsetVisitor, which works with
222/// \p APInts.
223struct SizeOffsetAPInt : public SizeOffsetType<APInt, SizeOffsetAPInt> {
224 SizeOffsetAPInt() = default;
227
228 static bool known(const APInt &V) { return V.getBitWidth() > 1; }
229};
230
231/// OffsetSpan - Used internally by \p ObjectSizeOffsetVisitor. Represents a
232/// point in memory as a pair of allocated bytes before and after it.
233///
234/// \c Before and \c After fields are signed values. It makes it possible to
235/// represent out-of-bound access, e.g. as a result of a GEP, at the expense of
236/// not being able to represent very large allocation.
238 APInt Before; /// Number of allocated bytes before this point.
239 APInt After; /// Number of allocated bytes after this point.
240
241 OffsetSpan() = default;
243
244 bool knownBefore() const { return known(Before); }
245 bool knownAfter() const { return known(After); }
246 bool anyKnown() const { return knownBefore() || knownAfter(); }
247 bool bothKnown() const { return knownBefore() && knownAfter(); }
248
249 bool operator==(const OffsetSpan &RHS) const {
250 return Before == RHS.Before && After == RHS.After;
251 }
252 bool operator!=(const OffsetSpan &RHS) const { return !(*this == RHS); }
253
254 static bool known(const APInt &V) { return V.getBitWidth() > 1; }
255};
256
257/// Evaluate the size and offset of an object pointed to by a Value*
258/// statically. Fails if size or offset are not known at compile time.
260 : public InstVisitor<ObjectSizeOffsetVisitor, OffsetSpan> {
261 const DataLayout &DL;
262 const TargetLibraryInfo *TLI;
263 ObjectSizeOpts Options;
264 unsigned IntTyBits;
265 APInt Zero;
267 unsigned InstructionsVisited;
268
270
271 static OffsetSpan unknown() { return OffsetSpan(); }
272
273public:
275 const TargetLibraryInfo *TLI,
276 LLVMContext &Context,
277 ObjectSizeOpts Options = {});
278
280
281 // These are "private", except they can't actually be made private. Only
282 // compute() should be used by external users.
297
298private:
300 findLoadOffsetRange(LoadInst &LoadFrom, BasicBlock &BB,
303 unsigned &ScannedInstCount);
304 OffsetSpan combineOffsetRange(OffsetSpan LHS, OffsetSpan RHS);
305 OffsetSpan computeImpl(Value *V);
306 OffsetSpan computeValue(Value *V);
307 bool checkedZextOrTrunc(APInt &I);
308};
309
310/// SizeOffsetValue - Used by \p ObjectSizeOffsetEvaluator, which works with
311/// \p Values.
313struct SizeOffsetValue : public SizeOffsetType<Value *, SizeOffsetValue> {
314 SizeOffsetValue() : SizeOffsetType(nullptr, nullptr) {}
317
318 static bool known(Value *V) { return V != nullptr; }
319};
320
321/// SizeOffsetWeakTrackingVH - Used by \p ObjectSizeOffsetEvaluator in a
322/// \p DenseMap.
324 : public SizeOffsetType<WeakTrackingVH, SizeOffsetWeakTrackingVH> {
330
331 static bool known(WeakTrackingVH V) { return V.pointsToAliveValue(); }
332};
333
334/// Evaluate the size and offset of an object pointed to by a Value*.
335/// May create code to compute the result at run-time.
337 : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetValue> {
339 using WeakEvalType = SizeOffsetWeakTrackingVH;
340 using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
341 using PtrSetTy = SmallPtrSet<const Value *, 8>;
342
343 const DataLayout &DL;
344 const TargetLibraryInfo *TLI;
345 LLVMContext &Context;
346 BuilderTy Builder;
347 IntegerType *IntTy;
348 Value *Zero;
349 CacheMapTy CacheMap;
350 PtrSetTy SeenVals;
351 ObjectSizeOpts EvalOpts;
352 SmallPtrSet<Instruction *, 8> InsertedInstructions;
353
354 SizeOffsetValue compute_(Value *V);
355
356public:
358 const TargetLibraryInfo *TLI,
359 LLVMContext &Context,
360 ObjectSizeOpts EvalOpts = {});
361
363
365
366 // The individual instruction visitors should be treated as private.
377};
378
379} // end namespace llvm
380
381#endif // LLVM_ANALYSIS_MEMORYBUILTINS_H
unsigned uint64_t
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ABI
Definition Compiler.h:215
SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks
This file defines the DenseMap class.
Hexagon Common GEP
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
This file defines the SmallPtrSet class.
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
an instruction to allocate memory on the stack
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...
A constant pointer value that points to null.
Definition Constants.h:716
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
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.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2903
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.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An instruction for reading from memory.
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()
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)
This class represents the LLVM 'select' instruction.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
'undef' values are things that do not have specified contents.
Definition Constants.h:1631
LLVM Value Representation.
Definition Value.h:75
Value handle that is nullable, but tries to track the Value.
An efficient, type-erasing, non-owning reference to a callable.
Abstract Attribute helper functions.
Definition Attributor.h:165
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...
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 std::optional< TypeSize > getBaseObjectSize(const Value *Ptr, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Like getObjectSize(), but only returns the size of base objects (like allocas, global variables and a...
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 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:1917
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.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
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:106
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)
bool operator!=(const SizeOffsetType< T, C > &RHS) const
bool operator==(const SizeOffsetType< T, C > &RHS) const
SizeOffsetType()=default
SizeOffsetType(T Size, T Offset)
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)