xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryBuiltins.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/Analysis/TargetFolder.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/InstVisitor.h"
23 #include "llvm/IR/ValueHandle.h"
24 #include "llvm/Support/Compiler.h"
25 #include <cstdint>
26 #include <optional>
27 #include <utility>
28 
29 namespace llvm {
30 
31 class AllocaInst;
32 class AAResults;
33 class Argument;
34 class ConstantPointerNull;
35 class DataLayout;
36 class ExtractElementInst;
37 class ExtractValueInst;
38 class GEPOperator;
39 class GlobalAlias;
40 class GlobalVariable;
41 class Instruction;
42 class IntegerType;
43 class IntrinsicInst;
44 class IntToPtrInst;
45 class LLVMContext;
46 class LoadInst;
47 class PHINode;
48 class SelectInst;
49 class Type;
50 class UndefValue;
51 class 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).
56 LLVM_ABI bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI);
57 LLVM_ABI bool
58 isAllocationFn(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.
63 LLVM_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.
67 LLVM_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).
72 LLVM_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).
76 LLVM_ABI bool isReallocLikeFn(const Function *F);
77 
78 /// If this is a call to a realloc function, return the reallocated operand.
79 LLVM_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()
86 LLVM_ABI bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
87 
88 /// If this if a call to a free function, return the freed operand.
89 LLVM_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.
105 LLVM_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.
111 LLVM_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.
119 LLVM_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.
128 LLVM_ABI Constant *getInitialValueOfAllocation(const Value *V,
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.
135 LLVM_ABI std::optional<StringRef>
136 getAllocationFamily(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.
143 struct ObjectSizeOpts {
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.
148     ExactSizeFromOffset,
149     /// All branches must be known and have the same underlying size and offset
150     /// to be merged.
151     ExactUnderlyingSizeAndOffset,
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.
160   Mode EvalMode = Mode::ExactSizeFromOffset;
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.
180 LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size,
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.
188 LLVM_ABI Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize,
189                                     const DataLayout &DL,
190                                     const TargetLibraryInfo *TLI,
191                                     bool MustSucceed);
192 LLVM_ABI Value *lowerObjectSizeCall(
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.
200 template <typename T, class C> struct SizeOffsetType {
201 public:
202   T Size;
203   T Offset;
204 
205   SizeOffsetType() = default;
SizeOffsetTypeSizeOffsetType206   SizeOffsetType(T Size, T Offset)
207       : Size(std::move(Size)), Offset(std::move(Offset)) {}
208 
knownSizeSizeOffsetType209   bool knownSize() const { return C::known(Size); }
knownOffsetSizeOffsetType210   bool knownOffset() const { return C::known(Offset); }
anyKnownSizeOffsetType211   bool anyKnown() const { return knownSize() || knownOffset(); }
bothKnownSizeOffsetType212   bool bothKnown() const { return knownSize() && knownOffset(); }
213 
214   bool operator==(const SizeOffsetType<T, C> &RHS) const {
215     return Size == RHS.Size && Offset == RHS.Offset;
216   }
217   bool operator!=(const SizeOffsetType<T, C> &RHS) const {
218     return !(*this == RHS);
219   }
220 };
221 
222 /// SizeOffsetAPInt - Used by \p ObjectSizeOffsetVisitor, which works with
223 /// \p APInts.
224 struct SizeOffsetAPInt : public SizeOffsetType<APInt, SizeOffsetAPInt> {
225   SizeOffsetAPInt() = default;
SizeOffsetAPIntSizeOffsetAPInt226   SizeOffsetAPInt(APInt Size, APInt Offset)
227       : SizeOffsetType(std::move(Size), std::move(Offset)) {}
228 
knownSizeOffsetAPInt229   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.
238 struct OffsetSpan {
239   APInt Before; /// Number of allocated bytes before this point.
240   APInt After;  /// Number of allocated bytes after this point.
241 
242   OffsetSpan() = default;
OffsetSpanOffsetSpan243   OffsetSpan(APInt Before, APInt After) : Before(Before), After(After) {}
244 
knownBeforeOffsetSpan245   bool knownBefore() const { return known(Before); }
knownAfterOffsetSpan246   bool knownAfter() const { return known(After); }
anyKnownOffsetSpan247   bool anyKnown() const { return knownBefore() || knownAfter(); }
bothKnownOffsetSpan248   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 
knownOffsetSpan255   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.
260 class ObjectSizeOffsetVisitor
261     : public InstVisitor<ObjectSizeOffsetVisitor, OffsetSpan> {
262   const DataLayout &DL;
263   const TargetLibraryInfo *TLI;
264   ObjectSizeOpts Options;
265   unsigned IntTyBits;
266   APInt Zero;
267   SmallDenseMap<Instruction *, OffsetSpan, 8> SeenInsts;
268   unsigned InstructionsVisited;
269 
270   APInt align(APInt Size, MaybeAlign Align);
271 
unknown()272   static OffsetSpan unknown() { return OffsetSpan(); }
273 
274 public:
275   LLVM_ABI ObjectSizeOffsetVisitor(const DataLayout &DL,
276                                    const TargetLibraryInfo *TLI,
277                                    LLVMContext &Context,
278                                    ObjectSizeOpts Options = {});
279 
280   LLVM_ABI SizeOffsetAPInt compute(Value *V);
281 
282   // These are "private", except they can't actually be made private. Only
283   // compute() should be used by external users.
284   LLVM_ABI OffsetSpan visitAllocaInst(AllocaInst &I);
285   LLVM_ABI OffsetSpan visitArgument(Argument &A);
286   LLVM_ABI OffsetSpan visitCallBase(CallBase &CB);
287   LLVM_ABI OffsetSpan visitConstantPointerNull(ConstantPointerNull &);
288   LLVM_ABI OffsetSpan visitExtractElementInst(ExtractElementInst &I);
289   LLVM_ABI OffsetSpan visitExtractValueInst(ExtractValueInst &I);
290   LLVM_ABI OffsetSpan visitGlobalAlias(GlobalAlias &GA);
291   LLVM_ABI OffsetSpan visitGlobalVariable(GlobalVariable &GV);
292   LLVM_ABI OffsetSpan visitIntToPtrInst(IntToPtrInst &);
293   LLVM_ABI OffsetSpan visitLoadInst(LoadInst &I);
294   LLVM_ABI OffsetSpan visitPHINode(PHINode &);
295   LLVM_ABI OffsetSpan visitSelectInst(SelectInst &I);
296   LLVM_ABI OffsetSpan visitUndefValue(UndefValue &);
297   LLVM_ABI OffsetSpan visitInstruction(Instruction &I);
298 
299 private:
300   OffsetSpan
301   findLoadOffsetRange(LoadInst &LoadFrom, BasicBlock &BB,
302                       BasicBlock::iterator From,
303                       SmallDenseMap<BasicBlock *, OffsetSpan, 8> &VisitedBlocks,
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.
313 struct SizeOffsetWeakTrackingVH;
314 struct SizeOffsetValue : public SizeOffsetType<Value *, SizeOffsetValue> {
SizeOffsetValueSizeOffsetValue315   SizeOffsetValue() : SizeOffsetType(nullptr, nullptr) {}
SizeOffsetValueSizeOffsetValue316   SizeOffsetValue(Value *Size, Value *Offset) : SizeOffsetType(Size, Offset) {}
317   LLVM_ABI SizeOffsetValue(const SizeOffsetWeakTrackingVH &SOT);
318 
knownSizeOffsetValue319   static bool known(Value *V) { return V != nullptr; }
320 };
321 
322 /// SizeOffsetWeakTrackingVH - Used by \p ObjectSizeOffsetEvaluator in a
323 /// \p DenseMap.
324 struct SizeOffsetWeakTrackingVH
325     : public SizeOffsetType<WeakTrackingVH, SizeOffsetWeakTrackingVH> {
SizeOffsetWeakTrackingVHSizeOffsetWeakTrackingVH326   SizeOffsetWeakTrackingVH() : SizeOffsetType(nullptr, nullptr) {}
SizeOffsetWeakTrackingVHSizeOffsetWeakTrackingVH327   SizeOffsetWeakTrackingVH(Value *Size, Value *Offset)
328       : SizeOffsetType(Size, Offset) {}
SizeOffsetWeakTrackingVHSizeOffsetWeakTrackingVH329   SizeOffsetWeakTrackingVH(const SizeOffsetValue &SOV)
330       : SizeOffsetType(SOV.Size, SOV.Offset) {}
331 
knownSizeOffsetWeakTrackingVH332   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.
337 class ObjectSizeOffsetEvaluator
338     : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetValue> {
339   using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
340   using WeakEvalType = SizeOffsetWeakTrackingVH;
341   using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
342   using PtrSetTy = SmallPtrSet<const Value *, 8>;
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 
357 public:
358   LLVM_ABI ObjectSizeOffsetEvaluator(const DataLayout &DL,
359                                      const TargetLibraryInfo *TLI,
360                                      LLVMContext &Context,
361                                      ObjectSizeOpts EvalOpts = {});
362 
unknown()363   static SizeOffsetValue unknown() { return SizeOffsetValue(); }
364 
365   LLVM_ABI SizeOffsetValue compute(Value *V);
366 
367   // The individual instruction visitors should be treated as private.
368   LLVM_ABI SizeOffsetValue visitAllocaInst(AllocaInst &I);
369   LLVM_ABI SizeOffsetValue visitCallBase(CallBase &CB);
370   LLVM_ABI SizeOffsetValue visitExtractElementInst(ExtractElementInst &I);
371   LLVM_ABI SizeOffsetValue visitExtractValueInst(ExtractValueInst &I);
372   LLVM_ABI SizeOffsetValue visitGEPOperator(GEPOperator &GEP);
373   LLVM_ABI SizeOffsetValue visitIntToPtrInst(IntToPtrInst &);
374   LLVM_ABI SizeOffsetValue visitLoadInst(LoadInst &I);
375   LLVM_ABI SizeOffsetValue visitPHINode(PHINode &PHI);
376   LLVM_ABI SizeOffsetValue visitSelectInst(SelectInst &I);
377   LLVM_ABI SizeOffsetValue visitInstruction(Instruction &I);
378 };
379 
380 } // end namespace llvm
381 
382 #endif // LLVM_ANALYSIS_MEMORYBUILTINS_H
383