LLVM  14.0.0git
MemProfiler.cpp
Go to the documentation of this file.
1 //===- MemProfiler.cpp - memory allocation and access profiler ------------===//
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 MemProfiler. 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 
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/Statistic.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Triple.h"
23 #include "llvm/IR/Constant.h"
24 #include "llvm/IR/DataLayout.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/GlobalValue.h"
27 #include "llvm/IR/IRBuilder.h"
28 #include "llvm/IR/Instruction.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/IR/Type.h"
32 #include "llvm/IR/Value.h"
33 #include "llvm/InitializePasses.h"
34 #include "llvm/Pass.h"
36 #include "llvm/Support/Debug.h"
40 
41 using namespace llvm;
42 
43 #define DEBUG_TYPE "memprof"
44 
45 constexpr int LLVM_MEM_PROFILER_VERSION = 1;
46 
47 // Size of memory mapped to a single shadow location.
49 
50 // Scale from granularity down to shadow size.
52 
53 constexpr char MemProfModuleCtorName[] = "memprof.module_ctor";
55 // On Emscripten, the system needs more than one priorities for constructors.
57 constexpr char MemProfInitName[] = "__memprof_init";
59  "__memprof_version_mismatch_check_v";
60 
62  "__memprof_shadow_memory_dynamic_address";
63 
64 constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
65 
66 // Command-line flags.
67 
69  "memprof-guard-against-version-mismatch",
70  cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden,
71  cl::init(true));
72 
73 // This flag may need to be replaced with -f[no-]memprof-reads.
74 static cl::opt<bool> ClInstrumentReads("memprof-instrument-reads",
75  cl::desc("instrument read instructions"),
76  cl::Hidden, cl::init(true));
77 
78 static cl::opt<bool>
79  ClInstrumentWrites("memprof-instrument-writes",
80  cl::desc("instrument write instructions"), cl::Hidden,
81  cl::init(true));
82 
84  "memprof-instrument-atomics",
85  cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
86  cl::init(true));
87 
89  "memprof-use-callbacks",
90  cl::desc("Use callbacks instead of inline instrumentation sequences."),
91  cl::Hidden, cl::init(false));
92 
94  ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix",
95  cl::desc("Prefix for memory access callbacks"),
96  cl::Hidden, cl::init("__memprof_"));
97 
98 // These flags allow to change the shadow mapping.
99 // The shadow mapping looks like
100 // Shadow = ((Mem & mask) >> scale) + offset
101 
102 static cl::opt<int> ClMappingScale("memprof-mapping-scale",
103  cl::desc("scale of memprof shadow mapping"),
105 
106 static cl::opt<int>
107  ClMappingGranularity("memprof-mapping-granularity",
108  cl::desc("granularity of memprof shadow mapping"),
110 
111 static cl::opt<bool> ClStack("memprof-instrument-stack",
112  cl::desc("Instrument scalar stack variables"),
113  cl::Hidden, cl::init(false));
114 
115 // Debug flags.
116 
117 static cl::opt<int> ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden,
118  cl::init(0));
119 
120 static cl::opt<std::string> ClDebugFunc("memprof-debug-func", cl::Hidden,
121  cl::desc("Debug func"));
122 
123 static cl::opt<int> ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"),
124  cl::Hidden, cl::init(-1));
125 
126 static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"),
127  cl::Hidden, cl::init(-1));
128 
129 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
130 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
131 STATISTIC(NumSkippedStackReads, "Number of non-instrumented stack reads");
132 STATISTIC(NumSkippedStackWrites, "Number of non-instrumented stack writes");
133 
134 namespace {
135 
136 /// This struct defines the shadow mapping using the rule:
137 /// shadow = ((mem & mask) >> Scale) ADD DynamicShadowOffset.
138 struct ShadowMapping {
139  ShadowMapping() {
140  Scale = ClMappingScale;
141  Granularity = ClMappingGranularity;
142  Mask = ~(Granularity - 1);
143  }
144 
145  int Scale;
146  int Granularity;
147  uint64_t Mask; // Computed as ~(Granularity-1)
148 };
149 
150 static uint64_t getCtorAndDtorPriority(Triple &TargetTriple) {
153 }
154 
155 struct InterestingMemoryAccess {
156  Value *Addr = nullptr;
157  bool IsWrite;
158  unsigned Alignment;
160  Value *MaybeMask = nullptr;
161 };
162 
163 /// Instrument the code in module to profile memory accesses.
164 class MemProfiler {
165 public:
166  MemProfiler(Module &M) {
167  C = &(M.getContext());
168  LongSize = M.getDataLayout().getPointerSizeInBits();
169  IntptrTy = Type::getIntNTy(*C, LongSize);
170  }
171 
172  /// If it is an interesting memory access, populate information
173  /// about the access and return a InterestingMemoryAccess struct.
174  /// Otherwise return None.
176  isInterestingMemoryAccess(Instruction *I) const;
177 
178  void instrumentMop(Instruction *I, const DataLayout &DL,
179  InterestingMemoryAccess &Access);
180  void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
181  Value *Addr, uint32_t TypeSize, bool IsWrite);
183  Instruction *I, Value *Addr,
184  unsigned Alignment, uint32_t TypeSize,
185  bool IsWrite);
186  void instrumentMemIntrinsic(MemIntrinsic *MI);
187  Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
188  bool instrumentFunction(Function &F);
189  bool maybeInsertMemProfInitAtFunctionEntry(Function &F);
190  bool insertDynamicShadowAtFunctionEntry(Function &F);
191 
192 private:
193  void initializeCallbacks(Module &M);
194 
195  LLVMContext *C;
196  int LongSize;
197  Type *IntptrTy;
198  ShadowMapping Mapping;
199 
200  // These arrays is indexed by AccessIsWrite
201  FunctionCallee MemProfMemoryAccessCallback[2];
202  FunctionCallee MemProfMemoryAccessCallbackSized[2];
203 
204  FunctionCallee MemProfMemmove, MemProfMemcpy, MemProfMemset;
205  Value *DynamicShadowOffset = nullptr;
206 };
207 
208 class MemProfilerLegacyPass : public FunctionPass {
209 public:
210  static char ID;
211 
212  explicit MemProfilerLegacyPass() : FunctionPass(ID) {
214  }
215 
216  StringRef getPassName() const override { return "MemProfilerFunctionPass"; }
217 
218  bool runOnFunction(Function &F) override {
219  MemProfiler Profiler(*F.getParent());
220  return Profiler.instrumentFunction(F);
221  }
222 };
223 
224 class ModuleMemProfiler {
225 public:
226  ModuleMemProfiler(Module &M) { TargetTriple = Triple(M.getTargetTriple()); }
227 
228  bool instrumentModule(Module &);
229 
230 private:
231  Triple TargetTriple;
232  ShadowMapping Mapping;
233  Function *MemProfCtorFunction = nullptr;
234 };
235 
236 class ModuleMemProfilerLegacyPass : public ModulePass {
237 public:
238  static char ID;
239 
240  explicit ModuleMemProfilerLegacyPass() : ModulePass(ID) {
242  }
243 
244  StringRef getPassName() const override { return "ModuleMemProfiler"; }
245 
246  void getAnalysisUsage(AnalysisUsage &AU) const override {}
247 
248  bool runOnModule(Module &M) override {
249  ModuleMemProfiler MemProfiler(M);
250  return MemProfiler.instrumentModule(M);
251  }
252 };
253 
254 } // end anonymous namespace
255 
257 
260  Module &M = *F.getParent();
261  MemProfiler Profiler(M);
262  if (Profiler.instrumentFunction(F))
263  return PreservedAnalyses::none();
264  return PreservedAnalyses::all();
265 }
266 
268 
271  ModuleMemProfiler Profiler(M);
272  if (Profiler.instrumentModule(M))
273  return PreservedAnalyses::none();
274  return PreservedAnalyses::all();
275 }
276 
278 
279 INITIALIZE_PASS_BEGIN(MemProfilerLegacyPass, "memprof",
280  "MemProfiler: profile memory allocations and accesses.",
281  false, false)
282 INITIALIZE_PASS_END(MemProfilerLegacyPass, "memprof",
283  "MemProfiler: profile memory allocations and accesses.",
285 
287  return new MemProfilerLegacyPass();
288 }
289 
291 
292 INITIALIZE_PASS(ModuleMemProfilerLegacyPass, "memprof-module",
293  "MemProfiler: profile memory allocations and accesses."
294  "ModulePass",
295  false, false)
296 
298  return new ModuleMemProfilerLegacyPass();
299 }
300 
301 Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
302  // (Shadow & mask) >> scale
303  Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
304  Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
305  // (Shadow >> scale) | offset
306  assert(DynamicShadowOffset);
307  return IRB.CreateAdd(Shadow, DynamicShadowOffset);
308 }
309 
310 // Instrument memset/memmove/memcpy
311 void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
312  IRBuilder<> IRB(MI);
313  if (isa<MemTransferInst>(MI)) {
314  IRB.CreateCall(
315  isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
316  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
317  IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
318  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
319  } else if (isa<MemSetInst>(MI)) {
320  IRB.CreateCall(
321  MemProfMemset,
322  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
323  IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
324  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
325  }
326  MI->eraseFromParent();
327 }
328 
330 MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
331  // Do not instrument the load fetching the dynamic shadow address.
332  if (DynamicShadowOffset == I)
333  return None;
334 
335  InterestingMemoryAccess Access;
336 
337  const DataLayout &DL = I->getModule()->getDataLayout();
338  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
339  if (!ClInstrumentReads)
340  return None;
341  Access.IsWrite = false;
342  Access.TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
343  Access.Alignment = LI->getAlignment();
344  Access.Addr = LI->getPointerOperand();
345  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
346  if (!ClInstrumentWrites)
347  return None;
348  Access.IsWrite = true;
349  Access.TypeSize =
350  DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
351  Access.Alignment = SI->getAlignment();
352  Access.Addr = SI->getPointerOperand();
353  } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
354  if (!ClInstrumentAtomics)
355  return None;
356  Access.IsWrite = true;
357  Access.TypeSize =
358  DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
359  Access.Alignment = 0;
360  Access.Addr = RMW->getPointerOperand();
361  } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
362  if (!ClInstrumentAtomics)
363  return None;
364  Access.IsWrite = true;
365  Access.TypeSize =
366  DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
367  Access.Alignment = 0;
368  Access.Addr = XCHG->getPointerOperand();
369  } else if (auto *CI = dyn_cast<CallInst>(I)) {
370  auto *F = CI->getCalledFunction();
371  if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
372  F->getIntrinsicID() == Intrinsic::masked_store)) {
373  unsigned OpOffset = 0;
374  if (F->getIntrinsicID() == Intrinsic::masked_store) {
375  if (!ClInstrumentWrites)
376  return None;
377  // Masked store has an initial operand for the value.
378  OpOffset = 1;
379  Access.IsWrite = true;
380  } else {
381  if (!ClInstrumentReads)
382  return None;
383  Access.IsWrite = false;
384  }
385 
386  auto *BasePtr = CI->getOperand(0 + OpOffset);
387  auto *Ty = cast<PointerType>(BasePtr->getType())->getElementType();
388  Access.TypeSize = DL.getTypeStoreSizeInBits(Ty);
389  if (auto *AlignmentConstant =
390  dyn_cast<ConstantInt>(CI->getOperand(1 + OpOffset)))
391  Access.Alignment = (unsigned)AlignmentConstant->getZExtValue();
392  else
393  Access.Alignment = 1; // No alignment guarantees. We probably got Undef
394  Access.MaybeMask = CI->getOperand(2 + OpOffset);
395  Access.Addr = BasePtr;
396  }
397  }
398 
399  if (!Access.Addr)
400  return None;
401 
402  // Do not instrument acesses from different address spaces; we cannot deal
403  // with them.
404  Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
405  if (PtrTy->getPointerAddressSpace() != 0)
406  return None;
407 
408  // Ignore swifterror addresses.
409  // swifterror memory addresses are mem2reg promoted by instruction
410  // selection. As such they cannot have regular uses like an instrumentation
411  // function and it makes no sense to track them as memory.
412  if (Access.Addr->isSwiftError())
413  return None;
414 
415  return Access;
416 }
417 
419  Instruction *I, Value *Addr,
420  unsigned Alignment,
421  uint32_t TypeSize, bool IsWrite) {
422  auto *VTy = cast<FixedVectorType>(
423  cast<PointerType>(Addr->getType())->getElementType());
424  uint64_t ElemTypeSize = DL.getTypeStoreSizeInBits(VTy->getScalarType());
425  unsigned Num = VTy->getNumElements();
426  auto *Zero = ConstantInt::get(IntptrTy, 0);
427  for (unsigned Idx = 0; Idx < Num; ++Idx) {
428  Value *InstrumentedAddress = nullptr;
429  Instruction *InsertBefore = I;
430  if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
431  // dyn_cast as we might get UndefValue
432  if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
433  if (Masked->isZero())
434  // Mask is constant false, so no instrumentation needed.
435  continue;
436  // If we have a true or undef value, fall through to instrumentAddress.
437  // with InsertBefore == I
438  }
439  } else {
440  IRBuilder<> IRB(I);
441  Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
442  Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
443  InsertBefore = ThenTerm;
444  }
445 
446  IRBuilder<> IRB(InsertBefore);
447  InstrumentedAddress =
448  IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
449  instrumentAddress(I, InsertBefore, InstrumentedAddress, ElemTypeSize,
450  IsWrite);
451  }
452 }
453 
454 void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
455  InterestingMemoryAccess &Access) {
456  // Skip instrumentation of stack accesses unless requested.
457  if (!ClStack && isa<AllocaInst>(getUnderlyingObject(Access.Addr))) {
458  if (Access.IsWrite)
459  ++NumSkippedStackWrites;
460  else
461  ++NumSkippedStackReads;
462  return;
463  }
464 
465  if (Access.IsWrite)
466  NumInstrumentedWrites++;
467  else
468  NumInstrumentedReads++;
469 
470  if (Access.MaybeMask) {
471  instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
472  Access.Alignment, Access.TypeSize,
473  Access.IsWrite);
474  } else {
475  // Since the access counts will be accumulated across the entire allocation,
476  // we only update the shadow access count for the first location and thus
477  // don't need to worry about alignment and type size.
478  instrumentAddress(I, I, Access.Addr, Access.TypeSize, Access.IsWrite);
479  }
480 }
481 
482 void MemProfiler::instrumentAddress(Instruction *OrigIns,
483  Instruction *InsertBefore, Value *Addr,
484  uint32_t TypeSize, bool IsWrite) {
485  IRBuilder<> IRB(InsertBefore);
486  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
487 
488  if (ClUseCalls) {
489  IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
490  return;
491  }
492 
493  // Create an inline sequence to compute shadow location, and increment the
494  // value by one.
495  Type *ShadowTy = Type::getInt64Ty(*C);
496  Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
497  Value *ShadowPtr = memToShadow(AddrLong, IRB);
498  Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
499  Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
501  ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
502  IRB.CreateStore(ShadowValue, ShadowAddr);
503 }
504 
505 // Create the variable for the profile file name.
507  const MDString *MemProfFilename =
508  dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
509  if (!MemProfFilename)
510  return;
511  assert(!MemProfFilename->getString().empty() &&
512  "Unexpected MemProfProfileFilename metadata with empty string");
513  Constant *ProfileNameConst = ConstantDataArray::getString(
514  M.getContext(), MemProfFilename->getString(), true);
515  GlobalVariable *ProfileNameVar = new GlobalVariable(
516  M, ProfileNameConst->getType(), /*isConstant=*/true,
518  Triple TT(M.getTargetTriple());
519  if (TT.supportsCOMDAT()) {
520  ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
521  ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
522  }
523 }
524 
525 bool ModuleMemProfiler::instrumentModule(Module &M) {
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 
541  return true;
542 }
543 
544 void MemProfiler::initializeCallbacks(Module &M) {
545  IRBuilder<> IRB(*C);
546 
547  for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
548  const std::string TypeStr = AccessIsWrite ? "store" : "load";
549 
550  SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
551  SmallVector<Type *, 2> Args1{1, IntptrTy};
552  MemProfMemoryAccessCallbackSized[AccessIsWrite] =
553  M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr + "N",
554  FunctionType::get(IRB.getVoidTy(), Args2, false));
555 
556  MemProfMemoryAccessCallback[AccessIsWrite] =
557  M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr,
558  FunctionType::get(IRB.getVoidTy(), Args1, false));
559  }
560  MemProfMemmove = M.getOrInsertFunction(
561  ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
562  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
563  MemProfMemcpy = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memcpy",
564  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
565  IRB.getInt8PtrTy(), IntptrTy);
566  MemProfMemset = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memset",
567  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
568  IRB.getInt32Ty(), IntptrTy);
569 }
570 
571 bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
572  // For each NSObject descendant having a +load method, this method is invoked
573  // by the ObjC runtime before any of the static constructors is called.
574  // Therefore we need to instrument such methods with a call to __memprof_init
575  // at the beginning in order to initialize our runtime before any access to
576  // the shadow memory.
577  // We cannot just ignore these methods, because they may call other
578  // instrumented functions.
579  if (F.getName().find(" load]") != std::string::npos) {
580  FunctionCallee MemProfInitFunction =
582  IRBuilder<> IRB(&F.front(), F.front().begin());
583  IRB.CreateCall(MemProfInitFunction, {});
584  return true;
585  }
586  return false;
587 }
588 
589 bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
590  IRBuilder<> IRB(&F.front().front());
591  Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
593  if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
594  cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
595  DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
596  return true;
597 }
598 
599 bool MemProfiler::instrumentFunction(Function &F) {
600  if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
601  return false;
602  if (ClDebugFunc == F.getName())
603  return false;
604  if (F.getName().startswith("__memprof_"))
605  return false;
606 
607  bool FunctionModified = false;
608 
609  // If needed, insert __memprof_init.
610  // This function needs to be called even if the function body is not
611  // instrumented.
612  if (maybeInsertMemProfInitAtFunctionEntry(F))
613  FunctionModified = true;
614 
615  LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
616 
617  initializeCallbacks(*F.getParent());
618 
619  FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
620 
621  SmallVector<Instruction *, 16> ToInstrument;
622 
623  // Fill the set of memory operations to instrument.
624  for (auto &BB : F) {
625  for (auto &Inst : BB) {
626  if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
627  ToInstrument.push_back(&Inst);
628  }
629  }
630 
631  int NumInstrumented = 0;
632  for (auto *Inst : ToInstrument) {
633  if (ClDebugMin < 0 || ClDebugMax < 0 ||
634  (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
636  isInterestingMemoryAccess(Inst);
637  if (Access)
638  instrumentMop(Inst, F.getParent()->getDataLayout(), *Access);
639  else
640  instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
641  }
642  NumInstrumented++;
643  }
644 
645  if (NumInstrumented > 0)
646  FunctionModified = true;
647 
648  LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
649  << F << "\n");
650 
651  return FunctionModified;
652 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
Instrumentation.h
llvm::IRBuilderBase::CreateIntCast
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:2186
llvm::initializeMemProfilerLegacyPassPass
void initializeMemProfilerLegacyPassPass(PassRegistry &)
llvm::IRBuilderBase::getInt32Ty
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:518
llvm::IRBuilderBase::CreateStore
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1699
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
ClDebugFunc
static cl::opt< std::string > ClDebugFunc("memprof-debug-func", cl::Hidden, cl::desc("Debug func"))
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:112
ClInstrumentWrites
static cl::opt< bool > ClInstrumentWrites("memprof-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::Function
Definition: Function.h:61
StringRef.h
Pass.h
llvm::PointerType::get
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Definition: Type.cpp:691
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Statistic.h
llvm::Type::getPointerAddressSpace
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:734
llvm::IRBuilder<>
llvm::GlobalVariable
Definition: GlobalVariable.h:40
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:325
ValueTracking.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
DefaultShadowGranularity
constexpr uint64_t DefaultShadowGranularity
Definition: MemProfiler.cpp:48
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
DefaultShadowScale
constexpr uint64_t DefaultShadowScale
Definition: MemProfiler.cpp:51
llvm::MemIntrinsic
This is the common base class for memset/memcpy/memmove.
Definition: IntrinsicInst.h:874
LLVM_MEM_PROFILER_VERSION
constexpr int LLVM_MEM_PROFILER_VERSION
Definition: MemProfiler.cpp:45
llvm::Optional
Definition: APInt.h:33
ClDebugMax
static cl::opt< int > ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"), cl::Hidden, cl::init(-1))
llvm::createProfileFileNameVar
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput)
Definition: InstrProf.cpp:1166
and
We currently generate a but we really shouldn eax ecx xorl edx divl ecx eax divl ecx movl eax ret A similar code sequence works for division We currently compile i32 v2 eax eax jo LBB1_2 and
Definition: README.txt:1271
llvm::Triple::isOSEmscripten
bool isOSEmscripten() const
Tests whether the OS is Emscripten.
Definition: Triple.h:615
llvm::BitmaskEnumDetail::Mask
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.
Definition: BitmaskEnum.h:80
llvm::IRBuilderBase::CreateIntToPtr
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2112
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::createMemProfilerFunctionPass
FunctionPass * createMemProfilerFunctionPass()
Definition: MemProfiler.cpp:286
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Instruction.h
CommandLine.h
GlobalValue.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::ModuleMemProfilerPass::ModuleMemProfilerPass
ModuleMemProfilerPass()
Definition: MemProfiler.cpp:267
profile
pgo instr Read PGO instrumentation profile
Definition: PGOInstrumentation.cpp:501
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::IRBuilderBase::CreateLoad
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:1660
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
MemProfInitName
constexpr char MemProfInitName[]
Definition: MemProfiler.cpp:57
false
Definition: StackSlotColoring.cpp:142
llvm::MemProfilerPass::MemProfilerPass
MemProfilerPass()
Definition: MemProfiler.cpp:256
llvm::Instruction
Definition: Instruction.h:45
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::codeview::EncodedFramePtrReg::BasePtr
@ BasePtr
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:900
llvm::getUnderlyingObject
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
Definition: ValueTracking.cpp:4356
ClInsertVersionCheck
static cl::opt< bool > ClInsertVersionCheck("memprof-guard-against-version-mismatch", cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden, cl::init(true))
ClDebug
static cl::opt< int > ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden, cl::init(0))
ClDebugMin
static cl::opt< int > ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"), cl::Hidden, cl::init(-1))
llvm::None
const NoneType None
Definition: None.h:23
Type.h
llvm::IRBuilderBase::CreateAnd
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1362
llvm::IRBuilderBase::CreatePointerCast
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2163
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(MemProfilerLegacyPass, "memprof", "MemProfiler: profile memory allocations and accesses.", false, false) INITIALIZE_PASS_END(MemProfilerLegacyPass
llvm::cl::opt< bool >
MemProfModuleCtorName
constexpr char MemProfModuleCtorName[]
Definition: MemProfiler.cpp:53
MemProfVersionCheckNamePrefix
constexpr char MemProfVersionCheckNamePrefix[]
Definition: MemProfiler.cpp:58
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:304
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::createSanitizerCtorAndInitFunctions
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function, and calls sanitizer's init function from it.
Definition: ModuleUtils.cpp:136
uint64_t
ClStack
static cl::opt< bool > ClStack("memprof-instrument-stack", cl::desc("Instrument scalar stack variables"), cl::Hidden, cl::init(false))
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::GlobalValue::WeakAnyLinkage
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:52
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::declareSanitizerInitFunction
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes)
Definition: ModuleUtils.cpp:115
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::PICLevel::NotPIC
@ NotPIC
Definition: CodeGen.h:33
llvm::GlobalObject::setComdat
void setComdat(Comdat *C)
Definition: GlobalObject.h:125
llvm::IRBuilderBase::getInt8PtrTy
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
Definition: IRBuilder.h:561
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
ClUseCalls
static cl::opt< bool > ClUseCalls("memprof-use-callbacks", cl::desc("Use callbacks instead of inline instrumentation sequences."), cl::Hidden, cl::init(false))
MemProfEmscriptenCtorAndDtorPriority
constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority
Definition: MemProfiler.cpp:56
llvm::GlobalValue::setLinkage
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:454
llvm::IRBuilderBase::CreateAdd
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1212
ClInstrumentReads
static cl::opt< bool > ClInstrumentReads("memprof-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::IRBuilderBase::CreateExtractElement
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2442
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Triple.h
DataLayout.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
uint32_t
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::ConstantDataArray::getString
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
Definition: Constants.cpp:3041
llvm::GlobalValue::AvailableExternallyLinkage
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:49
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:175
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:726
llvm::IRBuilderBase::CreateGEP
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition: IRBuilder.h:1799
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
Constant.h
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:204
llvm::createModuleMemProfilerLegacyPassPass
ModulePass * createModuleMemProfilerLegacyPassPass()
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition: Type.cpp:207
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
llvm::initializeModuleMemProfilerLegacyPassPass
void initializeModuleMemProfilerLegacyPassPass(PassRegistry &)
MemProfFilenameVar
constexpr char MemProfFilenameVar[]
Definition: MemProfiler.cpp:64
llvm::TypeSize
Definition: TypeSize.h:417
llvm::MemProfilerPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: MemProfiler.cpp:258
Function.h
llvm::ModuleMemProfilerPass::run
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition: MemProfiler.cpp:269
INITIALIZE_PASS
INITIALIZE_PASS(ModuleMemProfilerLegacyPass, "memprof-module", "MemProfiler: profile memory allocations and accesses." "ModulePass", false, false) ModulePass *llvm
Definition: MemProfiler.cpp:292
ClMappingGranularity
static cl::opt< int > ClMappingGranularity("memprof-mapping-granularity", cl::desc("granularity of memprof shadow mapping"), cl::Hidden, cl::init(DefaultShadowGranularity))
MemProfCtorAndDtorPriority
constexpr uint64_t MemProfCtorAndDtorPriority
Definition: MemProfiler.cpp:54
MemProfShadowMemoryDynamicAddress
constexpr char MemProfShadowMemoryDynamicAddress[]
Definition: MemProfiler.cpp:61
ClMappingScale
static cl::opt< int > ClMappingScale("memprof-mapping-scale", cl::desc("scale of memprof shadow mapping"), cl::Hidden, cl::init(DefaultShadowScale))
Vector
So we should use XX3Form_Rcr to implement instrinsic Convert DP outs ins xscvdpsp No builtin are required Round &Convert QP DP(dword[1] is set to zero) No builtin are required Round to Quad Precision because you need to assign rounding mode in instruction Provide builtin(set f128:$vT,(int_ppc_vsx_xsrqpi f128:$vB))(set f128 yields< n x< ty > >< result > yields< ty >< result > No builtin are required Load Store Vector
Definition: README_P9.txt:497
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
memprof
memprof
Definition: MemProfiler.cpp:282
SmallVector.h
llvm::IRBuilderBase::CreateLShr
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1322
ModuleUtils.h
ClInstrumentAtomics
static cl::opt< bool > ClInstrumentAtomics("memprof-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
MemProfiler.h
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
ClMemoryAccessCallbackPrefix
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__memprof_"))
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::IRBuilderBase::getVoidTy
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:556
LLVMContext.h
llvm::SplitBlockAndInsertIfThen
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
Definition: BasicBlockUtils.cpp:1418
llvm::appendToGlobalCtors
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.
Definition: ModuleUtils.cpp:66
llvm::cl::desc
Definition: CommandLine.h:414
llvm::MDString::getString
StringRef getString() const
Definition: Metadata.cpp:483
BasicBlockUtils.h
llvm::MDString
A single uniqued string.
Definition: Metadata.h:611
Value.h
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:521
Debug.h
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2395
instrumentMaskedLoadOrStore
static void instrumentMaskedLoadOrStore(AddressSanitizer *Pass, const DataLayout &DL, Type *IntptrTy, Value *Mask, Instruction *I, Value *Addr, MaybeAlign Alignment, unsigned Granularity, uint32_t TypeSize, bool IsWrite, Value *SizeArgument, bool UseCalls, uint32_t Exp)
Definition: AddressSanitizer.cpp:1620
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37