LLVM  4.0.0
EfficiencySanitizer.cpp
Go to the documentation of this file.
1 //===-- EfficiencySanitizer.cpp - performance tuner -----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of EfficiencySanitizer, a family of performance tuners
11 // that detects multiple performance issues via separate sub-tools.
12 //
13 // The instrumentation phase is straightforward:
14 // - Take action on every memory access: either inlined instrumentation,
15 // or Inserted calls to our run-time library.
16 // - Optimizations may apply to avoid instrumenting some of the accesses.
17 // - Turn mem{set,cpy,move} instrinsics into library calls.
18 // The rest is handled by the run-time library.
19 //===----------------------------------------------------------------------===//
20 
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/Statistic.h"
25 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/IRBuilder.h"
29 #include "llvm/IR/IntrinsicInst.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/IR/Type.h"
33 #include "llvm/Support/Debug.h"
38 
39 using namespace llvm;
40 
41 #define DEBUG_TYPE "esan"
42 
43 // The tool type must be just one of these ClTool* options, as the tools
44 // cannot be combined due to shadow memory constraints.
45 static cl::opt<bool>
46  ClToolCacheFrag("esan-cache-frag", cl::init(false),
47  cl::desc("Detect data cache fragmentation"), cl::Hidden);
48 static cl::opt<bool>
49  ClToolWorkingSet("esan-working-set", cl::init(false),
50  cl::desc("Measure the working set size"), cl::Hidden);
51 // Each new tool will get its own opt flag here.
52 // These are converted to EfficiencySanitizerOptions for use
53 // in the code.
54 
56  "esan-instrument-loads-and-stores", cl::init(true),
57  cl::desc("Instrument loads and stores"), cl::Hidden);
59  "esan-instrument-memintrinsics", cl::init(true),
60  cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden);
62  "esan-instrument-fastpath", cl::init(true),
63  cl::desc("Instrument fastpath"), cl::Hidden);
65  "esan-aux-field-info", cl::init(true),
66  cl::desc("Generate binary with auxiliary struct field information"),
67  cl::Hidden);
68 
69 // Experiments show that the performance difference can be 2x or more,
70 // and accuracy loss is typically negligible, so we turn this on by default.
72  "esan-assume-intra-cache-line", cl::init(true),
73  cl::desc("Assume each memory access touches just one cache line, for "
74  "better performance but with a potential loss of accuracy."),
75  cl::Hidden);
76 
77 STATISTIC(NumInstrumentedLoads, "Number of instrumented loads");
78 STATISTIC(NumInstrumentedStores, "Number of instrumented stores");
79 STATISTIC(NumFastpaths, "Number of instrumented fastpaths");
80 STATISTIC(NumAccessesWithIrregularSize,
81  "Number of accesses with a size outside our targeted callout sizes");
82 STATISTIC(NumIgnoredStructs, "Number of ignored structs");
83 STATISTIC(NumIgnoredGEPs, "Number of ignored GEP instructions");
84 STATISTIC(NumInstrumentedGEPs, "Number of instrumented GEP instructions");
85 STATISTIC(NumAssumedIntraCacheLine,
86  "Number of accesses assumed to be intra-cache-line");
87 
88 static const uint64_t EsanCtorAndDtorPriority = 0;
89 static const char *const EsanModuleCtorName = "esan.module_ctor";
90 static const char *const EsanModuleDtorName = "esan.module_dtor";
91 static const char *const EsanInitName = "__esan_init";
92 static const char *const EsanExitName = "__esan_exit";
93 
94 // We need to specify the tool to the runtime earlier than
95 // the ctor is called in some cases, so we set a global variable.
96 static const char *const EsanWhichToolName = "__esan_which_tool";
97 
98 // We must keep these Shadow* constants consistent with the esan runtime.
99 // FIXME: Try to place these shadow constants, the names of the __esan_*
100 // interface functions, and the ToolType enum into a header shared between
101 // llvm and compiler-rt.
103  uint64_t ShadowMask;
104  uint64_t ShadowOffs[3];
105 };
106 
108  0x00000fffffffffffull,
109  {
110  0x0000130000000000ull, 0x0000220000000000ull, 0x0000440000000000ull,
111  }};
112 
114  0x0fffffffffull,
115  {
116  0x1300000000ull, 0x2200000000ull, 0x4400000000ull,
117  }};
118 
119 // This array is indexed by the ToolType enum.
120 static const int ShadowScale[] = {
121  0, // ESAN_None.
122  2, // ESAN_CacheFrag: 4B:1B, so 4 to 1 == >>2.
123  6, // ESAN_WorkingSet: 64B:1B, so 64 to 1 == >>6.
124 };
125 
126 // MaxStructCounterNameSize is a soft size limit to avoid insanely long
127 // names for those extremely large structs.
128 static const unsigned MaxStructCounterNameSize = 512;
129 
130 namespace {
131 
133 OverrideOptionsFromCL(EfficiencySanitizerOptions Options) {
134  if (ClToolCacheFrag)
136  else if (ClToolWorkingSet)
138 
139  // Direct opt invocation with no params will have the default ESAN_None.
140  // We run the default tool in that case.
143 
144  return Options;
145 }
146 
147 // Create a constant for Str so that we can pass it to the run-time lib.
149  bool AllowMerging) {
150  Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
151  // We use private linkage for module-local strings. If they can be merged
152  // with another one, we set the unnamed_addr attribute.
153  GlobalVariable *GV =
154  new GlobalVariable(M, StrConst->getType(), true,
155  GlobalValue::PrivateLinkage, StrConst, "");
156  if (AllowMerging)
158  GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
159  return GV;
160 }
161 
162 /// EfficiencySanitizer: instrument each module to find performance issues.
163 class EfficiencySanitizer : public ModulePass {
164 public:
165  EfficiencySanitizer(
167  : ModulePass(ID), Options(OverrideOptionsFromCL(Opts)) {}
168  StringRef getPassName() const override;
169  void getAnalysisUsage(AnalysisUsage &AU) const override;
170  bool runOnModule(Module &M) override;
171  static char ID;
172 
173 private:
174  bool initOnModule(Module &M);
175  void initializeCallbacks(Module &M);
176  bool shouldIgnoreStructType(StructType *StructTy);
177  void createStructCounterName(
179  void createCacheFragAuxGV(
180  Module &M, const DataLayout &DL, StructType *StructTy,
181  GlobalVariable *&TypeNames, GlobalVariable *&Offsets, GlobalVariable *&Size);
182  GlobalVariable *createCacheFragInfoGV(Module &M, const DataLayout &DL,
183  Constant *UnitName);
184  Constant *createEsanInitToolInfoArg(Module &M, const DataLayout &DL);
185  void createDestructor(Module &M, Constant *ToolInfoArg);
186  bool runOnFunction(Function &F, Module &M);
187  bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
188  bool instrumentMemIntrinsic(MemIntrinsic *MI);
189  bool instrumentGetElementPtr(Instruction *I, Module &M);
190  bool insertCounterUpdate(Instruction *I, StructType *StructTy,
191  unsigned CounterIdx);
192  unsigned getFieldCounterIdx(StructType *StructTy) {
193  return 0;
194  }
195  unsigned getArrayCounterIdx(StructType *StructTy) {
196  return StructTy->getNumElements();
197  }
198  unsigned getStructCounterSize(StructType *StructTy) {
199  // The struct counter array includes:
200  // - one counter for each struct field,
201  // - one counter for the struct access within an array.
202  return (StructTy->getNumElements()/*field*/ + 1/*array*/);
203  }
204  bool shouldIgnoreMemoryAccess(Instruction *I);
205  int getMemoryAccessFuncIndex(Value *Addr, const DataLayout &DL);
206  Value *appToShadow(Value *Shadow, IRBuilder<> &IRB);
207  bool instrumentFastpath(Instruction *I, const DataLayout &DL, bool IsStore,
208  Value *Addr, unsigned Alignment);
209  // Each tool has its own fastpath routine:
210  bool instrumentFastpathCacheFrag(Instruction *I, const DataLayout &DL,
211  Value *Addr, unsigned Alignment);
212  bool instrumentFastpathWorkingSet(Instruction *I, const DataLayout &DL,
213  Value *Addr, unsigned Alignment);
214 
216  LLVMContext *Ctx;
217  Type *IntptrTy;
218  // Our slowpath involves callouts to the runtime library.
219  // Access sizes are powers of two: 1, 2, 4, 8, 16.
220  static const size_t NumberOfAccessSizes = 5;
221  Function *EsanAlignedLoad[NumberOfAccessSizes];
222  Function *EsanAlignedStore[NumberOfAccessSizes];
223  Function *EsanUnalignedLoad[NumberOfAccessSizes];
224  Function *EsanUnalignedStore[NumberOfAccessSizes];
225  // For irregular sizes of any alignment:
226  Function *EsanUnalignedLoadN, *EsanUnalignedStoreN;
227  Function *MemmoveFn, *MemcpyFn, *MemsetFn;
228  Function *EsanCtorFunction;
229  Function *EsanDtorFunction;
230  // Remember the counter variable for each struct type to avoid
231  // recomputing the variable name later during instrumentation.
232  std::map<Type *, GlobalVariable *> StructTyMap;
233  ShadowMemoryParams ShadowParams;
234 };
235 } // namespace
236 
237 char EfficiencySanitizer::ID = 0;
239  EfficiencySanitizer, "esan",
240  "EfficiencySanitizer: finds performance issues.", false, false)
243  EfficiencySanitizer, "esan",
244  "EfficiencySanitizer: finds performance issues.", false, false)
245 
246 StringRef EfficiencySanitizer::getPassName() const {
247  return "EfficiencySanitizer";
248 }
249 
250 void EfficiencySanitizer::getAnalysisUsage(AnalysisUsage &AU) const {
252 }
253 
254 ModulePass *
256  return new EfficiencySanitizer(Options);
257 }
258 
259 void EfficiencySanitizer::initializeCallbacks(Module &M) {
260  IRBuilder<> IRB(M.getContext());
261  // Initialize the callbacks.
262  for (size_t Idx = 0; Idx < NumberOfAccessSizes; ++Idx) {
263  const unsigned ByteSize = 1U << Idx;
264  std::string ByteSizeStr = utostr(ByteSize);
265  // We'll inline the most common (i.e., aligned and frequent sizes)
266  // load + store instrumentation: these callouts are for the slowpath.
267  SmallString<32> AlignedLoadName("__esan_aligned_load" + ByteSizeStr);
268  EsanAlignedLoad[Idx] =
270  AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
271  SmallString<32> AlignedStoreName("__esan_aligned_store" + ByteSizeStr);
272  EsanAlignedStore[Idx] =
274  AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
275  SmallString<32> UnalignedLoadName("__esan_unaligned_load" + ByteSizeStr);
276  EsanUnalignedLoad[Idx] =
278  UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
279  SmallString<32> UnalignedStoreName("__esan_unaligned_store" + ByteSizeStr);
280  EsanUnalignedStore[Idx] =
282  UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
283  }
284  EsanUnalignedLoadN = checkSanitizerInterfaceFunction(
285  M.getOrInsertFunction("__esan_unaligned_loadN", IRB.getVoidTy(),
286  IRB.getInt8PtrTy(), IntptrTy, nullptr));
287  EsanUnalignedStoreN = checkSanitizerInterfaceFunction(
288  M.getOrInsertFunction("__esan_unaligned_storeN", IRB.getVoidTy(),
289  IRB.getInt8PtrTy(), IntptrTy, nullptr));
291  M.getOrInsertFunction("memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
292  IRB.getInt8PtrTy(), IntptrTy, nullptr));
294  M.getOrInsertFunction("memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
295  IRB.getInt8PtrTy(), IntptrTy, nullptr));
297  M.getOrInsertFunction("memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
298  IRB.getInt32Ty(), IntptrTy, nullptr));
299 }
300 
301 bool EfficiencySanitizer::shouldIgnoreStructType(StructType *StructTy) {
302  if (StructTy == nullptr || StructTy->isOpaque() /* no struct body */)
303  return true;
304  return false;
305 }
306 
307 void EfficiencySanitizer::createStructCounterName(
309  // Append NumFields and field type ids to avoid struct conflicts
310  // with the same name but different fields.
311  if (StructTy->hasName())
312  NameStr += StructTy->getName();
313  else
314  NameStr += "struct.anon";
315  // We allow the actual size of the StructCounterName to be larger than
316  // MaxStructCounterNameSize and append $NumFields and at least one
317  // field type id.
318  // Append $NumFields.
319  NameStr += "$";
320  Twine(StructTy->getNumElements()).toVector(NameStr);
321  // Append struct field type ids in the reverse order.
322  for (int i = StructTy->getNumElements() - 1; i >= 0; --i) {
323  NameStr += "$";
324  Twine(StructTy->getElementType(i)->getTypeID()).toVector(NameStr);
325  if (NameStr.size() >= MaxStructCounterNameSize)
326  break;
327  }
328  if (StructTy->isLiteral()) {
329  // End with $ for literal struct.
330  NameStr += "$";
331  }
332 }
333 
334 // Create global variables with auxiliary information (e.g., struct field size,
335 // offset, and type name) for better user report.
336 void EfficiencySanitizer::createCacheFragAuxGV(
337  Module &M, const DataLayout &DL, StructType *StructTy,
338  GlobalVariable *&TypeName, GlobalVariable *&Offset,
339  GlobalVariable *&Size) {
340  auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
341  auto *Int32Ty = Type::getInt32Ty(*Ctx);
342  // FieldTypeName.
343  auto *TypeNameArrayTy = ArrayType::get(Int8PtrTy, StructTy->getNumElements());
344  TypeName = new GlobalVariable(M, TypeNameArrayTy, true,
346  SmallVector<Constant *, 16> TypeNameVec;
347  // FieldOffset.
348  auto *OffsetArrayTy = ArrayType::get(Int32Ty, StructTy->getNumElements());
349  Offset = new GlobalVariable(M, OffsetArrayTy, true,
351  SmallVector<Constant *, 16> OffsetVec;
352  // FieldSize
353  auto *SizeArrayTy = ArrayType::get(Int32Ty, StructTy->getNumElements());
354  Size = new GlobalVariable(M, SizeArrayTy, true,
357  for (unsigned i = 0; i < StructTy->getNumElements(); ++i) {
358  Type *Ty = StructTy->getElementType(i);
359  std::string Str;
360  raw_string_ostream StrOS(Str);
361  Ty->print(StrOS);
362  TypeNameVec.push_back(
364  createPrivateGlobalForString(M, StrOS.str(), true),
365  Int8PtrTy));
366  OffsetVec.push_back(
368  DL.getStructLayout(StructTy)->getElementOffset(i)));
370  DL.getTypeAllocSize(Ty)));
371  }
372  TypeName->setInitializer(ConstantArray::get(TypeNameArrayTy, TypeNameVec));
373  Offset->setInitializer(ConstantArray::get(OffsetArrayTy, OffsetVec));
374  Size->setInitializer(ConstantArray::get(SizeArrayTy, SizeVec));
375 }
376 
377 // Create the global variable for the cache-fragmentation tool.
378 GlobalVariable *EfficiencySanitizer::createCacheFragInfoGV(
379  Module &M, const DataLayout &DL, Constant *UnitName) {
381 
382  auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
383  auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
384  auto *Int32Ty = Type::getInt32Ty(*Ctx);
385  auto *Int32PtrTy = Type::getInt32PtrTy(*Ctx);
386  auto *Int64Ty = Type::getInt64Ty(*Ctx);
387  auto *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
388  // This structure should be kept consistent with the StructInfo struct
389  // in the runtime library.
390  // struct StructInfo {
391  // const char *StructName;
392  // u32 Size;
393  // u32 NumFields;
394  // u32 *FieldOffset; // auxiliary struct field info.
395  // u32 *FieldSize; // auxiliary struct field info.
396  // const char **FieldTypeName; // auxiliary struct field info.
397  // u64 *FieldCounters;
398  // u64 *ArrayCounter;
399  // };
400  auto *StructInfoTy =
401  StructType::get(Int8PtrTy, Int32Ty, Int32Ty, Int32PtrTy, Int32PtrTy,
402  Int8PtrPtrTy, Int64PtrTy, Int64PtrTy, nullptr);
403  auto *StructInfoPtrTy = StructInfoTy->getPointerTo();
404  // This structure should be kept consistent with the CacheFragInfo struct
405  // in the runtime library.
406  // struct CacheFragInfo {
407  // const char *UnitName;
408  // u32 NumStructs;
409  // StructInfo *Structs;
410  // };
411  auto *CacheFragInfoTy =
412  StructType::get(Int8PtrTy, Int32Ty, StructInfoPtrTy, nullptr);
413 
414  std::vector<StructType *> Vec = M.getIdentifiedStructTypes();
415  unsigned NumStructs = 0;
416  SmallVector<Constant *, 16> Initializers;
417 
418  for (auto &StructTy : Vec) {
419  if (shouldIgnoreStructType(StructTy)) {
420  ++NumIgnoredStructs;
421  continue;
422  }
423  ++NumStructs;
424 
425  // StructName.
427  createStructCounterName(StructTy, CounterNameStr);
428  GlobalVariable *StructCounterName = createPrivateGlobalForString(
429  M, CounterNameStr, /*AllowMerging*/true);
430 
431  // Counters.
432  // We create the counter array with StructCounterName and weak linkage
433  // so that the structs with the same name and layout from different
434  // compilation units will be merged into one.
435  auto *CounterArrayTy = ArrayType::get(Int64Ty,
436  getStructCounterSize(StructTy));
437  GlobalVariable *Counters =
438  new GlobalVariable(M, CounterArrayTy, false,
440  ConstantAggregateZero::get(CounterArrayTy),
441  CounterNameStr);
442 
443  // Remember the counter variable for each struct type.
444  StructTyMap.insert(std::pair<Type *, GlobalVariable *>(StructTy, Counters));
445 
446  // We pass the field type name array, offset array, and size array to
447  // the runtime for better reporting.
448  GlobalVariable *TypeName = nullptr, *Offset = nullptr, *Size = nullptr;
449  if (ClAuxFieldInfo)
450  createCacheFragAuxGV(M, DL, StructTy, TypeName, Offset, Size);
451 
452  Constant *FieldCounterIdx[2];
453  FieldCounterIdx[0] = ConstantInt::get(Int32Ty, 0);
454  FieldCounterIdx[1] = ConstantInt::get(Int32Ty,
455  getFieldCounterIdx(StructTy));
456  Constant *ArrayCounterIdx[2];
457  ArrayCounterIdx[0] = ConstantInt::get(Int32Ty, 0);
458  ArrayCounterIdx[1] = ConstantInt::get(Int32Ty,
459  getArrayCounterIdx(StructTy));
460  Initializers.push_back(
462  StructInfoTy,
463  ConstantExpr::getPointerCast(StructCounterName, Int8PtrTy),
465  DL.getStructLayout(StructTy)->getSizeInBytes()),
467  Offset == nullptr ? ConstantPointerNull::get(Int32PtrTy) :
468  ConstantExpr::getPointerCast(Offset, Int32PtrTy),
469  Size == nullptr ? ConstantPointerNull::get(Int32PtrTy) :
470  ConstantExpr::getPointerCast(Size, Int32PtrTy),
471  TypeName == nullptr ? ConstantPointerNull::get(Int8PtrPtrTy) :
472  ConstantExpr::getPointerCast(TypeName, Int8PtrPtrTy),
473  ConstantExpr::getGetElementPtr(CounterArrayTy, Counters,
474  FieldCounterIdx),
475  ConstantExpr::getGetElementPtr(CounterArrayTy, Counters,
476  ArrayCounterIdx),
477  nullptr));
478  }
479  // Structs.
480  Constant *StructInfo;
481  if (NumStructs == 0) {
482  StructInfo = ConstantPointerNull::get(StructInfoPtrTy);
483  } else {
484  auto *StructInfoArrayTy = ArrayType::get(StructInfoTy, NumStructs);
485  StructInfo = ConstantExpr::getPointerCast(
486  new GlobalVariable(M, StructInfoArrayTy, false,
488  ConstantArray::get(StructInfoArrayTy, Initializers)),
489  StructInfoPtrTy);
490  }
491 
492  auto *CacheFragInfoGV = new GlobalVariable(
493  M, CacheFragInfoTy, true, GlobalVariable::InternalLinkage,
494  ConstantStruct::get(CacheFragInfoTy,
495  UnitName,
496  ConstantInt::get(Int32Ty, NumStructs),
497  StructInfo,
498  nullptr));
499  return CacheFragInfoGV;
500 }
501 
502 // Create the tool-specific argument passed to EsanInit and EsanExit.
503 Constant *EfficiencySanitizer::createEsanInitToolInfoArg(Module &M,
504  const DataLayout &DL) {
505  // This structure contains tool-specific information about each compilation
506  // unit (module) and is passed to the runtime library.
507  GlobalVariable *ToolInfoGV = nullptr;
508 
509  auto *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
510  // Compilation unit name.
511  auto *UnitName = ConstantExpr::getPointerCast(
513  Int8PtrTy);
514 
515  // Create the tool-specific variable.
516  if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag)
517  ToolInfoGV = createCacheFragInfoGV(M, DL, UnitName);
518 
519  if (ToolInfoGV != nullptr)
520  return ConstantExpr::getPointerCast(ToolInfoGV, Int8PtrTy);
521 
522  // Create the null pointer if no tool-specific variable created.
523  return ConstantPointerNull::get(Int8PtrTy);
524 }
525 
526 void EfficiencySanitizer::createDestructor(Module &M, Constant *ToolInfoArg) {
527  PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
528  EsanDtorFunction = Function::Create(FunctionType::get(Type::getVoidTy(*Ctx),
529  false),
531  EsanModuleDtorName, &M);
532  ReturnInst::Create(*Ctx, BasicBlock::Create(*Ctx, "", EsanDtorFunction));
533  IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
535  M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(),
536  Int8PtrTy, nullptr));
537  EsanExit->setLinkage(Function::ExternalLinkage);
538  IRB_Dtor.CreateCall(EsanExit, {ToolInfoArg});
539  appendToGlobalDtors(M, EsanDtorFunction, EsanCtorAndDtorPriority);
540 }
541 
542 bool EfficiencySanitizer::initOnModule(Module &M) {
543 
544  Triple TargetTriple(M.getTargetTriple());
545  if (TargetTriple.getArch() == Triple::mips64 || TargetTriple.getArch() == Triple::mips64el)
546  ShadowParams = ShadowParams40;
547  else
548  ShadowParams = ShadowParams47;
549 
550  Ctx = &M.getContext();
551  const DataLayout &DL = M.getDataLayout();
552  IRBuilder<> IRB(M.getContext());
553  IntegerType *OrdTy = IRB.getInt32Ty();
554  PointerType *Int8PtrTy = Type::getInt8PtrTy(*Ctx);
555  IntptrTy = DL.getIntPtrType(M.getContext());
556  // Create the variable passed to EsanInit and EsanExit.
557  Constant *ToolInfoArg = createEsanInitToolInfoArg(M, DL);
558  // Constructor
559  // We specify the tool type both in the EsanWhichToolName global
560  // and as an arg to the init routine as a sanity check.
561  std::tie(EsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(
562  M, EsanModuleCtorName, EsanInitName, /*InitArgTypes=*/{OrdTy, Int8PtrTy},
563  /*InitArgs=*/{
564  ConstantInt::get(OrdTy, static_cast<int>(Options.ToolType)),
565  ToolInfoArg});
566  appendToGlobalCtors(M, EsanCtorFunction, EsanCtorAndDtorPriority);
567 
568  createDestructor(M, ToolInfoArg);
569 
570  new GlobalVariable(M, OrdTy, true,
572  ConstantInt::get(OrdTy,
573  static_cast<int>(Options.ToolType)),
575 
576  return true;
577 }
578 
579 Value *EfficiencySanitizer::appToShadow(Value *Shadow, IRBuilder<> &IRB) {
580  // Shadow = ((App & Mask) + Offs) >> Scale
581  Shadow = IRB.CreateAnd(Shadow, ConstantInt::get(IntptrTy, ShadowParams.ShadowMask));
582  uint64_t Offs;
583  int Scale = ShadowScale[Options.ToolType];
584  if (Scale <= 2)
585  Offs = ShadowParams.ShadowOffs[Scale];
586  else
587  Offs = ShadowParams.ShadowOffs[0] << Scale;
588  Shadow = IRB.CreateAdd(Shadow, ConstantInt::get(IntptrTy, Offs));
589  if (Scale > 0)
590  Shadow = IRB.CreateLShr(Shadow, Scale);
591  return Shadow;
592 }
593 
594 bool EfficiencySanitizer::shouldIgnoreMemoryAccess(Instruction *I) {
595  if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) {
596  // We'd like to know about cache fragmentation in vtable accesses and
597  // constant data references, so we do not currently ignore anything.
598  return false;
599  } else if (Options.ToolType == EfficiencySanitizerOptions::ESAN_WorkingSet) {
600  // TODO: the instrumentation disturbs the data layout on the stack, so we
601  // may want to add an option to ignore stack references (if we can
602  // distinguish them) to reduce overhead.
603  }
604  // TODO(bruening): future tools will be returning true for some cases.
605  return false;
606 }
607 
608 bool EfficiencySanitizer::runOnModule(Module &M) {
609  bool Res = initOnModule(M);
610  initializeCallbacks(M);
611  for (auto &F : M) {
612  Res |= runOnFunction(F, M);
613  }
614  return Res;
615 }
616 
617 bool EfficiencySanitizer::runOnFunction(Function &F, Module &M) {
618  // This is required to prevent instrumenting the call to __esan_init from
619  // within the module constructor.
620  if (&F == EsanCtorFunction)
621  return false;
622  SmallVector<Instruction *, 8> LoadsAndStores;
623  SmallVector<Instruction *, 8> MemIntrinCalls;
624  SmallVector<Instruction *, 8> GetElementPtrs;
625  bool Res = false;
626  const DataLayout &DL = M.getDataLayout();
627  const TargetLibraryInfo *TLI =
628  &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
629 
630  for (auto &BB : F) {
631  for (auto &Inst : BB) {
632  if ((isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
633  isa<AtomicRMWInst>(Inst) || isa<AtomicCmpXchgInst>(Inst)) &&
634  !shouldIgnoreMemoryAccess(&Inst))
635  LoadsAndStores.push_back(&Inst);
636  else if (isa<MemIntrinsic>(Inst))
637  MemIntrinCalls.push_back(&Inst);
638  else if (isa<GetElementPtrInst>(Inst))
639  GetElementPtrs.push_back(&Inst);
640  else if (CallInst *CI = dyn_cast<CallInst>(&Inst))
642  }
643  }
644 
646  for (auto Inst : LoadsAndStores) {
647  Res |= instrumentLoadOrStore(Inst, DL);
648  }
649  }
650 
652  for (auto Inst : MemIntrinCalls) {
653  Res |= instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
654  }
655  }
656 
657  if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) {
658  for (auto Inst : GetElementPtrs) {
659  Res |= instrumentGetElementPtr(Inst, M);
660  }
661  }
662 
663  return Res;
664 }
665 
666 bool EfficiencySanitizer::instrumentLoadOrStore(Instruction *I,
667  const DataLayout &DL) {
668  IRBuilder<> IRB(I);
669  bool IsStore;
670  Value *Addr;
671  unsigned Alignment;
672  if (LoadInst *Load = dyn_cast<LoadInst>(I)) {
673  IsStore = false;
674  Alignment = Load->getAlignment();
675  Addr = Load->getPointerOperand();
676  } else if (StoreInst *Store = dyn_cast<StoreInst>(I)) {
677  IsStore = true;
678  Alignment = Store->getAlignment();
679  Addr = Store->getPointerOperand();
680  } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
681  IsStore = true;
682  Alignment = 0;
683  Addr = RMW->getPointerOperand();
684  } else if (AtomicCmpXchgInst *Xchg = dyn_cast<AtomicCmpXchgInst>(I)) {
685  IsStore = true;
686  Alignment = 0;
687  Addr = Xchg->getPointerOperand();
688  } else
689  llvm_unreachable("Unsupported mem access type");
690 
691  Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
692  const uint32_t TypeSizeBytes = DL.getTypeStoreSizeInBits(OrigTy) / 8;
693  Value *OnAccessFunc = nullptr;
694 
695  // Convert 0 to the default alignment.
696  if (Alignment == 0)
697  Alignment = DL.getPrefTypeAlignment(OrigTy);
698 
699  if (IsStore)
700  NumInstrumentedStores++;
701  else
702  NumInstrumentedLoads++;
703  int Idx = getMemoryAccessFuncIndex(Addr, DL);
704  if (Idx < 0) {
705  OnAccessFunc = IsStore ? EsanUnalignedStoreN : EsanUnalignedLoadN;
706  IRB.CreateCall(OnAccessFunc,
707  {IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
708  ConstantInt::get(IntptrTy, TypeSizeBytes)});
709  } else {
710  if (ClInstrumentFastpath &&
711  instrumentFastpath(I, DL, IsStore, Addr, Alignment)) {
712  NumFastpaths++;
713  return true;
714  }
715  if (Alignment == 0 || (Alignment % TypeSizeBytes) == 0)
716  OnAccessFunc = IsStore ? EsanAlignedStore[Idx] : EsanAlignedLoad[Idx];
717  else
718  OnAccessFunc = IsStore ? EsanUnalignedStore[Idx] : EsanUnalignedLoad[Idx];
719  IRB.CreateCall(OnAccessFunc,
720  IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()));
721  }
722  return true;
723 }
724 
725 // It's simplest to replace the memset/memmove/memcpy intrinsics with
726 // calls that the runtime library intercepts.
727 // Our pass is late enough that calls should not turn back into intrinsics.
728 bool EfficiencySanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
729  IRBuilder<> IRB(MI);
730  bool Res = false;
731  if (isa<MemSetInst>(MI)) {
732  IRB.CreateCall(
733  MemsetFn,
734  {IRB.CreatePointerCast(MI->getArgOperand(0), IRB.getInt8PtrTy()),
735  IRB.CreateIntCast(MI->getArgOperand(1), IRB.getInt32Ty(), false),
736  IRB.CreateIntCast(MI->getArgOperand(2), IntptrTy, false)});
737  MI->eraseFromParent();
738  Res = true;
739  } else if (isa<MemTransferInst>(MI)) {
740  IRB.CreateCall(
741  isa<MemCpyInst>(MI) ? MemcpyFn : MemmoveFn,
742  {IRB.CreatePointerCast(MI->getArgOperand(0), IRB.getInt8PtrTy()),
743  IRB.CreatePointerCast(MI->getArgOperand(1), IRB.getInt8PtrTy()),
744  IRB.CreateIntCast(MI->getArgOperand(2), IntptrTy, false)});
745  MI->eraseFromParent();
746  Res = true;
747  } else
748  llvm_unreachable("Unsupported mem intrinsic type");
749  return Res;
750 }
751 
752 bool EfficiencySanitizer::instrumentGetElementPtr(Instruction *I, Module &M) {
754  bool Res = false;
755  if (GepInst == nullptr || GepInst->getNumIndices() == 1) {
756  ++NumIgnoredGEPs;
757  return false;
758  }
759  Type *SourceTy = GepInst->getSourceElementType();
760  StructType *StructTy;
761  ConstantInt *Idx;
762  // Check if GEP calculates address from a struct array.
763  if (isa<StructType>(SourceTy)) {
764  StructTy = cast<StructType>(SourceTy);
765  Idx = dyn_cast<ConstantInt>(GepInst->getOperand(1));
766  if ((Idx == nullptr || Idx->getSExtValue() != 0) &&
767  !shouldIgnoreStructType(StructTy) && StructTyMap.count(StructTy) != 0)
768  Res |= insertCounterUpdate(I, StructTy, getArrayCounterIdx(StructTy));
769  }
770  // Iterate all (except the first and the last) idx within each GEP instruction
771  // for possible nested struct field address calculation.
772  for (unsigned i = 1; i < GepInst->getNumIndices(); ++i) {
773  SmallVector<Value *, 8> IdxVec(GepInst->idx_begin(),
774  GepInst->idx_begin() + i);
775  Type *Ty = GetElementPtrInst::getIndexedType(SourceTy, IdxVec);
776  unsigned CounterIdx = 0;
777  if (isa<ArrayType>(Ty)) {
778  ArrayType *ArrayTy = cast<ArrayType>(Ty);
779  StructTy = dyn_cast<StructType>(ArrayTy->getElementType());
780  if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
781  continue;
782  // The last counter for struct array access.
783  CounterIdx = getArrayCounterIdx(StructTy);
784  } else if (isa<StructType>(Ty)) {
785  StructTy = cast<StructType>(Ty);
786  if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
787  continue;
788  // Get the StructTy's subfield index.
789  Idx = cast<ConstantInt>(GepInst->getOperand(i+1));
790  assert(Idx->getSExtValue() >= 0 &&
791  Idx->getSExtValue() < StructTy->getNumElements());
792  CounterIdx = getFieldCounterIdx(StructTy) + Idx->getSExtValue();
793  }
794  Res |= insertCounterUpdate(I, StructTy, CounterIdx);
795  }
796  if (Res)
797  ++NumInstrumentedGEPs;
798  else
799  ++NumIgnoredGEPs;
800  return Res;
801 }
802 
803 bool EfficiencySanitizer::insertCounterUpdate(Instruction *I,
804  StructType *StructTy,
805  unsigned CounterIdx) {
806  GlobalVariable *CounterArray = StructTyMap[StructTy];
807  if (CounterArray == nullptr)
808  return false;
809  IRBuilder<> IRB(I);
810  Constant *Indices[2];
811  // Xref http://llvm.org/docs/LangRef.html#i-getelementptr and
812  // http://llvm.org/docs/GetElementPtr.html.
813  // The first index of the GEP instruction steps through the first operand,
814  // i.e., the array itself.
815  Indices[0] = ConstantInt::get(IRB.getInt32Ty(), 0);
816  // The second index is the index within the array.
817  Indices[1] = ConstantInt::get(IRB.getInt32Ty(), CounterIdx);
818  Constant *Counter =
820  ArrayType::get(IRB.getInt64Ty(), getStructCounterSize(StructTy)),
821  CounterArray, Indices);
822  Value *Load = IRB.CreateLoad(Counter);
823  IRB.CreateStore(IRB.CreateAdd(Load, ConstantInt::get(IRB.getInt64Ty(), 1)),
824  Counter);
825  return true;
826 }
827 
828 int EfficiencySanitizer::getMemoryAccessFuncIndex(Value *Addr,
829  const DataLayout &DL) {
830  Type *OrigPtrTy = Addr->getType();
831  Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
832  assert(OrigTy->isSized());
833  // The size is always a multiple of 8.
834  uint32_t TypeSizeBytes = DL.getTypeStoreSizeInBits(OrigTy) / 8;
835  if (TypeSizeBytes != 1 && TypeSizeBytes != 2 && TypeSizeBytes != 4 &&
836  TypeSizeBytes != 8 && TypeSizeBytes != 16) {
837  // Irregular sizes do not have per-size call targets.
838  NumAccessesWithIrregularSize++;
839  return -1;
840  }
841  size_t Idx = countTrailingZeros(TypeSizeBytes);
842  assert(Idx < NumberOfAccessSizes);
843  return Idx;
844 }
845 
846 bool EfficiencySanitizer::instrumentFastpath(Instruction *I,
847  const DataLayout &DL, bool IsStore,
848  Value *Addr, unsigned Alignment) {
849  if (Options.ToolType == EfficiencySanitizerOptions::ESAN_CacheFrag) {
850  return instrumentFastpathCacheFrag(I, DL, Addr, Alignment);
851  } else if (Options.ToolType == EfficiencySanitizerOptions::ESAN_WorkingSet) {
852  return instrumentFastpathWorkingSet(I, DL, Addr, Alignment);
853  }
854  return false;
855 }
856 
857 bool EfficiencySanitizer::instrumentFastpathCacheFrag(Instruction *I,
858  const DataLayout &DL,
859  Value *Addr,
860  unsigned Alignment) {
861  // Do nothing.
862  return true; // Return true to avoid slowpath instrumentation.
863 }
864 
865 bool EfficiencySanitizer::instrumentFastpathWorkingSet(
866  Instruction *I, const DataLayout &DL, Value *Addr, unsigned Alignment) {
867  assert(ShadowScale[Options.ToolType] == 6); // The code below assumes this
868  IRBuilder<> IRB(I);
869  Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType();
870  const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
871  // Bail to the slowpath if the access might touch multiple cache lines.
872  // An access aligned to its size is guaranteed to be intra-cache-line.
873  // getMemoryAccessFuncIndex has already ruled out a size larger than 16
874  // and thus larger than a cache line for platforms this tool targets
875  // (and our shadow memory setup assumes 64-byte cache lines).
876  assert(TypeSize <= 128);
877  if (!(TypeSize == 8 ||
878  (Alignment % (TypeSize / 8)) == 0)) {
880  ++NumAssumedIntraCacheLine;
881  else
882  return false;
883  }
884 
885  // We inline instrumentation to set the corresponding shadow bits for
886  // each cache line touched by the application. Here we handle a single
887  // load or store where we've already ruled out the possibility that it
888  // might touch more than one cache line and thus we simply update the
889  // shadow memory for a single cache line.
890  // Our shadow memory model is fine with races when manipulating shadow values.
891  // We generate the following code:
892  //
893  // const char BitMask = 0x81;
894  // char *ShadowAddr = appToShadow(AppAddr);
895  // if ((*ShadowAddr & BitMask) != BitMask)
896  // *ShadowAddr |= Bitmask;
897  //
898  Value *AddrPtr = IRB.CreatePointerCast(Addr, IntptrTy);
899  Value *ShadowPtr = appToShadow(AddrPtr, IRB);
900  Type *ShadowTy = IntegerType::get(*Ctx, 8U);
901  Type *ShadowPtrTy = PointerType::get(ShadowTy, 0);
902  // The bottom bit is used for the current sampling period's working set.
903  // The top bit is used for the total working set. We set both on each
904  // memory access, if they are not already set.
905  Value *ValueMask = ConstantInt::get(ShadowTy, 0x81); // 10000001B
906 
907  Value *OldValue = IRB.CreateLoad(IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy));
908  // The AND and CMP will be turned into a TEST instruction by the compiler.
909  Value *Cmp = IRB.CreateICmpNE(IRB.CreateAnd(OldValue, ValueMask), ValueMask);
910  TerminatorInst *CmpTerm = SplitBlockAndInsertIfThen(Cmp, I, false);
911  // FIXME: do I need to call SetCurrentDebugLocation?
912  IRB.SetInsertPoint(CmpTerm);
913  // We use OR to set the shadow bits to avoid corrupting the middle 6 bits,
914  // which are used by the runtime library.
915  Value *NewVal = IRB.CreateOr(OldValue, ValueMask);
916  IRB.CreateStore(NewVal, IRB.CreateIntToPtr(ShadowPtr, ShadowPtrTy));
917  IRB.SetInsertPoint(I);
918 
919  return true;
920 }
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:76
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
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:2471
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
Definition: ModuleUtils.cpp:88
enum llvm::EfficiencySanitizerOptions::Type ToolType
Function * checkSanitizerInterfaceFunction(Constant *FuncOrBitcast)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1469
Type * getSourceElementType() const
Definition: Instructions.h:928
STATISTIC(NumFunctions,"Total number of functions")
size_t i
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
Definition: DerivedTypes.h:253
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
Definition: Instructions.h:504
static ConstantAggregateZero * get(Type *Ty)
Definition: Constants.cpp:1254
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
Definition: DataLayout.cpp:699
This class represents a function call, abstracting a target machine's calling convention.
static int Counter
static PointerType * getInt32PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:221
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:655
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Definition: Constants.h:1126
static const char *const EsanInitName
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:777
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:57
Externally visible function.
Definition: GlobalValue.h:49
std::vector< StructType * > getIdentifiedStructTypes() const
Definition: Module.cpp:433
An instruction for reading from memory.
Definition: Instructions.h:164
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:170
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
Definition: Instructions.h:669
static GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging)
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:218
unsigned getNumIndices() const
static PointerType * getInt64PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:225
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:347
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
ModulePass * createEfficiencySanitizerPass(const EfficiencySanitizerOptions &Options=EfficiencySanitizerOptions())
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
Definition: DataLayout.cpp:566
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition: IRBuilder.h:352
Class to represent struct types.
Definition: DerivedTypes.h:199
INITIALIZE_PASS_BEGIN(EfficiencySanitizer,"esan","EfficiencySanitizer: finds performance issues.", false, false) INITIALIZE_PASS_END(EfficiencySanitizer
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:588
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition...
Definition: DerivedTypes.h:249
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:813
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:193
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1094
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1358
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:873
#define F(x, y, z)
Definition: MD5.cpp:51
Class to represent array types.
Definition: DerivedTypes.h:345
static const int ShadowScale[]
op_iterator idx_begin()
Definition: Instructions.h:956
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:291
static std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:79
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
An instruction for storing to memory.
Definition: Instructions.h:300
static const char *const EsanModuleCtorName
Type * getElementType() const
Definition: DerivedTypes.h:336
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Definition: IRBuilder.h:127
Class to represent pointers.
Definition: DerivedTypes.h:443
static const char *const EsanModuleDtorName
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1003
uint64_t getElementOffset(unsigned Idx) const
Definition: DataLayout.h:517
static const ShadowMemoryParams ShadowParams47
EfficiencySanitizer false
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:254
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
Definition: Instructions.h:830
LoadInst * CreateLoad(Value *Ptr, const char *Name)
Definition: IRBuilder.h:1082
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
Subclasses of this class are all able to terminate a basic block.
Definition: InstrTypes.h:52
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
Definition: Constants.cpp:1323
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:111
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:123
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
Definition: DataLayout.h:399
static const char *const EsanWhichToolName
Type * getElementType(unsigned N) const
Definition: DerivedTypes.h:290
This is an important base class in LLVM.
Definition: Constant.h:42
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:888
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:154
uint32_t Offset
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
Definition: AsmWriter.cpp:3368
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
Value * getOperand(unsigned i) const
Definition: User.h:145
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:93
Class to represent integer types.
Definition: DerivedTypes.h:39
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:949
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
Definition: IRBuilder.h:385
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:213
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
static cl::opt< bool > ClInstrumentFastpath("esan-instrument-fastpath", cl::init(true), cl::desc("Instrument fastpath"), cl::Hidden)
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
Definition: DataLayout.cpp:709
static const uint64_t EsanCtorAndDtorPriority
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
Definition: Constants.cpp:1509
std::pair< Function *, Function * > 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.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:234
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
Definition: Constants.h:88
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:408
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:330
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:1425
bool hasName() const
Return true if this is a named struct that has a non-empty name.
Definition: DerivedTypes.h:259
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
Provides information about what library functions are available for the current target.
A constant pointer value that points to null.
Definition: Constants.h:529
TerminatorInst * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
uint64_t getSizeInBytes() const
Definition: DataLayout.h:503
static cl::opt< bool > ClInstrumentMemIntrinsics("esan-instrument-memintrinsics", cl::init(true), cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden)
static cl::opt< bool > ClToolCacheFrag("esan-cache-frag", cl::init(false), cl::desc("Detect data cache fragmentation"), cl::Hidden)
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:558
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:84
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
StringRef getName() const
Return the name for this struct type if it has an identity.
Definition: Type.cpp:510
static cl::opt< bool > ClToolWorkingSet("esan-working-set", cl::init(false), cl::desc("Measure the working set size"), cl::Hidden)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1402
static Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the type of the element that would be loaded with a load instruction with the specified param...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:384
void setUnnamedAddr(UnnamedAddr Val)
Definition: GlobalValue.h:203
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:169
#define I(x, y, z)
Definition: MD5.cpp:54
static cl::opt< bool > ClInstrumentLoadsAndStores("esan-instrument-loads-and-stores", cl::init(true), cl::desc("Instrument loads and stores"), cl::Hidden)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:235
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1579
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:606
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:53
Rename collisions when linking (static functions).
Definition: GlobalValue.h:56
void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition: Local.cpp:2068
static cl::opt< bool > ClAuxFieldInfo("esan-aux-field-info", cl::init(true), cl::desc("Generate binary with auxiliary struct field information"), cl::Hidden)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:987
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const ShadowMemoryParams ShadowParams40
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:463
LLVM Value Representation.
Definition: Value.h:71
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:951
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
static const unsigned MaxStructCounterNameSize
static const char *const EsanExitName
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
Definition: Function.h:117
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:289
static cl::opt< bool > ClAssumeIntraCacheLine("esan-assume-intra-cache-line", cl::init(true), cl::desc("Assume each memory access touches just one cache line, for ""better performance but with a potential loss of accuracy."), cl::Hidden)
IntegerType * Int32Ty
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:222