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

467 All.emplace_back(I);

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(F.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 (F)

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