39#define DEBUG_TYPE "sancov"
66 "sancov.module_ctor_trace_pc_guard";
68 "sancov.module_ctor_8bit_counters";
88 "sanitizer-coverage-level",
89 cl::desc(
"Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
90 "3: all blocks and critical edges"),
108 cl::desc(
"create a static PC table"),
113 cl::desc(
"increments 8-bit counter for every edge"),
123 cl::desc(
"Tracing of CMP and similar instructions"),
127 cl::desc(
"Tracing of DIV instructions"),
131 cl::desc(
"Tracing of load instructions"),
135 cl::desc(
"Tracing of store instructions"),
139 cl::desc(
"Tracing of GEP instructions"),
144 cl::desc(
"Reduce the number of instrumented blocks"),
148 cl::desc(
"max stack depth tracing"),
160 switch (LegacyCoverageLevel) {
207using PostDomTreeCallback =
210class ModuleSanitizerCoverage {
212 ModuleSanitizerCoverage(
217 Blocklist(Blocklist) {}
218 bool instrumentModule(
Module &M, DomTreeCallback DTCallback,
219 PostDomTreeCallback PDTCallback);
222 void createFunctionControlFlow(
Function &
F);
223 void instrumentFunction(
Function &
F, DomTreeCallback DTCallback,
224 PostDomTreeCallback PDTCallback);
225 void InjectCoverageForIndirectCalls(
Function &
F,
237 bool IsLeafFunc =
true);
238 GlobalVariable *CreateFunctionLocalArrayInSection(
size_t NumElements,
240 const char *Section);
244 bool IsLeafFunc =
true);
245 Function *CreateInitCallsForSections(
Module &M,
const char *CtorName,
246 const char *InitFunctionName,
Type *Ty,
247 const char *Section);
248 std::pair<Value *, Value *> CreateSecStartEnd(
Module &M,
const char *Section,
252 std::string getSectionStart(
const std::string &Section)
const;
253 std::string getSectionEnd(
const std::string &Section)
const;
256 std::array<FunctionCallee, 4> SanCovTraceCmpFunction;
257 std::array<FunctionCallee, 4> SanCovTraceConstCmpFunction;
258 std::array<FunctionCallee, 5> SanCovLoadFunction;
259 std::array<FunctionCallee, 5> SanCovStoreFunction;
260 std::array<FunctionCallee, 2> SanCovTraceDivFunction;
264 Type *PtrTy, *IntptrTy, *Int64Ty, *
Int32Ty, *Int16Ty, *Int8Ty, *Int1Ty;
266 std::string CurModuleUniqueId;
288 ModuleSanitizerCoverage ModuleSancov(
Options, Allowlist.get(),
297 if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
308std::pair<Value *, Value *>
309ModuleSanitizerCoverage::CreateSecStartEnd(
Module &M,
const char *Section,
320 getSectionStart(Section));
324 getSectionEnd(Section));
327 if (!TargetTriple.isOSBinFormatCOFF())
328 return std::make_pair(SecStart, SecEnd);
333 IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy,
sizeof(
uint64_t)));
334 return std::make_pair(
GEP, SecEnd);
337Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
338 Module &M,
const char *CtorName,
const char *InitFunctionName,
Type *Ty,
339 const char *Section) {
340 auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
341 auto SecStart = SecStartEnd.first;
342 auto SecEnd = SecStartEnd.second;
345 M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
348 if (TargetTriple.supportsCOMDAT()) {
350 CtorFunc->
setComdat(
M.getOrInsertComdat(CtorName));
356 if (TargetTriple.isOSBinFormatCOFF()) {
368bool ModuleSanitizerCoverage::instrumentModule(
369 Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
373 !Allowlist->inSection(
"coverage",
"src",
M.getSourceFileName()))
376 Blocklist->inSection(
"coverage",
"src",
M.getSourceFileName()))
378 C = &(
M.getContext());
379 DL = &
M.getDataLayout();
382 TargetTriple =
Triple(
M.getTargetTriple());
383 FunctionGuardArray =
nullptr;
384 Function8bitCounterArray =
nullptr;
385 FunctionBoolArray =
nullptr;
386 FunctionPCsArray =
nullptr;
387 FunctionCFsArray =
nullptr;
392 Int64Ty = IRB.getInt64Ty();
403 SanCovTraceCmpZeroExtAL =
405 SanCovTraceCmpZeroExtAL =
408 SanCovTraceCmpFunction[0] =
410 IRB.getInt8Ty(), IRB.getInt8Ty());
411 SanCovTraceCmpFunction[1] =
413 IRB.getInt16Ty(), IRB.getInt16Ty());
414 SanCovTraceCmpFunction[2] =
416 IRB.getInt32Ty(), IRB.getInt32Ty());
417 SanCovTraceCmpFunction[3] =
420 SanCovTraceConstCmpFunction[0] =
M.getOrInsertFunction(
422 SanCovTraceConstCmpFunction[1] =
M.getOrInsertFunction(
424 SanCovTraceConstCmpFunction[2] =
M.getOrInsertFunction(
426 SanCovTraceConstCmpFunction[3] =
430 SanCovLoadFunction[0] =
M.getOrInsertFunction(
SanCovLoad1, VoidTy, PtrTy);
431 SanCovLoadFunction[1] =
433 SanCovLoadFunction[2] =
435 SanCovLoadFunction[3] =
437 SanCovLoadFunction[4] =
440 SanCovStoreFunction[0] =
442 SanCovStoreFunction[1] =
444 SanCovStoreFunction[2] =
446 SanCovStoreFunction[3] =
448 SanCovStoreFunction[4] =
453 AL =
AL.addParamAttribute(*
C, 0, Attribute::ZExt);
454 SanCovTraceDivFunction[0] =
457 SanCovTraceDivFunction[1] =
459 SanCovTraceGepFunction =
461 SanCovTraceSwitchFunction =
464 Constant *SanCovLowestStackConstant =
466 SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
467 if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
469 "' should not be declared by the user");
472 SanCovLowestStack->setThreadLocalMode(
474 if (
Options.StackDepth && !SanCovLowestStack->isDeclaration())
482 instrumentFunction(
F, DTCallback, PDTCallback);
486 if (FunctionGuardArray)
490 if (Function8bitCounterArray)
494 if (FunctionBoolArray) {
504 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
507 if (Ctor &&
Options.CollectControlFlow) {
512 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
558 if (
Options.NoPrune || &
F.getEntryBlock() == BB)
562 &
F.getEntryBlock() != BB)
594 if (CMP->hasOneUse())
595 if (
auto BR = dyn_cast<BranchInst>(CMP->user_back()))
602void ModuleSanitizerCoverage::instrumentFunction(
603 Function &
F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
606 if (
F.getName().contains(
".module_ctor"))
608 if (
F.getName().starts_with(
"__sanitizer_"))
615 if (
F.getName() ==
"__local_stdio_printf_options" ||
616 F.getName() ==
"__local_stdio_scanf_options")
618 if (isa<UnreachableInst>(
F.getEntryBlock().getTerminator()))
623 if (
F.hasPersonalityFn() &&
626 if (Allowlist && !Allowlist->inSection(
"coverage",
"fun",
F.getName()))
628 if (Blocklist && Blocklist->inSection(
"coverage",
"fun",
F.getName()))
630 if (
F.hasFnAttribute(Attribute::NoSanitizeCoverage))
645 bool IsLeafFunc =
true;
650 for (
auto &Inst : BB) {
652 CallBase *CB = dyn_cast<CallBase>(&Inst);
657 if (
ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst))
660 if (isa<SwitchInst>(&Inst))
665 if (BO->getOpcode() == Instruction::SDiv ||
666 BO->getOpcode() == Instruction::UDiv)
672 if (
LoadInst *LI = dyn_cast<LoadInst>(&Inst))
675 if (
StoreInst *SI = dyn_cast<StoreInst>(&Inst))
678 if (isa<InvokeInst>(Inst) ||
679 (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst)))
684 if (
Options.CollectControlFlow)
685 createFunctionControlFlow(
F);
687 InjectCoverage(
F, BlocksToInstrument, IsLeafFunc);
688 InjectCoverageForIndirectCalls(
F, IndirCalls);
689 InjectTraceForCmp(
F, CmpTraceTargets);
690 InjectTraceForSwitch(
F, SwitchTraceTargets);
691 InjectTraceForDiv(
F, DivTraceTargets);
692 InjectTraceForGep(
F, GepTraceTargets);
693 InjectTraceForLoadsAndStores(
F, Loads, Stores);
696GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
697 size_t NumElements,
Function &
F,
Type *Ty,
const char *Section) {
703 if (TargetTriple.supportsCOMDAT() &&
704 (TargetTriple.isOSBinFormatELF() || !
F.isInterposable()))
708 Array->setAlignment(
Align(
DL->getTypeStoreSize(Ty).getFixedValue()));
719 if (
Array->hasComdat())
720 GlobalsToAppendToCompilerUsed.push_back(Array);
722 GlobalsToAppendToUsed.push_back(Array);
728ModuleSanitizerCoverage::CreatePCArray(
Function &
F,
730 size_t N = AllBlocks.
size();
733 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
734 for (
size_t i = 0; i <
N; i++) {
735 if (&
F.getEntryBlock() == AllBlocks[i]) {
738 ConstantInt::get(IntptrTy, 1), PtrTy));
745 auto *PCArray = CreateFunctionLocalArrayInSection(
N * 2,
F, PtrTy,
747 PCArray->setInitializer(
749 PCArray->setConstant(
true);
754void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
757 FunctionGuardArray = CreateFunctionLocalArrayInSection(
760 if (
Options.Inline8bitCounters)
761 Function8bitCounterArray = CreateFunctionLocalArrayInSection(
764 FunctionBoolArray = CreateFunctionLocalArrayInSection(
768 FunctionPCsArray = CreatePCArray(
F, AllBlocks);
771bool ModuleSanitizerCoverage::InjectCoverage(
Function &
F,
774 if (AllBlocks.
empty())
return false;
775 CreateFunctionLocalArrays(
F, AllBlocks);
776 for (
size_t i = 0,
N = AllBlocks.
size(); i <
N; i++)
777 InjectCoverageAtBlock(
F, *AllBlocks[i], i, IsLeafFunc);
788void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
790 if (IndirCalls.
empty())
794 for (
auto *
I : IndirCalls) {
798 if (isa<InlineAsm>(Callee))
800 IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
808void ModuleSanitizerCoverage::InjectTraceForSwitch(
810 for (
auto *
I : SwitchTraceTargets) {
815 if (
Cond->getType()->getScalarSizeInBits() >
816 Int64Ty->getScalarSizeInBits())
818 Initializers.
push_back(ConstantInt::get(Int64Ty,
SI->getNumCases()));
820 ConstantInt::get(Int64Ty,
Cond->getType()->getScalarSizeInBits()));
821 if (
Cond->getType()->getScalarSizeInBits() <
822 Int64Ty->getScalarSizeInBits())
823 Cond = IRB.CreateIntCast(
Cond, Int64Ty,
false);
824 for (
auto It :
SI->cases()) {
826 if (
C->getType()->getScalarSizeInBits() < 64)
827 C = ConstantInt::get(
C->getContext(),
C->getValue().zext(64));
832 return cast<ConstantInt>(
A)->getLimitedValue() <
833 cast<ConstantInt>(
B)->getLimitedValue();
839 "__sancov_gen_cov_switch_values");
840 IRB.CreateCall(SanCovTraceSwitchFunction, {
Cond, GV});
845void ModuleSanitizerCoverage::InjectTraceForDiv(
847 for (
auto *BO : DivTraceTargets) {
849 Value *A1 = BO->getOperand(1);
850 if (isa<ConstantInt>(A1))
continue;
854 int CallbackIdx =
TypeSize == 32 ? 0 :
856 if (CallbackIdx < 0)
continue;
858 IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
859 {IRB.CreateIntCast(A1, Ty,
true)});
863void ModuleSanitizerCoverage::InjectTraceForGep(
865 for (
auto *
GEP : GepTraceTargets) {
868 if (!isa<ConstantInt>(
Idx) &&
Idx->getType()->isIntegerTy())
869 IRB.CreateCall(SanCovTraceGepFunction,
870 {IRB.CreateIntCast(
Idx, IntptrTy,
true)});
874void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
876 auto CallbackIdx = [&](
Type *ElementTy) ->
int {
885 for (
auto *LI : Loads) {
887 auto Ptr = LI->getPointerOperand();
888 int Idx = CallbackIdx(LI->getType());
891 IRB.CreateCall(SanCovLoadFunction[
Idx],
Ptr);
893 for (
auto *SI : Stores) {
895 auto Ptr =
SI->getPointerOperand();
896 int Idx = CallbackIdx(
SI->getValueOperand()->getType());
899 IRB.CreateCall(SanCovStoreFunction[
Idx],
Ptr);
903void ModuleSanitizerCoverage::InjectTraceForCmp(
905 for (
auto *
I : CmpTraceTargets) {
906 if (
ICmpInst *ICMP = dyn_cast<ICmpInst>(
I)) {
913 int CallbackIdx =
TypeSize == 8 ? 0 :
917 if (CallbackIdx < 0)
continue;
919 auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
920 bool FirstIsConst = isa<ConstantInt>(A0);
921 bool SecondIsConst = isa<ConstantInt>(A1);
923 if (FirstIsConst && SecondIsConst)
continue;
925 if (FirstIsConst || SecondIsConst) {
926 CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
932 IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty,
true),
933 IRB.CreateIntCast(A1, Ty,
true)});
942 bool IsEntryBB = &BB == &
F.getEntryBlock();
945 if (
auto SP =
F.getSubprogram())
946 EntryLoc =
DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
955 IRB.SetCurrentDebugLocation(EntryLoc);
957 IRB.CreateCall(SanCovTracePC)
961 auto GuardPtr = IRB.CreateIntToPtr(
962 IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
963 ConstantInt::get(IntptrTy,
Idx * 4)),
965 IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
967 if (
Options.Inline8bitCounters) {
968 auto CounterPtr = IRB.CreateGEP(
969 Function8bitCounterArray->getValueType(), Function8bitCounterArray,
970 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
971 auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
972 auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
973 auto Store = IRB.CreateStore(Inc, CounterPtr);
974 Load->setNoSanitizeMetadata();
975 Store->setNoSanitizeMetadata();
978 auto FlagPtr = IRB.CreateGEP(
979 FunctionBoolArray->getValueType(), FunctionBoolArray,
980 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
981 auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
986 Load->setNoSanitizeMetadata();
987 Store->setNoSanitizeMetadata();
989 if (
Options.StackDepth && IsEntryBB && !IsLeafFunc) {
993 M, Intrinsic::frameaddress,
994 IRB.getPtrTy(
M->getDataLayout().getAllocaAddrSpace()));
997 auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
998 auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
999 auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
1002 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
1003 LowestStack->setNoSanitizeMetadata();
1004 Store->setNoSanitizeMetadata();
1009ModuleSanitizerCoverage::getSectionName(
const std::string &Section)
const {
1010 if (TargetTriple.isOSBinFormatCOFF()) {
1019 if (TargetTriple.isOSBinFormatMachO())
1025ModuleSanitizerCoverage::getSectionStart(
const std::string &Section)
const {
1026 if (TargetTriple.isOSBinFormatMachO())
1027 return "\1section$start$__DATA$__" +
Section;
1028 return "__start___" +
Section;
1032ModuleSanitizerCoverage::getSectionEnd(
const std::string &Section)
const {
1033 if (TargetTriple.isOSBinFormatMachO())
1034 return "\1section$end$__DATA$__" +
Section;
1038void ModuleSanitizerCoverage::createFunctionControlFlow(
Function &
F) {
1040 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
1042 for (
auto &BB :
F) {
1044 if (&BB == &
F.getEntryBlock())
1051 assert(SuccBB != &
F.getEntryBlock());
1058 for (
auto &Inst : BB) {
1059 if (
CallBase *CB = dyn_cast<CallBase>(&Inst)) {
1063 ConstantInt::get(IntptrTy, -1), PtrTy));
1066 if (CalledF && !CalledF->isIntrinsic())
1068 (
Constant *)IRB.CreatePointerCast(CalledF, PtrTy));
1076 FunctionCFsArray = CreateFunctionLocalArrayInSection(
1078 FunctionCFsArray->setInitializer(
1080 FunctionCFsArray->setConstant(
true);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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 is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
static cl::opt< bool > SplitAllCriticalEdges("phi-elim-split-all-critical-edges", cl::init(false), cl::Hidden, cl::desc("Split all critical edges during " "PHI elimination"))
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > ClCreatePCTable("sanitizer-coverage-pc-table", cl::desc("create a static PC table"), cl::Hidden, cl::init(false))
const char SanCovCFsSectionName[]
static cl::opt< bool > ClStoreTracing("sanitizer-coverage-trace-stores", cl::desc("Tracing of store instructions"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters", cl::desc("increments 8-bit counter for every edge"), cl::Hidden, cl::init(false))
const char SanCovTraceConstCmp4[]
const char SanCovBoolFlagSectionName[]
static bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT)
static cl::opt< bool > ClCollectCF("sanitizer-coverage-control-flow", cl::desc("collect control flow for each function"), cl::Hidden, cl::init(false))
const char SanCov8bitCountersInitName[]
static cl::opt< bool > ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag", cl::desc("sets a boolean flag for every edge"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClLoadTracing("sanitizer-coverage-trace-loads", cl::desc("Tracing of load instructions"), cl::Hidden, cl::init(false))
static bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT)
const char SanCovTraceSwitchName[]
const char SanCovTraceCmp1[]
const char SanCovModuleCtorTracePcGuardName[]
static cl::opt< bool > ClCMPTracing("sanitizer-coverage-trace-compares", cl::desc("Tracing of CMP and similar instructions"), cl::Hidden, cl::init(false))
const char SanCovCountersSectionName[]
const char SanCovPCsInitName[]
const char SanCovTracePCGuardName[]
const char SanCovModuleCtor8bitCountersName[]
const char SanCovTracePCGuardInitName[]
const char SanCovTraceDiv4[]
static const uint64_t SanCtorAndDtorPriority
const char SanCovBoolFlagInitName[]
static cl::opt< bool > ClStackDepth("sanitizer-coverage-stack-depth", cl::desc("max stack depth tracing"), cl::Hidden, cl::init(false))
const char SanCovTraceGep[]
static cl::opt< bool > ClTracePC("sanitizer-coverage-trace-pc", cl::desc("Experimental pc tracing"), cl::Hidden, cl::init(false))
const char SanCovLoad16[]
const char SanCovTraceConstCmp8[]
const char SanCovGuardsSectionName[]
const char SanCovStore1[]
const char SanCovTraceConstCmp2[]
const char SanCovTraceConstCmp1[]
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, const DominatorTree *DT, const PostDominatorTree *PDT, const SanitizerCoverageOptions &Options)
static cl::opt< bool > ClTracePCGuard("sanitizer-coverage-trace-pc-guard", cl::desc("pc tracing with a guard"), cl::Hidden, cl::init(false))
const char SanCovTraceDiv8[]
const char SanCovCFsInitName[]
const char SanCovStore2[]
static cl::opt< bool > ClPruneBlocks("sanitizer-coverage-prune-blocks", cl::desc("Reduce the number of instrumented blocks"), cl::Hidden, cl::init(true))
static cl::opt< int > ClCoverageLevel("sanitizer-coverage-level", cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, " "3: all blocks and critical edges"), cl::Hidden, cl::init(0))
const char SanCovPCsSectionName[]
const char SanCovTraceCmp8[]
const char SanCovStore16[]
const char SanCovModuleCtorBoolFlagName[]
static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, const SanitizerCoverageOptions &Options)
const char SanCovTraceCmp2[]
const char SanCovStore8[]
const char SanCovTracePCName[]
const char SanCovStore4[]
static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT)
const char SanCovTraceCmp4[]
const char SanCovLowestStackName[]
static cl::opt< bool > ClDIVTracing("sanitizer-coverage-trace-divs", cl::desc("Tracing of DIV instructions"), cl::Hidden, cl::init(false))
const char SanCovTracePCIndirName[]
static cl::opt< bool > ClGEPTracing("sanitizer-coverage-trace-geps", cl::desc("Tracing of GEP instructions"), cl::Hidden, cl::init(false))
This file defines the SmallVector class.
Defines the virtual file system interface vfs::FileSystem.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const
Add an argument attribute to the list.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction * getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic,...
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isIndirectCall() const
Return true if the callsite is an indirect call.
Value * getCalledOperand() const
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
const BasicBlock & getEntryBlock() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
void setComdat(Comdat *C)
void setLinkage(LinkageTypes LT)
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
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.
void abandon()
Mark an analysis as abandoned.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This is a utility class used to parse user-provided text files with "special case lists" for code san...
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt1Ty(LLVMContext &C)
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt16Ty(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
An efficient, type-erasing, non-owning reference to a callable.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
initializer< Ty > init(const Ty &Val)
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool succ_empty(const Instruction *I)
auto successors(const MachineBasicBlock *BB)
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
void sort(IteratorTy Start, IteratorTy End)
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Comdat * getOrCreateFunctionComdat(Function &F, Triple &T)
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
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.
auto predecessors(const MachineBasicBlock *BB)
bool pred_empty(const BasicBlock *BB)
BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB, BasicBlock::iterator IP)
Instrumentation passes often insert conditional checks into entry blocks.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Option class for critical edge splitting.
enum llvm::SanitizerCoverageOptions::Type CoverageType