Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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/Analysis/TargetLibraryInfo.h"
22
#include "llvm/IR/IRBuilder.h"
23
#include "llvm/IR/InstVisitor.h"
24
#include "llvm/IR/ValueHandle.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
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI);
57
bool isAllocationFn(const Value *V,
58
                    function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
59
 
60
/// Tests if a value is a call or invoke to a library function that
61
/// allocates memory via new.
62
bool isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI);
63
 
64
/// Tests if a value is a call or invoke to a library function that
65
/// allocates memory similar to malloc or calloc.
66
bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
67
 
68
/// Tests if a value is a call or invoke to a library function that
69
/// allocates memory (either malloc, calloc, or strdup like).
70
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
71
 
72
/// Tests if a function is a call or invoke to a library function that
73
/// reallocates memory (e.g., realloc).
74
bool isReallocLikeFn(const Function *F);
75
 
76
/// If this is a call to a realloc function, return the reallocated operand.
77
Value *getReallocatedOperand(const CallBase *CB);
78
 
79
//===----------------------------------------------------------------------===//
80
//  free Call Utility Functions.
81
//
82
 
83
/// isLibFreeFunction - Returns true if the function is a builtin free()
84
bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
85
 
86
/// If this if a call to a free function, return the freed operand.
87
Value *getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI);
88
 
89
//===----------------------------------------------------------------------===//
90
//  Properties of allocation functions
91
//
92
 
93
/// Return true if this is a call to an allocation function that does not have
94
/// side effects that we are required to preserve beyond the effect of
95
/// allocating a new object.
96
/// Ex: If our allocation routine has a counter for the number of objects
97
/// allocated, and the program prints it on exit, can the value change due
98
/// to optimization? Answer is highly language dependent.
99
/// Note: *Removable* really does mean removable; it does not mean observable.
100
/// A language (e.g. C++) can allow removing allocations without allowing
101
/// insertion or speculative execution of allocation routines.
102
bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI);
103
 
104
/// Gets the alignment argument for an aligned_alloc-like function, using either
105
/// built-in knowledge based on fuction names/signatures or allocalign
106
/// attributes. Note: the Value returned may not indicate a valid alignment, per
107
/// the definition of the allocalign attribute.
108
Value *getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI);
109
 
110
/// Return the size of the requested allocation. With a trivial mapper, this is
111
/// similar to calling getObjectSize(..., Exact), but without looking through
112
/// calls that return their argument. A mapper function can be used to replace
113
/// one Value* (operand to the allocation) with another. This is useful when
114
/// doing abstract interpretation.
115
std::optional<APInt> getAllocSize(
116
    const CallBase *CB, const TargetLibraryInfo *TLI,
117
    function_ref<const Value *(const Value *)> Mapper = [](const Value *V) {
118
      return V;
119
    });
120
 
121
/// If this is a call to an allocation function that initializes memory to a
122
/// fixed value, return said value in the requested type.  Otherwise, return
123
/// nullptr.
124
Constant *getInitialValueOfAllocation(const Value *V,
125
                                      const TargetLibraryInfo *TLI,
126
                                      Type *Ty);
127
 
128
/// If a function is part of an allocation family (e.g.
129
/// malloc/realloc/calloc/free), return the identifier for its family
130
/// of functions.
131
std::optional<StringRef> getAllocationFamily(const Value *I,
132
                                             const TargetLibraryInfo *TLI);
133
 
134
//===----------------------------------------------------------------------===//
135
//  Utility functions to compute size of objects.
136
//
137
 
138
/// Various options to control the behavior of getObjectSize.
139
struct ObjectSizeOpts {
140
  /// Controls how we handle conditional statements with unknown conditions.
141
  enum class Mode : uint8_t {
142
    /// All branches must be known and have the same size, starting from the
143
    /// offset, to be merged.
144
    ExactSizeFromOffset,
145
    /// All branches must be known and have the same underlying size and offset
146
    /// to be merged.
147
    ExactUnderlyingSizeAndOffset,
148
    /// Evaluate all branches of an unknown condition. If all evaluations
149
    /// succeed, pick the minimum size.
150
    Min,
151
    /// Same as Min, except we pick the maximum size of all of the branches.
152
    Max,
153
  };
154
 
155
  /// How we want to evaluate this object's size.
156
  Mode EvalMode = Mode::ExactSizeFromOffset;
157
  /// Whether to round the result up to the alignment of allocas, byval
158
  /// arguments, and global variables.
159
  bool RoundToAlign = false;
160
  /// If this is true, null pointers in address space 0 will be treated as
161
  /// though they can't be evaluated. Otherwise, null is always considered to
162
  /// point to a 0 byte region of memory.
163
  bool NullIsUnknownSize = false;
164
  /// If set, used for more accurate evaluation
165
  AAResults *AA = nullptr;
166
};
167
 
168
/// Compute the size of the object pointed by Ptr. Returns true and the
169
/// object size in Size if successful, and false otherwise. In this context, by
170
/// object we mean the region of memory starting at Ptr to the end of the
171
/// underlying object pointed to by Ptr.
172
///
173
/// WARNING: The object size returned is the allocation size.  This does not
174
/// imply dereferenceability at site of use since the object may be freeed in
175
/// between.
176
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
177
                   const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {});
178
 
179
/// Try to turn a call to \@llvm.objectsize into an integer value of the given
180
/// Type. Returns null on failure. If MustSucceed is true, this function will
181
/// not return null, and may return conservative values governed by the second
182
/// argument of the call to objectsize.
183
Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL,
184
                           const TargetLibraryInfo *TLI, bool MustSucceed);
185
Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL,
186
                           const TargetLibraryInfo *TLI, AAResults *AA,
187
                           bool MustSucceed);
188
 
189
using SizeOffsetType = std::pair<APInt, APInt>;
190
 
191
/// Evaluate the size and offset of an object pointed to by a Value*
192
/// statically. Fails if size or offset are not known at compile time.
193
class ObjectSizeOffsetVisitor
194
  : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
195
  const DataLayout &DL;
196
  const TargetLibraryInfo *TLI;
197
  ObjectSizeOpts Options;
198
  unsigned IntTyBits;
199
  APInt Zero;
200
  SmallPtrSet<Instruction *, 8> SeenInsts;
201
 
202
  APInt align(APInt Size, MaybeAlign Align);
203
 
204
  SizeOffsetType unknown() {
205
    return std::make_pair(APInt(), APInt());
206
  }
207
 
208
public:
209
  ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI,
210
                          LLVMContext &Context, ObjectSizeOpts Options = {});
211
 
212
  SizeOffsetType compute(Value *V);
213
 
214
  static bool knownSize(const SizeOffsetType &SizeOffset) {
215
    return SizeOffset.first.getBitWidth() > 1;
216
  }
217
 
218
  static bool knownOffset(const SizeOffsetType &SizeOffset) {
219
    return SizeOffset.second.getBitWidth() > 1;
220
  }
221
 
222
  static bool bothKnown(const SizeOffsetType &SizeOffset) {
223
    return knownSize(SizeOffset) && knownOffset(SizeOffset);
224
  }
225
 
226
  // These are "private", except they can't actually be made private. Only
227
  // compute() should be used by external users.
228
  SizeOffsetType visitAllocaInst(AllocaInst &I);
229
  SizeOffsetType visitArgument(Argument &A);
230
  SizeOffsetType visitCallBase(CallBase &CB);
231
  SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
232
  SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
233
  SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
234
  SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
235
  SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
236
  SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
237
  SizeOffsetType visitLoadInst(LoadInst &I);
238
  SizeOffsetType visitPHINode(PHINode&);
239
  SizeOffsetType visitSelectInst(SelectInst &I);
240
  SizeOffsetType visitUndefValue(UndefValue&);
241
  SizeOffsetType visitInstruction(Instruction &I);
242
 
243
private:
244
  SizeOffsetType findLoadSizeOffset(
245
      LoadInst &LoadFrom, BasicBlock &BB, BasicBlock::iterator From,
246
      SmallDenseMap<BasicBlock *, SizeOffsetType, 8> &VisitedBlocks,
247
      unsigned &ScannedInstCount);
248
  SizeOffsetType combineSizeOffset(SizeOffsetType LHS, SizeOffsetType RHS);
249
  SizeOffsetType computeImpl(Value *V);
250
  bool CheckedZextOrTrunc(APInt &I);
251
};
252
 
253
using SizeOffsetEvalType = std::pair<Value *, Value *>;
254
 
255
/// Evaluate the size and offset of an object pointed to by a Value*.
256
/// May create code to compute the result at run-time.
257
class ObjectSizeOffsetEvaluator
258
  : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
259
  using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
260
  using WeakEvalType = std::pair<WeakTrackingVH, WeakTrackingVH>;
261
  using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
262
  using PtrSetTy = SmallPtrSet<const Value *, 8>;
263
 
264
  const DataLayout &DL;
265
  const TargetLibraryInfo *TLI;
266
  LLVMContext &Context;
267
  BuilderTy Builder;
268
  IntegerType *IntTy;
269
  Value *Zero;
270
  CacheMapTy CacheMap;
271
  PtrSetTy SeenVals;
272
  ObjectSizeOpts EvalOpts;
273
  SmallPtrSet<Instruction *, 8> InsertedInstructions;
274
 
275
  SizeOffsetEvalType compute_(Value *V);
276
 
277
public:
278
  static SizeOffsetEvalType unknown() {
279
    return std::make_pair(nullptr, nullptr);
280
  }
281
 
282
  ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
283
                            LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
284
 
285
  SizeOffsetEvalType compute(Value *V);
286
 
287
  bool knownSize(SizeOffsetEvalType SizeOffset) {
288
    return SizeOffset.first;
289
  }
290
 
291
  bool knownOffset(SizeOffsetEvalType SizeOffset) {
292
    return SizeOffset.second;
293
  }
294
 
295
  bool anyKnown(SizeOffsetEvalType SizeOffset) {
296
    return knownSize(SizeOffset) || knownOffset(SizeOffset);
297
  }
298
 
299
  bool bothKnown(SizeOffsetEvalType SizeOffset) {
300
    return knownSize(SizeOffset) && knownOffset(SizeOffset);
301
  }
302
 
303
  // The individual instruction visitors should be treated as private.
304
  SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
305
  SizeOffsetEvalType visitCallBase(CallBase &CB);
306
  SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
307
  SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
308
  SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
309
  SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
310
  SizeOffsetEvalType visitLoadInst(LoadInst &I);
311
  SizeOffsetEvalType visitPHINode(PHINode &PHI);
312
  SizeOffsetEvalType visitSelectInst(SelectInst &I);
313
  SizeOffsetEvalType visitInstruction(Instruction &I);
314
};
315
 
316
} // end namespace llvm
317
 
318
#endif // LLVM_ANALYSIS_MEMORYBUILTINS_H