Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
MemoryBuiltins.cpp
Go to the documentation of this file.
1//===- MemoryBuiltins.cpp - Identify calls to memory builtins -------------===//
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#include "llvm/Analysis/MemoryBuiltins.h"
15#include "llvm/ADT/APInt.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/Statistic.h"
18#include "llvm/Analysis/AliasAnalysis.h"
19#include "llvm/Analysis/TargetFolder.h"
20#include "llvm/Analysis/TargetLibraryInfo.h"
21#include "llvm/Analysis/Utils/Local.h"
22#include "llvm/Analysis/ValueTracking.h"
23#include "llvm/IR/Argument.h"
24#include "llvm/IR/Attributes.h"
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/DerivedTypes.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/GlobalAlias.h"
30#include "llvm/IR/GlobalVariable.h"
31#include "llvm/IR/Instruction.h"
32#include "llvm/IR/Instructions.h"
33#include "llvm/IR/IntrinsicInst.h"
34#include "llvm/IR/Operator.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/Value.h"
37#include "llvm/Support/Casting.h"
38#include "llvm/Support/CommandLine.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/MathExtras.h"
41#include "llvm/Support/raw_ostream.h"
42#include <cassert>
43#include <cstdint>
44#include <iterator>
45#include <numeric>
46#include <optional>
47#include <utility>
48
49using namespacellvm;
50
51#define DEBUG_TYPE "memory-builtins"
52
53staticcl::opt<unsigned>ObjectSizeOffsetVisitorMaxVisitInstructions(
54"object-size-offset-visitor-max-visit-instructions",
55cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to "
56"look at"),
57cl::init(100));
58
59enumAllocType :uint8_t {
60OpNewLike = 1<<0,// allocates; never returns null
61MallocLike = 1<<1,// allocates; may return null
62StrDupLike = 1<<2,
63MallocOrOpNewLike =MallocLike |OpNewLike,
64AllocLike =MallocOrOpNewLike |StrDupLike,
65AnyAlloc =AllocLike
66};
67
68enum classMallocFamily {
69Malloc,
70CPPNew,// new(unsigned int)
71CPPNewAligned,// new(unsigned int, align_val_t)
72CPPNewArray,// new[](unsigned int)
73CPPNewArrayAligned,// new[](unsigned long, align_val_t)
74MSVCNew,// new(unsigned int)
75MSVCArrayNew,// new[](unsigned int)
76VecMalloc,
77KmpcAllocShared,
78};
79
80StringRefmangledNameForMallocFamily(constMallocFamily &Family) {
81switch (Family) {
82caseMallocFamily::Malloc:
83return"malloc";
84caseMallocFamily::CPPNew:
85return"_Znwm";
86caseMallocFamily::CPPNewAligned:
87return"_ZnwmSt11align_val_t";
88caseMallocFamily::CPPNewArray:
89return"_Znam";
90caseMallocFamily::CPPNewArrayAligned:
91return"_ZnamSt11align_val_t";
92caseMallocFamily::MSVCNew:
93return"??2@YAPAXI@Z";
94caseMallocFamily::MSVCArrayNew:
95return"??_U@YAPAXI@Z";
96caseMallocFamily::VecMalloc:
97return"vec_malloc";
98caseMallocFamily::KmpcAllocShared:
99return"__kmpc_alloc_shared";
100 }
101llvm_unreachable("missing an alloc family");
102}
103
104structAllocFnsTy {
105AllocTypeAllocTy;
106unsignedNumParams;
107// First and Second size parameters (or -1 if unused)
108intFstParam,SndParam;
109// Alignment parameter for aligned_alloc and aligned new
110intAlignParam;
111// Name of default allocator function to group malloc/free calls by family
112MallocFamilyFamily;
113};
114
115// clang-format off
116// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
117// know which functions are nounwind, noalias, nocapture parameters, etc.
118staticconst std::pair<LibFunc, AllocFnsTy>AllocationFnData[] = {
119 {LibFunc_Znwj, {OpNewLike, 1, 0, -1, -1,MallocFamily::CPPNew}},// new(unsigned int)
120 {LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1,MallocFamily::CPPNew}},// new(unsigned int, nothrow)
121 {LibFunc_ZnwjSt11align_val_t, {OpNewLike, 2, 0, -1, 1,MallocFamily::CPPNewAligned}},// new(unsigned int, align_val_t)
122 {LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1,MallocFamily::CPPNewAligned}},// new(unsigned int, align_val_t, nothrow)
123 {LibFunc_Znwm, {OpNewLike, 1, 0, -1, -1,MallocFamily::CPPNew}},// new(unsigned long)
124 {LibFunc_Znwm12__hot_cold_t, {OpNewLike, 2, 0, -1, -1,MallocFamily::CPPNew}},// new(unsigned long, __hot_cold_t)
125 {LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1,MallocFamily::CPPNew}},// new(unsigned long, nothrow)
126 {LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, {MallocLike, 3, 0, -1, -1,MallocFamily::CPPNew}},// new(unsigned long, nothrow, __hot_cold_t)
127 {LibFunc_ZnwmSt11align_val_t, {OpNewLike, 2, 0, -1, 1,MallocFamily::CPPNewAligned}},// new(unsigned long, align_val_t)
128 {LibFunc_ZnwmSt11align_val_t12__hot_cold_t, {OpNewLike, 3, 0, -1, 1,MallocFamily::CPPNewAligned}},// new(unsigned long, align_val_t, __hot_cold_t)
129 {LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1,MallocFamily::CPPNewAligned}},// new(unsigned long, align_val_t, nothrow)
130 {LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, {MallocLike, 4, 0, -1, 1,MallocFamily::CPPNewAligned}},// new(unsigned long, align_val_t, nothrow, __hot_cold_t)
131 {LibFunc_Znaj, {OpNewLike, 1, 0, -1, -1,MallocFamily::CPPNewArray}},// new[](unsigned int)
132 {LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1,MallocFamily::CPPNewArray}},// new[](unsigned int, nothrow)
133 {LibFunc_ZnajSt11align_val_t, {OpNewLike, 2, 0, -1, 1,MallocFamily::CPPNewArrayAligned}},// new[](unsigned int, align_val_t)
134 {LibFunc_ZnajSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1,MallocFamily::CPPNewArrayAligned}},// new[](unsigned int, align_val_t, nothrow)
135 {LibFunc_Znam, {OpNewLike, 1, 0, -1, -1,MallocFamily::CPPNewArray}},// new[](unsigned long)
136 {LibFunc_Znam12__hot_cold_t, {OpNewLike, 2, 0, -1, -1,MallocFamily::CPPNew}},// new[](unsigned long, __hot_cold_t)
137 {LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1, -1,MallocFamily::CPPNewArray}},// new[](unsigned long, nothrow)
138 {LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, {MallocLike, 3, 0, -1, -1,MallocFamily::CPPNew}},// new[](unsigned long, nothrow, __hot_cold_t)
139 {LibFunc_ZnamSt11align_val_t, {OpNewLike, 2, 0, -1, 1,MallocFamily::CPPNewArrayAligned}},// new[](unsigned long, align_val_t)
140 {LibFunc_ZnamSt11align_val_t12__hot_cold_t, {OpNewLike, 3, 0, -1, 1,MallocFamily::CPPNewAligned}},// new[](unsigned long, align_val_t, __hot_cold_t)
141 {LibFunc_ZnamSt11align_val_tRKSt9nothrow_t, {MallocLike, 3, 0, -1, 1,MallocFamily::CPPNewArrayAligned}},// new[](unsigned long, align_val_t, nothrow)
142 {LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, {MallocLike, 4, 0, -1, 1,MallocFamily::CPPNewAligned}},// new[](unsigned long, align_val_t, nothrow, __hot_cold_t)
143 {LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1, -1,MallocFamily::MSVCNew}},// new(unsigned int)
144 {LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1, -1,MallocFamily::MSVCNew}},// new(unsigned int, nothrow)
145 {LibFunc_msvc_new_longlong, {OpNewLike, 1, 0, -1, -1,MallocFamily::MSVCNew}},// new(unsigned long long)
146 {LibFunc_msvc_new_longlong_nothrow, {MallocLike, 2, 0, -1, -1,MallocFamily::MSVCNew}},// new(unsigned long long, nothrow)
147 {LibFunc_msvc_new_array_int, {OpNewLike, 1, 0, -1, -1,MallocFamily::MSVCArrayNew}},// new[](unsigned int)
148 {LibFunc_msvc_new_array_int_nothrow, {MallocLike, 2, 0, -1, -1,MallocFamily::MSVCArrayNew}},// new[](unsigned int, nothrow)
149 {LibFunc_msvc_new_array_longlong, {OpNewLike, 1, 0, -1, -1,MallocFamily::MSVCArrayNew}},// new[](unsigned long long)
150 {LibFunc_msvc_new_array_longlong_nothrow, {MallocLike, 2, 0, -1, -1,MallocFamily::MSVCArrayNew}},// new[](unsigned long long, nothrow)
151 {LibFunc_strdup, {StrDupLike, 1, -1, -1, -1,MallocFamily::Malloc}},
152 {LibFunc_dunder_strdup, {StrDupLike, 1, -1, -1, -1,MallocFamily::Malloc}},
153 {LibFunc_strndup, {StrDupLike, 2, 1, -1, -1,MallocFamily::Malloc}},
154 {LibFunc_dunder_strndup, {StrDupLike, 2, 1, -1, -1,MallocFamily::Malloc}},
155 {LibFunc___kmpc_alloc_shared, {MallocLike, 1, 0, -1, -1,MallocFamily::KmpcAllocShared}},
156};
157// clang-format on
158
159staticconstFunction *getCalledFunction(constValue *V) {
160// Don't care about intrinsics in this case.
161if (isa<IntrinsicInst>(V))
162returnnullptr;
163
164constauto *CB = dyn_cast<CallBase>(V);
165if (!CB)
166returnnullptr;
167
168if (CB->isNoBuiltin())
169returnnullptr;
170
171return CB->getCalledFunction();
172}
173
174/// Returns the allocation data for the given value if it's a call to a known
175/// allocation function.
176static std::optional<AllocFnsTy>
177getAllocationDataForFunction(constFunction *Callee,AllocType AllocTy,
178constTargetLibraryInfo *TLI) {
179// Don't perform a slow TLI lookup, if this function doesn't return a pointer
180// and thus can't be an allocation function.
181if (!Callee->getReturnType()->isPointerTy())
182return std::nullopt;
183
184// Make sure that the function is available.
185LibFunc TLIFn;
186if (!TLI || !TLI->getLibFunc(*Callee, TLIFn) || !TLI->has(TLIFn))
187return std::nullopt;
188
189constauto *Iter =find_if(
190AllocationFnData, [TLIFn](const std::pair<LibFunc, AllocFnsTy> &P) {
191returnP.first == TLIFn;
192 });
193
194if (Iter == std::end(AllocationFnData))
195return std::nullopt;
196
197constAllocFnsTy *FnData = &Iter->second;
198if ((FnData->AllocTy & AllocTy) != FnData->AllocTy)
199return std::nullopt;
200
201// Check function prototype.
202int FstParam = FnData->FstParam;
203int SndParam = FnData->SndParam;
204FunctionType *FTy = Callee->getFunctionType();
205
206if (FTy->getReturnType()->isPointerTy() &&
207 FTy->getNumParams() == FnData->NumParams &&
208 (FstParam < 0 ||
209 (FTy->getParamType(FstParam)->isIntegerTy(32) ||
210 FTy->getParamType(FstParam)->isIntegerTy(64))) &&
211 (SndParam < 0 ||
212 FTy->getParamType(SndParam)->isIntegerTy(32) ||
213 FTy->getParamType(SndParam)->isIntegerTy(64)))
214return *FnData;
215return std::nullopt;
216}
217
218static std::optional<AllocFnsTy>
219getAllocationData(constValue *V,AllocType AllocTy,
220constTargetLibraryInfo *TLI) {
221if (constFunction *Callee =getCalledFunction(V))
222returngetAllocationDataForFunction(Callee, AllocTy, TLI);
223return std::nullopt;
224}
225
226static std::optional<AllocFnsTy>
227getAllocationData(constValue *V,AllocType AllocTy,
228function_ref<constTargetLibraryInfo &(Function &)> GetTLI) {
229if (constFunction *Callee =getCalledFunction(V))
230returngetAllocationDataForFunction(
231 Callee, AllocTy, &GetTLI(const_cast<Function &>(*Callee)));
232return std::nullopt;
233}
234
235static std::optional<AllocFnsTy>
236getAllocationSize(constCallBase *CB,constTargetLibraryInfo *TLI) {
237if (constFunction *Callee =getCalledFunction(CB)) {
238// Prefer to use existing information over allocsize. This will give us an
239// accurate AllocTy.
240if (std::optional<AllocFnsTy> Data =
241getAllocationDataForFunction(Callee,AnyAlloc, TLI))
242return Data;
243 }
244
245Attribute Attr = CB->getFnAttr(Attribute::AllocSize);
246if (Attr ==Attribute())
247return std::nullopt;
248
249 std::pair<unsigned, std::optional<unsigned>> Args = Attr.getAllocSizeArgs();
250
251AllocFnsTy Result;
252// Because allocsize only tells us how many bytes are allocated, we're not
253// really allowed to assume anything, so we use MallocLike.
254 Result.AllocTy =MallocLike;
255 Result.NumParams = CB->arg_size();
256 Result.FstParam = Args.first;
257 Result.SndParam = Args.second.value_or(-1);
258// Allocsize has no way to specify an alignment argument
259 Result.AlignParam = -1;
260return Result;
261}
262
263staticAllocFnKindgetAllocFnKind(constValue *V) {
264if (constauto *CB = dyn_cast<CallBase>(V)) {
265Attribute Attr = CB->getFnAttr(Attribute::AllocKind);
266if (Attr.isValid())
267returnAllocFnKind(Attr.getValueAsInt());
268 }
269return AllocFnKind::Unknown;
270}
271
272staticAllocFnKindgetAllocFnKind(constFunction *F) {
273returnF->getAttributes().getAllocKind();
274}
275
276staticboolcheckFnAllocKind(constValue *V,AllocFnKind Wanted) {
277return (getAllocFnKind(V) & Wanted) != AllocFnKind::Unknown;
278}
279
280staticboolcheckFnAllocKind(constFunction *F,AllocFnKind Wanted) {
281return (getAllocFnKind(F) & Wanted) != AllocFnKind::Unknown;
282}
283
284/// Tests if a value is a call or invoke to a library function that
285/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
286/// like).
287boolllvm::isAllocationFn(constValue *V,constTargetLibraryInfo *TLI) {
288returngetAllocationData(V,AnyAlloc, TLI).has_value() ||
289checkFnAllocKind(V, AllocFnKind::Alloc | AllocFnKind::Realloc);
290}
291boolllvm::isAllocationFn(
292constValue *V,
293function_ref<constTargetLibraryInfo &(Function &)> GetTLI) {
294returngetAllocationData(V,AnyAlloc, GetTLI).has_value() ||
295checkFnAllocKind(V, AllocFnKind::Alloc | AllocFnKind::Realloc);
296}
297
298/// Tests if a value is a call or invoke to a library function that
299/// allocates memory via new.
300boolllvm::isNewLikeFn(constValue *V,constTargetLibraryInfo *TLI) {
301returngetAllocationData(V,OpNewLike, TLI).has_value();
302}
303
304/// Tests if a value is a call or invoke to a library function that
305/// allocates memory similar to malloc or calloc.
306boolllvm::isMallocOrCallocLikeFn(constValue *V,constTargetLibraryInfo *TLI) {
307// TODO: Function behavior does not match name.
308returngetAllocationData(V,MallocOrOpNewLike, TLI).has_value();
309}
310
311/// Tests if a value is a call or invoke to a library function that
312/// allocates memory (either malloc, calloc, or strdup like).
313boolllvm::isAllocLikeFn(constValue *V,constTargetLibraryInfo *TLI) {
314returngetAllocationData(V,AllocLike, TLI).has_value() ||
315checkFnAllocKind(V, AllocFnKind::Alloc);
316}
317
318/// Tests if a functions is a call or invoke to a library function that
319/// reallocates memory (e.g., realloc).
320boolllvm::isReallocLikeFn(constFunction *F) {
321returncheckFnAllocKind(F, AllocFnKind::Realloc);
322}
323
324Value *llvm::getReallocatedOperand(constCallBase *CB) {
325if (checkFnAllocKind(CB, AllocFnKind::Realloc))
326return CB->getArgOperandWithAttribute(Attribute::AllocatedPointer);
327returnnullptr;
328}
329
330boolllvm::isRemovableAlloc(constCallBase *CB,constTargetLibraryInfo *TLI) {
331// Note: Removability is highly dependent on the source language. For
332// example, recent C++ requires direct calls to the global allocation
333// [basic.stc.dynamic.allocation] to be observable unless part of a new
334// expression [expr.new paragraph 13].
335
336// Historically we've treated the C family allocation routines and operator
337// new as removable
338returnisAllocLikeFn(CB, TLI);
339}
340
341Value *llvm::getAllocAlignment(constCallBase *V,
342constTargetLibraryInfo *TLI) {
343const std::optional<AllocFnsTy> FnData =getAllocationData(V,AnyAlloc, TLI);
344if (FnData && FnData->AlignParam >= 0) {
345return V->getOperand(FnData->AlignParam);
346 }
347return V->getArgOperandWithAttribute(Attribute::AllocAlign);
348}
349
350/// When we're compiling N-bit code, and the user uses parameters that are
351/// greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
352/// trouble with APInt size issues. This function handles resizing + overflow
353/// checks for us. Check and zext or trunc \p I depending on IntTyBits and
354/// I's value.
355staticboolCheckedZextOrTrunc(APInt &I,unsigned IntTyBits) {
356// More bits than we can handle. Checking the bit width isn't necessary, but
357// it's faster than checking active bits, and should give `false` in the
358// vast majority of cases.
359if (I.getBitWidth() > IntTyBits &&I.getActiveBits() > IntTyBits)
360returnfalse;
361if (I.getBitWidth() != IntTyBits)
362I =I.zextOrTrunc(IntTyBits);
363returntrue;
364}
365
366std::optional<APInt>
367llvm::getAllocSize(constCallBase *CB,constTargetLibraryInfo *TLI,
368function_ref<constValue *(constValue *)> Mapper) {
369// Note: This handles both explicitly listed allocation functions and
370// allocsize. The code structure could stand to be cleaned up a bit.
371 std::optional<AllocFnsTy> FnData =getAllocationSize(CB, TLI);
372if (!FnData)
373return std::nullopt;
374
375// Get the index type for this address space, results and intermediate
376// computations are performed at that width.
377auto &DL = CB->getDataLayout();
378constunsigned IntTyBits =DL.getIndexTypeSizeInBits(CB->getType());
379
380// Handle strdup-like functions separately.
381if (FnData->AllocTy ==StrDupLike) {
382APIntSize(IntTyBits,GetStringLength(Mapper(CB->getArgOperand(0))));
383if (!Size)
384return std::nullopt;
385
386// Strndup limits strlen.
387if (FnData->FstParam > 0) {
388constConstantInt *Arg =
389 dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->FstParam)));
390if (!Arg)
391return std::nullopt;
392
393APInt MaxSize = Arg->getValue().zext(IntTyBits);
394if (Size.ugt(MaxSize))
395Size = MaxSize + 1;
396 }
397returnSize;
398 }
399
400constConstantInt *Arg =
401 dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->FstParam)));
402if (!Arg)
403return std::nullopt;
404
405APIntSize = Arg->getValue();
406if (!CheckedZextOrTrunc(Size, IntTyBits))
407return std::nullopt;
408
409// Size is determined by just 1 parameter.
410if (FnData->SndParam < 0)
411returnSize;
412
413 Arg = dyn_cast<ConstantInt>(Mapper(CB->getArgOperand(FnData->SndParam)));
414if (!Arg)
415return std::nullopt;
416
417APInt NumElems = Arg->getValue();
418if (!CheckedZextOrTrunc(NumElems, IntTyBits))
419return std::nullopt;
420
421bool Overflow;
422Size =Size.umul_ov(NumElems, Overflow);
423if (Overflow)
424return std::nullopt;
425returnSize;
426}
427
428Constant *llvm::getInitialValueOfAllocation(constValue *V,
429constTargetLibraryInfo *TLI,
430Type *Ty) {
431auto *Alloc = dyn_cast<CallBase>(V);
432if (!Alloc)
433returnnullptr;
434
435// malloc are uninitialized (undef)
436if (getAllocationData(Alloc,MallocOrOpNewLike, TLI).has_value())
437returnUndefValue::get(Ty);
438
439AllocFnKind AK =getAllocFnKind(Alloc);
440if ((AK & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
441returnUndefValue::get(Ty);
442if ((AK & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
443returnConstant::getNullValue(Ty);
444
445returnnullptr;
446}
447
448structFreeFnsTy {
449unsignedNumParams;
450// Name of default allocator function to group malloc/free calls by family
451MallocFamilyFamily;
452};
453
454// clang-format off
455staticconst std::pair<LibFunc, FreeFnsTy>FreeFnData[] = {
456 {LibFunc_ZdlPv, {1,MallocFamily::CPPNew}},// operator delete(void*)
457 {LibFunc_ZdaPv, {1,MallocFamily::CPPNewArray}},// operator delete[](void*)
458 {LibFunc_msvc_delete_ptr32, {1,MallocFamily::MSVCNew}},// operator delete(void*)
459 {LibFunc_msvc_delete_ptr64, {1,MallocFamily::MSVCNew}},// operator delete(void*)
460 {LibFunc_msvc_delete_array_ptr32, {1,MallocFamily::MSVCArrayNew}},// operator delete[](void*)
461 {LibFunc_msvc_delete_array_ptr64, {1,MallocFamily::MSVCArrayNew}},// operator delete[](void*)
462 {LibFunc_ZdlPvj, {2,MallocFamily::CPPNew}},// delete(void*, uint)
463 {LibFunc_ZdlPvm, {2,MallocFamily::CPPNew}},// delete(void*, ulong)
464 {LibFunc_ZdlPvRKSt9nothrow_t, {2,MallocFamily::CPPNew}},// delete(void*, nothrow)
465 {LibFunc_ZdlPvSt11align_val_t, {2,MallocFamily::CPPNewAligned}},// delete(void*, align_val_t)
466 {LibFunc_ZdaPvj, {2,MallocFamily::CPPNewArray}},// delete[](void*, uint)
467 {LibFunc_ZdaPvm, {2,MallocFamily::CPPNewArray}},// delete[](void*, ulong)
468 {LibFunc_ZdaPvRKSt9nothrow_t, {2,MallocFamily::CPPNewArray}},// delete[](void*, nothrow)
469 {LibFunc_ZdaPvSt11align_val_t, {2,MallocFamily::CPPNewArrayAligned}},// delete[](void*, align_val_t)
470 {LibFunc_msvc_delete_ptr32_int, {2,MallocFamily::MSVCNew}},// delete(void*, uint)
471 {LibFunc_msvc_delete_ptr64_longlong, {2,MallocFamily::MSVCNew}},// delete(void*, ulonglong)
472 {LibFunc_msvc_delete_ptr32_nothrow, {2,MallocFamily::MSVCNew}},// delete(void*, nothrow)
473 {LibFunc_msvc_delete_ptr64_nothrow, {2,MallocFamily::MSVCNew}},// delete(void*, nothrow)
474 {LibFunc_msvc_delete_array_ptr32_int, {2,MallocFamily::MSVCArrayNew}},// delete[](void*, uint)
475 {LibFunc_msvc_delete_array_ptr64_longlong, {2,MallocFamily::MSVCArrayNew}},// delete[](void*, ulonglong)
476 {LibFunc_msvc_delete_array_ptr32_nothrow, {2,MallocFamily::MSVCArrayNew}},// delete[](void*, nothrow)
477 {LibFunc_msvc_delete_array_ptr64_nothrow, {2,MallocFamily::MSVCArrayNew}},// delete[](void*, nothrow)
478 {LibFunc___kmpc_free_shared, {2,MallocFamily::KmpcAllocShared}},// OpenMP Offloading RTL free
479 {LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t, {3,MallocFamily::CPPNewAligned}},// delete(void*, align_val_t, nothrow)
480 {LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t, {3,MallocFamily::CPPNewArrayAligned}},// delete[](void*, align_val_t, nothrow)
481 {LibFunc_ZdlPvjSt11align_val_t, {3,MallocFamily::CPPNewAligned}},// delete(void*, unsigned int, align_val_t)
482 {LibFunc_ZdlPvmSt11align_val_t, {3,MallocFamily::CPPNewAligned}},// delete(void*, unsigned long, align_val_t)
483 {LibFunc_ZdaPvjSt11align_val_t, {3,MallocFamily::CPPNewArrayAligned}},// delete[](void*, unsigned int, align_val_t)
484 {LibFunc_ZdaPvmSt11align_val_t, {3,MallocFamily::CPPNewArrayAligned}},// delete[](void*, unsigned long, align_val_t)
485};
486// clang-format on
487
488std::optional<FreeFnsTy>getFreeFunctionDataForFunction(constFunction *Callee,
489constLibFunc TLIFn) {
490constauto *Iter =
491find_if(FreeFnData, [TLIFn](const std::pair<LibFunc, FreeFnsTy> &P) {
492returnP.first == TLIFn;
493 });
494if (Iter == std::end(FreeFnData))
495return std::nullopt;
496return Iter->second;
497}
498
499std::optional<StringRef>
500llvm::getAllocationFamily(constValue *I,constTargetLibraryInfo *TLI) {
501if (constFunction *Callee =getCalledFunction(I)) {
502LibFunc TLIFn;
503if (TLI && TLI->getLibFunc(*Callee, TLIFn) && TLI->has(TLIFn)) {
504// Callee is some known library function.
505constauto AllocData =
506getAllocationDataForFunction(Callee,AnyAlloc, TLI);
507if (AllocData)
508returnmangledNameForMallocFamily(AllocData->Family);
509constauto FreeData =getFreeFunctionDataForFunction(Callee, TLIFn);
510if (FreeData)
511returnmangledNameForMallocFamily(FreeData->Family);
512 }
513 }
514
515// Callee isn't a known library function, still check attributes.
516if (checkFnAllocKind(I, AllocFnKind::Free | AllocFnKind::Alloc |
517 AllocFnKind::Realloc)) {
518Attribute Attr = cast<CallBase>(I)->getFnAttr("alloc-family");
519if (Attr.isValid())
520return Attr.getValueAsString();
521 }
522return std::nullopt;
523}
524
525/// isLibFreeFunction - Returns true if the function is a builtin free()
526boolllvm::isLibFreeFunction(constFunction *F,constLibFunc TLIFn) {
527 std::optional<FreeFnsTy> FnData =getFreeFunctionDataForFunction(F, TLIFn);
528if (!FnData)
529returncheckFnAllocKind(F, AllocFnKind::Free);
530
531// Check free prototype.
532// FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
533// attribute will exist.
534FunctionType *FTy =F->getFunctionType();
535if (!FTy->getReturnType()->isVoidTy())
536returnfalse;
537if (FTy->getNumParams() != FnData->NumParams)
538returnfalse;
539if (!FTy->getParamType(0)->isPointerTy())
540returnfalse;
541
542returntrue;
543}
544
545Value *llvm::getFreedOperand(constCallBase *CB,constTargetLibraryInfo *TLI) {
546if (constFunction *Callee =getCalledFunction(CB)) {
547LibFunc TLIFn;
548if (TLI && TLI->getLibFunc(*Callee, TLIFn) && TLI->has(TLIFn) &&
549isLibFreeFunction(Callee, TLIFn)) {
550// All currently supported free functions free the first argument.
551return CB->getArgOperand(0);
552 }
553 }
554
555if (checkFnAllocKind(CB, AllocFnKind::Free))
556return CB->getArgOperandWithAttribute(Attribute::AllocatedPointer);
557
558returnnullptr;
559}
560
561//===----------------------------------------------------------------------===//
562// Utility functions to compute size of objects.
563//
564staticAPIntgetSizeWithOverflow(constSizeOffsetAPInt &Data) {
565APIntSize = Data.Size;
566APIntOffset = Data.Offset;
567
568if (Offset.isNegative() ||Size.ult(Offset))
569returnAPInt::getZero(Size.getBitWidth());
570
571returnSize -Offset;
572}
573
574/// Compute the size of the object pointed by Ptr. Returns true and the
575/// object size in Size if successful, and false otherwise.
576/// If RoundToAlign is true, then Size is rounded up to the alignment of
577/// allocas, byval arguments, and global variables.
578boolllvm::getObjectSize(constValue *Ptr,uint64_t &Size,constDataLayout &DL,
579constTargetLibraryInfo *TLI,ObjectSizeOpts Opts) {
580ObjectSizeOffsetVisitor Visitor(DL, TLI,Ptr->getContext(), Opts);
581SizeOffsetAPInt Data = Visitor.compute(const_cast<Value *>(Ptr));
582if (!Data.bothKnown())
583returnfalse;
584
585Size =getSizeWithOverflow(Data).getZExtValue();
586returntrue;
587}
588
589Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
590constDataLayout &DL,
591constTargetLibraryInfo *TLI,
592bool MustSucceed) {
593returnlowerObjectSizeCall(ObjectSize,DL, TLI,/*AAResults=*/nullptr,
594 MustSucceed);
595}
596
597Value *llvm::lowerObjectSizeCall(
598IntrinsicInst *ObjectSize,constDataLayout &DL,
599constTargetLibraryInfo *TLI,AAResults *AA,bool MustSucceed,
600SmallVectorImpl<Instruction *> *InsertedInstructions) {
601assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
602"ObjectSize must be a call to llvm.objectsize!");
603
604bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand(1))->isZero();
605ObjectSizeOpts EvalOptions;
606 EvalOptions.AA = AA;
607
608// Unless we have to fold this to something, try to be as accurate as
609// possible.
610if (MustSucceed)
611 EvalOptions.EvalMode =
612 MaxVal ? ObjectSizeOpts::Mode::Max : ObjectSizeOpts::Mode::Min;
613else
614 EvalOptions.EvalMode = ObjectSizeOpts::Mode::ExactSizeFromOffset;
615
616 EvalOptions.NullIsUnknownSize =
617 cast<ConstantInt>(ObjectSize->getArgOperand(2))->isOne();
618
619auto *ResultType = cast<IntegerType>(ObjectSize->getType());
620bool StaticOnly = cast<ConstantInt>(ObjectSize->getArgOperand(3))->isZero();
621if (StaticOnly) {
622// FIXME: Does it make sense to just return a failure value if the size won't
623// fit in the output and `!MustSucceed`?
624uint64_tSize;
625if (getObjectSize(ObjectSize->getArgOperand(0),Size,DL, TLI, EvalOptions) &&
626isUIntN(ResultType->getBitWidth(),Size))
627return ConstantInt::get(ResultType,Size);
628 }else {
629LLVMContext &Ctx = ObjectSize->getFunction()->getContext();
630ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, EvalOptions);
631SizeOffsetValue SizeOffsetPair = Eval.compute(ObjectSize->getArgOperand(0));
632
633if (SizeOffsetPair !=ObjectSizeOffsetEvaluator::unknown()) {
634IRBuilder<TargetFolder, IRBuilderCallbackInserter> Builder(
635 Ctx,TargetFolder(DL),IRBuilderCallbackInserter([&](Instruction *I) {
636if (InsertedInstructions)
637 InsertedInstructions->push_back(I);
638 }));
639 Builder.SetInsertPoint(ObjectSize);
640
641Value *Size = SizeOffsetPair.Size;
642Value *Offset = SizeOffsetPair.Offset;
643
644// If we've outside the end of the object, then we can always access
645// exactly 0 bytes.
646Value *ResultSize = Builder.CreateSub(Size,Offset);
647Value *UseZero = Builder.CreateICmpULT(Size,Offset);
648 ResultSize = Builder.CreateZExtOrTrunc(ResultSize, ResultType);
649Value *Ret = Builder.CreateSelect(
650 UseZero, ConstantInt::get(ResultType, 0), ResultSize);
651
652// The non-constant size expression cannot evaluate to -1.
653if (!isa<Constant>(Size) || !isa<Constant>(Offset))
654 Builder.CreateAssumption(
655 Builder.CreateICmpNE(Ret, ConstantInt::get(ResultType, -1)));
656
657return Ret;
658 }
659 }
660
661if (!MustSucceed)
662returnnullptr;
663
664return MaxVal ?Constant::getAllOnesValue(ResultType)
665 :Constant::getNullValue(ResultType);
666}
667
668STATISTIC(ObjectVisitorArgument,
669"Number of arguments with unsolved size and offset");
670STATISTIC(ObjectVisitorLoad,
671"Number of load instructions with unsolved size and offset");
672
673static std::optional<APInt>
674combinePossibleConstantValues(std::optional<APInt> LHS,
675 std::optional<APInt> RHS,
676ObjectSizeOpts::Mode EvalMode) {
677if (!LHS || !RHS)
678return std::nullopt;
679if (EvalMode == ObjectSizeOpts::Mode::Max)
680returnLHS->sge(*RHS) ? *LHS : *RHS;
681else
682returnLHS->sle(*RHS) ? *LHS : *RHS;
683}
684
685static std::optional<APInt>aggregatePossibleConstantValuesImpl(
686constValue *V,ObjectSizeOpts::Mode EvalMode,unsigned recursionDepth) {
687constexprunsigned maxRecursionDepth = 4;
688if (recursionDepth == maxRecursionDepth)
689return std::nullopt;
690
691if (constauto *CI = dyn_cast<ConstantInt>(V)) {
692return CI->getValue();
693 }elseif (constauto *SI = dyn_cast<SelectInst>(V)) {
694returncombinePossibleConstantValues(
695aggregatePossibleConstantValuesImpl(SI->getTrueValue(), EvalMode,
696 recursionDepth + 1),
697aggregatePossibleConstantValuesImpl(SI->getFalseValue(), EvalMode,
698 recursionDepth + 1),
699 EvalMode);
700 }elseif (constauto *PN = dyn_cast<PHINode>(V)) {
701unsigned Count = PN->getNumIncomingValues();
702if (Count == 0)
703return std::nullopt;
704auto Acc =aggregatePossibleConstantValuesImpl(
705 PN->getIncomingValue(0), EvalMode, recursionDepth + 1);
706for (unsignedI = 1; Acc &&I < Count; ++I) {
707auto Tmp =aggregatePossibleConstantValuesImpl(
708 PN->getIncomingValue(I), EvalMode, recursionDepth + 1);
709 Acc =combinePossibleConstantValues(Acc, Tmp, EvalMode);
710 }
711return Acc;
712 }
713
714return std::nullopt;
715}
716
717static std::optional<APInt>
718aggregatePossibleConstantValues(constValue *V,ObjectSizeOpts::Mode EvalMode) {
719if (auto *CI = dyn_cast<ConstantInt>(V))
720return CI->getValue();
721
722if (EvalMode != ObjectSizeOpts::Mode::Min &&
723 EvalMode != ObjectSizeOpts::Mode::Max)
724return std::nullopt;
725
726// Not using computeConstantRange here because we cannot guarantee it's not
727// doing optimization based on UB which we want to avoid when expanding
728// __builtin_object_size.
729returnaggregatePossibleConstantValuesImpl(V, EvalMode, 0u);
730}
731
732/// Align \p Size according to \p Alignment. If \p Size is greater than
733/// getSignedMaxValue(), set it as unknown as we can only represent signed value
734/// in OffsetSpan.
735APInt ObjectSizeOffsetVisitor::align(APIntSize,MaybeAlign Alignment) {
736if (Options.RoundToAlign && Alignment)
737Size =APInt(IntTyBits,alignTo(Size.getZExtValue(), *Alignment));
738
739returnSize.isNegative() ?APInt() :Size;
740}
741
742ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(constDataLayout &DL,
743constTargetLibraryInfo *TLI,
744LLVMContext &Context,
745ObjectSizeOptsOptions)
746 :DL(DL), TLI(TLI),Options(Options) {
747// Pointer size must be rechecked for each object visited since it could have
748// a different address space.
749}
750
751SizeOffsetAPIntObjectSizeOffsetVisitor::compute(Value *V) {
752 InstructionsVisited = 0;
753OffsetSpan Span = computeImpl(V);
754
755// In ExactSizeFromOffset mode, we don't care about the Before Field, so allow
756// us to overwrite it if needs be.
757if (Span.knownAfter() && !Span.knownBefore() &&
758 Options.EvalMode ==ObjectSizeOpts::Mode::ExactSizeFromOffset)
759 Span.Before =APInt::getZero(Span.After.getBitWidth());
760
761if (!Span.bothKnown())
762return {};
763
764return {Span.Before + Span.After, Span.Before};
765}
766
767OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
768unsigned InitialIntTyBits = DL.getIndexTypeSizeInBits(V->getType());
769
770// Stripping pointer casts can strip address space casts which can change the
771// index type size. The invariant is that we use the value type to determine
772// the index type size and if we stripped address space casts we have to
773// readjust the APInt as we pass it upwards in order for the APInt to match
774// the type the caller passed in.
775APIntOffset(InitialIntTyBits, 0);
776 V = V->stripAndAccumulateConstantOffsets(
777 DL,Offset,/* AllowNonInbounds */true,/* AllowInvariantGroup */true);
778
779// Give it another try with approximated analysis. We don't start with this
780// one because stripAndAccumulateConstantOffsets behaves differently wrt.
781// overflows if we provide an external Analysis.
782if ((Options.EvalMode ==ObjectSizeOpts::Mode::Min ||
783 Options.EvalMode ==ObjectSizeOpts::Mode::Max) &&
784 isa<GEPOperator>(V)) {
785// External Analysis used to compute the Min/Max value of individual Offsets
786// within a GEP.
787ObjectSizeOpts::Mode EvalMode =
788 Options.EvalMode ==ObjectSizeOpts::Mode::Min
789 ?ObjectSizeOpts::Mode::Max
790 :ObjectSizeOpts::Mode::Min;
791auto OffsetRangeAnalysis = [EvalMode](Value &VOffset,APInt &Offset) {
792if (auto PossibleOffset =
793aggregatePossibleConstantValues(&VOffset, EvalMode)) {
794Offset = *PossibleOffset;
795returntrue;
796 }
797returnfalse;
798 };
799
800V =V->stripAndAccumulateConstantOffsets(
801 DL,Offset,/* AllowNonInbounds */true,/* AllowInvariantGroup */true,
802/*ExternalAnalysis=*/OffsetRangeAnalysis);
803 }
804
805// Later we use the index type size and zero but it will match the type of the
806// value that is passed to computeImpl.
807 IntTyBits = DL.getIndexTypeSizeInBits(V->getType());
808 Zero =APInt::getZero(IntTyBits);
809OffsetSpan ORT = computeValue(V);
810
811bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
812if (!IndexTypeSizeChanged &&Offset.isZero())
813return ORT;
814
815// We stripped an address space cast that changed the index type size or we
816// accumulated some constant offset (or both). Readjust the bit width to match
817// the argument index type size and apply the offset, as required.
818if (IndexTypeSizeChanged) {
819if (ORT.knownBefore() &&
820 !::CheckedZextOrTrunc(ORT.Before, InitialIntTyBits))
821 ORT.Before =APInt();
822if (ORT.knownAfter() && !::CheckedZextOrTrunc(ORT.After, InitialIntTyBits))
823 ORT.After =APInt();
824 }
825// If the computed bound is "unknown" we cannot add the stripped offset.
826if (ORT.knownBefore()) {
827bool Overflow;
828 ORT.Before = ORT.Before.sadd_ov(Offset, Overflow);
829if (Overflow)
830 ORT.Before =APInt();
831 }
832if (ORT.knownAfter()) {
833bool Overflow;
834 ORT.After = ORT.After.ssub_ov(Offset, Overflow);
835if (Overflow)
836 ORT.After =APInt();
837 }
838
839// We end up pointing on a location that's outside of the original object.
840if (ORT.knownBefore() && ORT.Before.isNegative()) {
841// This means that we *may* be accessing memory before the allocation.
842// Conservatively return an unknown size.
843//
844// TODO: working with ranges instead of value would make it possible to take
845// a better decision.
846if (Options.EvalMode ==ObjectSizeOpts::Mode::Min ||
847 Options.EvalMode ==ObjectSizeOpts::Mode::Max) {
848return ObjectSizeOffsetVisitor::unknown();
849 }
850// Otherwise it's fine, caller can handle negative offset.
851 }
852return ORT;
853}
854
855OffsetSpan ObjectSizeOffsetVisitor::computeValue(Value *V) {
856if (Instruction *I = dyn_cast<Instruction>(V)) {
857// If we have already seen this instruction, bail out. Cycles can happen in
858// unreachable code after constant propagation.
859autoP = SeenInsts.try_emplace(I, ObjectSizeOffsetVisitor::unknown());
860if (!P.second)
861returnP.first->second;
862 ++InstructionsVisited;
863if (InstructionsVisited >ObjectSizeOffsetVisitorMaxVisitInstructions)
864return ObjectSizeOffsetVisitor::unknown();
865OffsetSpan Res =visit(*I);
866// Cache the result for later visits. If we happened to visit this during
867// the above recursion, we would consider it unknown until now.
868 SeenInsts[I] = Res;
869return Res;
870 }
871if (Argument *A = dyn_cast<Argument>(V))
872returnvisitArgument(*A);
873if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
874returnvisitConstantPointerNull(*P);
875if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
876returnvisitGlobalAlias(*GA);
877if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
878returnvisitGlobalVariable(*GV);
879if (UndefValue *UV = dyn_cast<UndefValue>(V))
880returnvisitUndefValue(*UV);
881
882LLVM_DEBUG(dbgs() <<"ObjectSizeOffsetVisitor::compute() unhandled value: "
883 << *V <<'\n');
884return ObjectSizeOffsetVisitor::unknown();
885}
886
887bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) {
888 return ::CheckedZextOrTrunc(I, IntTyBits);
889}
890
891OffsetSpanObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
892TypeSize ElemSize = DL.getTypeAllocSize(I.getAllocatedType());
893if (ElemSize.isScalable() && Options.EvalMode !=ObjectSizeOpts::Mode::Min)
894return ObjectSizeOffsetVisitor::unknown();
895if (!isUIntN(IntTyBits, ElemSize.getKnownMinValue()))
896return ObjectSizeOffsetVisitor::unknown();
897APIntSize(IntTyBits, ElemSize.getKnownMinValue());
898
899if (!I.isArrayAllocation())
900returnOffsetSpan(Zero, align(Size,I.getAlign()));
901
902Value *ArraySize =I.getArraySize();
903if (auto PossibleSize =
904aggregatePossibleConstantValues(ArraySize, Options.EvalMode)) {
905APInt NumElems = *PossibleSize;
906if (!CheckedZextOrTrunc(NumElems))
907return ObjectSizeOffsetVisitor::unknown();
908
909bool Overflow;
910Size =Size.umul_ov(NumElems, Overflow);
911
912return Overflow ? ObjectSizeOffsetVisitor::unknown()
913 :OffsetSpan(Zero, align(Size,I.getAlign()));
914 }
915return ObjectSizeOffsetVisitor::unknown();
916}
917
918OffsetSpanObjectSizeOffsetVisitor::visitArgument(Argument &A) {
919Type *MemoryTy =A.getPointeeInMemoryValueType();
920// No interprocedural analysis is done at the moment.
921if (!MemoryTy|| !MemoryTy->isSized()) {
922 ++ObjectVisitorArgument;
923return ObjectSizeOffsetVisitor::unknown();
924 }
925
926APIntSize(IntTyBits, DL.getTypeAllocSize(MemoryTy));
927returnOffsetSpan(Zero, align(Size,A.getParamAlign()));
928}
929
930OffsetSpanObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {
931auto Mapper = [this](constValue *V) ->constValue * {
932if (!V->getType()->isIntegerTy())
933return V;
934
935if (auto PossibleBound =
936aggregatePossibleConstantValues(V, Options.EvalMode))
937return ConstantInt::get(V->getType(), *PossibleBound);
938
939return V;
940 };
941
942if (std::optional<APInt>Size =getAllocSize(&CB, TLI, Mapper)) {
943// Very large unsigned value cannot be represented as OffsetSpan.
944if (Size->isNegative())
945return ObjectSizeOffsetVisitor::unknown();
946returnOffsetSpan(Zero, *Size);
947 }
948return ObjectSizeOffsetVisitor::unknown();
949}
950
951OffsetSpan
952ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull &CPN) {
953// If null is unknown, there's nothing we can do. Additionally, non-zero
954// address spaces can make use of null, so we don't presume to know anything
955// about that.
956//
957// TODO: How should this work with address space casts? We currently just drop
958// them on the floor, but it's unclear what we should do when a NULL from
959// addrspace(1) gets casted to addrspace(0) (or vice-versa).
960if (Options.NullIsUnknownSize || CPN.getType()->getAddressSpace())
961return ObjectSizeOffsetVisitor::unknown();
962returnOffsetSpan(Zero, Zero);
963}
964
965OffsetSpan
966ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst &) {
967return ObjectSizeOffsetVisitor::unknown();
968}
969
970OffsetSpanObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst &) {
971// Easy cases were already folded by previous passes.
972return ObjectSizeOffsetVisitor::unknown();
973}
974
975OffsetSpanObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {
976if (GA.isInterposable())
977return ObjectSizeOffsetVisitor::unknown();
978return computeImpl(GA.getAliasee());
979}
980
981OffsetSpanObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {
982if (!GV.getValueType()->isSized() || GV.hasExternalWeakLinkage() ||
983 ((!GV.hasInitializer() || GV.isInterposable()) &&
984 Options.EvalMode !=ObjectSizeOpts::Mode::Min))
985return ObjectSizeOffsetVisitor::unknown();
986
987APIntSize(IntTyBits, DL.getTypeAllocSize(GV.getValueType()));
988returnOffsetSpan(Zero, align(Size, GV.getAlign()));
989}
990
991OffsetSpanObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst &) {
992// clueless
993return ObjectSizeOffsetVisitor::unknown();
994}
995
996OffsetSpan ObjectSizeOffsetVisitor::findLoadOffsetRange(
997LoadInst &Load,BasicBlock &BB,BasicBlock::iteratorFrom,
998SmallDenseMap<BasicBlock *, OffsetSpan, 8> &VisitedBlocks,
999unsigned &ScannedInstCount) {
1000constexprunsigned MaxInstsToScan = 128;
1001
1002auto Where = VisitedBlocks.find(&BB);
1003if (Where != VisitedBlocks.end())
1004return Where->second;
1005
1006autoUnknown = [&BB, &VisitedBlocks]() {
1007return VisitedBlocks[&BB] = ObjectSizeOffsetVisitor::unknown();
1008 };
1009auto Known = [&BB, &VisitedBlocks](OffsetSpan SO) {
1010return VisitedBlocks[&BB] = SO;
1011 };
1012
1013do {
1014Instruction &I = *From;
1015
1016if (I.isDebugOrPseudoInst())
1017continue;
1018
1019if (++ScannedInstCount > MaxInstsToScan)
1020returnUnknown();
1021
1022if (!I.mayWriteToMemory())
1023continue;
1024
1025if (auto *SI = dyn_cast<StoreInst>(&I)) {
1026AliasResult AR =
1027 Options.AA->alias(SI->getPointerOperand(),Load.getPointerOperand());
1028switch ((AliasResult::Kind)AR) {
1029caseAliasResult::NoAlias:
1030continue;
1031caseAliasResult::MustAlias:
1032if (SI->getValueOperand()->getType()->isPointerTy())
1033return Known(computeImpl(SI->getValueOperand()));
1034else
1035returnUnknown();// No handling of non-pointer values by `compute`.
1036default:
1037returnUnknown();
1038 }
1039 }
1040
1041if (auto *CB = dyn_cast<CallBase>(&I)) {
1042Function *Callee = CB->getCalledFunction();
1043// Bail out on indirect call.
1044if (!Callee)
1045returnUnknown();
1046
1047LibFunc TLIFn;
1048if (!TLI || !TLI->getLibFunc(*CB->getCalledFunction(), TLIFn) ||
1049 !TLI->has(TLIFn))
1050returnUnknown();
1051
1052// TODO: There's probably more interesting case to support here.
1053if (TLIFn != LibFunc_posix_memalign)
1054returnUnknown();
1055
1056AliasResult AR =
1057 Options.AA->alias(CB->getOperand(0),Load.getPointerOperand());
1058switch ((AliasResult::Kind)AR) {
1059caseAliasResult::NoAlias:
1060continue;
1061caseAliasResult::MustAlias:
1062break;
1063default:
1064returnUnknown();
1065 }
1066
1067// Is the error status of posix_memalign correctly checked? If not it
1068// would be incorrect to assume it succeeds and load doesn't see the
1069// previous value.
1070 std::optional<bool> Checked =isImpliedByDomCondition(
1071ICmpInst::ICMP_EQ, CB, ConstantInt::get(CB->getType(), 0), &Load, DL);
1072if (!Checked || !*Checked)
1073returnUnknown();
1074
1075Value *Size = CB->getOperand(2);
1076auto *C = dyn_cast<ConstantInt>(Size);
1077if (!C)
1078returnUnknown();
1079
1080APInt CSize =C->getValue();
1081if (CSize.isNegative())
1082returnUnknown();
1083
1084return Known({APInt(CSize.getBitWidth(), 0), CSize});
1085 }
1086
1087returnUnknown();
1088 }while (From-- != BB.begin());
1089
1090SmallVector<OffsetSpan> PredecessorSizeOffsets;
1091for (auto *PredBB :predecessors(&BB)) {
1092 PredecessorSizeOffsets.push_back(findLoadOffsetRange(
1093 Load, *PredBB,BasicBlock::iterator(PredBB->getTerminator()),
1094 VisitedBlocks, ScannedInstCount));
1095if (!PredecessorSizeOffsets.back().bothKnown())
1096returnUnknown();
1097 }
1098
1099if (PredecessorSizeOffsets.empty())
1100returnUnknown();
1101
1102return Known(std::accumulate(
1103 PredecessorSizeOffsets.begin() + 1, PredecessorSizeOffsets.end(),
1104 PredecessorSizeOffsets.front(), [this](OffsetSpan LHS,OffsetSpan RHS) {
1105 return combineOffsetRange(LHS, RHS);
1106 }));
1107}
1108
1109OffsetSpanObjectSizeOffsetVisitor::visitLoadInst(LoadInst &LI) {
1110if (!Options.AA) {
1111 ++ObjectVisitorLoad;
1112return ObjectSizeOffsetVisitor::unknown();
1113 }
1114
1115SmallDenseMap<BasicBlock *, OffsetSpan, 8> VisitedBlocks;
1116unsigned ScannedInstCount = 0;
1117OffsetSpan SO =
1118 findLoadOffsetRange(LI, *LI.getParent(),BasicBlock::iterator(LI),
1119 VisitedBlocks, ScannedInstCount);
1120if (!SO.bothKnown())
1121 ++ObjectVisitorLoad;
1122return SO;
1123}
1124
1125OffsetSpan ObjectSizeOffsetVisitor::combineOffsetRange(OffsetSpan LHS,
1126OffsetSpan RHS) {
1127if (!LHS.bothKnown() || !RHS.bothKnown())
1128return ObjectSizeOffsetVisitor::unknown();
1129
1130switch (Options.EvalMode) {
1131caseObjectSizeOpts::Mode::Min:
1132return {LHS.Before.slt(RHS.Before) ?LHS.Before :RHS.Before,
1133LHS.After.slt(RHS.After) ?LHS.After :RHS.After};
1134caseObjectSizeOpts::Mode::Max: {
1135return {LHS.Before.sgt(RHS.Before) ?LHS.Before :RHS.Before,
1136LHS.After.sgt(RHS.After) ?LHS.After :RHS.After};
1137 }
1138caseObjectSizeOpts::Mode::ExactSizeFromOffset:
1139return {LHS.Before.eq(RHS.Before) ?LHS.Before :APInt(),
1140LHS.After.eq(RHS.After) ?LHS.After :APInt()};
1141caseObjectSizeOpts::Mode::ExactUnderlyingSizeAndOffset:
1142return (LHS == RHS) ?LHS : ObjectSizeOffsetVisitor::unknown();
1143 }
1144llvm_unreachable("missing an eval mode");
1145}
1146
1147OffsetSpanObjectSizeOffsetVisitor::visitPHINode(PHINode &PN) {
1148if (PN.getNumIncomingValues() == 0)
1149return ObjectSizeOffsetVisitor::unknown();
1150auto IncomingValues = PN.incoming_values();
1151return std::accumulate(IncomingValues.begin() + 1, IncomingValues.end(),
1152 computeImpl(*IncomingValues.begin()),
1153 [this](OffsetSpanLHS,Value *VRHS) {
1154 return combineOffsetRange(LHS, computeImpl(VRHS));
1155 });
1156}
1157
1158OffsetSpanObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
1159return combineOffsetRange(computeImpl(I.getTrueValue()),
1160 computeImpl(I.getFalseValue()));
1161}
1162
1163OffsetSpanObjectSizeOffsetVisitor::visitUndefValue(UndefValue &) {
1164returnOffsetSpan(Zero, Zero);
1165}
1166
1167OffsetSpanObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
1168LLVM_DEBUG(dbgs() <<"ObjectSizeOffsetVisitor unknown instruction:" <<I
1169 <<'\n');
1170return ObjectSizeOffsetVisitor::unknown();
1171}
1172
1173// Just set these right here...
1174SizeOffsetValue::SizeOffsetValue(constSizeOffsetWeakTrackingVH &SOT)
1175 :SizeOffsetType(SOT.Size, SOT.Offset) {}
1176
1177ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
1178constDataLayout &DL,constTargetLibraryInfo *TLI,LLVMContext &Context,
1179ObjectSizeOpts EvalOpts)
1180 :DL(DL), TLI(TLI), Context(Context),
1181 Builder(Context,TargetFolder(DL),
1182IRBuilderCallbackInserter(
1183 [&](Instruction *I) { InsertedInstructions.insert(I); })),
1184 EvalOpts(EvalOpts) {
1185// IntTy and Zero must be set for each compute() since the address space may
1186// be different for later objects.
1187}
1188
1189SizeOffsetValueObjectSizeOffsetEvaluator::compute(Value *V) {
1190// XXX - Are vectors of pointers possible here?
1191 IntTy = cast<IntegerType>(DL.getIndexType(V->getType()));
1192 Zero = ConstantInt::get(IntTy, 0);
1193
1194SizeOffsetValue Result = compute_(V);
1195
1196if (!Result.bothKnown()) {
1197// Erase everything that was computed in this iteration from the cache, so
1198// that no dangling references are left behind. We could be a bit smarter if
1199// we kept a dependency graph. It's probably not worth the complexity.
1200for (constValue *SeenVal : SeenVals) {
1201CacheMapTy::iterator CacheIt = CacheMap.find(SeenVal);
1202// non-computable results can be safely cached
1203if (CacheIt != CacheMap.end() && CacheIt->second.anyKnown())
1204 CacheMap.erase(CacheIt);
1205 }
1206
1207// Erase any instructions we inserted as part of the traversal.
1208for (Instruction *I : InsertedInstructions) {
1209I->replaceAllUsesWith(PoisonValue::get(I->getType()));
1210I->eraseFromParent();
1211 }
1212 }
1213
1214 SeenVals.clear();
1215 InsertedInstructions.clear();
1216return Result;
1217}
1218
1219SizeOffsetValue ObjectSizeOffsetEvaluator::compute_(Value *V) {
1220
1221// Only trust ObjectSizeOffsetVisitor in exact mode, otherwise fallback on
1222// dynamic computation.
1223ObjectSizeOpts VisitorEvalOpts(EvalOpts);
1224 VisitorEvalOpts.EvalMode =ObjectSizeOpts::Mode::ExactUnderlyingSizeAndOffset;
1225ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, VisitorEvalOpts);
1226
1227SizeOffsetAPInt Const = Visitor.compute(V);
1228if (Const.bothKnown())
1229returnSizeOffsetValue(ConstantInt::get(Context, Const.Size),
1230 ConstantInt::get(Context, Const.Offset));
1231
1232 V = V->stripPointerCasts();
1233
1234// Check cache.
1235CacheMapTy::iterator CacheIt = CacheMap.find(V);
1236if (CacheIt != CacheMap.end())
1237return CacheIt->second;
1238
1239// Always generate code immediately before the instruction being
1240// processed, so that the generated code dominates the same BBs.
1241BuilderTy::InsertPointGuard Guard(Builder);
1242if (Instruction *I = dyn_cast<Instruction>(V))
1243 Builder.SetInsertPoint(I);
1244
1245// Now compute the size and offset.
1246SizeOffsetValue Result;
1247
1248// Record the pointers that were handled in this run, so that they can be
1249// cleaned later if something fails. We also use this set to break cycles that
1250// can occur in dead code.
1251if (!SeenVals.insert(V).second) {
1252 Result =ObjectSizeOffsetEvaluator::unknown();
1253 }elseif (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
1254 Result =visitGEPOperator(*GEP);
1255 }elseif (Instruction *I = dyn_cast<Instruction>(V)) {
1256Result =visit(*I);
1257 }elseif (isa<Argument>(V) ||
1258 (isa<ConstantExpr>(V) &&
1259 cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
1260 isa<GlobalAlias>(V) ||
1261 isa<GlobalVariable>(V)) {
1262// Ignore values where we cannot do more than ObjectSizeVisitor.
1263Result =ObjectSizeOffsetEvaluator::unknown();
1264 }else {
1265LLVM_DEBUG(
1266dbgs() <<"ObjectSizeOffsetEvaluator::compute() unhandled value: " << *V
1267 <<'\n');
1268Result =ObjectSizeOffsetEvaluator::unknown();
1269 }
1270
1271// Don't reuse CacheIt since it may be invalid at this point.
1272 CacheMap[V] =SizeOffsetWeakTrackingVH(Result);
1273returnResult;
1274}
1275
1276SizeOffsetValueObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
1277if (!I.getAllocatedType()->isSized())
1278returnObjectSizeOffsetEvaluator::unknown();
1279
1280// must be a VLA or vscale.
1281assert(I.isArrayAllocation() ||I.getAllocatedType()->isScalableTy());
1282
1283// If needed, adjust the alloca's operand size to match the pointer indexing
1284// size. Subsequent math operations expect the types to match.
1285Value *ArraySize = Builder.CreateZExtOrTrunc(
1286I.getArraySize(),
1287 DL.getIndexType(I.getContext(), DL.getAllocaAddrSpace()));
1288assert(ArraySize->getType() == Zero->getType() &&
1289"Expected zero constant to have pointer index type");
1290
1291Value *Size = Builder.CreateTypeSize(
1292 ArraySize->getType(), DL.getTypeAllocSize(I.getAllocatedType()));
1293Size = Builder.CreateMul(Size, ArraySize);
1294returnSizeOffsetValue(Size, Zero);
1295}
1296
1297SizeOffsetValueObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) {
1298 std::optional<AllocFnsTy> FnData =getAllocationSize(&CB, TLI);
1299if (!FnData)
1300returnObjectSizeOffsetEvaluator::unknown();
1301
1302// Handle strdup-like functions separately.
1303if (FnData->AllocTy ==StrDupLike) {
1304// TODO: implement evaluation of strdup/strndup
1305returnObjectSizeOffsetEvaluator::unknown();
1306 }
1307
1308Value *FirstArg = CB.getArgOperand(FnData->FstParam);
1309 FirstArg = Builder.CreateZExtOrTrunc(FirstArg, IntTy);
1310if (FnData->SndParam < 0)
1311returnSizeOffsetValue(FirstArg, Zero);
1312
1313Value *SecondArg = CB.getArgOperand(FnData->SndParam);
1314 SecondArg = Builder.CreateZExtOrTrunc(SecondArg, IntTy);
1315Value *Size = Builder.CreateMul(FirstArg, SecondArg);
1316returnSizeOffsetValue(Size, Zero);
1317}
1318
1319SizeOffsetValue
1320ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst &) {
1321returnObjectSizeOffsetEvaluator::unknown();
1322}
1323
1324SizeOffsetValue
1325ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst &) {
1326returnObjectSizeOffsetEvaluator::unknown();
1327}
1328
1329SizeOffsetValueObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
1330SizeOffsetValue PtrData = compute_(GEP.getPointerOperand());
1331if (!PtrData.bothKnown())
1332returnObjectSizeOffsetEvaluator::unknown();
1333
1334Value *Offset =emitGEPOffset(&Builder, DL, &GEP,/*NoAssumptions=*/true);
1335Offset = Builder.CreateAdd(PtrData.Offset,Offset);
1336returnSizeOffsetValue(PtrData.Size,Offset);
1337}
1338
1339SizeOffsetValueObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst &) {
1340// clueless
1341returnObjectSizeOffsetEvaluator::unknown();
1342}
1343
1344SizeOffsetValueObjectSizeOffsetEvaluator::visitLoadInst(LoadInst &LI) {
1345returnObjectSizeOffsetEvaluator::unknown();
1346}
1347
1348SizeOffsetValueObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
1349// Create 2 PHIs: one for size and another for offset.
1350PHINode *SizePHI = Builder.CreatePHI(IntTy,PHI.getNumIncomingValues());
1351PHINode *OffsetPHI = Builder.CreatePHI(IntTy,PHI.getNumIncomingValues());
1352
1353// Insert right away in the cache to handle recursive PHIs.
1354 CacheMap[&PHI] =SizeOffsetWeakTrackingVH(SizePHI, OffsetPHI);
1355
1356// Compute offset/size for each PHI incoming pointer.
1357for (unsigned i = 0, e =PHI.getNumIncomingValues(); i != e; ++i) {
1358BasicBlock *IncomingBlock =PHI.getIncomingBlock(i);
1359 Builder.SetInsertPoint(IncomingBlock, IncomingBlock->getFirstInsertionPt());
1360SizeOffsetValue EdgeData = compute_(PHI.getIncomingValue(i));
1361
1362if (!EdgeData.bothKnown()) {
1363 OffsetPHI->replaceAllUsesWith(PoisonValue::get(IntTy));
1364 OffsetPHI->eraseFromParent();
1365 InsertedInstructions.erase(OffsetPHI);
1366 SizePHI->replaceAllUsesWith(PoisonValue::get(IntTy));
1367 SizePHI->eraseFromParent();
1368 InsertedInstructions.erase(SizePHI);
1369returnObjectSizeOffsetEvaluator::unknown();
1370 }
1371 SizePHI->addIncoming(EdgeData.Size, IncomingBlock);
1372 OffsetPHI->addIncoming(EdgeData.Offset, IncomingBlock);
1373 }
1374
1375Value *Size = SizePHI, *Offset = OffsetPHI;
1376if (Value *Tmp = SizePHI->hasConstantValue()) {
1377Size = Tmp;
1378 SizePHI->replaceAllUsesWith(Size);
1379 SizePHI->eraseFromParent();
1380 InsertedInstructions.erase(SizePHI);
1381 }
1382if (Value *Tmp = OffsetPHI->hasConstantValue()) {
1383Offset = Tmp;
1384 OffsetPHI->replaceAllUsesWith(Offset);
1385 OffsetPHI->eraseFromParent();
1386 InsertedInstructions.erase(OffsetPHI);
1387 }
1388returnSizeOffsetValue(Size,Offset);
1389}
1390
1391SizeOffsetValueObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
1392SizeOffsetValue TrueSide = compute_(I.getTrueValue());
1393SizeOffsetValue FalseSide = compute_(I.getFalseValue());
1394
1395if (!TrueSide.bothKnown() || !FalseSide.bothKnown())
1396returnObjectSizeOffsetEvaluator::unknown();
1397if (TrueSide == FalseSide)
1398return TrueSide;
1399
1400Value *Size =
1401 Builder.CreateSelect(I.getCondition(), TrueSide.Size, FalseSide.Size);
1402Value *Offset =
1403 Builder.CreateSelect(I.getCondition(), TrueSide.Offset, FalseSide.Offset);
1404returnSizeOffsetValue(Size,Offset);
1405}
1406
1407SizeOffsetValueObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) {
1408LLVM_DEBUG(dbgs() <<"ObjectSizeOffsetEvaluator unknown instruction:" <<I
1409 <<'\n');
1410returnObjectSizeOffsetEvaluator::unknown();
1411}
PHI
Rewrite undef for PHI
Definition:AMDGPURewriteUndefForPHI.cpp:100
APInt.h
This file implements a class to represent arbitrary precision integral constant values and operations...
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition:ARMSLSHardening.cpp:73
AliasAnalysis.h
Local.h
Attributes.h
This file contains the simple types necessary to represent the attributes associated with functions a...
From
BlockVerifier::State From
Definition:BlockVerifier.cpp:57
A
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Casting.h
CommandLine.h
Constants.h
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DataLayout.h
Debug.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
DerivedTypes.h
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
GlobalAlias.h
GlobalVariable.h
GEP
Hexagon Common GEP
Definition:HexagonCommonGEP.cpp:170
Argument.h
Function.h
Instruction.h
IntrinsicInst.h
Operator.h
Type.h
Value.h
Instructions.h
Options
static LVOptions Options
Definition:LVOptions.cpp:25
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MathExtras.h
MallocFamily
MallocFamily
Definition:MemoryBuiltins.cpp:68
MallocFamily::Malloc
@ Malloc
MallocFamily::CPPNew
@ CPPNew
MallocFamily::MSVCArrayNew
@ MSVCArrayNew
MallocFamily::CPPNewArray
@ CPPNewArray
MallocFamily::CPPNewAligned
@ CPPNewAligned
MallocFamily::MSVCNew
@ MSVCNew
MallocFamily::VecMalloc
@ VecMalloc
MallocFamily::KmpcAllocShared
@ KmpcAllocShared
MallocFamily::CPPNewArrayAligned
@ CPPNewArrayAligned
combinePossibleConstantValues
static std::optional< APInt > combinePossibleConstantValues(std::optional< APInt > LHS, std::optional< APInt > RHS, ObjectSizeOpts::Mode EvalMode)
Definition:MemoryBuiltins.cpp:674
getAllocFnKind
static AllocFnKind getAllocFnKind(const Value *V)
Definition:MemoryBuiltins.cpp:263
getAllocationDataForFunction
static std::optional< AllocFnsTy > getAllocationDataForFunction(const Function *Callee, AllocType AllocTy, const TargetLibraryInfo *TLI)
Returns the allocation data for the given value if it's a call to a known allocation function.
Definition:MemoryBuiltins.cpp:177
getAllocationData
static std::optional< AllocFnsTy > getAllocationData(const Value *V, AllocType AllocTy, const TargetLibraryInfo *TLI)
Definition:MemoryBuiltins.cpp:219
getFreeFunctionDataForFunction
std::optional< FreeFnsTy > getFreeFunctionDataForFunction(const Function *Callee, const LibFunc TLIFn)
Definition:MemoryBuiltins.cpp:488
checkFnAllocKind
static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted)
Definition:MemoryBuiltins.cpp:276
mangledNameForMallocFamily
StringRef mangledNameForMallocFamily(const MallocFamily &Family)
Definition:MemoryBuiltins.cpp:80
getAllocationSize
static std::optional< AllocFnsTy > getAllocationSize(const CallBase *CB, const TargetLibraryInfo *TLI)
Definition:MemoryBuiltins.cpp:236
CheckedZextOrTrunc
static bool CheckedZextOrTrunc(APInt &I, unsigned IntTyBits)
When we're compiling N-bit code, and the user uses parameters that are greater than N bits (e....
Definition:MemoryBuiltins.cpp:355
FreeFnData
static const std::pair< LibFunc, FreeFnsTy > FreeFnData[]
Definition:MemoryBuiltins.cpp:455
getCalledFunction
static const Function * getCalledFunction(const Value *V)
Definition:MemoryBuiltins.cpp:159
aggregatePossibleConstantValues
static std::optional< APInt > aggregatePossibleConstantValues(const Value *V, ObjectSizeOpts::Mode EvalMode)
Definition:MemoryBuiltins.cpp:718
ObjectSizeOffsetVisitorMaxVisitInstructions
static cl::opt< unsigned > ObjectSizeOffsetVisitorMaxVisitInstructions("object-size-offset-visitor-max-visit-instructions", cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to " "look at"), cl::init(100))
aggregatePossibleConstantValuesImpl
static std::optional< APInt > aggregatePossibleConstantValuesImpl(const Value *V, ObjectSizeOpts::Mode EvalMode, unsigned recursionDepth)
Definition:MemoryBuiltins.cpp:685
AllocationFnData
static const std::pair< LibFunc, AllocFnsTy > AllocationFnData[]
Definition:MemoryBuiltins.cpp:118
AllocType
AllocType
Definition:MemoryBuiltins.cpp:59
MallocLike
@ MallocLike
Definition:MemoryBuiltins.cpp:61
AnyAlloc
@ AnyAlloc
Definition:MemoryBuiltins.cpp:65
AllocLike
@ AllocLike
Definition:MemoryBuiltins.cpp:64
StrDupLike
@ StrDupLike
Definition:MemoryBuiltins.cpp:62
OpNewLike
@ OpNewLike
Definition:MemoryBuiltins.cpp:60
MallocOrOpNewLike
@ MallocOrOpNewLike
Definition:MemoryBuiltins.cpp:63
getSizeWithOverflow
static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data)
Definition:MemoryBuiltins.cpp:564
MemoryBuiltins.h
P
#define P(N)
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
STLExtras.h
This file contains some templates that are useful if you are working with the STL at all.
Statistic.h
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
STATISTIC
#define STATISTIC(VARNAME, DESC)
Definition:Statistic.h:166
TargetFolder.h
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
TargetLibraryInfo.h
getOpcode
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition:VPlanSLP.cpp:191
ValueTracking.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
FunctionType
Definition:ItaniumDemangle.h:823
llvm::AAResults
Definition:AliasAnalysis.h:314
llvm::AAResults::alias
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
Definition:AliasAnalysis.cpp:105
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::APInt::zext
APInt zext(unsigned width) const
Zero extend to a new width.
Definition:APInt.cpp:986
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition:APInt.h:1520
llvm::APInt::getBitWidth
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition:APInt.h:1468
llvm::APInt::isNegative
bool isNegative() const
Determine sign of this APInt.
Definition:APInt.h:329
llvm::APInt::sadd_ov
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1902
llvm::APInt::getZero
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition:APInt.h:200
llvm::APInt::ssub_ov
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1915
llvm::AliasResult
The possible results of an alias query.
Definition:AliasAnalysis.h:77
llvm::AliasResult::Kind
Kind
Definition:AliasAnalysis.h:89
llvm::AliasResult::NoAlias
@ NoAlias
The two locations do not alias at all.
Definition:AliasAnalysis.h:95
llvm::AliasResult::MustAlias
@ MustAlias
The two locations precisely alias each other.
Definition:AliasAnalysis.h:102
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition:Instructions.h:63
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition:Argument.h:31
llvm::Attribute
Definition:Attributes.h:67
llvm::Attribute::getValueAsInt
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition:Attributes.cpp:371
llvm::Attribute::getAllocSizeArgs
std::pair< unsigned, std::optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute.
Definition:Attributes.cpp:454
llvm::Attribute::getValueAsString
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition:Attributes.cpp:392
llvm::Attribute::isValid
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition:Attributes.h:208
llvm::BasicBlock
LLVM Basic Block Representation.
Definition:BasicBlock.h:61
llvm::BasicBlock::begin
iterator begin()
Instruction iterator methods.
Definition:BasicBlock.h:451
llvm::BasicBlock::getFirstInsertionPt
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition:BasicBlock.cpp:426
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition:BasicBlock.h:177
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition:InstrTypes.h:1112
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition:InstrTypes.h:1341
llvm::CallBase::getFnAttr
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
Definition:InstrTypes.h:1605
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition:InstrTypes.h:1286
llvm::CallBase::getArgOperandWithAttribute
Value * getArgOperandWithAttribute(Attribute::AttrKind Kind) const
If one of the arguments has the specified attribute, returns its operand value.
Definition:Instructions.cpp:396
llvm::CallBase::arg_size
unsigned arg_size() const
Definition:InstrTypes.h:1284
llvm::CmpInst::ICMP_EQ
@ ICMP_EQ
equal
Definition:InstrTypes.h:694
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition:Constants.h:83
llvm::ConstantInt::getValue
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition:Constants.h:148
llvm::ConstantPointerNull
A constant pointer value that points to null.
Definition:Constants.h:552
llvm::ConstantPointerNull::getType
PointerType * getType() const
Specialize the getType() method to always return an PointerType, which reduces the amount of casting ...
Definition:Constants.h:568
llvm::Constant
This is an important base class in LLVM.
Definition:Constant.h:42
llvm::Constant::getAllOnesValue
static Constant * getAllOnesValue(Type *Ty)
Definition:Constants.cpp:420
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition:Constants.cpp:373
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition:DataLayout.h:63
llvm::DataLayout::getIndexTypeSizeInBits
unsigned getIndexTypeSizeInBits(Type *Ty) const
Layout size of the index used in GEP calculation.
Definition:DataLayout.cpp:754
llvm::DataLayout::getAllocaAddrSpace
unsigned getAllocaAddrSpace() const
Definition:DataLayout.h:229
llvm::DataLayout::getIndexType
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
Definition:DataLayout.cpp:878
llvm::DataLayout::getTypeAllocSize
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition:DataLayout.h:457
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition:DenseMap.h:156
llvm::DenseMapBase::erase
bool erase(const KeyT &Val)
Definition:DenseMap.h:321
llvm::DenseMapBase::iterator
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition:DenseMap.h:71
llvm::DenseMapBase::end
iterator end()
Definition:DenseMap.h:84
llvm::DenseMapIterator
Definition:DenseMap.h:1189
llvm::ExtractElementInst
This instruction extracts a single (scalar) element from a VectorType value.
Definition:Instructions.h:1775
llvm::ExtractValueInst
This instruction extracts a struct member or array element value from an aggregate value.
Definition:Instructions.h:2397
llvm::FunctionType
Class to represent function types.
Definition:DerivedTypes.h:105
llvm::FunctionType::getNumParams
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition:DerivedTypes.h:144
llvm::FunctionType::getParamType
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition:DerivedTypes.h:137
llvm::FunctionType::getReturnType
Type * getReturnType() const
Definition:DerivedTypes.h:126
llvm::Function
Definition:Function.h:63
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition:Function.cpp:369
llvm::GEPOperator
Definition:Operator.h:425
llvm::GlobalAlias
Definition:GlobalAlias.h:28
llvm::GlobalAlias::getAliasee
const Constant * getAliasee() const
Definition:GlobalAlias.h:86
llvm::GlobalObject::getAlign
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
Definition:GlobalObject.h:79
llvm::GlobalValue::hasExternalWeakLinkage
bool hasExternalWeakLinkage() const
Definition:GlobalValue.h:530
llvm::GlobalValue::isInterposable
bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
Definition:Globals.cpp:105
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition:GlobalValue.h:297
llvm::GlobalVariable
Definition:GlobalVariable.h:39
llvm::GlobalVariable::hasInitializer
bool hasInitializer() const
Definitions have initializers, declarations don't.
Definition:GlobalVariable.h:106
llvm::IRBuilderBase::InsertPointGuard
Definition:IRBuilder.h:394
llvm::IRBuilderBase::CreateICmpULT
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Definition:IRBuilder.h:2286
llvm::IRBuilderBase::CreateZExtOrTrunc
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition:IRBuilder.h:2051
llvm::IRBuilderBase::CreateAssumption
CallInst * CreateAssumption(Value *Cond, ArrayRef< OperandBundleDef > OpBundles={})
Create an assume intrinsic call that allows the optimizer to assume that the provided condition will ...
Definition:IRBuilder.cpp:521
llvm::IRBuilderBase::CreateSelect
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition:IRBuilder.cpp:1053
llvm::IRBuilderBase::CreateTypeSize
Value * CreateTypeSize(Type *DstType, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Definition:IRBuilder.cpp:103
llvm::IRBuilderBase::CreateICmpNE
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition:IRBuilder.h:2274
llvm::IRBuilderBase::CreatePHI
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition:IRBuilder.h:2435
llvm::IRBuilderBase::CreateSub
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition:IRBuilder.h:1387
llvm::IRBuilderBase::CreateAdd
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition:IRBuilder.h:1370
llvm::IRBuilderBase::SetInsertPoint
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition:IRBuilder.h:199
llvm::IRBuilderBase::CreateMul
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition:IRBuilder.h:1404
llvm::IRBuilderCallbackInserter
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
Definition:IRBuilder.h:74
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition:IRBuilder.h:2705
llvm::InstVisitor< ObjectSizeOffsetVisitor, OffsetSpan >::visit
void visit(Iterator Start, Iterator End)
Definition:InstVisitor.h:87
llvm::Instruction
Definition:Instruction.h:68
llvm::Instruction::eraseFromParent
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition:Instruction.cpp:94
llvm::Instruction::getFunction
const Function * getFunction() const
Return the function this instruction belongs to.
Definition:Instruction.cpp:72
llvm::Instruction::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Definition:Instruction.cpp:76
llvm::IntToPtrInst
This class represents a cast from an integer to a pointer.
Definition:Instructions.h:4816
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition:IntrinsicInst.h:48
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition:IntrinsicInst.h:55
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::LoadInst
An instruction for reading from memory.
Definition:Instructions.h:176
llvm::ObjectSizeOffsetEvaluator
Evaluate the size and offset of an object pointed to by a Value*.
Definition:MemoryBuiltins.h:328
llvm::ObjectSizeOffsetEvaluator::visitExtractValueInst
SizeOffsetValue visitExtractValueInst(ExtractValueInst &I)
Definition:MemoryBuiltins.cpp:1325
llvm::ObjectSizeOffsetEvaluator::visitExtractElementInst
SizeOffsetValue visitExtractElementInst(ExtractElementInst &I)
Definition:MemoryBuiltins.cpp:1320
llvm::ObjectSizeOffsetEvaluator::compute
SizeOffsetValue compute(Value *V)
Definition:MemoryBuiltins.cpp:1189
llvm::ObjectSizeOffsetEvaluator::visitInstruction
SizeOffsetValue visitInstruction(Instruction &I)
Definition:MemoryBuiltins.cpp:1407
llvm::ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts EvalOpts={})
Definition:MemoryBuiltins.cpp:1177
llvm::ObjectSizeOffsetEvaluator::visitLoadInst
SizeOffsetValue visitLoadInst(LoadInst &I)
Definition:MemoryBuiltins.cpp:1344
llvm::ObjectSizeOffsetEvaluator::visitGEPOperator
SizeOffsetValue visitGEPOperator(GEPOperator &GEP)
Definition:MemoryBuiltins.cpp:1329
llvm::ObjectSizeOffsetEvaluator::visitIntToPtrInst
SizeOffsetValue visitIntToPtrInst(IntToPtrInst &)
Definition:MemoryBuiltins.cpp:1339
llvm::ObjectSizeOffsetEvaluator::visitPHINode
SizeOffsetValue visitPHINode(PHINode &PHI)
Definition:MemoryBuiltins.cpp:1348
llvm::ObjectSizeOffsetEvaluator::visitCallBase
SizeOffsetValue visitCallBase(CallBase &CB)
Definition:MemoryBuiltins.cpp:1297
llvm::ObjectSizeOffsetEvaluator::visitSelectInst
SizeOffsetValue visitSelectInst(SelectInst &I)
Definition:MemoryBuiltins.cpp:1391
llvm::ObjectSizeOffsetEvaluator::visitAllocaInst
SizeOffsetValue visitAllocaInst(AllocaInst &I)
Definition:MemoryBuiltins.cpp:1276
llvm::ObjectSizeOffsetEvaluator::unknown
static SizeOffsetValue unknown()
Definition:MemoryBuiltins.h:351
llvm::ObjectSizeOffsetVisitor
Evaluate the size and offset of an object pointed to by a Value* statically.
Definition:MemoryBuiltins.h:253
llvm::ObjectSizeOffsetVisitor::visitSelectInst
OffsetSpan visitSelectInst(SelectInst &I)
Definition:MemoryBuiltins.cpp:1158
llvm::ObjectSizeOffsetVisitor::visitExtractValueInst
OffsetSpan visitExtractValueInst(ExtractValueInst &I)
Definition:MemoryBuiltins.cpp:970
llvm::ObjectSizeOffsetVisitor::visitConstantPointerNull
OffsetSpan visitConstantPointerNull(ConstantPointerNull &)
Definition:MemoryBuiltins.cpp:952
llvm::ObjectSizeOffsetVisitor::visitExtractElementInst
OffsetSpan visitExtractElementInst(ExtractElementInst &I)
Definition:MemoryBuiltins.cpp:966
llvm::ObjectSizeOffsetVisitor::visitGlobalVariable
OffsetSpan visitGlobalVariable(GlobalVariable &GV)
Definition:MemoryBuiltins.cpp:981
llvm::ObjectSizeOffsetVisitor::visitCallBase
OffsetSpan visitCallBase(CallBase &CB)
Definition:MemoryBuiltins.cpp:930
llvm::ObjectSizeOffsetVisitor::visitIntToPtrInst
OffsetSpan visitIntToPtrInst(IntToPtrInst &)
Definition:MemoryBuiltins.cpp:991
llvm::ObjectSizeOffsetVisitor::visitAllocaInst
OffsetSpan visitAllocaInst(AllocaInst &I)
Definition:MemoryBuiltins.cpp:891
llvm::ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor
ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts Options={})
Definition:MemoryBuiltins.cpp:742
llvm::ObjectSizeOffsetVisitor::visitLoadInst
OffsetSpan visitLoadInst(LoadInst &I)
Definition:MemoryBuiltins.cpp:1109
llvm::ObjectSizeOffsetVisitor::visitPHINode
OffsetSpan visitPHINode(PHINode &)
Definition:MemoryBuiltins.cpp:1147
llvm::ObjectSizeOffsetVisitor::visitGlobalAlias
OffsetSpan visitGlobalAlias(GlobalAlias &GA)
Definition:MemoryBuiltins.cpp:975
llvm::ObjectSizeOffsetVisitor::visitInstruction
OffsetSpan visitInstruction(Instruction &I)
Definition:MemoryBuiltins.cpp:1167
llvm::ObjectSizeOffsetVisitor::compute
SizeOffsetAPInt compute(Value *V)
Definition:MemoryBuiltins.cpp:751
llvm::ObjectSizeOffsetVisitor::visitUndefValue
OffsetSpan visitUndefValue(UndefValue &)
Definition:MemoryBuiltins.cpp:1163
llvm::ObjectSizeOffsetVisitor::visitArgument
OffsetSpan visitArgument(Argument &A)
Definition:MemoryBuiltins.cpp:918
llvm::PHINode
Definition:Instructions.h:2600
llvm::PHINode::addIncoming
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Definition:Instructions.h:2735
llvm::PHINode::incoming_values
op_range incoming_values()
Definition:Instructions.h:2665
llvm::PHINode::hasConstantValue
Value * hasConstantValue() const
If the specified PHI node always merges together the same value, return the value,...
Definition:Instructions.cpp:209
llvm::PHINode::getNumIncomingValues
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Definition:Instructions.h:2671
llvm::PointerType::getAddressSpace
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition:DerivedTypes.h:703
llvm::PoisonValue::get
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition:Constants.cpp:1878
llvm::SelectInst
This class represents the LLVM 'select' instruction.
Definition:Instructions.h:1657
llvm::SmallDenseMap
Definition:DenseMap.h:883
llvm::SmallPtrSetImplBase::clear
void clear()
Definition:SmallPtrSet.h:97
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition:SmallPtrSet.h:384
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::end
iterator end()
Definition:SmallVector.h:269
llvm::SmallVectorTemplateCommon::front
reference front()
Definition:SmallVector.h:299
llvm::SmallVectorTemplateCommon::begin
iterator begin()
Definition:SmallVector.h:267
llvm::SmallVectorTemplateCommon::back
reference back()
Definition:SmallVector.h:308
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::TargetFolder
TargetFolder - Create constants with target dependent folding.
Definition:TargetFolder.h:34
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition:TargetLibraryInfo.h:280
llvm::TargetLibraryInfo::has
bool has(LibFunc F) const
Tests whether a library function is available.
Definition:TargetLibraryInfo.h:387
llvm::TargetLibraryInfo::getLibFunc
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Definition:TargetLibraryInfo.h:345
llvm::TypeSize
Definition:TypeSize.h:334
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::isPointerTy
bool isPointerTy() const
True if this is an instance of PointerType.
Definition:Type.h:264
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition:Type.h:310
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition:Type.h:139
llvm::UndefValue
'undef' values are things that do not have specified contents.
Definition:Constants.h:1412
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition:Constants.cpp:1859
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition:User.h:228
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition:Value.cpp:534
llvm::cl::opt
Definition:CommandLine.h:1423
llvm::details::FixedOrScalableQuantity::isScalable
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition:TypeSize.h:171
llvm::details::FixedOrScalableQuantity::getKnownMinValue
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition:TypeSize.h:168
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition:STLFunctionalExtras.h:37
llvm::ilist_detail::node_parent_access::getParent
const ParentTy * getParent() const
Definition:ilist_node.h:32
uint64_t
uint8_t
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::M68k::MemAddrModeKind::V
@ V
llvm::SIEncodingFamily::SI
@ SI
Definition:SIDefines.h:36
llvm::SPII::Load
@ Load
Definition:SparcInstrInfo.h:32
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition:CommandLine.h:443
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::pdb::PDB_SymType::Callee
@ Callee
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::CGDataKind::Unknown
@ Unknown
llvm::getInitialValueOfAllocation
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,...
Definition:MemoryBuiltins.cpp:428
llvm::isUIntN
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition:MathExtras.h:256
llvm::AllocFnKind
AllocFnKind
Definition:Attributes.h:49
llvm::LibFunc
LibFunc
Definition:TargetLibraryInfo.h:68
llvm::isRemovableAlloc
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...
Definition:MemoryBuiltins.cpp:330
llvm::getAllocationFamily
std::optional< StringRef > getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI)
If a function is part of an allocation family (e.g.
Definition:MemoryBuiltins.cpp:500
llvm::lowerObjectSizeCall
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.
Definition:MemoryBuiltins.cpp:589
llvm::getAllocAlignment
Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
Definition:MemoryBuiltins.cpp:341
llvm::isLibFreeFunction
bool isLibFreeFunction(const Function *F, const LibFunc TLIFn)
isLibFreeFunction - Returns true if the function is a builtin free()
Definition:MemoryBuiltins.cpp:526
llvm::getReallocatedOperand
Value * getReallocatedOperand(const CallBase *CB)
If this is a call to a realloc function, return the reallocated operand.
Definition:MemoryBuiltins.cpp:324
llvm::isAllocLikeFn
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,...
Definition:MemoryBuiltins.cpp:313
llvm::getObjectSize
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.
Definition:MemoryBuiltins.cpp:578
llvm::emitGEPOffset
Value * emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, bool NoAssumptions=false)
Given a getelementptr instruction/constantexpr, emit the code necessary to compute the offset from th...
Definition:Local.cpp:22
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::GetStringLength
uint64_t GetStringLength(const Value *V, unsigned CharSize=8)
If we can compute the length of the string pointed to by the specified pointer, return 'len+1'.
Definition:ValueTracking.cpp:6687
llvm::isMallocOrCallocLikeFn
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...
Definition:MemoryBuiltins.cpp:306
llvm::isReallocLikeFn
bool isReallocLikeFn(const Function *F)
Tests if a function is a call or invoke to a library function that reallocates memory (e....
Definition:MemoryBuiltins.cpp:320
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::getFreedOperand
Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
Definition:MemoryBuiltins.cpp:545
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1766
llvm::predecessors
auto predecessors(const MachineBasicBlock *BB)
Definition:MachineBasicBlock.h:1377
llvm::isAllocationFn
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...
Definition:MemoryBuiltins.cpp:287
llvm::getAllocSize
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.
Definition:MemoryBuiltins.cpp:367
llvm::isImpliedByDomCondition
std::optional< bool > isImpliedByDomCondition(const Value *Cond, const Instruction *ContextI, const DataLayout &DL)
Return the boolean condition value in the context of the given instruction if it is known based on do...
Definition:ValueTracking.cpp:9680
llvm::isNewLikeFn
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.
Definition:MemoryBuiltins.cpp:300
raw_ostream.h
AllocFnsTy
Definition:MemoryBuiltins.cpp:104
AllocFnsTy::Family
MallocFamily Family
Definition:MemoryBuiltins.cpp:112
AllocFnsTy::FstParam
int FstParam
Definition:MemoryBuiltins.cpp:108
AllocFnsTy::SndParam
int SndParam
Definition:MemoryBuiltins.cpp:108
AllocFnsTy::AlignParam
int AlignParam
Definition:MemoryBuiltins.cpp:110
AllocFnsTy::NumParams
unsigned NumParams
Definition:MemoryBuiltins.cpp:106
AllocFnsTy::AllocTy
AllocType AllocTy
Definition:MemoryBuiltins.cpp:105
FreeFnsTy
Definition:MemoryBuiltins.cpp:448
FreeFnsTy::Family
MallocFamily Family
Definition:MemoryBuiltins.cpp:451
FreeFnsTy::NumParams
unsigned NumParams
Definition:MemoryBuiltins.cpp:449
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition:Alignment.h:117
llvm::ObjectSizeOpts
Various options to control the behavior of getObjectSize.
Definition:MemoryBuiltins.h:138
llvm::ObjectSizeOpts::NullIsUnknownSize
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
Definition:MemoryBuiltins.h:162
llvm::ObjectSizeOpts::EvalMode
Mode EvalMode
How we want to evaluate this object's size.
Definition:MemoryBuiltins.h:155
llvm::ObjectSizeOpts::AA
AAResults * AA
If set, used for more accurate evaluation.
Definition:MemoryBuiltins.h:164
llvm::ObjectSizeOpts::RoundToAlign
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
Definition:MemoryBuiltins.h:158
llvm::ObjectSizeOpts::Mode
Mode
Controls how we handle conditional statements with unknown conditions.
Definition:MemoryBuiltins.h:140
llvm::ObjectSizeOpts::Mode::ExactUnderlyingSizeAndOffset
@ ExactUnderlyingSizeAndOffset
All branches must be known and have the same underlying size and offset to be merged.
llvm::ObjectSizeOpts::Mode::Max
@ Max
Same as Min, except we pick the maximum size of all of the branches.
llvm::ObjectSizeOpts::Mode::Min
@ Min
Evaluate all branches of an unknown condition.
llvm::ObjectSizeOpts::Mode::ExactSizeFromOffset
@ ExactSizeFromOffset
All branches must be known and have the same size, starting from the offset, to be merged.
llvm::OffsetSpan
OffsetSpan - Used internally by ObjectSizeOffsetVisitor.
Definition:MemoryBuiltins.h:230
llvm::OffsetSpan::knownBefore
bool knownBefore() const
Definition:MemoryBuiltins.h:237
llvm::OffsetSpan::After
APInt After
Number of allocated bytes before this point.
Definition:MemoryBuiltins.h:232
llvm::OffsetSpan::knownAfter
bool knownAfter() const
Definition:MemoryBuiltins.h:238
llvm::OffsetSpan::bothKnown
bool bothKnown() const
Definition:MemoryBuiltins.h:240
llvm::OffsetSpan::Before
APInt Before
Definition:MemoryBuiltins.h:231
llvm::SizeOffsetAPInt
SizeOffsetAPInt - Used by ObjectSizeOffsetVisitor, which works with APInts.
Definition:MemoryBuiltins.h:216
llvm::SizeOffsetType
SizeOffsetType - A base template class for the object size visitors.
Definition:MemoryBuiltins.h:192
llvm::SizeOffsetType::Size
T Size
Definition:MemoryBuiltins.h:194
llvm::SizeOffsetType::Offset
T Offset
Definition:MemoryBuiltins.h:195
llvm::SizeOffsetType::bothKnown
bool bothKnown() const
Definition:MemoryBuiltins.h:204
llvm::SizeOffsetValue
Definition:MemoryBuiltins.h:304
llvm::SizeOffsetValue::SizeOffsetValue
SizeOffsetValue()
Definition:MemoryBuiltins.h:305
llvm::SizeOffsetWeakTrackingVH
SizeOffsetWeakTrackingVH - Used by ObjectSizeOffsetEvaluator in a DenseMap.
Definition:MemoryBuiltins.h:315
llvm::cl::desc
Definition:CommandLine.h:409

Generated on Thu Jul 17 2025 10:58:58 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp