LLVM  13.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"
22 #include "llvm/IR/Constant.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/GlobalValue.h"
26 #include "llvm/IR/IRBuilder.h"
27 #include "llvm/IR/Instruction.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/IR/Value.h"
32 #include "llvm/InitializePasses.h"
33 #include "llvm/Pass.h"
35 #include "llvm/Support/Debug.h"
39 
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "memprof"
43 
44 constexpr int LLVM_MEM_PROFILER_VERSION = 1;
45 
46 // Size of memory mapped to a single shadow location.
47 constexpr uint64_t DefaultShadowGranularity = 64;
48 
49 // Scale from granularity down to shadow size.
50 constexpr uint64_t DefaultShadowScale = 3;
51 
52 constexpr char MemProfModuleCtorName[] = "memprof.module_ctor";
53 constexpr uint64_t MemProfCtorAndDtorPriority = 1;
54 // On Emscripten, the system needs more than one priorities for constructors.
55 constexpr uint64_t MemProfEmscriptenCtorAndDtorPriority = 50;
56 constexpr char MemProfInitName[] = "__memprof_init";
58  "__memprof_version_mismatch_check_v";
59 
61  "__memprof_shadow_memory_dynamic_address";
62 
63 constexpr char MemProfFilenameVar[] = "__memprof_profile_filename";
64 
65 // Command-line flags.
66 
68  "memprof-guard-against-version-mismatch",
69  cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden,
70  cl::init(true));
71 
72 // This flag may need to be replaced with -f[no-]memprof-reads.
73 static cl::opt<bool> ClInstrumentReads("memprof-instrument-reads",
74  cl::desc("instrument read instructions"),
75  cl::Hidden, cl::init(true));
76 
77 static cl::opt<bool>
78  ClInstrumentWrites("memprof-instrument-writes",
79  cl::desc("instrument write instructions"), cl::Hidden,
80  cl::init(true));
81 
83  "memprof-instrument-atomics",
84  cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
85  cl::init(true));
86 
88  "memprof-use-callbacks",
89  cl::desc("Use callbacks instead of inline instrumentation sequences."),
90  cl::Hidden, cl::init(false));
91 
93  ClMemoryAccessCallbackPrefix("memprof-memory-access-callback-prefix",
94  cl::desc("Prefix for memory access callbacks"),
95  cl::Hidden, cl::init("__memprof_"));
96 
97 // These flags allow to change the shadow mapping.
98 // The shadow mapping looks like
99 // Shadow = ((Mem & mask) >> scale) + offset
100 
101 static cl::opt<int> ClMappingScale("memprof-mapping-scale",
102  cl::desc("scale of memprof shadow mapping"),
104 
105 static cl::opt<int>
106  ClMappingGranularity("memprof-mapping-granularity",
107  cl::desc("granularity of memprof shadow mapping"),
109 
110 // Debug flags.
111 
112 static cl::opt<int> ClDebug("memprof-debug", cl::desc("debug"), cl::Hidden,
113  cl::init(0));
114 
115 static cl::opt<std::string> ClDebugFunc("memprof-debug-func", cl::Hidden,
116  cl::desc("Debug func"));
117 
118 static cl::opt<int> ClDebugMin("memprof-debug-min", cl::desc("Debug min inst"),
119  cl::Hidden, cl::init(-1));
120 
121 static cl::opt<int> ClDebugMax("memprof-debug-max", cl::desc("Debug max inst"),
122  cl::Hidden, cl::init(-1));
123 
124 STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
125 STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
126 
127 namespace {
128 
129 /// This struct defines the shadow mapping using the rule:
130 /// shadow = ((mem & mask) >> Scale) ADD DynamicShadowOffset.
131 struct ShadowMapping {
132  ShadowMapping() {
133  Scale = ClMappingScale;
134  Granularity = ClMappingGranularity;
135  Mask = ~(Granularity - 1);
136  }
137 
138  int Scale;
139  int Granularity;
140  uint64_t Mask; // Computed as ~(Granularity-1)
141 };
142 
143 static uint64_t getCtorAndDtorPriority(Triple &TargetTriple) {
146 }
147 
148 struct InterestingMemoryAccess {
149  Value *Addr = nullptr;
150  bool IsWrite;
151  unsigned Alignment;
152  uint64_t TypeSize;
153  Value *MaybeMask = nullptr;
154 };
155 
156 /// Instrument the code in module to profile memory accesses.
157 class MemProfiler {
158 public:
159  MemProfiler(Module &M) {
160  C = &(M.getContext());
161  LongSize = M.getDataLayout().getPointerSizeInBits();
162  IntptrTy = Type::getIntNTy(*C, LongSize);
163  }
164 
165  /// If it is an interesting memory access, populate information
166  /// about the access and return a InterestingMemoryAccess struct.
167  /// Otherwise return None.
169  isInterestingMemoryAccess(Instruction *I) const;
170 
171  void instrumentMop(Instruction *I, const DataLayout &DL,
172  InterestingMemoryAccess &Access);
173  void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
174  Value *Addr, uint32_t TypeSize, bool IsWrite);
176  Instruction *I, Value *Addr,
177  unsigned Alignment, uint32_t TypeSize,
178  bool IsWrite);
179  void instrumentMemIntrinsic(MemIntrinsic *MI);
180  Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
181  bool instrumentFunction(Function &F);
182  bool maybeInsertMemProfInitAtFunctionEntry(Function &F);
183  bool insertDynamicShadowAtFunctionEntry(Function &F);
184 
185 private:
186  void initializeCallbacks(Module &M);
187 
188  LLVMContext *C;
189  int LongSize;
190  Type *IntptrTy;
191  ShadowMapping Mapping;
192 
193  // These arrays is indexed by AccessIsWrite
194  FunctionCallee MemProfMemoryAccessCallback[2];
195  FunctionCallee MemProfMemoryAccessCallbackSized[2];
196 
197  FunctionCallee MemProfMemmove, MemProfMemcpy, MemProfMemset;
198  Value *DynamicShadowOffset = nullptr;
199 };
200 
201 class MemProfilerLegacyPass : public FunctionPass {
202 public:
203  static char ID;
204 
205  explicit MemProfilerLegacyPass() : FunctionPass(ID) {
207  }
208 
209  StringRef getPassName() const override { return "MemProfilerFunctionPass"; }
210 
211  bool runOnFunction(Function &F) override {
212  MemProfiler Profiler(*F.getParent());
213  return Profiler.instrumentFunction(F);
214  }
215 };
216 
217 class ModuleMemProfiler {
218 public:
219  ModuleMemProfiler(Module &M) { TargetTriple = Triple(M.getTargetTriple()); }
220 
221  bool instrumentModule(Module &);
222 
223 private:
224  Triple TargetTriple;
225  ShadowMapping Mapping;
226  Function *MemProfCtorFunction = nullptr;
227 };
228 
229 class ModuleMemProfilerLegacyPass : public ModulePass {
230 public:
231  static char ID;
232 
233  explicit ModuleMemProfilerLegacyPass() : ModulePass(ID) {
235  }
236 
237  StringRef getPassName() const override { return "ModuleMemProfiler"; }
238 
239  void getAnalysisUsage(AnalysisUsage &AU) const override {}
240 
241  bool runOnModule(Module &M) override {
242  ModuleMemProfiler MemProfiler(M);
243  return MemProfiler.instrumentModule(M);
244  }
245 };
246 
247 } // end anonymous namespace
248 
250 
253  Module &M = *F.getParent();
254  MemProfiler Profiler(M);
255  if (Profiler.instrumentFunction(F))
256  return PreservedAnalyses::none();
257  return PreservedAnalyses::all();
258 
259  return PreservedAnalyses::all();
260 }
261 
263 
266  ModuleMemProfiler Profiler(M);
267  if (Profiler.instrumentModule(M))
268  return PreservedAnalyses::none();
269  return PreservedAnalyses::all();
270 }
271 
273 
274 INITIALIZE_PASS_BEGIN(MemProfilerLegacyPass, "memprof",
275  "MemProfiler: profile memory allocations and accesses.",
276  false, false)
277 INITIALIZE_PASS_END(MemProfilerLegacyPass, "memprof",
278  "MemProfiler: profile memory allocations and accesses.",
280 
282  return new MemProfilerLegacyPass();
283 }
284 
286 
287 INITIALIZE_PASS(ModuleMemProfilerLegacyPass, "memprof-module",
288  "MemProfiler: profile memory allocations and accesses."
289  "ModulePass",
290  false, false)
291 
293  return new ModuleMemProfilerLegacyPass();
294 }
295 
296 Value *MemProfiler::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
297  // (Shadow & mask) >> scale
298  Shadow = IRB.CreateAnd(Shadow, Mapping.Mask);
299  Shadow = IRB.CreateLShr(Shadow, Mapping.Scale);
300  // (Shadow >> scale) | offset
301  assert(DynamicShadowOffset);
302  return IRB.CreateAdd(Shadow, DynamicShadowOffset);
303 }
304 
305 // Instrument memset/memmove/memcpy
306 void MemProfiler::instrumentMemIntrinsic(MemIntrinsic *MI) {
307  IRBuilder<> IRB(MI);
308  if (isa<MemTransferInst>(MI)) {
309  IRB.CreateCall(
310  isa<MemMoveInst>(MI) ? MemProfMemmove : MemProfMemcpy,
311  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
312  IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
313  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
314  } else if (isa<MemSetInst>(MI)) {
315  IRB.CreateCall(
316  MemProfMemset,
317  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
318  IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
319  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
320  }
321  MI->eraseFromParent();
322 }
323 
325 MemProfiler::isInterestingMemoryAccess(Instruction *I) const {
326  // Do not instrument the load fetching the dynamic shadow address.
327  if (DynamicShadowOffset == I)
328  return None;
329 
330  InterestingMemoryAccess Access;
331 
332  const DataLayout &DL = I->getModule()->getDataLayout();
333  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
334  if (!ClInstrumentReads)
335  return None;
336  Access.IsWrite = false;
337  Access.TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
338  Access.Alignment = LI->getAlignment();
339  Access.Addr = LI->getPointerOperand();
340  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
341  if (!ClInstrumentWrites)
342  return None;
343  Access.IsWrite = true;
344  Access.TypeSize =
345  DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
346  Access.Alignment = SI->getAlignment();
347  Access.Addr = SI->getPointerOperand();
348  } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
349  if (!ClInstrumentAtomics)
350  return None;
351  Access.IsWrite = true;
352  Access.TypeSize =
353  DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
354  Access.Alignment = 0;
355  Access.Addr = RMW->getPointerOperand();
356  } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
357  if (!ClInstrumentAtomics)
358  return None;
359  Access.IsWrite = true;
360  Access.TypeSize =
361  DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
362  Access.Alignment = 0;
363  Access.Addr = XCHG->getPointerOperand();
364  } else if (auto *CI = dyn_cast<CallInst>(I)) {
365  auto *F = CI->getCalledFunction();
366  if (F && (F->getIntrinsicID() == Intrinsic::masked_load ||
367  F->getIntrinsicID() == Intrinsic::masked_store)) {
368  unsigned OpOffset = 0;
369  if (F->getIntrinsicID() == Intrinsic::masked_store) {
370  if (!ClInstrumentWrites)
371  return None;
372  // Masked store has an initial operand for the value.
373  OpOffset = 1;
374  Access.IsWrite = true;
375  } else {
376  if (!ClInstrumentReads)
377  return None;
378  Access.IsWrite = false;
379  }
380 
381  auto *BasePtr = CI->getOperand(0 + OpOffset);
382  auto *Ty = cast<PointerType>(BasePtr->getType())->getElementType();
383  Access.TypeSize = DL.getTypeStoreSizeInBits(Ty);
384  if (auto *AlignmentConstant =
385  dyn_cast<ConstantInt>(CI->getOperand(1 + OpOffset)))
386  Access.Alignment = (unsigned)AlignmentConstant->getZExtValue();
387  else
388  Access.Alignment = 1; // No alignment guarantees. We probably got Undef
389  Access.MaybeMask = CI->getOperand(2 + OpOffset);
390  Access.Addr = BasePtr;
391  }
392  }
393 
394  if (!Access.Addr)
395  return None;
396 
397  // Do not instrument acesses from different address spaces; we cannot deal
398  // with them.
399  Type *PtrTy = cast<PointerType>(Access.Addr->getType()->getScalarType());
400  if (PtrTy->getPointerAddressSpace() != 0)
401  return None;
402 
403  // Ignore swifterror addresses.
404  // swifterror memory addresses are mem2reg promoted by instruction
405  // selection. As such they cannot have regular uses like an instrumentation
406  // function and it makes no sense to track them as memory.
407  if (Access.Addr->isSwiftError())
408  return None;
409 
410  return Access;
411 }
412 
414  Instruction *I, Value *Addr,
415  unsigned Alignment,
416  uint32_t TypeSize, bool IsWrite) {
417  auto *VTy = cast<FixedVectorType>(
418  cast<PointerType>(Addr->getType())->getElementType());
419  uint64_t ElemTypeSize = DL.getTypeStoreSizeInBits(VTy->getScalarType());
420  unsigned Num = VTy->getNumElements();
421  auto *Zero = ConstantInt::get(IntptrTy, 0);
422  for (unsigned Idx = 0; Idx < Num; ++Idx) {
423  Value *InstrumentedAddress = nullptr;
424  Instruction *InsertBefore = I;
425  if (auto *Vector = dyn_cast<ConstantVector>(Mask)) {
426  // dyn_cast as we might get UndefValue
427  if (auto *Masked = dyn_cast<ConstantInt>(Vector->getOperand(Idx))) {
428  if (Masked->isZero())
429  // Mask is constant false, so no instrumentation needed.
430  continue;
431  // If we have a true or undef value, fall through to instrumentAddress.
432  // with InsertBefore == I
433  }
434  } else {
435  IRBuilder<> IRB(I);
436  Value *MaskElem = IRB.CreateExtractElement(Mask, Idx);
437  Instruction *ThenTerm = SplitBlockAndInsertIfThen(MaskElem, I, false);
438  InsertBefore = ThenTerm;
439  }
440 
441  IRBuilder<> IRB(InsertBefore);
442  InstrumentedAddress =
443  IRB.CreateGEP(VTy, Addr, {Zero, ConstantInt::get(IntptrTy, Idx)});
444  instrumentAddress(I, InsertBefore, InstrumentedAddress, ElemTypeSize,
445  IsWrite);
446  }
447 }
448 
449 void MemProfiler::instrumentMop(Instruction *I, const DataLayout &DL,
450  InterestingMemoryAccess &Access) {
451  if (Access.IsWrite)
452  NumInstrumentedWrites++;
453  else
454  NumInstrumentedReads++;
455 
456  if (Access.MaybeMask) {
457  instrumentMaskedLoadOrStore(DL, Access.MaybeMask, I, Access.Addr,
458  Access.Alignment, Access.TypeSize,
459  Access.IsWrite);
460  } else {
461  // Since the access counts will be accumulated across the entire allocation,
462  // we only update the shadow access count for the first location and thus
463  // don't need to worry about alignment and type size.
464  instrumentAddress(I, I, Access.Addr, Access.TypeSize, Access.IsWrite);
465  }
466 }
467 
468 void MemProfiler::instrumentAddress(Instruction *OrigIns,
469  Instruction *InsertBefore, Value *Addr,
470  uint32_t TypeSize, bool IsWrite) {
471  IRBuilder<> IRB(InsertBefore);
472  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
473 
474  if (ClUseCalls) {
475  IRB.CreateCall(MemProfMemoryAccessCallback[IsWrite], AddrLong);
476  return;
477  }
478 
479  // Create an inline sequence to compute shadow location, and increment the
480  // value by one.
481  Type *ShadowTy = Type::getInt64Ty(*C);
482  Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
483  Value *ShadowPtr = memToShadow(AddrLong, IRB);
484  Value *ShadowAddr = IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy);
485  Value *ShadowValue = IRB.CreateLoad(ShadowTy, ShadowAddr);
487  ShadowValue = IRB.CreateAdd(ShadowValue, Inc);
488  IRB.CreateStore(ShadowValue, ShadowAddr);
489 }
490 
491 // Create the variable for the profile file name.
493  const MDString *MemProfFilename =
494  dyn_cast_or_null<MDString>(M.getModuleFlag("MemProfProfileFilename"));
495  if (!MemProfFilename)
496  return;
497  assert(!MemProfFilename->getString().empty() &&
498  "Unexpected MemProfProfileFilename metadata with empty string");
499  Constant *ProfileNameConst = ConstantDataArray::getString(
500  M.getContext(), MemProfFilename->getString(), true);
501  GlobalVariable *ProfileNameVar = new GlobalVariable(
502  M, ProfileNameConst->getType(), /*isConstant=*/true,
504  Triple TT(M.getTargetTriple());
505  if (TT.supportsCOMDAT()) {
506  ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
507  ProfileNameVar->setComdat(M.getOrInsertComdat(MemProfFilenameVar));
508  }
509 }
510 
511 bool ModuleMemProfiler::instrumentModule(Module &M) {
512  // Create a module constructor.
513  std::string MemProfVersion = std::to_string(LLVM_MEM_PROFILER_VERSION);
514  std::string VersionCheckName =
516  : "";
517  std::tie(MemProfCtorFunction, std::ignore) =
519  MemProfInitName, /*InitArgTypes=*/{},
520  /*InitArgs=*/{}, VersionCheckName);
521 
522  const uint64_t Priority = getCtorAndDtorPriority(TargetTriple);
523  appendToGlobalCtors(M, MemProfCtorFunction, Priority);
524 
526 
527  return true;
528 }
529 
530 void MemProfiler::initializeCallbacks(Module &M) {
531  IRBuilder<> IRB(*C);
532 
533  for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
534  const std::string TypeStr = AccessIsWrite ? "store" : "load";
535 
536  SmallVector<Type *, 3> Args2 = {IntptrTy, IntptrTy};
537  SmallVector<Type *, 2> Args1{1, IntptrTy};
538  MemProfMemoryAccessCallbackSized[AccessIsWrite] =
539  M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr + "N",
540  FunctionType::get(IRB.getVoidTy(), Args2, false));
541 
542  MemProfMemoryAccessCallback[AccessIsWrite] =
543  M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + TypeStr,
544  FunctionType::get(IRB.getVoidTy(), Args1, false));
545  }
546  MemProfMemmove = M.getOrInsertFunction(
547  ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
548  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy);
549  MemProfMemcpy = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memcpy",
550  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
551  IRB.getInt8PtrTy(), IntptrTy);
552  MemProfMemset = M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "memset",
553  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
554  IRB.getInt32Ty(), IntptrTy);
555 }
556 
557 bool MemProfiler::maybeInsertMemProfInitAtFunctionEntry(Function &F) {
558  // For each NSObject descendant having a +load method, this method is invoked
559  // by the ObjC runtime before any of the static constructors is called.
560  // Therefore we need to instrument such methods with a call to __memprof_init
561  // at the beginning in order to initialize our runtime before any access to
562  // the shadow memory.
563  // We cannot just ignore these methods, because they may call other
564  // instrumented functions.
565  if (F.getName().find(" load]") != std::string::npos) {
566  FunctionCallee MemProfInitFunction =
568  IRBuilder<> IRB(&F.front(), F.front().begin());
569  IRB.CreateCall(MemProfInitFunction, {});
570  return true;
571  }
572  return false;
573 }
574 
575 bool MemProfiler::insertDynamicShadowAtFunctionEntry(Function &F) {
576  IRBuilder<> IRB(&F.front().front());
577  Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
579  if (F.getParent()->getPICLevel() == PICLevel::NotPIC)
580  cast<GlobalVariable>(GlobalDynamicAddress)->setDSOLocal(true);
581  DynamicShadowOffset = IRB.CreateLoad(IntptrTy, GlobalDynamicAddress);
582  return true;
583 }
584 
585 bool MemProfiler::instrumentFunction(Function &F) {
586  if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
587  return false;
588  if (ClDebugFunc == F.getName())
589  return false;
590  if (F.getName().startswith("__memprof_"))
591  return false;
592 
593  bool FunctionModified = false;
594 
595  // If needed, insert __memprof_init.
596  // This function needs to be called even if the function body is not
597  // instrumented.
598  if (maybeInsertMemProfInitAtFunctionEntry(F))
599  FunctionModified = true;
600 
601  LLVM_DEBUG(dbgs() << "MEMPROF instrumenting:\n" << F << "\n");
602 
603  initializeCallbacks(*F.getParent());
604 
605  FunctionModified |= insertDynamicShadowAtFunctionEntry(F);
606 
607  SmallVector<Instruction *, 16> ToInstrument;
608 
609  // Fill the set of memory operations to instrument.
610  for (auto &BB : F) {
611  for (auto &Inst : BB) {
612  if (isInterestingMemoryAccess(&Inst) || isa<MemIntrinsic>(Inst))
613  ToInstrument.push_back(&Inst);
614  }
615  }
616 
617  int NumInstrumented = 0;
618  for (auto *Inst : ToInstrument) {
619  if (ClDebugMin < 0 || ClDebugMax < 0 ||
620  (NumInstrumented >= ClDebugMin && NumInstrumented <= ClDebugMax)) {
622  isInterestingMemoryAccess(Inst);
623  if (Access)
624  instrumentMop(Inst, F.getParent()->getDataLayout(), *Access);
625  else
626  instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
627  }
628  NumInstrumented++;
629  }
630 
631  if (NumInstrumented > 0)
632  FunctionModified = true;
633 
634  LLVM_DEBUG(dbgs() << "MEMPROF done instrumenting: " << FunctionModified << " "
635  << F << "\n");
636 
637  return FunctionModified;
638 }
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:2143
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:1685
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm
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:687
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1167
Statistic.h
llvm::Type::getPointerAddressSpace
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:728
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:321
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:47
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:46
Module.h
DefaultShadowScale
constexpr uint64_t DefaultShadowScale
Definition: MemProfiler.cpp:50
llvm::MemIntrinsic
This is the common base class for memset/memcpy/memmove.
Definition: IntrinsicInst.h:834
LLVM_MEM_PROFILER_VERSION
constexpr int LLVM_MEM_PROFILER_VERSION
Definition: MemProfiler.cpp:44
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:1160
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:2069
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
llvm::createMemProfilerFunctionPass
FunctionPass * createMemProfilerFunctionPass()
Definition: MemProfiler.cpp:281
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:132
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:262
profile
pgo instr Read PGO instrumentation profile
Definition: PGOInstrumentation.cpp:495
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:1646
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
MemProfInitName
constexpr char MemProfInitName[]
Definition: MemProfiler.cpp:56
false
Definition: StackSlotColoring.cpp:142
llvm::MemProfilerPass::MemProfilerPass
MemProfilerPass()
Definition: MemProfiler.cpp:249
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:898
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:1348
llvm::IRBuilderBase::CreatePointerCast
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2120
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:52
MemProfVersionCheckNamePrefix
constexpr char MemProfVersionCheckNamePrefix[]
Definition: MemProfiler.cpp:57
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:303
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:134
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:55
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:1198
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:2399
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:3053
llvm::GlobalValue::AvailableExternallyLinkage
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:49
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:728
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:198
llvm::createModuleMemProfilerLegacyPassPass
ModulePass * createModuleMemProfilerLegacyPassPass()
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition: Type.cpp:201
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:63
llvm::TypeSize
Definition: TypeSize.h:417
llvm::MemProfilerPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: MemProfiler.cpp:251
Function.h
llvm::ModuleMemProfilerPass::run
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition: MemProfiler.cpp:264
INITIALIZE_PASS
INITIALIZE_PASS(ModuleMemProfilerLegacyPass, "memprof-module", "MemProfiler: profile memory allocations and accesses." "ModulePass", false, false) ModulePass *llvm
Definition: MemProfiler.cpp:287
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:53
MemProfShadowMemoryDynamicAddress
constexpr char MemProfShadowMemoryDynamicAddress[]
Definition: MemProfiler.cpp:60
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:277
SmallVector.h
llvm::IRBuilderBase::CreateLShr
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1308
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:62
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:164
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:477
BasicBlockUtils.h
llvm::IRBuilderBase::CreateGEP
Value * CreateGEP(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Definition: IRBuilder.h:1777
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:522
Debug.h
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2352
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:1574
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38