41#define DEBUG_TYPE "sancov"
68 "sancov.module_ctor_trace_pc_guard";
70 "sancov.module_ctor_8bit_counters";
90 "sanitizer-coverage-level",
91 cl::desc(
"Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
92 "3: all blocks and critical edges"),
100 cl::desc(
"pc tracing with a guard"),
110 cl::desc(
"create a static PC table"),
115 cl::desc(
"increments 8-bit counter for every edge"),
125 cl::desc(
"Tracing of CMP and similar instructions"),
129 cl::desc(
"Tracing of DIV instructions"),
133 cl::desc(
"Tracing of load instructions"),
137 cl::desc(
"Tracing of store instructions"),
141 cl::desc(
"Tracing of GEP instructions"),
146 cl::desc(
"Reduce the number of instrumented blocks"),
150 cl::desc(
"max stack depth tracing"),
162 switch (LegacyCoverageLevel) {
209using PostDomTreeCallback =
212class ModuleSanitizerCoverage {
214 ModuleSanitizerCoverage(
219 Blocklist(Blocklist) {}
220 bool instrumentModule(
Module &M, DomTreeCallback DTCallback,
221 PostDomTreeCallback PDTCallback);
224 void createFunctionControlFlow(
Function &
F);
225 void instrumentFunction(
Function &
F, DomTreeCallback DTCallback,
226 PostDomTreeCallback PDTCallback);
227 void InjectCoverageForIndirectCalls(
Function &
F,
239 bool IsLeafFunc =
true);
240 GlobalVariable *CreateFunctionLocalArrayInSection(
size_t NumElements,
242 const char *Section);
246 bool IsLeafFunc =
true);
247 Function *CreateInitCallsForSections(
Module &M,
const char *CtorName,
248 const char *InitFunctionName,
Type *Ty,
249 const char *Section);
250 std::pair<Value *, Value *> CreateSecStartEnd(
Module &M,
const char *Section,
254 I->setMetadata(LLVMContext::MD_nosanitize,
MDNode::get(*C, std::nullopt));
257 std::string getSectionName(
const std::string &Section)
const;
258 std::string getSectionStart(
const std::string &Section)
const;
259 std::string getSectionEnd(
const std::string &Section)
const;
262 std::array<FunctionCallee, 4> SanCovTraceCmpFunction;
263 std::array<FunctionCallee, 4> SanCovTraceConstCmpFunction;
264 std::array<FunctionCallee, 5> SanCovLoadFunction;
265 std::array<FunctionCallee, 5> SanCovStoreFunction;
266 std::array<FunctionCallee, 2> SanCovTraceDivFunction;
270 Type *Int128PtrTy, *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *
Int32Ty,
271 *Int32PtrTy, *Int16PtrTy, *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty,
274 std::string CurModuleUniqueId;
296 ModuleSanitizerCoverage ModuleSancov(
Options, Allowlist.get(),
305 if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
316std::pair<Value *, Value *>
317ModuleSanitizerCoverage::CreateSecStartEnd(
Module &M,
const char *Section,
328 getSectionStart(Section));
332 getSectionEnd(Section));
335 if (!TargetTriple.isOSBinFormatCOFF())
336 return std::make_pair(SecStart, SecEnd);
340 auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
341 auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr,
347Function *ModuleSanitizerCoverage::CreateInitCallsForSections(
348 Module &M,
const char *CtorName,
const char *InitFunctionName,
Type *Ty,
349 const char *Section) {
350 auto SecStartEnd = CreateSecStartEnd(M, Section, Ty);
351 auto SecStart = SecStartEnd.first;
352 auto SecEnd = SecStartEnd.second;
356 M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
359 if (TargetTriple.supportsCOMDAT()) {
361 CtorFunc->
setComdat(
M.getOrInsertComdat(CtorName));
367 if (TargetTriple.isOSBinFormatCOFF()) {
379bool ModuleSanitizerCoverage::instrumentModule(
380 Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
384 !Allowlist->inSection(
"coverage",
"src",
M.getSourceFileName()))
387 Blocklist->inSection(
"coverage",
"src",
M.getSourceFileName()))
389 C = &(
M.getContext());
390 DL = &
M.getDataLayout();
393 TargetTriple =
Triple(
M.getTargetTriple());
394 FunctionGuardArray =
nullptr;
395 Function8bitCounterArray =
nullptr;
396 FunctionBoolArray =
nullptr;
397 FunctionPCsArray =
nullptr;
398 FunctionCFsArray =
nullptr;
409 Int64Ty = IRB.getInt64Ty();
420 SanCovTraceCmpZeroExtAL =
422 SanCovTraceCmpZeroExtAL =
425 SanCovTraceCmpFunction[0] =
427 IRB.getInt8Ty(), IRB.getInt8Ty());
428 SanCovTraceCmpFunction[1] =
430 IRB.getInt16Ty(), IRB.getInt16Ty());
431 SanCovTraceCmpFunction[2] =
433 IRB.getInt32Ty(), IRB.getInt32Ty());
434 SanCovTraceCmpFunction[3] =
437 SanCovTraceConstCmpFunction[0] =
M.getOrInsertFunction(
439 SanCovTraceConstCmpFunction[1] =
M.getOrInsertFunction(
441 SanCovTraceConstCmpFunction[2] =
M.getOrInsertFunction(
443 SanCovTraceConstCmpFunction[3] =
447 SanCovLoadFunction[0] =
M.getOrInsertFunction(
SanCovLoad1, VoidTy, Int8PtrTy);
448 SanCovLoadFunction[1] =
450 SanCovLoadFunction[2] =
452 SanCovLoadFunction[3] =
454 SanCovLoadFunction[4] =
457 SanCovStoreFunction[0] =
459 SanCovStoreFunction[1] =
461 SanCovStoreFunction[2] =
463 SanCovStoreFunction[3] =
465 SanCovStoreFunction[4] =
470 AL =
AL.addParamAttribute(*
C, 0, Attribute::ZExt);
471 SanCovTraceDivFunction[0] =
474 SanCovTraceDivFunction[1] =
476 SanCovTraceGepFunction =
478 SanCovTraceSwitchFunction =
481 Constant *SanCovLowestStackConstant =
483 SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
484 if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
486 "' should not be declared by the user");
489 SanCovLowestStack->setThreadLocalMode(
491 if (
Options.StackDepth && !SanCovLowestStack->isDeclaration())
499 instrumentFunction(
F, DTCallback, PDTCallback);
503 if (FunctionGuardArray)
507 if (Function8bitCounterArray)
511 if (FunctionBoolArray) {
521 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
524 if (Ctor &&
Options.CollectControlFlow) {
529 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
575 if (
Options.NoPrune || &
F.getEntryBlock() == BB)
579 &
F.getEntryBlock() != BB)
611 if (CMP->hasOneUse())
612 if (
auto BR = dyn_cast<BranchInst>(CMP->user_back()))
619void ModuleSanitizerCoverage::instrumentFunction(
620 Function &
F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
623 if (
F.getName().find(
".module_ctor") != std::string::npos)
625 if (
F.getName().startswith(
"__sanitizer_"))
632 if (
F.getName() ==
"__local_stdio_printf_options" ||
633 F.getName() ==
"__local_stdio_scanf_options")
635 if (isa<UnreachableInst>(
F.getEntryBlock().getTerminator()))
640 if (
F.hasPersonalityFn() &&
643 if (Allowlist && !Allowlist->inSection(
"coverage",
"fun",
F.getName()))
645 if (Blocklist && Blocklist->inSection(
"coverage",
"fun",
F.getName()))
647 if (
F.hasFnAttribute(Attribute::NoSanitizeCoverage))
662 bool IsLeafFunc =
true;
667 for (
auto &Inst : BB) {
669 CallBase *CB = dyn_cast<CallBase>(&Inst);
674 if (
ICmpInst *CMP = dyn_cast<ICmpInst>(&Inst))
677 if (isa<SwitchInst>(&Inst))
682 if (BO->getOpcode() == Instruction::SDiv ||
683 BO->getOpcode() == Instruction::UDiv)
689 if (
LoadInst *LI = dyn_cast<LoadInst>(&Inst))
692 if (
StoreInst *SI = dyn_cast<StoreInst>(&Inst))
695 if (isa<InvokeInst>(Inst) ||
696 (isa<CallInst>(Inst) && !isa<IntrinsicInst>(Inst)))
701 if (
Options.CollectControlFlow)
702 createFunctionControlFlow(
F);
704 InjectCoverage(
F, BlocksToInstrument, IsLeafFunc);
705 InjectCoverageForIndirectCalls(
F, IndirCalls);
706 InjectTraceForCmp(
F, CmpTraceTargets);
707 InjectTraceForSwitch(
F, SwitchTraceTargets);
708 InjectTraceForDiv(
F, DivTraceTargets);
709 InjectTraceForGep(
F, GepTraceTargets);
710 InjectTraceForLoadsAndStores(
F, Loads, Stores);
713GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
714 size_t NumElements,
Function &
F,
Type *Ty,
const char *Section) {
720 if (TargetTriple.supportsCOMDAT() &&
721 (TargetTriple.isOSBinFormatELF() || !
F.isInterposable()))
724 Array->setSection(getSectionName(Section));
725 Array->setAlignment(
Align(
DL->getTypeStoreSize(Ty).getFixedValue()));
736 if (
Array->hasComdat())
737 GlobalsToAppendToCompilerUsed.push_back(Array);
739 GlobalsToAppendToUsed.push_back(Array);
745ModuleSanitizerCoverage::CreatePCArray(
Function &
F,
747 size_t N = AllBlocks.
size();
750 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
751 for (
size_t i = 0; i <
N; i++) {
752 if (&
F.getEntryBlock() == AllBlocks[i]) {
762 auto *PCArray = CreateFunctionLocalArrayInSection(
N * 2,
F, IntptrPtrTy,
764 PCArray->setInitializer(
766 PCArray->setConstant(
true);
771void ModuleSanitizerCoverage::CreateFunctionLocalArrays(
774 FunctionGuardArray = CreateFunctionLocalArrayInSection(
777 if (
Options.Inline8bitCounters)
778 Function8bitCounterArray = CreateFunctionLocalArrayInSection(
781 FunctionBoolArray = CreateFunctionLocalArrayInSection(
785 FunctionPCsArray = CreatePCArray(
F, AllBlocks);
788bool ModuleSanitizerCoverage::InjectCoverage(
Function &
F,
791 if (AllBlocks.
empty())
return false;
792 CreateFunctionLocalArrays(
F, AllBlocks);
793 for (
size_t i = 0,
N = AllBlocks.
size(); i <
N; i++)
794 InjectCoverageAtBlock(
F, *AllBlocks[i], i, IsLeafFunc);
805void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
807 if (IndirCalls.
empty())
811 for (
auto *
I : IndirCalls) {
815 if (isa<InlineAsm>(
Callee))
817 IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(
Callee, IntptrTy));
825void ModuleSanitizerCoverage::InjectTraceForSwitch(
827 for (
auto *
I : SwitchTraceTargets) {
832 if (
Cond->getType()->getScalarSizeInBits() >
833 Int64Ty->getScalarSizeInBits())
838 if (
Cond->getType()->getScalarSizeInBits() <
839 Int64Ty->getScalarSizeInBits())
840 Cond = IRB.CreateIntCast(
Cond, Int64Ty,
false);
841 for (
auto It :
SI->cases()) {
843 if (
C->getType()->getScalarSizeInBits() <
844 Int64Ty->getScalarSizeInBits())
850 return cast<ConstantInt>(
A)->getLimitedValue() <
851 cast<ConstantInt>(
B)->getLimitedValue();
857 "__sancov_gen_cov_switch_values");
858 IRB.CreateCall(SanCovTraceSwitchFunction,
859 {
Cond, IRB.CreatePointerCast(GV, Int64PtrTy)});
864void ModuleSanitizerCoverage::InjectTraceForDiv(
866 for (
auto *BO : DivTraceTargets) {
868 Value *A1 = BO->getOperand(1);
869 if (isa<ConstantInt>(A1))
continue;
873 int CallbackIdx =
TypeSize == 32 ? 0 :
875 if (CallbackIdx < 0)
continue;
877 IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
878 {IRB.CreateIntCast(A1, Ty,
true)});
882void ModuleSanitizerCoverage::InjectTraceForGep(
884 for (
auto *
GEP : GepTraceTargets) {
887 if (!isa<ConstantInt>(
Idx) &&
Idx->getType()->isIntegerTy())
888 IRB.CreateCall(SanCovTraceGepFunction,
889 {IRB.CreateIntCast(
Idx, IntptrTy,
true)});
893void ModuleSanitizerCoverage::InjectTraceForLoadsAndStores(
895 auto CallbackIdx = [&](
Type *ElementTy) ->
int {
906 for (
auto *LI : Loads) {
908 auto Ptr = LI->getPointerOperand();
909 int Idx = CallbackIdx(LI->getType());
912 IRB.CreateCall(SanCovLoadFunction[
Idx],
915 for (
auto *SI : Stores) {
917 auto Ptr =
SI->getPointerOperand();
918 int Idx = CallbackIdx(
SI->getValueOperand()->getType());
921 IRB.CreateCall(SanCovStoreFunction[
Idx],
926void ModuleSanitizerCoverage::InjectTraceForCmp(
928 for (
auto *
I : CmpTraceTargets) {
929 if (
ICmpInst *ICMP = dyn_cast<ICmpInst>(
I)) {
936 int CallbackIdx =
TypeSize == 8 ? 0 :
940 if (CallbackIdx < 0)
continue;
942 auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx];
943 bool FirstIsConst = isa<ConstantInt>(A0);
944 bool SecondIsConst = isa<ConstantInt>(A1);
946 if (FirstIsConst && SecondIsConst)
continue;
948 if (FirstIsConst || SecondIsConst) {
949 CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx];
955 IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty,
true),
956 IRB.CreateIntCast(A1, Ty,
true)});
965 bool IsEntryBB = &BB == &
F.getEntryBlock();
968 if (
auto SP =
F.getSubprogram())
969 EntryLoc =
DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
978 IRB.SetCurrentDebugLocation(EntryLoc);
980 IRB.CreateCall(SanCovTracePC)
984 auto GuardPtr = IRB.CreateIntToPtr(
985 IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
988 IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
990 if (
Options.Inline8bitCounters) {
991 auto CounterPtr = IRB.CreateGEP(
992 Function8bitCounterArray->getValueType(), Function8bitCounterArray,
993 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
994 auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
996 auto Store = IRB.CreateStore(Inc, CounterPtr);
997 SetNoSanitizeMetadata(Load);
998 SetNoSanitizeMetadata(Store);
1001 auto FlagPtr = IRB.CreateGEP(
1002 FunctionBoolArray->getValueType(), FunctionBoolArray,
1003 {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
1004 auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
1009 SetNoSanitizeMetadata(Load);
1010 SetNoSanitizeMetadata(Store);
1012 if (
Options.StackDepth && IsEntryBB && !IsLeafFunc) {
1016 M, Intrinsic::frameaddress,
1017 IRB.getInt8PtrTy(
M->getDataLayout().getAllocaAddrSpace()));
1020 auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
1021 auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
1022 auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
1025 auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
1026 SetNoSanitizeMetadata(LowestStack);
1027 SetNoSanitizeMetadata(Store);
1032ModuleSanitizerCoverage::getSectionName(
const std::string &Section)
const {
1033 if (TargetTriple.isOSBinFormatCOFF()) {
1042 if (TargetTriple.isOSBinFormatMachO())
1048ModuleSanitizerCoverage::getSectionStart(
const std::string &Section)
const {
1049 if (TargetTriple.isOSBinFormatMachO())
1050 return "\1section$start$__DATA$__" +
Section;
1051 return "__start___" +
Section;
1055ModuleSanitizerCoverage::getSectionEnd(
const std::string &Section)
const {
1056 if (TargetTriple.isOSBinFormatMachO())
1057 return "\1section$end$__DATA$__" +
Section;
1061void ModuleSanitizerCoverage::createFunctionControlFlow(
Function &
F) {
1063 IRBuilder<> IRB(&*
F.getEntryBlock().getFirstInsertionPt());
1065 for (
auto &BB :
F) {
1067 if (&BB == &
F.getEntryBlock())
1074 assert(SuccBB != &
F.getEntryBlock());
1081 for (
auto &Inst : BB) {
1082 if (
CallBase *CB = dyn_cast<CallBase>(&Inst)) {
1089 if (CalledF && !CalledF->isIntrinsic())
1091 (
Constant *)IRB.CreatePointerCast(CalledF, IntptrPtrTy));
1099 FunctionCFsArray = CreateFunctionLocalArrayInSection(
1101 FunctionCFsArray->setInitializer(
1103 FunctionCFsArray->setConstant(
true);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This header is deprecated in favour of llvm/TargetParser/Triple.h.
amdgpu Simplify well known AMD library false FunctionCallee Callee
SmallVector< MachineOperand, 4 > Cond
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
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)
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
static ConstantInt * getTrue(LLVMContext &Context)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
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)
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, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, 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