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,
148 class EfficiencySanitizer :
public ModulePass {
152 :
ModulePass(
ID), Options(OverrideOptionsFromCL(Opts)) {}
155 bool runOnModule(
Module &M)
override;
159 bool initOnModule(
Module &M);
160 void initializeCallbacks(
Module &M);
161 bool shouldIgnoreStructType(
StructType *StructTy);
162 void createStructCounterName(
164 void createCacheFragAuxGV(
176 unsigned CounterIdx);
177 unsigned getFieldCounterIdx(
StructType *StructTy) {
180 unsigned getArrayCounterIdx(
StructType *StructTy) {
183 unsigned getStructCounterSize(
StructType *StructTy) {
193 Value *Addr,
unsigned Alignment);
196 Value *Addr,
unsigned Alignment);
198 Value *Addr,
unsigned Alignment);
205 static const size_t NumberOfAccessSizes = 5;
206 Function *EsanAlignedLoad[NumberOfAccessSizes];
207 Function *EsanAlignedStore[NumberOfAccessSizes];
208 Function *EsanUnalignedLoad[NumberOfAccessSizes];
209 Function *EsanUnalignedStore[NumberOfAccessSizes];
211 Function *EsanUnalignedLoadN, *EsanUnalignedStoreN;
212 Function *MemmoveFn, *MemcpyFn, *MemsetFn;
217 std::map<Type *, GlobalVariable *> StructTyMap;
224 EfficiencySanitizer,
"esan",
225 "EfficiencySanitizer: finds performance issues.",
false,
false)
228 EfficiencySanitizer,
"esan",
229 "EfficiencySanitizer: finds performance issues.",
false,
false)
231 StringRef EfficiencySanitizer::getPassName()
const {
232 return "EfficiencySanitizer";
235 void EfficiencySanitizer::getAnalysisUsage(
AnalysisUsage &AU)
const {
241 return new EfficiencySanitizer(Options);
244 void EfficiencySanitizer::initializeCallbacks(
Module &M) {
247 for (
size_t Idx = 0; Idx < NumberOfAccessSizes; ++Idx) {
248 const unsigned ByteSize = 1U << Idx;
249 std::string ByteSizeStr =
utostr(ByteSize);
253 EsanAlignedLoad[Idx] =
255 AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
256 SmallString<32> AlignedStoreName(
"__esan_aligned_store" + ByteSizeStr);
257 EsanAlignedStore[Idx] =
259 AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
260 SmallString<32> UnalignedLoadName(
"__esan_unaligned_load" + ByteSizeStr);
261 EsanUnalignedLoad[Idx] =
263 UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
264 SmallString<32> UnalignedStoreName(
"__esan_unaligned_store" + ByteSizeStr);
265 EsanUnalignedStore[Idx] =
267 UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy()));
271 IRB.getInt8PtrTy(), IntptrTy));
274 IRB.getInt8PtrTy(), IntptrTy));
277 IRB.getInt8PtrTy(), IntptrTy));
280 IRB.getInt8PtrTy(), IntptrTy));
283 IRB.getInt32Ty(), IntptrTy));
286 bool EfficiencySanitizer::shouldIgnoreStructType(
StructType *StructTy) {
287 if (StructTy ==
nullptr || StructTy->
isOpaque() )
292 void EfficiencySanitizer::createStructCounterName(
297 NameStr += StructTy->
getName();
299 NameStr +=
"struct.anon";
321 void EfficiencySanitizer::createCacheFragAuxGV(
368 auto *Int8PtrPtrTy = Int8PtrTy->getPointerTo();
387 Int8PtrPtrTy, Int64PtrTy, Int64PtrTy);
388 auto *StructInfoPtrTy = StructInfoTy->getPointerTo();
399 unsigned NumStructs = 0;
402 for (
auto &StructTy : Vec) {
403 if (shouldIgnoreStructType(StructTy)) {
411 createStructCounterName(StructTy, CounterNameStr);
413 M, CounterNameStr,
true);
420 getStructCounterSize(StructTy));
428 StructTyMap.insert(std::pair<Type *, GlobalVariable *>(StructTy, Counters));
432 GlobalVariable *TypeName =
nullptr, *Offset =
nullptr, *Size =
nullptr;
434 createCacheFragAuxGV(M, DL, StructTy, TypeName, Offset, Size);
439 getFieldCounterIdx(StructTy));
443 getArrayCounterIdx(StructTy));
464 if (NumStructs == 0) {
467 auto *StructInfoArrayTy =
ArrayType::get(StructInfoTy, NumStructs);
479 return CacheFragInfoGV;
483 Constant *EfficiencySanitizer::createEsanInitToolInfoArg(
Module &M,
497 ToolInfoGV = createCacheFragInfoGV(M, DL, UnitName);
499 if (ToolInfoGV !=
nullptr)
506 void EfficiencySanitizer::createDestructor(
Module &M,
Constant *ToolInfoArg) {
513 IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator());
522 bool EfficiencySanitizer::initOnModule(
Module &M) {
525 if (TargetTriple.isMIPS64())
537 Constant *ToolInfoArg = createEsanInitToolInfoArg(M, DL);
548 createDestructor(M, ToolInfoArg);
553 static_cast<int>(Options.ToolType)),
565 Offs = ShadowParams.ShadowOffs[Scale];
567 Offs = ShadowParams.ShadowOffs[0] << Scale;
574 bool EfficiencySanitizer::shouldIgnoreMemoryAccess(
Instruction *
I) {
588 bool EfficiencySanitizer::runOnModule(
Module &M) {
589 bool Res = initOnModule(M);
590 initializeCallbacks(M);
600 if (&F == EsanCtorFunction)
608 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
611 for (
auto &Inst : BB) {
612 if ((isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
613 isa<AtomicRMWInst>(Inst) || isa<AtomicCmpXchgInst>(Inst)) &&
614 !shouldIgnoreMemoryAccess(&Inst))
616 else if (isa<MemIntrinsic>(Inst))
618 else if (isa<GetElementPtrInst>(Inst))
620 else if (
CallInst *CI = dyn_cast<CallInst>(&Inst))
626 for (
auto Inst : LoadsAndStores) {
627 Res |= instrumentLoadOrStore(Inst, DL);
632 for (
auto Inst : MemIntrinCalls) {
633 Res |= instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
638 for (
auto Inst : GetElementPtrs) {
639 Res |= instrumentGetElementPtr(Inst, M);
646 bool EfficiencySanitizer::instrumentLoadOrStore(
Instruction *I,
654 Alignment =
Load->getAlignment();
655 Addr =
Load->getPointerOperand();
658 Alignment =
Store->getAlignment();
659 Addr =
Store->getPointerOperand();
660 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
663 Addr = RMW->getPointerOperand();
667 Addr = Xchg->getPointerOperand();
671 Type *OrigTy = cast<PointerType>(Addr->
getType())->getElementType();
673 Value *OnAccessFunc =
nullptr;
680 NumInstrumentedStores++;
682 NumInstrumentedLoads++;
683 int Idx = getMemoryAccessFuncIndex(Addr, DL);
685 OnAccessFunc = IsStore ? EsanUnalignedStoreN : EsanUnalignedLoadN;
691 instrumentFastpath(I, DL, IsStore, Addr, Alignment)) {
695 if (Alignment == 0 || (Alignment % TypeSizeBytes) == 0)
696 OnAccessFunc = IsStore ? EsanAlignedStore[Idx] : EsanAlignedLoad[Idx];
698 OnAccessFunc = IsStore ? EsanUnalignedStore[Idx] : EsanUnalignedLoad[Idx];
708 bool EfficiencySanitizer::instrumentMemIntrinsic(
MemIntrinsic *
MI) {
711 if (isa<MemSetInst>(MI)) {
719 }
else if (isa<MemTransferInst>(MI)) {
721 isa<MemCpyInst>(MI) ? MemcpyFn : MemmoveFn,
743 if (isa<StructType>(SourceTy)) {
744 StructTy = cast<StructType>(SourceTy);
746 if ((Idx ==
nullptr || Idx->getSExtValue() != 0) &&
747 !shouldIgnoreStructType(StructTy) && StructTyMap.count(StructTy) != 0)
748 Res |= insertCounterUpdate(I, StructTy, getArrayCounterIdx(StructTy));
756 unsigned CounterIdx = 0;
757 if (isa<ArrayType>(Ty)) {
758 ArrayType *ArrayTy = cast<ArrayType>(Ty);
760 if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
763 CounterIdx = getArrayCounterIdx(StructTy);
764 }
else if (isa<StructType>(Ty)) {
765 StructTy = cast<StructType>(Ty);
766 if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
769 Idx = cast<ConstantInt>(GepInst->
getOperand(i+1));
772 CounterIdx = getFieldCounterIdx(StructTy) + Idx->
getSExtValue();
774 Res |= insertCounterUpdate(I, StructTy, CounterIdx);
777 ++NumInstrumentedGEPs;
783 bool EfficiencySanitizer::insertCounterUpdate(
Instruction *I,
785 unsigned CounterIdx) {
787 if (CounterArray ==
nullptr)
801 CounterArray, Indices);
808 int EfficiencySanitizer::getMemoryAccessFuncIndex(
Value *Addr,
811 Type *OrigTy = cast<PointerType>(OrigPtrTy)->getElementType();
815 if (TypeSizeBytes != 1 && TypeSizeBytes != 2 && TypeSizeBytes != 4 &&
816 TypeSizeBytes != 8 && TypeSizeBytes != 16) {
818 NumAccessesWithIrregularSize++;
822 assert(Idx < NumberOfAccessSizes);
826 bool EfficiencySanitizer::instrumentFastpath(
Instruction *I,
828 Value *Addr,
unsigned Alignment) {
830 return instrumentFastpathCacheFrag(I, DL, Addr, Alignment);
832 return instrumentFastpathWorkingSet(I, DL, Addr, Alignment);
837 bool EfficiencySanitizer::instrumentFastpathCacheFrag(
Instruction *I,
840 unsigned Alignment) {
845 bool EfficiencySanitizer::instrumentFastpathWorkingSet(
849 Type *OrigTy = cast<PointerType>(Addr->
getType())->getElementType();
857 if (!(TypeSize == 8 ||
858 (Alignment % (TypeSize / 8)) == 0)) {
860 ++NumAssumedIntraCacheLine;
879 Value *ShadowPtr = appToShadow(AddrPtr, IRB);
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
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="")
This class represents lattice values for constants.
Type * getElementType(unsigned N) const
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
A Module instance is used to store all the information related to an LLVM module. ...
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant *> IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
unsigned getNumElements() const
Random access to the elements.
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
void push_back(const T &Elt)
static ConstantAggregateZero * get(Type *Ty)
This class represents a function call, abstracting a target machine's calling convention.
static PointerType * getInt32PtrTy(LLVMContext &C, unsigned AS=0)
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)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
static const char *const EsanInitName
Externally visible function.
STATISTIC(NumFunctions, "Total number of functions")
An instruction for reading from memory.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
static PointerType * getInt64PtrTy(LLVMContext &C, unsigned AS=0)
static Constant * get(ArrayType *T, ArrayRef< Constant *> V)
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * getArgOperand(unsigned i) const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
ModulePass * createEfficiencySanitizerPass(const EfficiencySanitizerOptions &Options=EfficiencySanitizerOptions())
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
TypeID getTypeID() const
Return the type id for the type.
Class to represent struct types.
LLVMContext & getContext() const
Get the global data context.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Type * getSourceElementType() const
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
unsigned getNumIndices() const
Type * getType() const
All values are typed, get the type of this value.
Class to represent array types.
static const int ShadowScale[]
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
An instruction for storing to memory.
static const char *const EsanModuleCtorName
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Value * getOperand(unsigned i) const
Class to represent pointers.
static const char *const EsanModuleDtorName
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
static const ShadowMemoryParams ShadowParams47
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
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 bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
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...
The instances of the Type class are immutable: once they are created, they are never changed...
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.
This is an important class for using LLVM in a threaded context.
static const char *const EsanWhichToolName
This is an important base class in LLVM.
INITIALIZE_PASS_BEGIN(EfficiencySanitizer, "esan", "EfficiencySanitizer: finds performance issues.", false, false) INITIALIZE_PASS_END(EfficiencySanitizer
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
StringRef getName() const
Return the name for this struct type if it has an identity.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Constant * get(StructType *T, ArrayRef< Constant *> V)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Class to represent integer types.
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)
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
std::vector< StructType * > getIdentifiedStructTypes() const
static cl::opt< bool > ClInstrumentFastpath("esan-instrument-fastpath", cl::init(true), cl::desc("Instrument fastpath"), cl::Hidden)
static const uint64_t EsanCtorAndDtorPriority
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
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.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &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.
Provides information about what library functions are available for the current target.
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.
GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, const char *NamePrefix="")
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.
std::string utostr(uint64_t X, bool isNeg=false)
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition...
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="")
Instruction * 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 getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
uint64_t getElementOffset(unsigned Idx) const
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...
static IntegerType * getInt32Ty(LLVMContext &C)
void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
static cl::opt< bool > ClInstrumentLoadsAndStores("esan-instrument-loads-and-stores", cl::init(true), cl::desc("Instrument loads and stores"), cl::Hidden)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
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...
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
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)
Type * getElementType() const
StringRef - Represent a constant reference to a string, i.e.
static const unsigned MaxStructCounterNameSize
static const char *const EsanExitName
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
bool hasName() const
Return true if this is a named struct that has a non-empty name.