41 #define DEBUG_TYPE "esan"
56 "esan-instrument-loads-and-stores",
cl::init(
true),
59 "esan-instrument-memintrinsics",
cl::init(
true),
62 "esan-instrument-fastpath",
cl::init(
true),
65 "esan-aux-field-info",
cl::init(
true),
66 cl::desc(
"Generate binary with auxiliary struct field information"),
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."),
77 STATISTIC(NumInstrumentedLoads,
"Number of instrumented loads");
78 STATISTIC(NumInstrumentedStores,
"Number of instrumented stores");
79 STATISTIC(NumFastpaths,
"Number of instrumented fastpaths");
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");
86 "Number of accesses assumed to be intra-cache-line");
104 uint64_t ShadowOffs[3];
108 0x00000fffffffffffull,
110 0x0000130000000000ull, 0x0000220000000000ull, 0x0000440000000000ull,
116 0x1300000000ull, 0x2200000000ull, 0x4400000000ull,
163 class EfficiencySanitizer :
public ModulePass {
167 :
ModulePass(
ID), Options(OverrideOptionsFromCL(Opts)) {}
170 bool runOnModule(
Module &M)
override;
174 bool initOnModule(
Module &M);
175 void initializeCallbacks(
Module &M);
176 bool shouldIgnoreStructType(
StructType *StructTy);
177 void createStructCounterName(
179 void createCacheFragAuxGV(
191 unsigned CounterIdx);
192 unsigned getFieldCounterIdx(
StructType *StructTy) {
195 unsigned getArrayCounterIdx(
StructType *StructTy) {
198 unsigned getStructCounterSize(
StructType *StructTy) {
208 Value *Addr,
unsigned Alignment);
211 Value *Addr,
unsigned Alignment);
213 Value *Addr,
unsigned Alignment);
220 static const size_t NumberOfAccessSizes = 5;
221 Function *EsanAlignedLoad[NumberOfAccessSizes];
222 Function *EsanAlignedStore[NumberOfAccessSizes];
223 Function *EsanUnalignedLoad[NumberOfAccessSizes];
224 Function *EsanUnalignedStore[NumberOfAccessSizes];
226 Function *EsanUnalignedLoadN, *EsanUnalignedStoreN;
227 Function *MemmoveFn, *MemcpyFn, *MemsetFn;
232 std::map<Type *, GlobalVariable *> StructTyMap;
239 EfficiencySanitizer,
"esan",
240 "EfficiencySanitizer: finds performance issues.",
false,
false)
244 "EfficiencySanitizer: finds performance issues.",
false, false)
246 StringRef EfficiencySanitizer::getPassName()
const {
247 return "EfficiencySanitizer";
250 void EfficiencySanitizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
256 return new EfficiencySanitizer(Options);
259 void EfficiencySanitizer::initializeCallbacks(
Module &M) {
262 for (
size_t Idx = 0; Idx < NumberOfAccessSizes; ++Idx) {
263 const unsigned ByteSize = 1U << Idx;
264 std::string ByteSizeStr =
utostr(ByteSize);
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));
286 IRB.getInt8PtrTy(), IntptrTy,
nullptr));
289 IRB.getInt8PtrTy(), IntptrTy,
nullptr));
292 IRB.getInt8PtrTy(), IntptrTy,
nullptr));
295 IRB.getInt8PtrTy(), IntptrTy,
nullptr));
298 IRB.getInt32Ty(), IntptrTy,
nullptr));
301 bool EfficiencySanitizer::shouldIgnoreStructType(
StructType *StructTy) {
302 if (StructTy ==
nullptr || StructTy->
isOpaque() )
307 void EfficiencySanitizer::createStructCounterName(
312 NameStr += StructTy->
getName();
314 NameStr +=
"struct.anon";
336 void EfficiencySanitizer::createCacheFragAuxGV(
383 auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
402 Int8PtrPtrTy, Int64PtrTy, Int64PtrTy,
nullptr);
403 auto *StructInfoPtrTy = StructInfoTy->getPointerTo();
411 auto *CacheFragInfoTy =
415 unsigned NumStructs = 0;
418 for (
auto &StructTy : Vec) {
419 if (shouldIgnoreStructType(StructTy)) {
427 createStructCounterName(StructTy, CounterNameStr);
429 M, CounterNameStr,
true);
436 getStructCounterSize(StructTy));
444 StructTyMap.insert(std::pair<Type *, GlobalVariable *>(StructTy, Counters));
448 GlobalVariable *TypeName =
nullptr, *Offset =
nullptr, *Size =
nullptr;
450 createCacheFragAuxGV(M, DL, StructTy, TypeName, Offset, Size);
455 getFieldCounterIdx(StructTy));
459 getArrayCounterIdx(StructTy));
473 ConstantExpr::getGetElementPtr(CounterArrayTy, Counters,
475 ConstantExpr::getGetElementPtr(CounterArrayTy, Counters,
481 if (NumStructs == 0) {
484 auto *StructInfoArrayTy =
ArrayType::get(StructInfoTy, NumStructs);
499 return CacheFragInfoGV;
503 Constant *EfficiencySanitizer::createEsanInitToolInfoArg(
Module &M,
517 ToolInfoGV = createCacheFragInfoGV(M, DL, UnitName);
519 if (ToolInfoGV !=
nullptr)
526 void EfficiencySanitizer::createDestructor(
Module &M,
Constant *ToolInfoArg) {
533 IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
536 Int8PtrTy,
nullptr));
542 bool EfficiencySanitizer::initOnModule(
Module &M) {
557 Constant *ToolInfoArg = createEsanInitToolInfoArg(M, DL);
568 createDestructor(M, ToolInfoArg);
573 static_cast<int>(Options.ToolType)),
585 Offs = ShadowParams.ShadowOffs[Scale];
587 Offs = ShadowParams.ShadowOffs[0] << Scale;
594 bool EfficiencySanitizer::shouldIgnoreMemoryAccess(
Instruction *
I) {
608 bool EfficiencySanitizer::runOnModule(
Module &M) {
609 bool Res = initOnModule(M);
610 initializeCallbacks(M);
612 Res |= runOnFunction(
F, M);
620 if (&F == EsanCtorFunction)
628 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
631 for (
auto &Inst : BB) {
632 if ((isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
633 isa<AtomicRMWInst>(Inst) || isa<AtomicCmpXchgInst>(Inst)) &&
634 !shouldIgnoreMemoryAccess(&Inst))
636 else if (isa<MemIntrinsic>(Inst))
638 else if (isa<GetElementPtrInst>(Inst))
640 else if (
CallInst *CI = dyn_cast<CallInst>(&Inst))
646 for (
auto Inst : LoadsAndStores) {
647 Res |= instrumentLoadOrStore(Inst, DL);
652 for (
auto Inst : MemIntrinCalls) {
653 Res |= instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
658 for (
auto Inst : GetElementPtrs) {
659 Res |= instrumentGetElementPtr(Inst, M);
666 bool EfficiencySanitizer::instrumentLoadOrStore(
Instruction *I,
674 Alignment =
Load->getAlignment();
675 Addr =
Load->getPointerOperand();
678 Alignment =
Store->getAlignment();
679 Addr =
Store->getPointerOperand();
680 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
683 Addr = RMW->getPointerOperand();
687 Addr = Xchg->getPointerOperand();
691 Type *OrigTy = cast<PointerType>(Addr->
getType())->getElementType();
693 Value *OnAccessFunc =
nullptr;
700 NumInstrumentedStores++;
702 NumInstrumentedLoads++;
703 int Idx = getMemoryAccessFuncIndex(Addr, DL);
705 OnAccessFunc = IsStore ? EsanUnalignedStoreN : EsanUnalignedLoadN;
711 instrumentFastpath(I, DL, IsStore, Addr, Alignment)) {
715 if (Alignment == 0 || (Alignment % TypeSizeBytes) == 0)
716 OnAccessFunc = IsStore ? EsanAlignedStore[Idx] : EsanAlignedLoad[Idx];
718 OnAccessFunc = IsStore ? EsanUnalignedStore[Idx] : EsanUnalignedLoad[Idx];
728 bool EfficiencySanitizer::instrumentMemIntrinsic(
MemIntrinsic *
MI) {
731 if (isa<MemSetInst>(MI)) {
739 }
else if (isa<MemTransferInst>(MI)) {
741 isa<MemCpyInst>(MI) ? MemcpyFn : MemmoveFn,
763 if (isa<StructType>(SourceTy)) {
764 StructTy = cast<StructType>(SourceTy);
766 if ((Idx ==
nullptr || Idx->getSExtValue() != 0) &&
767 !shouldIgnoreStructType(StructTy) && StructTyMap.count(StructTy) != 0)
768 Res |= insertCounterUpdate(I, StructTy, getArrayCounterIdx(StructTy));
776 unsigned CounterIdx = 0;
777 if (isa<ArrayType>(Ty)) {
778 ArrayType *ArrayTy = cast<ArrayType>(Ty);
780 if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
783 CounterIdx = getArrayCounterIdx(StructTy);
784 }
else if (isa<StructType>(Ty)) {
785 StructTy = cast<StructType>(Ty);
786 if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
790 assert(Idx->getSExtValue() >= 0 &&
791 Idx->getSExtValue() < StructTy->getNumElements());
792 CounterIdx = getFieldCounterIdx(StructTy) + Idx->getSExtValue();
794 Res |= insertCounterUpdate(I, StructTy, CounterIdx);
797 ++NumInstrumentedGEPs;
803 bool EfficiencySanitizer::insertCounterUpdate(
Instruction *I,
805 unsigned CounterIdx) {
807 if (CounterArray ==
nullptr)
821 CounterArray, Indices);
828 int EfficiencySanitizer::getMemoryAccessFuncIndex(
Value *Addr,
831 Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
835 if (TypeSizeBytes != 1 && TypeSizeBytes != 2 && TypeSizeBytes != 4 &&
836 TypeSizeBytes != 8 && TypeSizeBytes != 16) {
838 NumAccessesWithIrregularSize++;
842 assert(Idx < NumberOfAccessSizes);
846 bool EfficiencySanitizer::instrumentFastpath(
Instruction *I,
848 Value *Addr,
unsigned Alignment) {
850 return instrumentFastpathCacheFrag(I, DL, Addr, Alignment);
852 return instrumentFastpathWorkingSet(I, DL, Addr, Alignment);
857 bool EfficiencySanitizer::instrumentFastpathCacheFrag(
Instruction *I,
860 unsigned Alignment) {
865 bool EfficiencySanitizer::instrumentFastpathWorkingSet(
869 Type *OrigTy = cast<PointerType>(Addr->
getType())->getElementType();
877 if (!(TypeSize == 8 ||
878 (Alignment % (TypeSize / 8)) == 0)) {
880 ++NumAssumedIntraCacheLine;
899 Value *ShadowPtr = appToShadow(AddrPtr, IRB);
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
enum llvm::EfficiencySanitizerOptions::Type ToolType
Function * checkSanitizerInterfaceFunction(Constant *FuncOrBitcast)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Type * getSourceElementType() const
STATISTIC(NumFunctions,"Total number of functions")
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
A Module instance is used to store all the information related to an LLVM module. ...
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
static ConstantAggregateZero * get(Type *Ty)
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
This class represents a function call, abstracting a target machine's calling convention.
static PointerType * getInt32PtrTy(LLVMContext &C, unsigned AS=0)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static const char *const EsanInitName
Like Internal, but omit from symbol table.
Externally visible function.
std::vector< StructType * > getIdentifiedStructTypes() const
An instruction for reading from memory.
static IntegerType * getInt64Ty(LLVMContext &C)
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
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.
unsigned getNumIndices() const
static PointerType * getInt64PtrTy(LLVMContext &C, unsigned AS=0)
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
ModulePass * createEfficiencySanitizerPass(const EfficiencySanitizerOptions &Options=EfficiencySanitizerOptions())
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Class to represent struct types.
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...
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
A constant value that is initialized with an expression using other constant values.
Class to represent array types.
static const int ShadowScale[]
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static std::string utostr(uint64_t X, bool isNeg=false)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
TypeID getTypeID() const
Return the type id for the type.
An instruction for storing to memory.
static const char *const EsanModuleCtorName
Type * getElementType() const
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Class to represent pointers.
static const char *const EsanModuleDtorName
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
uint64_t getElementOffset(unsigned Idx) const
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.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
LoadInst * CreateLoad(Value *Ptr, const char *Name)
initializer< Ty > init(const Ty &Val)
Subclasses of this class are all able to terminate a basic block.
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
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...
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
static const char *const EsanWhichToolName
Type * getElementType(unsigned N) const
This is an important base class in LLVM.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
Value * getOperand(unsigned i) const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Class to represent integer types.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
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...
static const uint64_t EsanCtorAndDtorPriority
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
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.
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
bool hasName() const
Return true if this is a named struct that has a non-empty name.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
A constant pointer value that points to null.
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
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.
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.
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.
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="")
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.
void setUnnamedAddr(UnnamedAddr Val)
static IntegerType * getInt32Ty(LLVMContext &C)
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
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Keep one copy of named function when linking (weak)
Rename collisions when linking (static functions).
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...
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="")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const ShadowMemoryParams ShadowParams40
A raw_ostream that writes to an std::string.
LLVM Value Representation.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
StringRef - Represent a constant reference to a string, i.e.
static const unsigned MaxStructCounterNameSize
static const char *const EsanExitName
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
unsigned getNumElements() const
Random access to the elements.
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)
LLVMContext & getContext() const
Get the global data context.