LLVM: lib/Transforms/Instrumentation/ThreadSanitizer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
48
49using namespace llvm;
50
51#define DEBUG_TYPE "tsan"
52
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)"),
66 cl::desc("Instrument atomics"),
69 "tsan-instrument-memintrinsics", cl::init(true),
70 cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden);
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"),
87
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");
95STATISTIC(NumOmittedReadsFromConstantGlobals,
96 "Number of reads from constant globals");
97STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads");
98STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing");
99
102
103namespace {
104
105
106
107
108
109
110
111struct ThreadSanitizer {
112 ThreadSanitizer() {
113
116 << "warning: Option -tsan-compound-read-before-write has no effect "
117 "when -tsan-instrument-read-before-write is set.\n";
118 }
119 }
120
122
123private:
124
125
126 struct InstructionInfo {
127
128
129 static constexpr unsigned kCompoundRW = (1U << 0);
130
131 explicit InstructionInfo(Instruction *Inst) : Inst(Inst) {}
132
134 unsigned Flags = 0;
135 };
136
138 bool instrumentLoadOrStore(const InstructionInfo &II, const DataLayout &DL);
144 bool addrPointsToConstantData(Value *Addr);
146 void InsertRuntimeIgnores(Function &F);
147
148 Type *IntptrTy;
153
175};
176
177void insertModuleCtor(Module &M) {
180 {},
181
182
184}
185}
186
189 ThreadSanitizer TSan;
193}
194
197
200 insertModuleCtor(M);
202}
206 IntptrTy = DL.getIntPtrType(Ctx);
207
209 AttributeList Attr;
210 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
211
212 TsanFuncEntry = M.getOrInsertFunction("__tsan_func_entry", Attr,
213 IRB.getVoidTy(), IRB.getPtrTy());
214 TsanFuncExit =
215 M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy());
216 TsanIgnoreBegin = M.getOrInsertFunction("__tsan_ignore_thread_begin", Attr,
217 IRB.getVoidTy());
218 TsanIgnoreEnd =
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(),
228 IRB.getPtrTy());
229
231 TsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(),
232 IRB.getPtrTy());
233
234 SmallString<64> UnalignedReadName("__tsan_unaligned_read" + ByteSizeStr);
235 TsanUnalignedRead[i] = M.getOrInsertFunction(
236 UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
237
238 SmallString<64> UnalignedWriteName("__tsan_unaligned_write" + ByteSizeStr);
239 TsanUnalignedWrite[i] = M.getOrInsertFunction(
240 UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
241
242 SmallString<64> VolatileReadName("__tsan_volatile_read" + ByteSizeStr);
243 TsanVolatileRead[i] = M.getOrInsertFunction(
244 VolatileReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
245
246 SmallString<64> VolatileWriteName("__tsan_volatile_write" + ByteSizeStr);
247 TsanVolatileWrite[i] = M.getOrInsertFunction(
248 VolatileWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
249
250 SmallString<64> UnalignedVolatileReadName("__tsan_unaligned_volatile_read" +
251 ByteSizeStr);
252 TsanUnalignedVolatileRead[i] = M.getOrInsertFunction(
253 UnalignedVolatileReadName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
254
256 "__tsan_unaligned_volatile_write" + ByteSizeStr);
257 TsanUnalignedVolatileWrite[i] = M.getOrInsertFunction(
258 UnalignedVolatileWriteName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
259
260 SmallString<64> CompoundRWName("__tsan_read_write" + ByteSizeStr);
261 TsanCompoundRW[i] = M.getOrInsertFunction(
262 CompoundRWName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
263
264 SmallString<64> UnalignedCompoundRWName("__tsan_unaligned_read_write" +
265 ByteSizeStr);
266 TsanUnalignedCompoundRW[i] = M.getOrInsertFunction(
267 UnalignedCompoundRWName, Attr, IRB.getVoidTy(), IRB.getPtrTy());
268
271 SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load");
272 TsanAtomicLoad[i] =
273 M.getOrInsertFunction(AtomicLoadName,
274 TLI.getAttrList(&Ctx, {1}, true,
275 BitSize <= 32, Attr),
276 Ty, PtrTy, OrdTy);
277
278
279 using Idxs = std::vector;
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(
284 AtomicStoreName,
285 TLI.getAttrList(&Ctx, Idxs2Or12, true, false, Attr),
286 IRB.getVoidTy(), PtrTy, Ty, OrdTy);
287
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";
306 else
307 continue;
309 TsanAtomicRMW[Op][i] = M.getOrInsertFunction(
310 RMWName,
311 TLI.getAttrList(&Ctx, Idxs2Or12, true,
312 BitSize <= 32, Attr),
313 Ty, PtrTy, Ty, OrdTy);
314 }
315
316 SmallString<32> AtomicCASName("__tsan_atomic" + BitSizeStr +
317 "_compare_exchange_val");
318 TsanAtomicCAS[i] = M.getOrInsertFunction(
319 AtomicCASName,
320 TLI.getAttrList(&Ctx, Idxs34Or1234, true,
321 BitSize <= 32, Attr),
322 Ty, PtrTy, Ty, Ty, OrdTy, OrdTy);
323 }
324 TsanVptrUpdate =
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",
331 TLI.getAttrList(&Ctx, {0}, true, false, Attr),
332 IRB.getVoidTy(), OrdTy);
333
334 TsanAtomicSignalFence = M.getOrInsertFunction(
335 "__tsan_atomic_signal_fence",
336 TLI.getAttrList(&Ctx, {0}, true, false, Attr),
337 IRB.getVoidTy(), OrdTy);
338
339 MemmoveFn =
340 M.getOrInsertFunction("__tsan_memmove", Attr, IRB.getPtrTy(),
341 IRB.getPtrTy(), IRB.getPtrTy(), IntptrTy);
342 MemcpyFn =
343 M.getOrInsertFunction("__tsan_memcpy", Attr, IRB.getPtrTy(),
344 IRB.getPtrTy(), IRB.getPtrTy(), IntptrTy);
345 MemsetFn = M.getOrInsertFunction(
346 "__tsan_memset",
347 TLI.getAttrList(&Ctx, {1}, true, false, Attr),
348 IRB.getPtrTy(), IRB.getPtrTy(), IRB.getInt32Ty(), IntptrTy);
349}
350
352 if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
353 return Tag->isTBAAVtableAccess();
354 return false;
355}
356
357
358
360
362
364 if (GV->hasSection()) {
366
367 auto OF = M->getTargetTriple().getObjectFormat();
370 return false;
371 }
372 }
373
374
375
376 if (Addr) {
379 return false;
380 }
381
382 return true;
383}
384
385bool ThreadSanitizer::addrPointsToConstantData(Value *Addr) {
386
388 Addr = GEP->getPointerOperand();
389
391 if (GV->isConstant()) {
392
393 NumOmittedReadsFromConstantGlobals++;
394 return true;
395 }
398
399 NumOmittedReadsFromVtable++;
400 return true;
401 }
402 }
403 return false;
404}
405
406
407
408
409
410
411
412
413
414
415
416
417
418void ThreadSanitizer::chooseInstructionsToInstrument(
422
427
429 continue;
430
431 if (!IsWrite) {
432 const auto WriteEntry = WriteTargets.find(Addr);
434 auto &WI = All[WriteEntry->second];
435
436
437 const bool AnyVolatile =
440 if (!AnyVolatile) {
441
442
443 WI.Flags |= InstructionInfo::kCompoundRW;
444 NumOmittedReadsBeforeWrite++;
445 continue;
446 }
447 }
448
449 if (addrPointsToConstantData(Addr)) {
450
451 continue;
452 }
453 }
454
456
459
460
461
462 NumOmittedNonCaptured++;
463 continue;
464 }
465
466
468 if (IsWrite) {
469
470
471 WriteTargets[Addr] = All.size() - 1;
472 }
473 }
475}
476
478
480 if (!SSID)
481 return false;
484 return true;
485}
486
487void ThreadSanitizer::InsertRuntimeIgnores(Function &F) {
489 F.getEntryBlock().getFirstNonPHIIt());
490 IRB.CreateCall(TsanIgnoreBegin);
492 while (IRBuilder<> *AtExit = EE.Next()) {
494 AtExit->CreateCall(TsanIgnoreEnd);
495 }
496}
497
498bool ThreadSanitizer::sanitizeFunction(Function &F,
500
501
503 return false;
504
505
506
507 if (F.hasFnAttribute(Attribute::Naked))
508 return false;
509
510
511
512 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
513 return false;
514
520 bool Res = false;
522 bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);
524
525
526 for (auto &BB : F) {
527 for (auto &Inst : BB) {
528
529 if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
530 continue;
534 LocalLoadsAndStores.push_back(&Inst);
541 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores,
543 }
544 }
545 chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, DL);
546 }
547
548
549
550
551
552
554 for (const auto &II : AllLoadsAndStores) {
555 Res |= instrumentLoadOrStore(II, DL);
556 }
557
558
559
561 for (auto *Inst : AtomicAccesses) {
562 Res |= instrumentAtomic(Inst, DL);
563 }
564
566 for (auto *Inst : MemIntrinCalls) {
567 Res |= instrumentMemIntrinsic(Inst);
568 }
569
570 if (F.hasFnAttribute("sanitize_thread_no_checking_at_run_time")) {
571 assert(.hasFnAttribute(Attribute::SanitizeThread));
573 InsertRuntimeIgnores(F);
574 }
575
576
579 F.getEntryBlock().getFirstNonPHIIt());
580 Value *ReturnAddress =
581 IRB.CreateIntrinsic(Intrinsic::returnaddress, IRB.getInt32(0));
582 IRB.CreateCall(TsanFuncEntry, ReturnAddress);
583
585 while (IRBuilder<> *AtExit = EE.Next()) {
587 AtExit->CreateCall(TsanFuncExit, {});
588 }
589 Res = true;
590 }
591 return Res;
592}
593
594bool ThreadSanitizer::instrumentLoadOrStore(const InstructionInfo &II,
601
602
603
604
606 return false;
607
608 int Idx = getMemoryAccessFuncIndex(OrigTy, Addr, DL);
609 if (Idx < 0)
610 return false;
614
615
616
618 StoredValue = IRB.CreateExtractElement(
619 StoredValue, ConstantInt::get(IRB.getInt32Ty(), 0));
621 StoredValue = IRB.CreateIntToPtr(StoredValue, IRB.getPtrTy());
622
623 IRB.CreateCall(TsanVptrUpdate, {Addr, StoredValue});
624 NumInstrumentedVtableWrites++;
625 return true;
626 }
628 IRB.CreateCall(TsanVptrLoad, Addr);
629 NumInstrumentedVtableReads++;
630 return true;
631 }
632
635 const bool IsCompoundRW =
640 assert((!IsVolatile || !IsCompoundRW) && "Compound volatile invalid!");
641
642 const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
644 if (Alignment >= Align(8) || (Alignment.value() % (TypeSize / 8)) == 0) {
645 if (IsCompoundRW)
646 OnAccessFunc = TsanCompoundRW[Idx];
647 else if (IsVolatile)
648 OnAccessFunc = IsWrite ? TsanVolatileWrite[Idx] : TsanVolatileRead[Idx];
649 else
650 OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx];
651 } else {
652 if (IsCompoundRW)
653 OnAccessFunc = TsanUnalignedCompoundRW[Idx];
654 else if (IsVolatile)
655 OnAccessFunc = IsWrite ? TsanUnalignedVolatileWrite[Idx]
656 : TsanUnalignedVolatileRead[Idx];
657 else
658 OnAccessFunc = IsWrite ? TsanUnalignedWrite[Idx] : TsanUnalignedRead[Idx];
659 }
660 IRB.CreateCall(OnAccessFunc, Addr);
661 if (IsCompoundRW || IsWrite)
662 NumInstrumentedWrites++;
663 if (IsCompoundRW || !IsWrite)
664 NumInstrumentedReads++;
665 return true;
666}
667
670 switch (ord) {
675
676
681 }
683}
684
685
686
687
688
689
690
691
692
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);
698 IRB.CreateCall(
699 MemsetFn,
700 {M->getArgOperand(0),
701 Cast1,
702 Cast2});
703 I->eraseFromParent();
705 IRB.CreateCall(
707 {M->getArgOperand(0),
708 M->getArgOperand(1),
709 IRB.CreateIntCast(M->getArgOperand(2), IntptrTy, false)});
710 I->eraseFromParent();
711 }
712 return false;
713}
714
715
716
717
718
719
720
721
722
726 Value *Addr = LI->getPointerOperand();
727 Type *OrigTy = LI->getType();
728 int Idx = getMemoryAccessFuncIndex(OrigTy, Addr, DL);
729 if (Idx < 0)
730 return false;
733 Value *C = IRB.CreateCall(TsanAtomicLoad[Idx], Args);
734 Value *Cast = IRB.CreateBitOrPointerCast(C, OrigTy);
736 I->eraseFromParent();
738 Value *Addr = SI->getPointerOperand();
739 int Idx =
740 getMemoryAccessFuncIndex(SI->getValueOperand()->getType(), Addr, DL);
741 if (Idx < 0)
742 return false;
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();
752 Value *Addr = RMWI->getPointerOperand();
753 int Idx =
754 getMemoryAccessFuncIndex(RMWI->getValOperand()->getType(), Addr, DL);
755 if (Idx < 0)
756 return false;
757 FunctionCallee F = TsanAtomicRMW[RMWI->getOperation()][Idx];
758 if ()
759 return false;
760 const unsigned ByteSize = 1U << Idx;
761 const unsigned BitSize = ByteSize * 8;
763 Value *Val = RMWI->getValOperand();
764 Value *Args[] = {Addr, IRB.CreateBitOrPointerCast(Val, Ty),
766 Value *C = IRB.CreateCall(F, Args);
767 I->replaceAllUsesWith(IRB.CreateBitOrPointerCast(C, Val->getType()));
768 I->eraseFromParent();
770 Value *Addr = CASI->getPointerOperand();
771 Type *OrigOldValTy = CASI->getNewValOperand()->getType();
772 int Idx = getMemoryAccessFuncIndex(OrigOldValTy, Addr, DL);
773 if (Idx < 0)
774 return false;
775 const unsigned ByteSize = 1U << Idx;
776 const unsigned BitSize = ByteSize * 8;
778 Value *CmpOperand =
779 IRB.CreateBitOrPointerCast(CASI->getCompareOperand(), Ty);
780 Value *NewOperand =
781 IRB.CreateBitOrPointerCast(CASI->getNewValOperand(), Ty);
783 CmpOperand,
784 NewOperand,
787 CallInst *C = IRB.CreateCall(TsanAtomicCAS[Idx], Args);
788 Value *Success = IRB.CreateICmpEQ(C, CmpOperand);
790 if (Ty != OrigOldValTy) {
791
792 OldVal = IRB.CreateIntToPtr(C, OrigOldValTy);
793 }
794
796 IRB.CreateInsertValue(PoisonValue::get(CASI->getType()), OldVal, 0);
797 Res = IRB.CreateInsertValue(Res, Success, 1);
798
800 I->eraseFromParent();
804 ? TsanAtomicSignalFence
805 : TsanAtomicThreadFence;
806 IRB.CreateCall(F, Args);
807 FI->eraseFromParent();
808 }
809 return true;
810}
811
812int ThreadSanitizer::getMemoryAccessFuncIndex(Type *OrigTy, Value *Addr,
816
817 return -1;
818 }
819 uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy);
822 NumAccessesWithBadSize++;
823
824 return -1;
825 }
828 return Idx;
829}
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
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, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static bool shouldInstrumentReadWriteFromAddress(const Module *M, Value *Addr)
Definition ThreadSanitizer.cpp:359
static bool isVtableAccess(Instruction *I)
Definition ThreadSanitizer.cpp:351
static bool isTsanAtomic(const Instruction *I)
Definition ThreadSanitizer.cpp:477
const char kTsanModuleCtorName[]
Definition ThreadSanitizer.cpp:100
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)
Definition ThreadSanitizer.cpp:668
static cl::opt< bool > ClInstrumentMemIntrinsics("tsan-instrument-memintrinsics", cl::init(true), cl::desc("Instrument memintrinsics (memset/memcpy/memmove)"), cl::Hidden)
const char kTsanInitName[]
Definition ThreadSanitizer.cpp:101
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
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,...
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
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.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror 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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
std::string utostr(uint64_t X, bool isNeg=false)
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.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
@ 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.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr 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)
Definition ThreadSanitizer.cpp:195
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Definition ThreadSanitizer.cpp:187