40#define DEBUG_TYPE "sancov"
67 "sancov.module_ctor_trace_pc_guard";
69 "sancov.module_ctor_8bit_counters";
89 "sanitizer-coverage-level",
90 cl::desc(
"Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
91 "3: all blocks and critical edges"),
108 cl::desc(
"create a static PC table"),
113 cl::desc(
"increments 8-bit counter for every edge"),
118 cl::desc(
"sets a boolean flag 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"),
159 switch (LegacyCoverageLevel) {
205class ModuleSanitizerCoverage {
208 using PostDomTreeCallback =
211 ModuleSanitizerCoverage(
Module &M, DomTreeCallback DTCallback,
212 PostDomTreeCallback PDTCallback,
216 :
M(
M), DTCallback(DTCallback), PDTCallback(PDTCallback),
217 Options(Options), Allowlist(Allowlist), Blocklist(Blocklist) {}
219 bool instrumentModule();
222 void createFunctionControlFlow(
Function &
F);
224 void InjectCoverageForIndirectCalls(
Function &
F,
236 bool IsLeafFunc =
true);
237 GlobalVariable *CreateFunctionLocalArrayInSection(
size_t NumElements,
239 const char *Section);
243 bool IsLeafFunc =
true);
244 Function *CreateInitCallsForSections(
Module &M,
const char *CtorName,
245 const char *InitFunctionName,
Type *Ty,
246 const char *Section);
247 std::pair<Value *, Value *> CreateSecStartEnd(
Module &M,
const char *Section,
251 std::string getSectionStart(
const std::string &Section)
const;
252 std::string getSectionEnd(
const std::string &Section)
const;
255 DomTreeCallback DTCallback;
256 PostDomTreeCallback PDTCallback;
260 std::array<FunctionCallee, 4> SanCovTraceCmpFunction;
261 std::array<FunctionCallee, 4> SanCovTraceConstCmpFunction;
262 std::array<FunctionCallee, 5> SanCovLoadFunction;
263 std::array<FunctionCallee, 5> SanCovStoreFunction;
264 std::array<FunctionCallee, 2> SanCovTraceDivFunction;
268 Type *PtrTy, *IntptrTy, *Int64Ty, *Int32Ty, *Int16Ty, *Int8Ty, *Int1Ty;
270 std::string CurModuleUniqueId;
299 ModuleSanitizerCoverage ModuleSancov(M, DTCallback, PDTCallback,
300 OverrideFromCL(Options), Allowlist.get(),
302 if (!ModuleSancov.instrumentModule())
313std::pair<Value *, Value *>
314ModuleSanitizerCoverage::CreateSecStartEnd(
Module &M,
const char *Section,
325 getSectionStart(Section));
329 getSectionEnd(Section));
332 if (!TargetTriple.isOSBinFormatCOFF())
333 return std::make_pair(SecStart, SecEnd);
338 IRB.CreatePtrAdd(SecStart, ConstantInt::get(IntptrTy,
sizeof(
uint64_t)));
339 return std::make_pair(
GEP, SecEnd);
342Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
343 Module &M,
const char *CtorName,
const char *InitFunctionName,
Type *Ty,
344 const char *Section) {
345 auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
346 auto SecStart = SecStartEnd.first;
347 auto SecEnd = SecStartEnd.second;
350 M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
353 if (TargetTriple.supportsCOMDAT()) {
355 CtorFunc->
setComdat(
M.getOrInsertComdat(CtorName));
361 if (TargetTriple.isOSBinFormatCOFF()) {
373bool ModuleSanitizerCoverage::instrumentModule() {
377 !Allowlist->inSection(
"coverage",
"src",
M.getSourceFileName()))
380 Blocklist->inSection(
"coverage",
"src",
M.getSourceFileName()))
382 C = &(
M.getContext());
383 DL = &
M.getDataLayout();
386 TargetTriple =
Triple(
M.getTargetTriple());
387 FunctionGuardArray =
nullptr;
388 Function8bitCounterArray =
nullptr;
389 FunctionBoolArray =
nullptr;
390 FunctionPCsArray =
nullptr;
391 FunctionCFsArray =
nullptr;
396 Int64Ty = IRB.getInt64Ty();
397 Int32Ty = IRB.getInt32Ty();
398 Int16Ty = IRB.getInt16Ty();
399 Int8Ty = IRB.getInt8Ty();
400 Int1Ty = IRB.getInt1Ty();
407 SanCovTraceCmpZeroExtAL =
409 SanCovTraceCmpZeroExtAL =
412 SanCovTraceCmpFunction[0] =
414 IRB.getInt8Ty(), IRB.getInt8Ty());
415 SanCovTraceCmpFunction[1] =
417 IRB.getInt16Ty(), IRB.getInt16Ty());
418 SanCovTraceCmpFunction[2] =
420 IRB.getInt32Ty(), IRB.getInt32Ty());
421 SanCovTraceCmpFunction[3] =
424 SanCovTraceConstCmpFunction[0] =
M.getOrInsertFunction(
426 SanCovTraceConstCmpFunction[1] =
M.getOrInsertFunction(
428 SanCovTraceConstCmpFunction[2] =
M.getOrInsertFunction(
430 SanCovTraceConstCmpFunction[3] =
434 SanCovLoadFunction[0] =
M.getOrInsertFunction(
SanCovLoad1, VoidTy, PtrTy);
435 SanCovLoadFunction[1] =
437 SanCovLoadFunction[2] =
439 SanCovLoadFunction[3] =
441 SanCovLoadFunction[4] =
444 SanCovStoreFunction[0] =
446 SanCovStoreFunction[1] =
448 SanCovStoreFunction[2] =
450 SanCovStoreFunction[3] =
452 SanCovStoreFunction[4] =
457 AL =
AL.addParamAttribute(*
C, 0, Attribute::ZExt);
458 SanCovTraceDivFunction[0] =
461 SanCovTraceDivFunction[1] =
463 SanCovTraceGepFunction =
465 SanCovTraceSwitchFunction =
468 Constant *SanCovLowestStackConstant =
470 SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
471 if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
473 "' should not be declared by the user");
476 SanCovLowestStack->setThreadLocalMode(
478 if (
Options.StackDepth && !SanCovLowestStack->isDeclaration())
486 instrumentFunction(
F);
490 if (FunctionGuardArray)
494 if (Function8bitCounterArray)
498 if (FunctionBoolArray) {
508 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
511 if (Ctor &&
Options.CollectControlFlow) {
516 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
562 if (
Options.NoPrune || &
F.getEntryBlock() == BB)
566 &
F.getEntryBlock() != BB)
597 if (CMP->hasOneUse())
598 if (
auto BR = dyn_cast<BranchInst>(CMP->user_back()))
605void ModuleSanitizerCoverage::instrumentFunction(
Function &
F) {
608 if (
F.getName().contains(
".module_ctor"))
610 if (
F.getName().starts_with(
"__sanitizer_"))
617 if (
F.getName() ==
"__local_stdio_printf_options" ||
618 F.getName() ==
"__local_stdio_scanf_options")
620 if (isa<UnreachableInst>(
F.getEntryBlock().getTerminator()))
625 if (
F.hasPersonalityFn() &&
628 if (Allowlist && !Allowlist->inSection(
"coverage",
"fun",
F.getName()))
630 if (Blocklist && Blocklist->inSection(
"coverage",
"fun",
F.getName()))
632 if (
F.hasFnAttribute(Attribute::NoSanitizeCoverage))
634 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
651 bool IsLeafFunc =
true;
656 for (
auto &Inst : BB) {
658 CallBase *CB = dyn_cast<CallBase>(&Inst);
663 if (
ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst))
666 if (isa<SwitchInst>(&Inst))
671 if (BO->getOpcode() == Instruction::SDiv ||
672 BO->getOpcode() == Instruction::UDiv)
678 if (
LoadInst *LI = dyn_cast<LoadInst>(&Inst))
681 if (
StoreInst *SI = dyn_cast<StoreInst>(&Inst))
684 if (isa<InvokeInst>(Inst) ||
685 (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst)))
690 if (
Options.CollectControlFlow)
691 createFunctionControlFlow(
F);
693 InjectCoverage(
F, BlocksToInstrument, IsLeafFunc);
694 InjectCoverageForIndirectCalls(
F, IndirCalls);
695 InjectTraceForCmp(
F, CmpTraceTargets);
696 InjectTraceForSwitch(
F, SwitchTraceTargets);
697 InjectTraceForDiv(
F, DivTraceTargets);
698 InjectTraceForGep(
F, GepTraceTargets);
699 InjectTraceForLoadsAndStores(
F, Loads, Stores);
702GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
703 size_t NumElements,
Function &
F,
Type *Ty,
const char *Section) {
709 if (TargetTriple.supportsCOMDAT() &&
710 (TargetTriple.isOSBinFormatELF() || !
F.isInterposable()))
714 Array->setAlignment(
Align(
DL->getTypeStoreSize(Ty).getFixedValue()));
725 if (
Array->hasComdat())
726 GlobalsToAppendToCompilerUsed.push_back(Array);
728 GlobalsToAppendToUsed.push_back(Array);
734ModuleSanitizerCoverage::CreatePCArray(
Function &
F,
736 size_t N = AllBlocks.
size();
739 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
740 for (
size_t i = 0; i <
N; i++) {
741 if (&
F.getEntryBlock() == AllBlocks[i]) {
744 ConstantInt::get(IntptrTy, 1), PtrTy));
751 auto *PCArray = CreateFunctionLocalArrayInSection(
N * 2,
F, PtrTy,
753 PCArray->setInitializer(
755 PCArray->setConstant(
true);
760void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
763 FunctionGuardArray = CreateFunctionLocalArrayInSection(
766 if (
Options.Inline8bitCounters)
767 Function8bitCounterArray = CreateFunctionLocalArrayInSection(
770 FunctionBoolArray = CreateFunctionLocalArrayInSection(
774 FunctionPCsArray = CreatePCArray(
F, AllBlocks);
777bool ModuleSanitizerCoverage::InjectCoverage(
Function &
F,
780 if (AllBlocks.
empty())
return false;
781 CreateFunctionLocalArrays(
F, AllBlocks);
782 for (
size_t i = 0,
N = AllBlocks.
size(); i <
N; i++)
783 InjectCoverageAtBlock(
F, *AllBlocks[i], i, IsLeafFunc);
794void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
796 if (IndirCalls.
empty())
800 for (
auto *
I : IndirCalls) {
804 if (isa<InlineAsm>(Callee))
806 IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
814void ModuleSanitizerCoverage::InjectTraceForSwitch(
816 for (
auto *
I : SwitchTraceTargets) {
821 if (
Cond->getType()->getScalarSizeInBits() >
822 Int64Ty->getScalarSizeInBits())
824 Initializers.
push_back(ConstantInt::get(Int64Ty,
SI->getNumCases()));
826 ConstantInt::get(Int64Ty,
Cond->getType()->getScalarSizeInBits()));
827 if (
Cond->getType()->getScalarSizeInBits() <
828 Int64Ty->getScalarSizeInBits())
829 Cond = IRB.CreateIntCast(
Cond, Int64Ty,
false);
830 for (
auto It :
SI->cases()) {
832 if (
C->getType()->getScalarSizeInBits() < 64)
833 C = ConstantInt::get(
C->getContext(),
C->getValue().zext(64));
838 return cast<ConstantInt>(
A)->getLimitedValue() <
839 cast<ConstantInt>(
B)->getLimitedValue();
845 "__sancov_gen_cov_switch_values");
846 IRB.CreateCall(SanCovTraceSwitchFunction, {
Cond, GV});
851void ModuleSanitizerCoverage::InjectTraceForDiv(
853 for (
auto *BO : DivTraceTargets) {
855 Value *A1 = BO->getOperand(1);
856 if (isa<ConstantInt>(A1))
continue;
860 int CallbackIdx =
TypeSize == 32 ? 0 :
862 if (CallbackIdx < 0)
continue;
864 IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
865 {IRB.CreateIntCast(A1, Ty,
true)});
869void ModuleSanitizerCoverage::InjectTraceForGep(
871 for (
auto *
GEP : GepTraceTargets) {
874 if (!isa<ConstantInt>(
Idx) &&
Idx->getType()->isIntegerTy())
875 IRB.CreateCall(SanCovTraceGepFunction,
876 {IRB.CreateIntCast(
Idx, IntptrTy,
true)});
880void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
882 auto CallbackIdx = [&](
Type *ElementTy) ->
int {
891 for (
auto *LI : Loads) {
893 auto Ptr = LI->getPointerOperand();
894 int Idx = CallbackIdx(LI->getType());
897 IRB.CreateCall(SanCovLoadFunction[
Idx],
Ptr);
899 for (
auto *SI : Stores) {
901 auto Ptr =
SI->getPointerOperand();
902 int Idx = CallbackIdx(
SI->getValueOperand()->getType());
905 IRB.CreateCall(SanCovStoreFunction[
Idx],
Ptr);
909void ModuleSanitizerCoverage::InjectTraceForCmp(
911 for (
auto *
I : CmpTraceTargets) {
912 if (
ICmpInst *ICMP = dyn_cast<ICmpInst>(
I)) {
919 int CallbackIdx =
TypeSize == 8 ? 0 :
923 if (CallbackIdx < 0)
continue;
925 auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
926 bool FirstIsConst = isa<ConstantInt>(A0);
927 bool SecondIsConst = isa<ConstantInt>(A1);
929 if (FirstIsConst && SecondIsConst)
continue;
931 if (FirstIsConst || SecondIsConst) {
932 CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
938 IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty,
true),
939 IRB.CreateIntCast(A1, Ty,
true)});
948 bool IsEntryBB = &BB == &
F.getEntryBlock();
951 if (
auto SP =
F.getSubprogram())
952 EntryLoc =
DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
961 IRB.SetCurrentDebugLocation(EntryLoc);
963 IRB.CreateCall(SanCovTracePC)
967 auto GuardPtr = IRB.CreateIntToPtr(
968 IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
969 ConstantInt::get(IntptrTy,
Idx * 4)),
971 IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
973 if (
Options.Inline8bitCounters) {
974 auto CounterPtr = IRB.CreateGEP(
975 Function8bitCounterArray->getValueType(), Function8bitCounterArray,
976 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
977 auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
978 auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
979 auto Store = IRB.CreateStore(Inc, CounterPtr);
980 Load->setNoSanitizeMetadata();
981 Store->setNoSanitizeMetadata();
984 auto FlagPtr = IRB.CreateGEP(
985 FunctionBoolArray->getValueType(), FunctionBoolArray,
986 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
987 auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
989 IRB.CreateIsNull(Load), &*IP,
false,
993 Load->setNoSanitizeMetadata();
994 Store->setNoSanitizeMetadata();
996 if (
Options.StackDepth && IsEntryBB && !IsLeafFunc) {
1000 M, Intrinsic::frameaddress,
1001 IRB.getPtrTy(
M->getDataLayout().getAllocaAddrSpace()));
1004 auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
1005 auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
1006 auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
1008 IsStackLower, &*IP,
false,
1011 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
1012 LowestStack->setNoSanitizeMetadata();
1013 Store->setNoSanitizeMetadata();
1018ModuleSanitizerCoverage::getSectionName(
const std::string &Section)
const {
1019 if (TargetTriple.isOSBinFormatCOFF()) {
1028 if (TargetTriple.isOSBinFormatMachO())
1034ModuleSanitizerCoverage::getSectionStart(
const std::string &Section)
const {
1035 if (TargetTriple.isOSBinFormatMachO())
1036 return "\1section$start$__DATA$__" +
Section;
1037 return "__start___" +
Section;
1041ModuleSanitizerCoverage::getSectionEnd(
const std::string &Section)
const {
1042 if (TargetTriple.isOSBinFormatMachO())
1043 return "\1section$end$__DATA$__" +
Section;
1047void ModuleSanitizerCoverage::createFunctionControlFlow(
Function &
F) {
1049 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
1051 for (
auto &BB :
F) {
1053 if (&BB == &
F.getEntryBlock())
1060 assert(SuccBB != &
F.getEntryBlock());
1067 for (
auto &Inst : BB) {
1068 if (
CallBase *CB = dyn_cast<CallBase>(&Inst)) {
1072 ConstantInt::get(IntptrTy, -1), PtrTy));
1075 if (CalledF && !CalledF->isIntrinsic())
1077 (
Constant *)IRB.CreatePointerCast(CalledF, PtrTy));
1085 FunctionCFsArray = CreateFunctionLocalArrayInSection(
1087 FunctionCFsArray->setInitializer(
1089 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"))
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > ClLoadTracing("sanitizer-coverage-trace-loads", cl::desc("Tracing of load instructions"), cl::Hidden)
const char SanCovCFsSectionName[]
static bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree &PDT)
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)
static cl::opt< bool > ClStackDepth("sanitizer-coverage-stack-depth", cl::desc("max stack depth tracing"), cl::Hidden)
static cl::opt< bool > ClInlineBoolFlag("sanitizer-coverage-inline-bool-flag", cl::desc("sets a boolean flag for every edge"), cl::Hidden)
const char SanCovTraceConstCmp4[]
const char SanCovBoolFlagSectionName[]
const char SanCov8bitCountersInitName[]
const char SanCovTraceSwitchName[]
const char SanCovTraceCmp1[]
const char SanCovModuleCtorTracePcGuardName[]
const char SanCovCountersSectionName[]
static cl::opt< bool > ClCreatePCTable("sanitizer-coverage-pc-table", cl::desc("create a static PC table"), cl::Hidden)
const char SanCovPCsInitName[]
const char SanCovTracePCGuardName[]
const char SanCovModuleCtor8bitCountersName[]
const char SanCovTracePCGuardInitName[]
static cl::opt< bool > ClCollectCF("sanitizer-coverage-control-flow", cl::desc("collect control flow for each function"), cl::Hidden)
const char SanCovTraceDiv4[]
static const uint64_t SanCtorAndDtorPriority
const char SanCovBoolFlagInitName[]
const char SanCovTraceGep[]
const char SanCovLoad16[]
const char SanCovTraceConstCmp8[]
const char SanCovGuardsSectionName[]
const char SanCovStore1[]
const char SanCovTraceConstCmp2[]
const char SanCovTraceConstCmp1[]
static bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree &DT)
static cl::opt< bool > ClStoreTracing("sanitizer-coverage-trace-stores", cl::desc("Tracing of store instructions"), cl::Hidden)
static cl::opt< bool > ClTracePCGuard("sanitizer-coverage-trace-pc-guard", cl::desc("pc tracing with a guard"), cl::Hidden)
const char SanCovTraceDiv8[]
static cl::opt< bool > ClGEPTracing("sanitizer-coverage-trace-geps", cl::desc("Tracing of GEP instructions"), cl::Hidden)
const char SanCovCFsInitName[]
static cl::opt< bool > ClTracePC("sanitizer-coverage-trace-pc", cl::desc("Experimental pc tracing"), cl::Hidden)
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))
const char SanCovPCsSectionName[]
static bool isFullDominator(const BasicBlock *BB, const DominatorTree &DT)
static cl::opt< bool > ClCMPTracing("sanitizer-coverage-trace-compares", cl::desc("Tracing of CMP and similar instructions"), cl::Hidden)
const char SanCovTraceCmp8[]
const char SanCovStore16[]
static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree &DT, const SanitizerCoverageOptions &Options)
static cl::opt< bool > ClDIVTracing("sanitizer-coverage-trace-divs", cl::desc("Tracing of DIV instructions"), cl::Hidden)
static cl::opt< bool > ClInline8bitCounters("sanitizer-coverage-inline-8bit-counters", cl::desc("increments 8-bit counter for every edge"), cl::Hidden)
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, const DominatorTree &DT, const PostDominatorTree &PDT, const SanitizerCoverageOptions &Options)
const char SanCovModuleCtorBoolFlagName[]
const char SanCovTraceCmp2[]
const char SanCovStore8[]
const char SanCovTracePCName[]
const char SanCovStore4[]
const char SanCovTraceCmp4[]
const char SanCovLowestStackName[]
const char SanCovTracePCIndirName[]
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.
MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
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 * getIntNTy(LLVMContext &C, unsigned N)
static Type * getVoidTy(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