51#define DEBUG_TYPE "tsan"
54 "tsan-instrument-memory-accesses",
cl::init(
true),
58 cl::desc(
"Instrument function entry and exit"),
61 "tsan-handle-cxx-exceptions",
cl::init(
true),
62 cl::desc(
"Handle C++ exceptions (insert cleanup blocks for unwinding)"),
69 "tsan-instrument-memintrinsics",
cl::init(
true),
72 "tsan-distinguish-volatile",
cl::init(
false),
73 cl::desc(
"Emit special instrumentation for accesses to volatiles"),
76 "tsan-instrument-read-before-write",
cl::init(
false),
77 cl::desc(
"Do not eliminate read instrumentation for read-before-writes"),
80 "tsan-compound-read-before-write",
cl::init(
false),
81 cl::desc(
"Emit special compound instrumentation for reads-before-writes"),
85 cl::desc(
"Omit accesses due to pointer capturing"),
88STATISTIC(NumInstrumentedReads,
"Number of instrumented reads");
89STATISTIC(NumInstrumentedWrites,
"Number of instrumented writes");
91 "Number of reads ignored due to following writes");
92STATISTIC(NumAccessesWithBadSize,
"Number of accesses with bad size");
93STATISTIC(NumInstrumentedVtableWrites,
"Number of vtable ptr writes");
94STATISTIC(NumInstrumentedVtableReads,
"Number of vtable ptr reads");
96 "Number of reads from constant globals");
97STATISTIC(NumOmittedReadsFromVtable,
"Number of vtable reads");
98STATISTIC(NumOmittedNonCaptured,
"Number of accesses ignored due to capturing");
111struct ThreadSanitizer {
116 <<
"warning: Option -tsan-compound-read-before-write has no effect "
117 "when -tsan-instrument-read-before-write is set.\n";
126 struct InstructionInfo {
129 static constexpr unsigned kCompoundRW = (1U << 0);
131 explicit InstructionInfo(
Instruction *Inst) : Inst(Inst) {}
138 bool instrumentLoadOrStore(
const InstructionInfo &
II,
const DataLayout &
DL);
144 bool addrPointsToConstantData(
Value *
Addr);
154 static const size_t kNumberOfAccessSizes = 5;
168 [kNumberOfAccessSizes];
177void insertModuleCtor(
Module &M) {
189 ThreadSanitizer TSan;
206 IntptrTy =
DL.getIntPtrType(Ctx);
212 TsanFuncEntry = M.getOrInsertFunction(
"__tsan_func_entry", Attr,
213 IRB.getVoidTy(), IRB.getPtrTy());
215 M.getOrInsertFunction(
"__tsan_func_exit", Attr, IRB.getVoidTy());
216 TsanIgnoreBegin = M.getOrInsertFunction(
"__tsan_ignore_thread_begin", Attr,
219 M.getOrInsertFunction(
"__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
222 const unsigned ByteSize = 1U << i;
223 const unsigned BitSize = ByteSize * 8;
224 std::string ByteSizeStr = utostr(ByteSize);
225 std::string BitSizeStr = utostr(BitSize);
227 TsanRead[i] = M.getOrInsertFunction(ReadName, Attr, IRB.getVoidTy(),
231 TsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(),
234 SmallString<64> UnalignedReadName(
"__tsan_unaligned_read" + ByteSizeStr);
235 TsanUnalignedRead[i] = M.getOrInsertFunction(
236 UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
238 SmallString<64> UnalignedWriteName(
"__tsan_unaligned_write" + ByteSizeStr);
239 TsanUnalignedWrite[i] = M.getOrInsertFunction(
240 UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
242 SmallString<64> VolatileReadName(
"__tsan_volatile_read" + ByteSizeStr);
243 TsanVolatileRead[i] = M.getOrInsertFunction(
244 VolatileReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
246 SmallString<64> VolatileWriteName(
"__tsan_volatile_write" + ByteSizeStr);
247 TsanVolatileWrite[i] = M.getOrInsertFunction(
248 VolatileWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
250 SmallString<64> UnalignedVolatileReadName(
"__tsan_unaligned_volatile_read" +
252 TsanUnalignedVolatileRead[i] = M.getOrInsertFunction(
253 UnalignedVolatileReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
256 "__tsan_unaligned_volatile_write" + ByteSizeStr);
257 TsanUnalignedVolatileWrite[i] = M.getOrInsertFunction(
258 UnalignedVolatileWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
261 TsanCompoundRW[i] = M.getOrInsertFunction(
262 CompoundRWName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
264 SmallString<64> UnalignedCompoundRWName(
"__tsan_unaligned_read_write" +
266 TsanUnalignedCompoundRW[i] = M.getOrInsertFunction(
267 UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
271 SmallString<32> AtomicLoadName(
"__tsan_atomic" + BitSizeStr +
"_load");
273 M.getOrInsertFunction(AtomicLoadName,
275 BitSize <= 32, Attr),
279 using Idxs = std::vector<unsigned>;
280 Idxs Idxs2Or12 ((BitSize <= 32) ? Idxs({1, 2}) : Idxs({2}));
281 Idxs Idxs34Or1234((BitSize <= 32) ? Idxs({1, 2, 3, 4}) : Idxs({3, 4}));
282 SmallString<32> AtomicStoreName(
"__tsan_atomic" + BitSizeStr +
"_store");
283 TsanAtomicStore[i] =
M.getOrInsertFunction(
285 TLI.
getAttrList(&Ctx, Idxs2Or12,
true,
false, Attr),
286 IRB.getVoidTy(), PtrTy, Ty, OrdTy);
290 TsanAtomicRMW[
Op][i] =
nullptr;
291 const char *NamePart =
nullptr;
293 NamePart =
"_exchange";
295 NamePart =
"_fetch_add";
297 NamePart =
"_fetch_sub";
299 NamePart =
"_fetch_and";
301 NamePart =
"_fetch_or";
303 NamePart =
"_fetch_xor";
305 NamePart =
"_fetch_nand";
309 TsanAtomicRMW[
Op][i] =
M.getOrInsertFunction(
312 BitSize <= 32, Attr),
313 Ty, PtrTy, Ty, OrdTy);
317 "_compare_exchange_val");
318 TsanAtomicCAS[i] =
M.getOrInsertFunction(
321 BitSize <= 32, Attr),
322 Ty, PtrTy, Ty, Ty, OrdTy, OrdTy);
325 M.getOrInsertFunction(
"__tsan_vptr_update", Attr, IRB.getVoidTy(),
326 IRB.getPtrTy(), IRB.getPtrTy());
327 TsanVptrLoad =
M.getOrInsertFunction(
"__tsan_vptr_read", Attr,
328 IRB.getVoidTy(), IRB.getPtrTy());
329 TsanAtomicThreadFence =
M.getOrInsertFunction(
330 "__tsan_atomic_thread_fence",
332 IRB.getVoidTy(), OrdTy);
334 TsanAtomicSignalFence =
M.getOrInsertFunction(
335 "__tsan_atomic_signal_fence",
337 IRB.getVoidTy(), OrdTy);
340 M.getOrInsertFunction(
"__tsan_memmove", Attr, IRB.getPtrTy(),
341 IRB.getPtrTy(), IRB.getPtrTy(), IntptrTy);
343 M.getOrInsertFunction(
"__tsan_memcpy", Attr, IRB.getPtrTy(),
344 IRB.getPtrTy(), IRB.getPtrTy(), IntptrTy);
345 MemsetFn =
M.getOrInsertFunction(
348 IRB.getPtrTy(), IRB.getPtrTy(), IRB.getInt32Ty(), IntptrTy);
352 if (
MDNode *
Tag =
I->getMetadata(LLVMContext::MD_tbaa))
353 return Tag->isTBAAVtableAccess();
361 Addr =
Addr->stripInBoundsOffsets();
364 if (GV->hasSection()) {
367 auto OF = M->getTargetTriple().getObjectFormat();
377 Type *PtrTy = cast<PointerType>(
Addr->getType()->getScalarType());
385bool ThreadSanitizer::addrPointsToConstantData(
Value *
Addr) {
388 Addr =
GEP->getPointerOperand();
391 if (GV->isConstant()) {
393 NumOmittedReadsFromConstantGlobals++;
399 NumOmittedReadsFromVtable++;
418void ThreadSanitizer::chooseInstructionsToInstrument(
424 const bool IsWrite = isa<StoreInst>(*
I);
425 Value *
Addr = IsWrite ? cast<StoreInst>(
I)->getPointerOperand()
426 : cast<LoadInst>(
I)->getPointerOperand();
432 const auto WriteEntry = WriteTargets.
find(
Addr);
434 auto &WI =
All[WriteEntry->second];
437 const bool AnyVolatile =
439 cast<StoreInst>(WI.Inst)->isVolatile());
443 WI.Flags |= InstructionInfo::kCompoundRW;
444 NumOmittedReadsBeforeWrite++;
449 if (addrPointsToConstantData(
Addr)) {
462 NumOmittedNonCaptured++;
471 WriteTargets[
Addr] =
All.size() - 1;
482 if (isa<LoadInst>(
I) || isa<StoreInst>(
I))
487void ThreadSanitizer::InsertRuntimeIgnores(
Function &
F) {
489 F.getEntryBlock().getFirstNonPHIIt());
490 IRB.CreateCall(TsanIgnoreBegin);
494 AtExit->CreateCall(TsanIgnoreEnd);
498bool ThreadSanitizer::sanitizeFunction(
Function &
F,
507 if (
F.hasFnAttribute(Attribute::Naked))
512 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
522 bool SanitizeFunction =
F.hasFnAttribute(Attribute::SanitizeThread);
527 for (
auto &Inst : BB) {
529 if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
533 else if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
535 else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {
536 if (
CallInst *CI = dyn_cast<CallInst>(&Inst))
538 if (isa<MemIntrinsic>(Inst))
541 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
545 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
DL);
554 for (
const auto &
II : AllLoadsAndStores) {
555 Res |= instrumentLoadOrStore(
II,
DL);
561 for (
auto *Inst : AtomicAccesses) {
562 Res |= instrumentAtomic(Inst,
DL);
566 for (
auto *Inst : MemIntrinCalls) {
567 Res |= instrumentMemIntrinsic(Inst);
570 if (
F.hasFnAttribute(
"sanitize_thread_no_checking_at_run_time")) {
571 assert(!
F.hasFnAttribute(Attribute::SanitizeThread));
573 InsertRuntimeIgnores(
F);
579 F.getEntryBlock().getFirstNonPHIIt());
580 Value *ReturnAddress =
581 IRB.CreateIntrinsic(Intrinsic::returnaddress, IRB.getInt32(0));
582 IRB.CreateCall(TsanFuncEntry, ReturnAddress);
587 AtExit->CreateCall(TsanFuncExit, {});
594bool ThreadSanitizer::instrumentLoadOrStore(
const InstructionInfo &
II,
597 const bool IsWrite = isa<StoreInst>(*
II.Inst);
598 Value *
Addr = IsWrite ? cast<StoreInst>(
II.Inst)->getPointerOperand()
599 : cast<LoadInst>(
II.Inst)->getPointerOperand();
605 if (
Addr->isSwiftError())
608 int Idx = getMemoryAccessFuncIndex(OrigTy,
Addr,
DL);
613 Value *StoredValue = cast<StoreInst>(
II.Inst)->getValueOperand();
617 if (isa<VectorType>(StoredValue->
getType()))
618 StoredValue = IRB.CreateExtractElement(
619 StoredValue, ConstantInt::get(IRB.getInt32Ty(), 0));
621 StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getPtrTy());
623 IRB.CreateCall(TsanVptrUpdate, {
Addr, StoredValue});
624 NumInstrumentedVtableWrites++;
628 IRB.CreateCall(TsanVptrLoad,
Addr);
629 NumInstrumentedVtableReads++;
633 const Align Alignment = IsWrite ? cast<StoreInst>(
II.Inst)->getAlign()
634 : cast<LoadInst>(
II.Inst)->getAlign();
635 const bool IsCompoundRW =
638 (IsWrite ? cast<StoreInst>(
II.Inst)->isVolatile()
639 : cast<LoadInst>(
II.Inst)->isVolatile());
640 assert((!IsVolatile || !IsCompoundRW) &&
"Compound volatile invalid!");
646 OnAccessFunc = TsanCompoundRW[
Idx];
648 OnAccessFunc = IsWrite ? TsanVolatileWrite[
Idx] : TsanVolatileRead[
Idx];
650 OnAccessFunc = IsWrite ? TsanWrite[
Idx] : TsanRead[
Idx];
653 OnAccessFunc = TsanUnalignedCompoundRW[
Idx];
655 OnAccessFunc = IsWrite ? TsanUnalignedVolatileWrite[
Idx]
656 : TsanUnalignedVolatileRead[
Idx];
658 OnAccessFunc = IsWrite ? TsanUnalignedWrite[
Idx] : TsanUnalignedRead[
Idx];
660 IRB.CreateCall(OnAccessFunc,
Addr);
661 if (IsCompoundRW || IsWrite)
662 NumInstrumentedWrites++;
663 if (IsCompoundRW || !IsWrite)
664 NumInstrumentedReads++;
693bool ThreadSanitizer::instrumentMemIntrinsic(
Instruction *
I) {
696 Value *Cast1 = IRB.CreateIntCast(
M->getArgOperand(1), IRB.getInt32Ty(),
false);
697 Value *Cast2 = IRB.CreateIntCast(
M->getArgOperand(2), IntptrTy,
false);
700 {
M->getArgOperand(0),
703 I->eraseFromParent();
706 isa<MemCpyInst>(M) ? MemcpyFn : MemmoveFn,
707 {
M->getArgOperand(0),
709 IRB.CreateIntCast(
M->getArgOperand(2), IntptrTy,
false)});
710 I->eraseFromParent();
725 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
727 Type *OrigTy = LI->getType();
728 int Idx = getMemoryAccessFuncIndex(OrigTy,
Addr,
DL);
733 Value *
C = IRB.CreateCall(TsanAtomicLoad[
Idx], Args);
734 Value *Cast = IRB.CreateBitOrPointerCast(
C, OrigTy);
735 I->replaceAllUsesWith(Cast);
736 I->eraseFromParent();
737 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
740 getMemoryAccessFuncIndex(
SI->getValueOperand()->getType(),
Addr,
DL);
743 const unsigned ByteSize = 1U <<
Idx;
744 const unsigned BitSize = ByteSize * 8;
747 IRB.CreateBitOrPointerCast(
SI->getValueOperand(), Ty),
749 IRB.CreateCall(TsanAtomicStore[
Idx], Args);
750 SI->eraseFromParent();
754 getMemoryAccessFuncIndex(RMWI->getValOperand()->getType(),
Addr,
DL);
760 const unsigned ByteSize = 1U <<
Idx;
761 const unsigned BitSize = ByteSize * 8;
763 Value *Val = RMWI->getValOperand();
766 Value *
C = IRB.CreateCall(
F, Args);
767 I->replaceAllUsesWith(IRB.CreateBitOrPointerCast(
C, Val->
getType()));
768 I->eraseFromParent();
771 Type *OrigOldValTy = CASI->getNewValOperand()->getType();
772 int Idx = getMemoryAccessFuncIndex(OrigOldValTy,
Addr,
DL);
775 const unsigned ByteSize = 1U <<
Idx;
776 const unsigned BitSize = ByteSize * 8;
779 IRB.CreateBitOrPointerCast(CASI->getCompareOperand(), Ty);
781 IRB.CreateBitOrPointerCast(CASI->getNewValOperand(), Ty);
790 if (Ty != OrigOldValTy) {
792 OldVal = IRB.CreateIntToPtr(
C, OrigOldValTy);
797 Res = IRB.CreateInsertValue(Res,
Success, 1);
799 I->replaceAllUsesWith(Res);
800 I->eraseFromParent();
801 }
else if (
FenceInst *FI = dyn_cast<FenceInst>(
I)) {
804 ? TsanAtomicSignalFence
805 : TsanAtomicThreadFence;
806 IRB.CreateCall(
F, Args);
807 FI->eraseFromParent();
812int ThreadSanitizer::getMemoryAccessFuncIndex(
Type *OrigTy,
Value *
Addr,
822 NumAccessesWithBadSize++;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static cl::opt< bool > ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics", cl::desc("instrument memory intrinsics"), cl::Hidden, cl::init(true))
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file defines the SmallString class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr)
static bool isVtableAccess(Instruction *I)
static bool isTsanAtomic(const Instruction *I)
const char kTsanModuleCtorName[]
static cl::opt< bool > ClInstrumentFuncEntryExit("tsan-instrument-func-entry-exit", cl::init(true), cl::desc("Instrument function entry and exit"), cl::Hidden)
static ConstantInt * createOrdering(IRBuilder<> *IRB, AtomicOrdering ord)
static cl::opt< bool > ClInstrumentMemIntrinsics("tsan-instrument-memintrinsics", cl::init(true), cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden)
const char kTsanInitName[]
static cl::opt< bool > ClDistinguishVolatile("tsan-distinguish-volatile", cl::init(false), cl::desc("Emit special instrumentation for accesses to volatiles"), cl::Hidden)
static cl::opt< bool > ClOmitNonCaptured("tsan-omit-by-pointer-capturing", cl::init(true), cl::desc("Omit accesses due to pointer capturing"), cl::Hidden)
static cl::opt< bool > ClCompoundReadBeforeWrite("tsan-compound-read-before-write", cl::init(false), cl::desc("Emit special compound instrumentation for reads-before-writes"), cl::Hidden)
static cl::opt< bool > ClInstrumentAtomics("tsan-instrument-atomics", cl::init(true), cl::desc("Instrument atomics"), cl::Hidden)
static cl::opt< bool > ClHandleCxxExceptions("tsan-handle-cxx-exceptions", cl::init(true), cl::desc("Handle C++ exceptions (insert cleanup blocks for unwinding)"), cl::Hidden)
static cl::opt< bool > ClInstrumentReadBeforeWrite("tsan-instrument-read-before-write", cl::init(false), cl::desc("Do not eliminate read instrumentation for read-before-writes"), cl::Hidden)
static cl::opt< bool > ClInstrumentMemoryAccesses("tsan-instrument-memory-accesses", cl::init(true), cl::desc("Instrument memory accesses"), cl::Hidden)
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
AttributeList addFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add a function attribute to the list.
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
EscapeEnumerator - This is a little algorithm to find all escape points from a function so that "fina...
An instruction for ordering other memory operations.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char IsVolatile[]
Key for Kernel::Arg::Metadata::mIsVolatile.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto reverse(ContainerTy &&C)
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
std::optional< SyncScope::ID > getAtomicSyncScopeID(const Instruction *I)
A helper function that returns an atomic operation's sync scope; returns std::nullopt if it is not an...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
LLVM_ABI 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.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
LLVM_ABI 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...
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
static void ensureDebugInfo(IRBuilder<> &IRB, const Function &F)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)