LLVM 23.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
19#include "llvm/ADT/Statistic.h"
20#include "llvm/ADT/StringRef.h"
24#include "llvm/IR/Constant.h"
25#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/GlobalValue.h"
29#include "llvm/IR/IRBuilder.h"
30#include "llvm/IR/Instruction.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/Type.h"
34#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.
52
53// Size of memory mapped to a single histogram bucket.
55
56// Scale from granularity down to shadow size.
58
59constexpr char MemProfModuleCtorName[] = "memprof.module_ctor";
61// On Emscripten, the system needs more than one priorities for constructors.
63constexpr char MemProfInitName[] = "__memprof_init";
65 "__memprof_version_mismatch_check_v";
66
68 "__memprof_shadow_memory_dynamic_address";
69
70constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
71
72constexpr char MemProfHistogramFlagVar[] = "__memprof_histogram";
73
74// Command-line flags.
75
77 "memprof-guard-against-version-mismatch",
78 cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden,
79 cl::init(true));
80
81// This flag may need to be replaced with -f[no-]memprof-reads.
82static cl::opt<bool> ClInstrumentReads("memprof-instrument-reads",
83 cl::desc("instrument read instructions"),
84 cl::Hidden, cl::init(true));
85
86static cl::opt<bool>
87 ClInstrumentWrites("memprof-instrument-writes",
88 cl::desc("instrument write instructions"), cl::Hidden,
89 cl::init(true));
90
92 "memprof-instrument-atomics",
93 cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
94 cl::init(true));
95
97 "memprof-use-callbacks",
98 cl::desc("Use callbacks instead of inline instrumentation sequences."),
99 cl::Hidden, cl::init(false));
100
102 ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix",
103 cl::desc("Prefix for memory access callbacks"),
104 cl::Hidden, cl::init("__memprof_"));
105
106// These flags allow to change the shadow mapping.
107// The shadow mapping looks like
108// Shadow = ((Mem & mask) >> scale) + offset
109
110static cl::opt<int> ClMappingScale("memprof-mapping-scale",
111 cl::desc("scale of memprof shadow mapping"),
113
114static cl::opt<int>
115 ClMappingGranularity("memprof-mapping-granularity",
116 cl::desc("granularity of memprof shadow mapping"),
118
119static cl::opt<bool> ClStack("memprof-instrument-stack",
120 cl::desc("Instrument scalar stack variables"),
121 cl::Hidden, cl::init(false));
122
123// Debug flags.
124
125static cl::opt<int> ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden,
126 cl::init(0));
127
128static cl::opt<std::string> ClDebugFunc("memprof-debug-func", cl::Hidden,
129 cl::desc("Debug func"));
130
131static cl::opt<int> ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"),
132 cl::Hidden, cl::init(-1));
133
134static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"),
135 cl::Hidden, cl::init(-1));
136
137static cl::opt<bool> ClHistogram("memprof-histogram",
138 cl::desc("Collect access count histograms"),
139 cl::Hidden, cl::init(false));
140
142 MemprofRuntimeDefaultOptions("memprof-runtime-default-options",
143 cl::desc("The default memprof options"),
144 cl::Hidden, cl::init(""));
145
146// Instrumentation statistics
147STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
148STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
149STATISTIC(NumSkippedStackReads, "Number of non-instrumented stack reads");
150STATISTIC(NumSkippedStackWrites, "Number of non-instrumented stack writes");
151
152namespace {
153
154/// This struct defines the shadow mapping using the rule:
155/// shadow = ((mem & mask) >> Scale) ADD DynamicShadowOffset.
156struct ShadowMapping {
157 ShadowMapping() {
158 Scale = ClMappingScale;
160 Mask = ~(Granularity - 1);
161 }
162
163 int Scale;
164 int Granularity;
165 uint64_t Mask; // Computed as ~(Granularity-1)
166};
167
168static uint64_t getCtorAndDtorPriority(Triple &TargetTriple) {
171}
172
173struct InterestingMemoryAccess {
174 Value *Addr = nullptr;
175 bool IsWrite;
176 Type *AccessTy;
177 Value *MaybeMask = nullptr;
178};
179
180/// Instrument the code in module to profile memory accesses.
181class MemProfiler {
182public:
183 MemProfiler(Module &M) {
184 C = &(M.getContext());
185 LongSize = M.getDataLayout().getPointerSizeInBits();
186 IntptrTy = Type::getIntNTy(*C, LongSize);
187 PtrTy = PointerType::getUnqual(*C);
188 }
189
190 /// If it is an interesting memory access, populate information
191 /// about the access and return a InterestingMemoryAccess struct.
192 /// Otherwise return std::nullopt.
193 std::optional<InterestingMemoryAccess>
194 isInterestingMemoryAccess(Instruction *I) const;
195
196 void instrumentMop(Instruction *I, const DataLayout &DL,
197 InterestingMemoryAccess &Access);
198 void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
199 Value *Addr, bool IsWrite);
200 void instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
201 Instruction *I, Value *Addr, Type *AccessTy,
202 bool IsWrite);
203 void instrumentMemIntrinsic(MemIntrinsic *MI);
204 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
205 bool instrumentFunction(Function &F);
206 bool maybeInsertMemProfInitAtFunctionEntry(Function &F);
207 bool insertDynamicShadowAtFunctionEntry(Function &F);
208
209private:
210 void initializeCallbacks(Module &M);
211
212 LLVMContext *C;
213 int LongSize;
214 Type *IntptrTy;
215 PointerType *PtrTy;
216 ShadowMapping Mapping;
217
218 // These arrays is indexed by AccessIsWrite
219 FunctionCallee MemProfMemoryAccessCallback[2];
220
221 FunctionCallee MemProfMemmove, MemProfMemcpy, MemProfMemset;
222 Value *DynamicShadowOffset = nullptr;
223};
224
225class ModuleMemProfiler {
226public:
227 ModuleMemProfiler(Module &M) { TargetTriple = M.getTargetTriple(); }
228
229 bool instrumentModule(Module &);
230
231private:
232 Triple TargetTriple;
233 ShadowMapping Mapping;
234 Function *MemProfCtorFunction = nullptr;
235};
236
237} // end anonymous namespace
238
240
244 "Memprof with histogram only supports default mapping granularity");
245 Module &M = *F.getParent();
246 MemProfiler Profiler(M);
247 if (Profiler.instrumentFunction(F))
249 return PreservedAnalyses::all();
250}
251
253
256
257 ModuleMemProfiler Profiler(M);
258 if (Profiler.instrumentModule(M))
260 return PreservedAnalyses::all();
261}
262
263Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
264 // (Shadow & mask) >> scale
265 Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
266 Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
267 // (Shadow >> scale) | offset
268 assert(DynamicShadowOffset);
269 return IRB.CreateAdd(Shadow, DynamicShadowOffset);
270}
271
272// Instrument memset/memmove/memcpy
273void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
274 IRBuilder<> IRB(MI);
276 IRB.CreateCall(isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
277 {MI->getOperand(0), MI->getOperand(1),
278 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
279 } else if (isa<MemSetInst>(MI)) {
280 IRB.CreateCall(
281 MemProfMemset,
282 {MI->getOperand(0),
283 IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
284 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
285 }
286 MI->eraseFromParent();
287}
288
289std::optional<InterestingMemoryAccess>
290MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
291 // Do not instrument the load fetching the dynamic shadow address.
292 if (DynamicShadowOffset == I)
293 return std::nullopt;
294
295 InterestingMemoryAccess Access;
296
297 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
299 return std::nullopt;
300 Access.IsWrite = false;
301 Access.AccessTy = LI->getType();
302 Access.Addr = LI->getPointerOperand();
303 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
305 return std::nullopt;
306 Access.IsWrite = true;
307 Access.AccessTy = SI->getValueOperand()->getType();
308 Access.Addr = SI->getPointerOperand();
309 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
311 return std::nullopt;
312 Access.IsWrite = true;
313 Access.AccessTy = RMW->getValOperand()->getType();
314 Access.Addr = RMW->getPointerOperand();
315 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
317 return std::nullopt;
318 Access.IsWrite = true;
319 Access.AccessTy = XCHG->getCompareOperand()->getType();
320 Access.Addr = XCHG->getPointerOperand();
321 } else if (auto *CI = dyn_cast<CallInst>(I)) {
322 auto *F = CI->getCalledFunction();
323 if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
324 F->getIntrinsicID() == Intrinsic::masked_store)) {
325 unsigned OpOffset = 0;
326 if (F->getIntrinsicID() == Intrinsic::masked_store) {
328 return std::nullopt;
329 // Masked store has an initial operand for the value.
330 OpOffset = 1;
331 Access.AccessTy = CI->getArgOperand(0)->getType();
332 Access.IsWrite = true;
333 } else {
335 return std::nullopt;
336 Access.AccessTy = CI->getType();
337 Access.IsWrite = false;
338 }
339
340 auto *BasePtr = CI->getOperand(0 + OpOffset);
341 Access.MaybeMask = CI->getOperand(1 + OpOffset);
342 Access.Addr = BasePtr;
343 }
344 }
345
346 if (!Access.Addr)
347 return std::nullopt;
348
349 // Do not instrument accesses from different address spaces; we cannot deal
350 // with them.
351 Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
352 if (PtrTy->getPointerAddressSpace() != 0)
353 return std::nullopt;
354
355 // Ignore swifterror addresses.
356 // swifterror memory addresses are mem2reg promoted by instruction
357 // selection. As such they cannot have regular uses like an instrumentation
358 // function and it makes no sense to track them as memory.
359 if (Access.Addr->isSwiftError())
360 return std::nullopt;
361
362 // Peel off GEPs and BitCasts.
363 auto *Addr = Access.Addr->stripInBoundsOffsets();
364
366 // Do not instrument PGO counter updates.
367 if (GV->hasSection()) {
368 StringRef SectionName = GV->getSection();
369 // Check if the global is in the PGO counters section.
370 auto OF = I->getModule()->getTargetTriple().getObjectFormat();
371 if (SectionName.ends_with(
372 getInstrProfSectionName(IPSK_cnts, OF, /*AddSegmentInfo=*/false)))
373 return std::nullopt;
374 }
375
376 // Do not instrument accesses to LLVM internal variables.
377 if (GV->getName().starts_with("__llvm") ||
378 GV->getName().starts_with(getInstrProfVarPrefix()))
379 return std::nullopt;
380 }
381
382 return Access;
383}
384
385void MemProfiler::instrumentMaskedLoadOrStore(const DataLayout &DL, Value *Mask,
386 Instruction *I, Value *Addr,
387 Type *AccessTy, bool IsWrite) {
388 auto *VTy = cast<FixedVectorType>(AccessTy);
389 unsigned Num = VTy->getNumElements();
390 auto *Zero = ConstantInt::get(IntptrTy, 0);
391 for (unsigned Idx = 0; Idx < Num; ++Idx) {
392 Value *InstrumentedAddress = nullptr;
393 Instruction *InsertBefore = I;
394 if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
395 // dyn_cast as we might get UndefValue
396 if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
397 if (Masked->isZero())
398 // Mask is constant false, so no instrumentation needed.
399 continue;
400 // If we have a true or undef value, fall through to instrumentAddress.
401 // with InsertBefore == I
402 }
403 } else {
404 IRBuilder<> IRB(I);
405 Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
406 Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
407 InsertBefore = ThenTerm;
408 }
409
410 IRBuilder<> IRB(InsertBefore);
411 InstrumentedAddress =
412 IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
413 instrumentAddress(I, InsertBefore, InstrumentedAddress, IsWrite);
414 }
415}
416
417void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
418 InterestingMemoryAccess &Access) {
419 // Skip instrumentation of stack accesses unless requested.
421 if (Access.IsWrite)
422 ++NumSkippedStackWrites;
423 else
424 ++NumSkippedStackReads;
425 return;
426 }
427
428 if (Access.IsWrite)
429 NumInstrumentedWrites++;
430 else
431 NumInstrumentedReads++;
432
433 if (Access.MaybeMask) {
434 instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
435 Access.AccessTy, Access.IsWrite);
436 } else {
437 // Since the access counts will be accumulated across the entire allocation,
438 // we only update the shadow access count for the first location and thus
439 // don't need to worry about alignment and type size.
440 instrumentAddress(I, I, Access.Addr, Access.IsWrite);
441 }
442}
443
444void MemProfiler::instrumentAddress(Instruction *OrigIns,
445 Instruction *InsertBefore, Value *Addr,
446 bool IsWrite) {
447 IRBuilder<> IRB(InsertBefore);
448 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
449
450 if (ClUseCalls) {
451 IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
452 return;
453 }
454
455 Type *ShadowTy = ClHistogram ? Type::getInt8Ty(*C) : Type::getInt64Ty(*C);
456 Type *ShadowPtrTy = PointerType::get(*C, 0);
457
458 Value *ShadowPtr = memToShadow(AddrLong, IRB);
459 Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
460 Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
461 // If we are profiling with histograms, add overflow protection at 255.
462 if (ClHistogram) {
463 Value *MaxCount = ConstantInt::get(Type::getInt8Ty(*C), 255);
464 Value *Cmp = IRB.CreateICmpULT(ShadowValue, MaxCount);
465 Instruction *IncBlock =
466 SplitBlockAndInsertIfThen(Cmp, InsertBefore, /*Unreachable=*/false);
467 IRB.SetInsertPoint(IncBlock);
468 }
469 Value *Inc = ConstantInt::get(ShadowTy, 1);
470 ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
471 IRB.CreateStore(ShadowValue, ShadowAddr);
472}
473
474// Create the variable for the profile file name.
476 const MDString *MemProfFilename =
477 dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
478 if (!MemProfFilename)
479 return;
480 assert(!MemProfFilename->getString().empty() &&
481 "Unexpected MemProfProfileFilename metadata with empty string");
482 Constant *ProfileNameConst = ConstantDataArray::getString(
483 M.getContext(), MemProfFilename->getString(), true);
484 GlobalVariable *ProfileNameVar = new GlobalVariable(
485 M, ProfileNameConst->getType(), /*isConstant=*/true,
487 const Triple &TT = M.getTargetTriple();
488 if (TT.supportsCOMDAT()) {
490 ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
491 }
492}
493
494// Set MemprofHistogramFlag as a Global variable in IR. This makes it accessible
495// to the runtime, changing shadow count behavior.
497 const StringRef VarName(MemProfHistogramFlagVar);
498 Type *IntTy1 = Type::getInt1Ty(M.getContext());
499 auto MemprofHistogramFlag = new GlobalVariable(
500 M, IntTy1, true, GlobalValue::WeakAnyLinkage,
501 Constant::getIntegerValue(IntTy1, APInt(1, ClHistogram)), VarName);
502 const Triple &TT = M.getTargetTriple();
503 if (TT.supportsCOMDAT()) {
504 MemprofHistogramFlag->setLinkage(GlobalValue::ExternalLinkage);
505 MemprofHistogramFlag->setComdat(M.getOrInsertComdat(VarName));
506 }
507 appendToCompilerUsed(M, MemprofHistogramFlag);
508}
509
512 M.getContext(), MemprofRuntimeDefaultOptions, /*AddNull=*/true);
513 GlobalVariable *OptionsVar =
514 new GlobalVariable(M, OptionsConst->getType(), /*isConstant=*/true,
515 GlobalValue::WeakAnyLinkage, OptionsConst,
517 const Triple &TT = M.getTargetTriple();
518 if (TT.supportsCOMDAT()) {
520 OptionsVar->setComdat(M.getOrInsertComdat(OptionsVar->getName()));
521 }
522}
523
524bool ModuleMemProfiler::instrumentModule(Module &M) {
525
526 // Create a module constructor.
527 std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
528 std::string VersionCheckName =
530 : "";
531 std::tie(MemProfCtorFunction, std::ignore) =
533 MemProfInitName, /*InitArgTypes=*/{},
534 /*InitArgs=*/{}, VersionCheckName);
535
536 const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
537 appendToGlobalCtors(M, MemProfCtorFunction, Priority);
538
540
542
544
545 return true;
546}
547
548void MemProfiler::initializeCallbacks(Module &M) {
549 IRBuilder<> IRB(*C);
550
551 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
552 const std::string TypeStr = AccessIsWrite ? "store" : "load";
553 const std::string HistPrefix = ClHistogram ? "hist_" : "";
554
555 SmallVector<Type *, 2> Args1{1, IntptrTy};
556 MemProfMemoryAccessCallback[AccessIsWrite] = M.getOrInsertFunction(
557 ClMemoryAccessCallbackPrefix + HistPrefix + TypeStr,
558 FunctionType::get(IRB.getVoidTy(), Args1, false));
559 }
560 MemProfMemmove = M.getOrInsertFunction(
561 ClMemoryAccessCallbackPrefix + "memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
562 MemProfMemcpy = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memcpy",
563 PtrTy, PtrTy, PtrTy, IntptrTy);
564 MemProfMemset =
565 M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memset", PtrTy,
566 PtrTy, IRB.getInt32Ty(), IntptrTy);
567}
568
569bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
570 // For each NSObject descendant having a +load method, this method is invoked
571 // by the ObjC runtime before any of the static constructors is called.
572 // Therefore we need to instrument such methods with a call to __memprof_init
573 // at the beginning in order to initialize our runtime before any access to
574 // the shadow memory.
575 // We cannot just ignore these methods, because they may call other
576 // instrumented functions.
577 if (F.getName().contains(" load]")) {
578 FunctionCallee MemProfInitFunction =
580 IRBuilder<> IRB(&F.front(), F.front().begin());
581 IRB.CreateCall(MemProfInitFunction, {});
582 return true;
583 }
584 return false;
585}
586
587bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
588 IRBuilder<> IRB(&F.front().front());
589 Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
591 if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
592 cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
593 DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
594 return true;
595}
596
597bool MemProfiler::instrumentFunction(Function &F) {
598 if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
599 return false;
600 if (ClDebugFunc == F.getName())
601 return false;
602 if (F.getName().starts_with("__memprof_"))
603 return false;
604
605 bool FunctionModified = false;
606
607 // If needed, insert __memprof_init.
608 // This function needs to be called even if the function body is not
609 // instrumented.
610 if (maybeInsertMemProfInitAtFunctionEntry(F))
611 FunctionModified = true;
612
613 LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
614
615 initializeCallbacks(*F.getParent());
616
618
619 // Fill the set of memory operations to instrument.
620 for (auto &BB : F) {
621 for (auto &Inst : BB) {
622 if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
623 ToInstrument.push_back(&Inst);
624 }
625 }
626
627 if (ToInstrument.empty()) {
628 LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified
629 << " " << F << "\n");
630
631 return FunctionModified;
632 }
633
634 FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
635
636 int NumInstrumented = 0;
637 for (auto *Inst : ToInstrument) {
638 if (ClDebugMin < 0 || ClDebugMax < 0 ||
639 (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
640 std::optional<InterestingMemoryAccess> Access =
641 isInterestingMemoryAccess(Inst);
642 if (Access)
643 instrumentMop(Inst, F.getDataLayout(), *Access);
644 else
645 instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
646 }
647 NumInstrumented++;
648 }
649
650 if (NumInstrumented > 0)
651 FunctionModified = true;
652
653 LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
654 << F << "\n");
655
656 return FunctionModified;
657}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< int > ClDebugMin("asan-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static cl::opt< bool > ClInsertVersionCheck("asan-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugMax("asan-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClStack("asan-stack", cl::desc("Handle stack memory"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< int > ClMappingScale("asan-mapping-scale", cl::desc("scale of asan shadow mapping"), cl::Hidden, cl::init(0))
static cl::opt< std::string > ClDebugFunc("asan-debug-func", cl::Hidden, cl::desc("Debug func"))
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
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
Machine Check Debug Module
static cl::opt< int > ClMappingGranularity("memprof-mapping-granularity", cl::desc("granularity of memprof shadow mapping"), cl::Hidden, cl::init(DefaultMemGranularity))
constexpr char MemProfVersionCheckNamePrefix[]
static cl::opt< int > ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
void createMemprofHistogramFlagVar(Module &M)
constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority
static cl::opt< std::string > MemprofRuntimeDefaultOptions("memprof-runtime-default-options", cl::desc("The default memprof options"), cl::Hidden, cl::init(""))
static cl::opt< std::string > ClDebugFunc("memprof-debug-func", cl::Hidden, cl::desc("Debug func"))
constexpr char MemProfShadowMemoryDynamicAddress[]
constexpr uint64_t MemProfCtorAndDtorPriority
constexpr int LLVM_MEM_PROFILER_VERSION
static cl::opt< bool > ClUseCalls("memprof-use-callbacks", cl::desc("Use callbacks instead of inline instrumentation sequences."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInstrumentAtomics("memprof-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInsertVersionCheck("memprof-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
constexpr char MemProfInitName[]
constexpr char MemProfFilenameVar[]
static cl::opt< bool > ClStack("memprof-instrument-stack", cl::desc("Instrument scalar stack variables"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClHistogram("memprof-histogram", cl::desc("Collect access count histograms"), cl::Hidden, cl::init(false))
constexpr uint64_t DefaultMemGranularity
void createMemprofDefaultOptionsVar(Module &M)
constexpr uint64_t HistogramGranularity
constexpr uint64_t DefaultShadowScale
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__memprof_"))
constexpr char MemProfModuleCtorName[]
static cl::opt< bool > ClInstrumentReads("memprof-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
static cl::opt< bool > ClInstrumentWrites("memprof-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static cl::opt< int > ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
static cl::opt< int > ClMappingScale("memprof-mapping-scale", cl::desc("scale of memprof shadow mapping"), cl::Hidden, cl::init(DefaultShadowScale))
constexpr char MemProfHistogramFlagVar[]
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:114
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:223
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:2383
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2608
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2282
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2230
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1553
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:586
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2003
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:1913
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1591
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1926
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1443
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2546
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2308
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:207
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:624
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2847
An instruction for reading from memory.
A single uniqued string.
Definition Metadata.h:722
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:632
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:67
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition Triple.h:760
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:311
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:310
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
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.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
initializer< Ty > init(const Ty &Val)
llvm::StringRef getMemprofOptionsSymbolName()
Definition MemProf.h:62
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
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.
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:207
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
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
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 ...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....