blob: 49f9e58ffad78b705300f2b8ef8148a32bf3fd8d [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//==- llvm/Analysis/MemoryBuiltins.h - Calls to memory builtins --*- C++ -*-==//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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"
Andrew Walbran3d2c1972020-04-07 12:24:26 +010021#include "llvm/Analysis/TargetLibraryInfo.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#include "llvm/IR/CallSite.h"
23#include "llvm/IR/IRBuilder.h"
24#include "llvm/IR/InstVisitor.h"
25#include "llvm/IR/ValueHandle.h"
26#include <cstdint>
27#include <utility>
28
29namespace llvm {
30
31class AllocaInst;
32class Argument;
33class CallInst;
34class ConstantInt;
35class ConstantPointerNull;
36class DataLayout;
37class ExtractElementInst;
38class ExtractValueInst;
39class GEPOperator;
40class GlobalAlias;
41class GlobalVariable;
42class Instruction;
43class IntegerType;
44class IntrinsicInst;
45class IntToPtrInst;
46class LLVMContext;
47class LoadInst;
48class PHINode;
49class PointerType;
50class SelectInst;
51class TargetLibraryInfo;
52class Type;
53class UndefValue;
54class Value;
55
Andrew Scullcdfcccc2018-10-05 20:58:37 +010056/// Tests if a value is a call or invoke to a library function that
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010057/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
58/// like).
59bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
60 bool LookThroughBitCast = false);
61
Andrew Scullcdfcccc2018-10-05 20:58:37 +010062/// Tests if a value is a call or invoke to a function that returns a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
64bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
65 bool LookThroughBitCast = false);
66
Andrew Scullcdfcccc2018-10-05 20:58:37 +010067/// Tests if a value is a call or invoke to a library function that
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010068/// allocates uninitialized memory (such as malloc).
69bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
70 bool LookThroughBitCast = false);
71
Andrew Scullcdfcccc2018-10-05 20:58:37 +010072/// Tests if a value is a call or invoke to a library function that
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010073/// allocates zero-filled memory (such as calloc).
74bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
75 bool LookThroughBitCast = false);
76
Andrew Scullcdfcccc2018-10-05 20:58:37 +010077/// Tests if a value is a call or invoke to a library function that
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010078/// allocates memory similar to malloc or calloc.
79bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
80 bool LookThroughBitCast = false);
81
Andrew Scullcdfcccc2018-10-05 20:58:37 +010082/// Tests if a value is a call or invoke to a library function that
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083/// allocates memory (either malloc, calloc, or strdup like).
84bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
85 bool LookThroughBitCast = false);
86
Andrew Walbran3d2c1972020-04-07 12:24:26 +010087/// Tests if a value is a call or invoke to a library function that
88/// reallocates memory (e.g., realloc).
89bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
90 bool LookThroughBitCast = false);
91
92/// Tests if a function is a call or invoke to a library function that
93/// reallocates memory (e.g., realloc).
94bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI);
95
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010096//===----------------------------------------------------------------------===//
97// malloc Call Utility Functions.
98//
99
100/// extractMallocCall - Returns the corresponding CallInst if the instruction
101/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
102/// ignore InvokeInst here.
103const CallInst *extractMallocCall(const Value *I, const TargetLibraryInfo *TLI);
104inline CallInst *extractMallocCall(Value *I, const TargetLibraryInfo *TLI) {
105 return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
106}
107
108/// getMallocType - Returns the PointerType resulting from the malloc call.
109/// The PointerType depends on the number of bitcast uses of the malloc call:
110/// 0: PointerType is the malloc calls' return type.
111/// 1: PointerType is the bitcast's result type.
112/// >1: Unique PointerType cannot be determined, return NULL.
113PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI);
114
115/// getMallocAllocatedType - Returns the Type allocated by malloc call.
116/// The Type depends on the number of bitcast uses of the malloc call:
117/// 0: PointerType is the malloc calls' return type.
118/// 1: PointerType is the bitcast's result type.
119/// >1: Unique PointerType cannot be determined, return NULL.
120Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
121
122/// getMallocArraySize - Returns the array size of a malloc call. If the
123/// argument passed to malloc is a multiple of the size of the malloced type,
124/// then return that multiple. For non-array mallocs, the multiple is
125/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
126/// determined.
127Value *getMallocArraySize(CallInst *CI, const DataLayout &DL,
128 const TargetLibraryInfo *TLI,
129 bool LookThroughSExt = false);
130
131//===----------------------------------------------------------------------===//
132// calloc Call Utility Functions.
133//
134
135/// extractCallocCall - Returns the corresponding CallInst if the instruction
136/// is a calloc call.
137const CallInst *extractCallocCall(const Value *I, const TargetLibraryInfo *TLI);
138inline CallInst *extractCallocCall(Value *I, const TargetLibraryInfo *TLI) {
139 return const_cast<CallInst*>(extractCallocCall((const Value*)I, TLI));
140}
141
142
143//===----------------------------------------------------------------------===//
144// free Call Utility Functions.
145//
146
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100147/// isLibFreeFunction - Returns true if the function is a builtin free()
148bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
149
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100150/// isFreeCall - Returns non-null if the value is a call to the builtin free()
151const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
152
153inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
154 return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
155}
156
157//===----------------------------------------------------------------------===//
158// Utility functions to compute size of objects.
159//
160
161/// Various options to control the behavior of getObjectSize.
162struct ObjectSizeOpts {
163 /// Controls how we handle conditional statements with unknown conditions.
164 enum class Mode : uint8_t {
165 /// Fail to evaluate an unknown condition.
166 Exact,
167 /// Evaluate all branches of an unknown condition. If all evaluations
168 /// succeed, pick the minimum size.
169 Min,
170 /// Same as Min, except we pick the maximum size of all of the branches.
171 Max
172 };
173
174 /// How we want to evaluate this object's size.
175 Mode EvalMode = Mode::Exact;
176 /// Whether to round the result up to the alignment of allocas, byval
177 /// arguments, and global variables.
178 bool RoundToAlign = false;
179 /// If this is true, null pointers in address space 0 will be treated as
180 /// though they can't be evaluated. Otherwise, null is always considered to
181 /// point to a 0 byte region of memory.
182 bool NullIsUnknownSize = false;
183};
184
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100185/// Compute the size of the object pointed by Ptr. Returns true and the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100186/// object size in Size if successful, and false otherwise. In this context, by
187/// object we mean the region of memory starting at Ptr to the end of the
188/// underlying object pointed to by Ptr.
189bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
190 const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {});
191
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100192/// Try to turn a call to \@llvm.objectsize into an integer value of the given
Andrew Walbran16937d02019-10-22 13:54:20 +0100193/// Type. Returns null on failure. If MustSucceed is true, this function will
194/// not return null, and may return conservative values governed by the second
195/// argument of the call to objectsize.
196Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL,
197 const TargetLibraryInfo *TLI, bool MustSucceed);
198
199
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100200
201using SizeOffsetType = std::pair<APInt, APInt>;
202
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100203/// Evaluate the size and offset of an object pointed to by a Value*
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100204/// statically. Fails if size or offset are not known at compile time.
205class ObjectSizeOffsetVisitor
206 : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
207 const DataLayout &DL;
208 const TargetLibraryInfo *TLI;
209 ObjectSizeOpts Options;
210 unsigned IntTyBits;
211 APInt Zero;
212 SmallPtrSet<Instruction *, 8> SeenInsts;
213
214 APInt align(APInt Size, uint64_t Align);
215
216 SizeOffsetType unknown() {
217 return std::make_pair(APInt(), APInt());
218 }
219
220public:
221 ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI,
222 LLVMContext &Context, ObjectSizeOpts Options = {});
223
224 SizeOffsetType compute(Value *V);
225
226 static bool knownSize(const SizeOffsetType &SizeOffset) {
227 return SizeOffset.first.getBitWidth() > 1;
228 }
229
230 static bool knownOffset(const SizeOffsetType &SizeOffset) {
231 return SizeOffset.second.getBitWidth() > 1;
232 }
233
234 static bool bothKnown(const SizeOffsetType &SizeOffset) {
235 return knownSize(SizeOffset) && knownOffset(SizeOffset);
236 }
237
238 // These are "private", except they can't actually be made private. Only
239 // compute() should be used by external users.
240 SizeOffsetType visitAllocaInst(AllocaInst &I);
241 SizeOffsetType visitArgument(Argument &A);
242 SizeOffsetType visitCallSite(CallSite CS);
243 SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
244 SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
245 SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
246 SizeOffsetType visitGEPOperator(GEPOperator &GEP);
247 SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
248 SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
249 SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
250 SizeOffsetType visitLoadInst(LoadInst &I);
251 SizeOffsetType visitPHINode(PHINode&);
252 SizeOffsetType visitSelectInst(SelectInst &I);
253 SizeOffsetType visitUndefValue(UndefValue&);
254 SizeOffsetType visitInstruction(Instruction &I);
255
256private:
257 bool CheckedZextOrTrunc(APInt &I);
258};
259
260using SizeOffsetEvalType = std::pair<Value *, Value *>;
261
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100262/// Evaluate the size and offset of an object pointed to by a Value*.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100263/// May create code to compute the result at run-time.
264class ObjectSizeOffsetEvaluator
265 : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100266 using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100267 using WeakEvalType = std::pair<WeakTrackingVH, WeakTrackingVH>;
268 using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
269 using PtrSetTy = SmallPtrSet<const Value *, 8>;
270
271 const DataLayout &DL;
272 const TargetLibraryInfo *TLI;
273 LLVMContext &Context;
274 BuilderTy Builder;
275 IntegerType *IntTy;
276 Value *Zero;
277 CacheMapTy CacheMap;
278 PtrSetTy SeenVals;
Andrew Walbran16937d02019-10-22 13:54:20 +0100279 ObjectSizeOpts EvalOpts;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100280 SmallPtrSet<Instruction *, 8> InsertedInstructions;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100281
282 SizeOffsetEvalType compute_(Value *V);
283
284public:
Andrew Walbran16937d02019-10-22 13:54:20 +0100285 static SizeOffsetEvalType unknown() {
286 return std::make_pair(nullptr, nullptr);
287 }
288
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100289 ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
Andrew Walbran16937d02019-10-22 13:54:20 +0100290 LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100291
292 SizeOffsetEvalType compute(Value *V);
293
294 bool knownSize(SizeOffsetEvalType SizeOffset) {
295 return SizeOffset.first;
296 }
297
298 bool knownOffset(SizeOffsetEvalType SizeOffset) {
299 return SizeOffset.second;
300 }
301
302 bool anyKnown(SizeOffsetEvalType SizeOffset) {
303 return knownSize(SizeOffset) || knownOffset(SizeOffset);
304 }
305
306 bool bothKnown(SizeOffsetEvalType SizeOffset) {
307 return knownSize(SizeOffset) && knownOffset(SizeOffset);
308 }
309
310 // The individual instruction visitors should be treated as private.
311 SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
312 SizeOffsetEvalType visitCallSite(CallSite CS);
313 SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
314 SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
315 SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
316 SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
317 SizeOffsetEvalType visitLoadInst(LoadInst &I);
318 SizeOffsetEvalType visitPHINode(PHINode &PHI);
319 SizeOffsetEvalType visitSelectInst(SelectInst &I);
320 SizeOffsetEvalType visitInstruction(Instruction &I);
321};
322
323} // end namespace llvm
324
325#endif // LLVM_ANALYSIS_MEMORYBUILTINS_H