LLVM 24.0.0git
MemProfInstrumentation.cpp
Go to the documentation of this file.
1//===- MemProfInstrumentation.cpp - memory alloc and access instrumentation ==//
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 file is a part of MemProf. Memory accesses are instrumented
10// to increment the access count held in a shadow memory location, or
11// alternatively to call into the runtime. Memory intrinsic calls (memmove,
12// memcpy, memset) are changed to call the memory profiling runtime version
13// instead.
14//
15//===----------------------------------------------------------------------===//
16
20#include "llvm/ADT/Statistic.h"
21#include "llvm/ADT/StringRef.h"
25#include "llvm/IR/Constant.h"
26#include "llvm/IR/DataLayout.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/GlobalValue.h"
30#include "llvm/IR/IRBuilder.h"
31#include "llvm/IR/Instruction.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/Type.h"
35#include "llvm/IR/Value.h"
38#include "llvm/Support/Debug.h"
42
43using namespace llvm;
44using namespace llvm::memprof;
45
46#define DEBUG_TYPE "memprof"
47
48constexpr int LLVM_MEM_PROFILER_VERSION = 1;
49
50// Size of memory mapped to a single shadow location.
51[[maybe_unused]] constexpr uint64_t DefaultMemGranularity = 64;
52
53// Size of memory mapped to a single histogram bucket.
55
56constexpr char MemProfModuleCtorName[] = "memprof.module_ctor";
58// On Emscripten, the system needs more than one priorities for constructors.
60constexpr char MemProfInitName[] = "__memprof_init";
62 "__memprof_version_mismatch_check_v";
63
65 "__memprof_shadow_memory_dynamic_address";
66
67constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
68
69constexpr char MemProfHistogramFlagVar[] = "__memprof_histogram";
70
71// Instrumentation statistics
72STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
73STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
74STATISTIC(NumSkippedStackReads, "Number of non-instrumented stack reads");
75STATISTIC(NumSkippedStackWrites, "Number of non-instrumented stack writes");
76
77namespace {
78
79/// This struct defines the shadow mapping using the rule:
80/// shadow = ((mem & mask) >> Scale) ADD DynamicShadowOffset.
81struct ShadowMapping {
82 ShadowMapping(const InstrumentationOptions &Opts) {
83 Scale = Opts.memprof_mapping_scale;
84 Granularity = Opts.memprof_histogram ? HistogramGranularity
85 : Opts.memprof_mapping_granularity;
86 Mask = ~(Granularity - 1);
87 }
88
89 int Scale;
90 int Granularity;
91 uint64_t Mask; // Computed as ~(Granularity-1)
92};
93
94static uint64_t getCtorAndDtorPriority(Triple &TargetTriple) {
97}
98
99struct InterestingMemoryAccess {
100 Value *Addr = nullptr;
101 bool IsWrite;
102 Type *AccessTy;
103 Value *MaybeMask = nullptr;
104};
105
106/// Instrument the code in module to profile memory accesses.
107class MemProfiler {
108public:
109 MemProfiler(const InstrumentationOptions &Opts, Module &M)
110 : Opts(Opts), Mapping(Opts) {
111 C = &(M.getContext());
112 LongSize = M.getDataLayout().getPointerSizeInBits();
113 IntptrTy = Type::getIntNTy(*C, LongSize);
114 PtrTy = PointerType::getUnqual(*C);
115 }
116
117 /// If it is an interesting memory access, populate information
118 /// about the access and return a InterestingMemoryAccess struct.
119 /// Otherwise return std::nullopt.
120 std::optional<InterestingMemoryAccess>
121 isInterestingMemoryAccess(Instruction *I) const;
122
123 void instrumentMop(Instruction *I, const DataLayout &DL,
124 InterestingMemoryAccess &Access);
125 void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
126 Value *Addr, bool IsWrite);
127 void instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
128 Instruction *I, Value *Addr, Type *AccessTy,
129 bool IsWrite);
130 void instrumentMemIntrinsic(MemIntrinsic *MI);
131 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
132 bool instrumentFunction(Function &F);
133 bool maybeInsertMemProfInitAtFunctionEntry(Function &F);
134 bool insertDynamicShadowAtFunctionEntry(Function &F);
135
136private:
137 void initializeCallbacks(Module &M);
138
139 const InstrumentationOptions &Opts;
140 LLVMContext *C;
141 int LongSize;
142 Type *IntptrTy;
143 PointerType *PtrTy;
144 ShadowMapping Mapping;
145
146 // These arrays is indexed by AccessIsWrite
147 FunctionCallee MemProfMemoryAccessCallback[2];
148
149 FunctionCallee MemProfMemmove, MemProfMemcpy, MemProfMemset;
150 Value *DynamicShadowOffset = nullptr;
151};
152
153class ModuleMemProfiler {
154public:
155 ModuleMemProfiler(const InstrumentationOptions &Opts, Module &M)
156 : Opts(Opts), Mapping(Opts) {
157 TargetTriple = M.getTargetTriple();
158 }
159
160 bool instrumentModule(Module &);
161
162private:
163 const InstrumentationOptions &Opts;
164 Triple TargetTriple;
165 ShadowMapping Mapping;
166 Function *MemProfCtorFunction = nullptr;
167};
168
169} // end anonymous namespace
170
172
175 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
176 assert((!Opts.memprof_histogram ||
177 Opts.memprof_mapping_granularity == DefaultMemGranularity) &&
178 "Memprof with histogram only supports default mapping granularity");
179 Module &M = *F.getParent();
180 MemProfiler Profiler(Opts, M);
181 if (Profiler.instrumentFunction(F))
183 return PreservedAnalyses::all();
184}
185
187
190
191 ModuleMemProfiler Profiler(InstrumentationOptions::Global, M);
192 if (Profiler.instrumentModule(M))
194 return PreservedAnalyses::all();
195}
196
197Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
198 // (Shadow & mask) >> scale
199 Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
200 Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
201 // (Shadow >> scale) | offset
202 assert(DynamicShadowOffset);
203 return IRB.CreateAdd(Shadow, DynamicShadowOffset);
204}
205
206// Instrument memset/memmove/memcpy
207void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
208 IRBuilder<> IRB(MI);
210 IRB.CreateCall(isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
211 {MI->getOperand(0), MI->getOperand(1),
212 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
213 } else if (isa<MemSetInst>(MI)) {
214 IRB.CreateCall(
215 MemProfMemset,
216 {MI->getOperand(0),
217 IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
218 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
219 }
220 MI->eraseFromParent();
221}
222
223std::optional<InterestingMemoryAccess>
224MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
225 // Do not instrument the load fetching the dynamic shadow address.
226 if (DynamicShadowOffset == I)
227 return std::nullopt;
228
229 InterestingMemoryAccess Access;
230
231 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
232 if (!Opts.memprof_instrument_reads)
233 return std::nullopt;
234 Access.IsWrite = false;
235 Access.AccessTy = LI->getType();
236 Access.Addr = LI->getPointerOperand();
237 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
238 if (!Opts.memprof_instrument_writes)
239 return std::nullopt;
240 Access.IsWrite = true;
241 Access.AccessTy = SI->getValueOperand()->getType();
242 Access.Addr = SI->getPointerOperand();
243 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
244 if (!Opts.memprof_instrument_atomics)
245 return std::nullopt;
246 Access.IsWrite = true;
247 Access.AccessTy = RMW->getValOperand()->getType();
248 Access.Addr = RMW->getPointerOperand();
249 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
250 if (!Opts.memprof_instrument_atomics)
251 return std::nullopt;
252 Access.IsWrite = true;
253 Access.AccessTy = XCHG->getCompareOperand()->getType();
254 Access.Addr = XCHG->getPointerOperand();
255 } else if (auto *CI = dyn_cast<CallInst>(I)) {
256 auto *F = CI->getCalledFunction();
257 if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
258 F->getIntrinsicID() == Intrinsic::masked_store)) {
259 unsigned OpOffset = 0;
260 if (F->getIntrinsicID() == Intrinsic::masked_store) {
261 if (!Opts.memprof_instrument_writes)
262 return std::nullopt;
263 // Masked store has an initial operand for the value.
264 OpOffset = 1;
265 Access.AccessTy = CI->getArgOperand(0)->getType();
266 Access.IsWrite = true;
267 } else {
268 if (!Opts.memprof_instrument_reads)
269 return std::nullopt;
270 Access.AccessTy = CI->getType();
271 Access.IsWrite = false;
272 }
273
274 auto *BasePtr = CI->getOperand(0 + OpOffset);
275 Access.MaybeMask = CI->getOperand(1 + OpOffset);
276 Access.Addr = BasePtr;
277 }
278 }
279
280 if (!Access.Addr)
281 return std::nullopt;
282
283 // Do not instrument accesses from different address spaces; we cannot deal
284 // with them.
285 Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
286 if (PtrTy->getPointerAddressSpace() != 0)
287 return std::nullopt;
288
289 // Ignore swifterror addresses.
290 // swifterror memory addresses are mem2reg promoted by instruction
291 // selection. As such they cannot have regular uses like an instrumentation
292 // function and it makes no sense to track them as memory.
293 if (Access.Addr->isSwiftError())
294 return std::nullopt;
295
296 // Peel off GEPs and BitCasts.
297 auto *Addr = Access.Addr->stripInBoundsOffsets();
298
300 // Do not instrument PGO counter updates.
301 if (GV->hasSection()) {
302 StringRef SectionName = GV->getSection();
303 // Check if the global is in the PGO counters section.
304 auto OF = I->getModule()->getTargetTriple().getObjectFormat();
305 if (SectionName.ends_with(
306 getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false)))
307 return std::nullopt;
308 }
309
310 // Do not instrument accesses to LLVM internal variables.
311 if (GV->getName().starts_with("__llvm") ||
312 GV->getName().starts_with(getInstrProfVarPrefix()))
313 return std::nullopt;
314 }
315
316 return Access;
317}
318
319void MemProfiler::instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
320 Instruction *I, Value *Addr,
321 Type *AccessTy, bool IsWrite) {
322 auto *VTy = cast<FixedVectorType>(AccessTy);
323 unsigned Num = VTy->getNumElements();
324 auto *Zero = ConstantInt::get(IntptrTy, 0);
325 for (unsigned Idx = 0; Idx < Num; ++Idx) {
326 Value *InstrumentedAddress = nullptr;
327 Instruction *InsertBefore = I;
328 if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
329 // dyn_cast as we might get UndefValue
330 if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
331 if (Masked->isZero())
332 // Mask is constant false, so no instrumentation needed.
333 continue;
334 // If we have a true or undef value, fall through to instrumentAddress.
335 // with InsertBefore == I
336 }
337 } else {
338 IRBuilder<> IRB(I);
339 Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
340 Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
341 InsertBefore = ThenTerm;
342 }
343
344 IRBuilder<> IRB(InsertBefore);
345 InstrumentedAddress =
346 IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
347 instrumentAddress(I, InsertBefore, InstrumentedAddress, IsWrite);
348 }
349}
350
351void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
352 InterestingMemoryAccess &Access) {
353 // Skip instrumentation of stack accesses unless requested.
354 if (!Opts.memprof_instrument_stack &&
356 if (Access.IsWrite)
357 ++NumSkippedStackWrites;
358 else
359 ++NumSkippedStackReads;
360 return;
361 }
362
363 if (Access.IsWrite)
364 NumInstrumentedWrites++;
365 else
366 NumInstrumentedReads++;
367
368 if (Access.MaybeMask) {
369 instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
370 Access.AccessTy, Access.IsWrite);
371 } else {
372 // Since the access counts will be accumulated across the entire allocation,
373 // we only update the shadow access count for the first location and thus
374 // don't need to worry about alignment and type size.
375 instrumentAddress(I, I, Access.Addr, Access.IsWrite);
376 }
377}
378
379void MemProfiler::instrumentAddress(Instruction *OrigIns,
380 Instruction *InsertBefore, Value *Addr,
381 bool IsWrite) {
382 IRBuilder<> IRB(InsertBefore);
383 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
384
385 if (Opts.memprof_use_callbacks) {
386 IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
387 return;
388 }
389
390 Type *ShadowTy =
391 Opts.memprof_histogram ? Type::getInt8Ty(*C) : Type::getInt64Ty(*C);
392 Type *ShadowPtrTy = PointerType::get(*C, 0);
393
394 Value *ShadowPtr = memToShadow(AddrLong, IRB);
395 Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
396 Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
397 // If we are profiling with histograms, add overflow protection at 255.
398 if (Opts.memprof_histogram) {
399 Value *MaxCount = ConstantInt::get(Type::getInt8Ty(*C), 255);
400 Value *Cmp = IRB.CreateICmpULT(ShadowValue, MaxCount);
401 Instruction *IncBlock =
402 SplitBlockAndInsertIfThen(Cmp, InsertBefore, /*Unreachable=*/false);
403 IRB.SetInsertPoint(IncBlock);
404 }
405 Value *Inc = ConstantInt::get(ShadowTy, 1);
406 ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
407 IRB.CreateStore(ShadowValue, ShadowAddr);
408}
409
410// Create the variable for the profile file name.
412 const MDString *MemProfFilename =
413 dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
414 if (!MemProfFilename)
415 return;
416 assert(!MemProfFilename->getString().empty() &&
417 "Unexpected MemProfProfileFilename metadata with empty string");
418 Constant *ProfileNameConst = ConstantDataArray::getString(
419 M.getContext(), MemProfFilename->getString(), true);
420 GlobalVariable *ProfileNameVar = new GlobalVariable(
421 M, ProfileNameConst->getType(), /*isConstant=*/true,
423 const Triple &TT = M.getTargetTriple();
424 if (TT.supportsCOMDAT()) {
426 ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
427 }
428}
429
430// Set MemprofHistogramFlag as a Global variable in IR. This makes it accessible
431// to the runtime, changing shadow count behavior.
432void createMemprofHistogramFlagVar(const InstrumentationOptions &Opts,
433 Module &M) {
434 const StringRef VarName(MemProfHistogramFlagVar);
435 Type *IntTy1 = Type::getInt1Ty(M.getContext());
436 auto MemprofHistogramFlag = new GlobalVariable(
437 M, IntTy1, true, GlobalValue::WeakAnyLinkage,
438 Constant::getIntegerValue(IntTy1, APInt(1, Opts.memprof_histogram)),
439 VarName);
440 const Triple &TT = M.getTargetTriple();
441 if (TT.supportsCOMDAT()) {
442 MemprofHistogramFlag->setLinkage(GlobalValue::ExternalLinkage);
443 MemprofHistogramFlag->setComdat(M.getOrInsertComdat(VarName));
444 }
445 appendToCompilerUsed(M, MemprofHistogramFlag);
446}
447
448void createMemprofDefaultOptionsVar(const InstrumentationOptions &Opts,
449 Module &M) {
451 M.getContext(), Opts.memprof_runtime_default_options, /*AddNull=*/true);
452 GlobalVariable *OptionsVar =
453 new GlobalVariable(M, OptionsConst->getType(), /*isConstant=*/true,
454 GlobalValue::WeakAnyLinkage, OptionsConst,
456 const Triple &TT = M.getTargetTriple();
457 if (TT.supportsCOMDAT()) {
459 OptionsVar->setComdat(M.getOrInsertComdat(OptionsVar->getName()));
460 }
461}
462
463bool ModuleMemProfiler::instrumentModule(Module &M) {
464
465 // Create a module constructor.
466 std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
467 std::string VersionCheckName =
468 Opts.memprof_guard_against_version_mismatch
469 ? (MemProfVersionCheckNamePrefix + MemProfVersion)
470 : "";
471 std::tie(MemProfCtorFunction, std::ignore) =
473 MemProfInitName, /*InitArgTypes=*/{},
474 /*InitArgs=*/{}, VersionCheckName);
475
476 const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
477 appendToGlobalCtors(M, MemProfCtorFunction, Priority);
478
480
482
484
485 return true;
486}
487
488void MemProfiler::initializeCallbacks(Module &M) {
489 IRBuilder<> IRB(M);
490
491 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
492 const std::string TypeStr = AccessIsWrite ? "store" : "load";
493 const std::string HistPrefix = Opts.memprof_histogram ? "hist_" : "";
494
495 SmallVector<Type *, 2> Args1{1, IntptrTy};
496 MemProfMemoryAccessCallback[AccessIsWrite] = M.getOrInsertFunction(
497 (Opts.memprof_memory_access_callback_prefix + HistPrefix + TypeStr)
498 .str(),
499 FunctionType::get(IRB.getVoidTy(), Args1, false));
500 }
501 MemProfMemmove = M.getOrInsertFunction(
502 (Opts.memprof_memory_access_callback_prefix + "memmove").str(), PtrTy,
503 PtrTy, PtrTy, IntptrTy);
504 MemProfMemcpy = M.getOrInsertFunction(
505 (Opts.memprof_memory_access_callback_prefix + "memcpy").str(), PtrTy,
506 PtrTy, PtrTy, IntptrTy);
507 MemProfMemset = M.getOrInsertFunction(
508 (Opts.memprof_memory_access_callback_prefix + "memset").str(), PtrTy,
509 PtrTy, IRB.getInt32Ty(), IntptrTy);
510}
511
512bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
513 // For each NSObject descendant having a +load method, this method is invoked
514 // by the ObjC runtime before any of the static constructors is called.
515 // Therefore we need to instrument such methods with a call to __memprof_init
516 // at the beginning in order to initialize our runtime before any access to
517 // the shadow memory.
518 // We cannot just ignore these methods, because they may call other
519 // instrumented functions.
520 if (F.getName().contains(" load]")) {
521 FunctionCallee MemProfInitFunction =
523 IRBuilder<> IRB(F.front().begin());
524 IRB.CreateCall(MemProfInitFunction, {});
525 return true;
526 }
527 return false;
528}
529
530bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
531 IRBuilder<> IRB(&F.front().front());
532 Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
534 if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
535 cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
536 DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
537 return true;
538}
539
540bool MemProfiler::instrumentFunction(Function &F) {
541 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
542 return false;
543 if (Opts.memprof_debug_func == F.getName())
544 return false;
545 if (F.getName().starts_with("__memprof_"))
546 return false;
547
548 bool FunctionModified = false;
549
550 // If needed, insert __memprof_init.
551 // This function needs to be called even if the function body is not
552 // instrumented.
553 if (maybeInsertMemProfInitAtFunctionEntry(F))
554 FunctionModified = true;
555
556 LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
557
558 initializeCallbacks(*F.getParent());
559
561
562 // Fill the set of memory operations to instrument.
563 for (auto &BB : F) {
564 for (auto &Inst : BB) {
565 if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
566 ToInstrument.push_back(&Inst);
567 }
568 }
569
570 if (ToInstrument.empty()) {
571 LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified
572 << " " << F << "\n");
573
574 return FunctionModified;
575 }
576
577 FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
578
579 int NumInstrumented = 0;
580 for (auto *Inst : ToInstrument) {
581 if (Opts.memprof_debug_min < 0 || Opts.memprof_debug_max < 0 ||
582 (NumInstrumented >= Opts.memprof_debug_min &&
583 NumInstrumented <= Opts.memprof_debug_max)) {
584 std::optional<InterestingMemoryAccess> Access =
585 isInterestingMemoryAccess(Inst);
586 if (Access)
587 instrumentMop(Inst, F.getDataLayout(), *Access);
588 else
589 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
590 }
591 NumInstrumented++;
592 }
593
594 if (NumInstrumented > 0)
595 FunctionModified = true;
596
597 LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
598 << F << "\n");
599
600 return FunctionModified;
601}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
DXIL Resource Access
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
constexpr char MemProfVersionCheckNamePrefix[]
constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority
constexpr char MemProfShadowMemoryDynamicAddress[]
constexpr uint64_t MemProfCtorAndDtorPriority
constexpr int LLVM_MEM_PROFILER_VERSION
constexpr char MemProfInitName[]
constexpr char MemProfFilenameVar[]
constexpr uint64_t DefaultMemGranularity
constexpr uint64_t HistogramGranularity
constexpr char MemProfModuleCtorName[]
void createMemprofDefaultOptionsVar(const InstrumentationOptions &Opts, Module &M)
constexpr char MemProfHistogramFlagVar[]
void createMemprofHistogramFlagVar(const InstrumentationOptions &Opts, Module &M)
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
Class for arbitrary precision integers.
Definition APInt.h:78
A container for analyses that lazily runs them and caches their results.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
void setLinkage(LinkageTypes LT)
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition GlobalValue.h:57
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2407
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2666
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2306
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2247
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1537
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:531
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2020
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1916
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1575
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1934
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1427
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2570
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2332
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:199
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:569
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2918
An instruction for reading from memory.
A single uniqued string.
Definition Metadata.h:733
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:615
This is the common base class for memset/memcpy/memmove.
LLVM_ABI MemProfilerPass()
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition Triple.h:846
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
void instrumentAddress(Module &M, IRBuilder<> &IRB, Instruction *OrigIns, Instruction *InsertBefore, Value *Addr, Align Alignment, TypeSize TypeStoreSize, bool IsWrite, Value *SizeArgument, bool UseCalls, bool Recover, int AsanScale, int AsanOffset)
Instrument the memory operand Addr.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
llvm::StringRef getMemprofOptionsSymbolName()
Definition MemProf.h:60
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
LLVM_ABI std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
StringRef getInstrProfVarPrefix()
Return the prefix of the name of the variables to function as a filter.
Definition InstrProf.h:123
LLVM_ABI void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput)
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...