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 =
176 F.getContext().getLibraryOptions().get<InstrumentationOptions>();
177 assert((!Opts.memprof_histogram ||
178 Opts.memprof_mapping_granularity == DefaultMemGranularity) &&
179 "Memprof with histogram only supports default mapping granularity");
180 Module &M = *F.getParent();
181 MemProfiler Profiler(Opts, M);
182 if (Profiler.instrumentFunction(F))
184 return PreservedAnalyses::all();
185}
186
188
191
192 const InstrumentationOptions &Opts =
193 M.getContext().getLibraryOptions().get<InstrumentationOptions>();
194 ModuleMemProfiler Profiler(Opts, M);
195 if (Profiler.instrumentModule(M))
197 return PreservedAnalyses::all();
198}
199
200Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
201 // (Shadow & mask) >> scale
202 Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
203 Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
204 // (Shadow >> scale) | offset
205 assert(DynamicShadowOffset);
206 return IRB.CreateAdd(Shadow, DynamicShadowOffset);
207}
208
209// Instrument memset/memmove/memcpy
210void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
211 IRBuilder<> IRB(MI);
213 IRB.CreateCall(isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
214 {MI->getOperand(0), MI->getOperand(1),
215 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
216 } else if (isa<MemSetInst>(MI)) {
217 IRB.CreateCall(
218 MemProfMemset,
219 {MI->getOperand(0),
220 IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
221 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
222 }
223 MI->eraseFromParent();
224}
225
226std::optional<InterestingMemoryAccess>
227MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
228 // Do not instrument the load fetching the dynamic shadow address.
229 if (DynamicShadowOffset == I)
230 return std::nullopt;
231
232 InterestingMemoryAccess Access;
233
234 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
235 if (!Opts.memprof_instrument_reads)
236 return std::nullopt;
237 Access.IsWrite = false;
238 Access.AccessTy = LI->getType();
239 Access.Addr = LI->getPointerOperand();
240 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
241 if (!Opts.memprof_instrument_writes)
242 return std::nullopt;
243 Access.IsWrite = true;
244 Access.AccessTy = SI->getValueOperand()->getType();
245 Access.Addr = SI->getPointerOperand();
246 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
247 if (!Opts.memprof_instrument_atomics)
248 return std::nullopt;
249 Access.IsWrite = true;
250 Access.AccessTy = RMW->getValOperand()->getType();
251 Access.Addr = RMW->getPointerOperand();
252 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
253 if (!Opts.memprof_instrument_atomics)
254 return std::nullopt;
255 Access.IsWrite = true;
256 Access.AccessTy = XCHG->getCompareOperand()->getType();
257 Access.Addr = XCHG->getPointerOperand();
258 } else if (auto *CI = dyn_cast<CallInst>(I)) {
259 auto *F = CI->getCalledFunction();
260 if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
261 F->getIntrinsicID() == Intrinsic::masked_store)) {
262 unsigned OpOffset = 0;
263 if (F->getIntrinsicID() == Intrinsic::masked_store) {
264 if (!Opts.memprof_instrument_writes)
265 return std::nullopt;
266 // Masked store has an initial operand for the value.
267 OpOffset = 1;
268 Access.AccessTy = CI->getArgOperand(0)->getType();
269 Access.IsWrite = true;
270 } else {
271 if (!Opts.memprof_instrument_reads)
272 return std::nullopt;
273 Access.AccessTy = CI->getType();
274 Access.IsWrite = false;
275 }
276
277 auto *BasePtr = CI->getOperand(0 + OpOffset);
278 Access.MaybeMask = CI->getOperand(1 + OpOffset);
279 Access.Addr = BasePtr;
280 }
281 }
282
283 if (!Access.Addr)
284 return std::nullopt;
285
286 // Do not instrument accesses from different address spaces; we cannot deal
287 // with them.
288 Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
289 if (PtrTy->getPointerAddressSpace() != 0)
290 return std::nullopt;
291
292 // Ignore swifterror addresses.
293 // swifterror memory addresses are mem2reg promoted by instruction
294 // selection. As such they cannot have regular uses like an instrumentation
295 // function and it makes no sense to track them as memory.
296 if (Access.Addr->isSwiftError())
297 return std::nullopt;
298
299 // Peel off GEPs and BitCasts.
300 auto *Addr = Access.Addr->stripInBoundsOffsets();
301
303 // Do not instrument PGO counter updates.
304 if (GV->hasSection()) {
305 StringRef SectionName = GV->getSection();
306 // Check if the global is in the PGO counters section.
307 auto OF = I->getModule()->getTargetTriple().getObjectFormat();
308 if (SectionName.ends_with(
309 getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false)))
310 return std::nullopt;
311 }
312
313 // Do not instrument accesses to LLVM internal variables.
314 if (GV->getName().starts_with("__llvm") ||
315 GV->getName().starts_with(getInstrProfVarPrefix()))
316 return std::nullopt;
317 }
318
319 return Access;
320}
321
322void MemProfiler::instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
323 Instruction *I, Value *Addr,
324 Type *AccessTy, bool IsWrite) {
325 auto *VTy = cast<FixedVectorType>(AccessTy);
326 unsigned Num = VTy->getNumElements();
327 auto *Zero = ConstantInt::get(IntptrTy, 0);
328 for (unsigned Idx = 0; Idx < Num; ++Idx) {
329 Value *InstrumentedAddress = nullptr;
330 Instruction *InsertBefore = I;
331 if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
332 // dyn_cast as we might get UndefValue
333 if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
334 if (Masked->isZero())
335 // Mask is constant false, so no instrumentation needed.
336 continue;
337 // If we have a true or undef value, fall through to instrumentAddress.
338 // with InsertBefore == I
339 }
340 } else {
341 IRBuilder<> IRB(I);
342 Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
343 Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
344 InsertBefore = ThenTerm;
345 }
346
347 IRBuilder<> IRB(InsertBefore);
348 InstrumentedAddress =
349 IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
350 instrumentAddress(I, InsertBefore, InstrumentedAddress, IsWrite);
351 }
352}
353
354void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
355 InterestingMemoryAccess &Access) {
356 // Skip instrumentation of stack accesses unless requested.
357 if (!Opts.memprof_instrument_stack &&
359 if (Access.IsWrite)
360 ++NumSkippedStackWrites;
361 else
362 ++NumSkippedStackReads;
363 return;
364 }
365
366 if (Access.IsWrite)
367 NumInstrumentedWrites++;
368 else
369 NumInstrumentedReads++;
370
371 if (Access.MaybeMask) {
372 instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
373 Access.AccessTy, Access.IsWrite);
374 } else {
375 // Since the access counts will be accumulated across the entire allocation,
376 // we only update the shadow access count for the first location and thus
377 // don't need to worry about alignment and type size.
378 instrumentAddress(I, I, Access.Addr, Access.IsWrite);
379 }
380}
381
382void MemProfiler::instrumentAddress(Instruction *OrigIns,
383 Instruction *InsertBefore, Value *Addr,
384 bool IsWrite) {
385 IRBuilder<> IRB(InsertBefore);
386 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
387
388 if (Opts.memprof_use_callbacks) {
389 IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
390 return;
391 }
392
393 Type *ShadowTy =
394 Opts.memprof_histogram ? Type::getInt8Ty(*C) : Type::getInt64Ty(*C);
395 Type *ShadowPtrTy = PointerType::get(*C, 0);
396
397 Value *ShadowPtr = memToShadow(AddrLong, IRB);
398 Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
399 Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
400 // If we are profiling with histograms, add overflow protection at 255.
401 if (Opts.memprof_histogram) {
402 Value *MaxCount = ConstantInt::get(Type::getInt8Ty(*C), 255);
403 Value *Cmp = IRB.CreateICmpULT(ShadowValue, MaxCount);
404 Instruction *IncBlock =
405 SplitBlockAndInsertIfThen(Cmp, InsertBefore, /*Unreachable=*/false);
406 IRB.SetInsertPoint(IncBlock);
407 }
408 Value *Inc = ConstantInt::get(ShadowTy, 1);
409 ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
410 IRB.CreateStore(ShadowValue, ShadowAddr);
411}
412
413// Create the variable for the profile file name.
415 const MDString *MemProfFilename =
416 dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
417 if (!MemProfFilename)
418 return;
419 assert(!MemProfFilename->getString().empty() &&
420 "Unexpected MemProfProfileFilename metadata with empty string");
421 Constant *ProfileNameConst = ConstantDataArray::getString(
422 M.getContext(), MemProfFilename->getString(), true);
423 GlobalVariable *ProfileNameVar = new GlobalVariable(
424 M, ProfileNameConst->getType(), /*isConstant=*/true,
426 const Triple &TT = M.getTargetTriple();
427 if (TT.supportsCOMDAT()) {
429 ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
430 }
431}
432
433// Set MemprofHistogramFlag as a Global variable in IR. This makes it accessible
434// to the runtime, changing shadow count behavior.
435void createMemprofHistogramFlagVar(const InstrumentationOptions &Opts,
436 Module &M) {
437 const StringRef VarName(MemProfHistogramFlagVar);
438 Type *IntTy1 = Type::getInt1Ty(M.getContext());
439 auto MemprofHistogramFlag = new GlobalVariable(
440 M, IntTy1, true, GlobalValue::WeakAnyLinkage,
441 Constant::getIntegerValue(IntTy1, APInt(1, Opts.memprof_histogram)),
442 VarName);
443 const Triple &TT = M.getTargetTriple();
444 if (TT.supportsCOMDAT()) {
445 MemprofHistogramFlag->setLinkage(GlobalValue::ExternalLinkage);
446 MemprofHistogramFlag->setComdat(M.getOrInsertComdat(VarName));
447 }
448 appendToCompilerUsed(M, MemprofHistogramFlag);
449}
450
451void createMemprofDefaultOptionsVar(const InstrumentationOptions &Opts,
452 Module &M) {
454 M.getContext(), Opts.memprof_runtime_default_options, /*AddNull=*/true);
455 GlobalVariable *OptionsVar =
456 new GlobalVariable(M, OptionsConst->getType(), /*isConstant=*/true,
457 GlobalValue::WeakAnyLinkage, OptionsConst,
459 const Triple &TT = M.getTargetTriple();
460 if (TT.supportsCOMDAT()) {
462 OptionsVar->setComdat(M.getOrInsertComdat(OptionsVar->getName()));
463 }
464}
465
466bool ModuleMemProfiler::instrumentModule(Module &M) {
467
468 // Create a module constructor.
469 std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
470 std::string VersionCheckName =
471 Opts.memprof_guard_against_version_mismatch
472 ? (MemProfVersionCheckNamePrefix + MemProfVersion)
473 : "";
474 std::tie(MemProfCtorFunction, std::ignore) =
476 MemProfInitName, /*InitArgTypes=*/{},
477 /*InitArgs=*/{}, VersionCheckName);
478
479 const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
480 appendToGlobalCtors(M, MemProfCtorFunction, Priority);
481
483
485
487
488 return true;
489}
490
491void MemProfiler::initializeCallbacks(Module &M) {
492 IRBuilder<> IRB(M);
493
494 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
495 const std::string TypeStr = AccessIsWrite ? "store" : "load";
496 const std::string HistPrefix = Opts.memprof_histogram ? "hist_" : "";
497
498 SmallVector<Type *, 2> Args1{1, IntptrTy};
499 MemProfMemoryAccessCallback[AccessIsWrite] = M.getOrInsertFunction(
500 (Opts.memprof_memory_access_callback_prefix + HistPrefix + TypeStr)
501 .str(),
502 FunctionType::get(IRB.getVoidTy(), Args1, false));
503 }
504 MemProfMemmove = M.getOrInsertFunction(
505 (Opts.memprof_memory_access_callback_prefix + "memmove").str(), PtrTy,
506 PtrTy, PtrTy, IntptrTy);
507 MemProfMemcpy = M.getOrInsertFunction(
508 (Opts.memprof_memory_access_callback_prefix + "memcpy").str(), PtrTy,
509 PtrTy, PtrTy, IntptrTy);
510 MemProfMemset = M.getOrInsertFunction(
511 (Opts.memprof_memory_access_callback_prefix + "memset").str(), PtrTy,
512 PtrTy, IRB.getInt32Ty(), IntptrTy);
513}
514
515bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
516 // For each NSObject descendant having a +load method, this method is invoked
517 // by the ObjC runtime before any of the static constructors is called.
518 // Therefore we need to instrument such methods with a call to __memprof_init
519 // at the beginning in order to initialize our runtime before any access to
520 // the shadow memory.
521 // We cannot just ignore these methods, because they may call other
522 // instrumented functions.
523 if (F.getName().contains(" load]")) {
524 FunctionCallee MemProfInitFunction =
526 IRBuilder<> IRB(F.front().begin());
527 IRB.CreateCall(MemProfInitFunction, {});
528 return true;
529 }
530 return false;
531}
532
533bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
534 IRBuilder<> IRB(&F.front().front());
535 Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
537 if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
538 cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
539 DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
540 return true;
541}
542
543bool MemProfiler::instrumentFunction(Function &F) {
544 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
545 return false;
546 if (Opts.memprof_debug_func == F.getName())
547 return false;
548 if (F.getName().starts_with("__memprof_"))
549 return false;
550
551 bool FunctionModified = false;
552
553 // If needed, insert __memprof_init.
554 // This function needs to be called even if the function body is not
555 // instrumented.
556 if (maybeInsertMemProfInitAtFunctionEntry(F))
557 FunctionModified = true;
558
559 LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
560
561 initializeCallbacks(*F.getParent());
562
564
565 // Fill the set of memory operations to instrument.
566 for (auto &BB : F) {
567 for (auto &Inst : BB) {
568 if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
569 ToInstrument.push_back(&Inst);
570 }
571 }
572
573 if (ToInstrument.empty()) {
574 LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified
575 << " " << F << "\n");
576
577 return FunctionModified;
578 }
579
580 FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
581
582 int NumInstrumented = 0;
583 for (auto *Inst : ToInstrument) {
584 if (Opts.memprof_debug_min < 0 || Opts.memprof_debug_max < 0 ||
585 (NumInstrumented >= Opts.memprof_debug_min &&
586 NumInstrumented <= Opts.memprof_debug_max)) {
587 std::optional<InterestingMemoryAccess> Access =
588 isInterestingMemoryAccess(Inst);
589 if (Access)
590 instrumentMop(Inst, F.getDataLayout(), *Access);
591 else
592 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
593 }
594 NumInstrumented++;
595 }
596
597 if (NumInstrumented > 0)
598 FunctionModified = true;
599
600 LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
601 << F << "\n");
602
603 return FunctionModified;
604}
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 ...