19#include "llvm/Config/llvm-config.h"
33#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
41#define DEBUG_TYPE "debugify"
50 cl::desc(
"Suppress verbose debugify output"));
53 "debugify-func-limit",
54 cl::desc(
"Set max number of processed functions per pass."),
63 "debugify-level",
cl::desc(
"Kind of debug info to add"),
65 clEnumValN(Level::LocationsAndVariables,
"location+variables",
66 "Locations and Variables")),
67 cl::init(Level::LocationsAndVariables));
71#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
73 "enable-origin-stacktraces",
74 cl::desc(
"Collect DebugLoc origin stacktraces; a comma-separated list of "
75 "passes may be given, in which case stacktraces will be collected "
76 "in those passes only"),
84 llvm::DebugLocOriginCollectionEnabled =
false;
87 if (EnableOriginStacktraces.
size() == 1 &&
88 EnableOriginStacktraces[0].
empty()) {
89 llvm::DebugLocOriginCollectionEnabled =
true;
92 llvm::DebugLocOriginCollectionEnabled =
95static void unsetDebugLocOriginCollection() {
96 llvm::DebugLocOriginCollectionEnabled =
false;
101static SymbolizedAddressMap SymbolizedAddrs;
102static AddressSet UnsymbolizedAddrs;
107 if (!UnsymbolizedAddrs.empty()) {
108 sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
109 UnsymbolizedAddrs.clear();
111 const DbgLocOrigin::StackTracesTy &OriginStackTraces =
112 I->getDebugLoc().getOriginStackTraces();
115 for (
size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
117 OS <<
"========================================\n";
118 auto &[
Depth, StackTrace] = OriginStackTraces[TraceIdx];
119 unsigned VirtualFrameNo = 0;
120 for (
int Frame = 0; Frame <
Depth; ++Frame) {
121 assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
122 "Expected each address to have been symbolized.");
123 for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
125 std::log10(
Depth) + 2)
126 <<
' ' << SymbolizedFrame <<
'\n';
133 auto &OriginStackTraces =
I.getDebugLoc().getOriginStackTraces();
134 for (
auto &[
Depth, StackTrace] : OriginStackTraces) {
135 for (
int Frame = 0; Frame <
Depth; ++Frame) {
136 void *Addr = StackTrace[Frame];
137 if (!SymbolizedAddrs.contains(Addr))
138 UnsymbolizedAddrs.insert(Addr);
146static void unsetDebugLocOriginCollection() {}
149 "enable-origin-stacktraces",
150 cl::desc(
"Collect DebugLoc origin stacktraces; requires "
151 "LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING=COVERAGE_AND_ORIGIN"),
155 "without LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING="
156 "COVERAGE_AND_ORIGIN\n";
163 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
167 return F.isDeclaration() || !
F.hasExactDefinition();
187 if (M.getNamedMetadata(
"llvm.dbg.cu")) {
188 dbg() << Banner <<
"Skipping module with debug info\n";
198 auto getCachedDIType = [&](
Type *Ty) ->
DIType * {
208 unsigned NextLine = 1;
209 unsigned NextVar = 1;
212 "debugify",
true,
"", 0);
216 if (isFunctionSkipped(
F))
219 bool InsertedDbgVal =
false;
222 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
223 if (
F.hasPrivateLinkage() ||
F.hasInternalLinkage())
224 SPFlags |= DISubprogram::SPFlagLocalToUnit;
226 SPType, NextLine, DINode::FlagZero, SPFlags,
227 nullptr,
nullptr,
nullptr,
nullptr,
"",
236 Value *V = &TemplateInst;
238 V = ConstantInt::get(Int32Ty, 0);
241 getCachedDIType(V->getType()),
250 uint64_t AtomGroup = ApplyAtomGroups ? NextLine : 0;
251 uint8_t AtomRank = ApplyAtomGroups ? 1 : 0;
254 AtomGroup, AtomRank));
257 if (DebugifyLevel < Level::LocationsAndVariables)
266 Instruction *LastInst = findTerminatingInstruction(BB);
267 assert(LastInst &&
"Expected basic block with a terminator");
272 assert(InsertPt != BB.end() &&
"Expected to find an insertion point");
275 InsertPt.setHeadBit(
false);
278 for (
Instruction *
I = &*BB.begin();
I != LastInst;
I =
I->getNextNode()) {
280 if (
I->getType()->isVoidTy())
286 InsertPt = std::next(
I->getIterator());
288 insertDbgVal(*
I, InsertPt);
289 InsertedDbgVal =
true;
297 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
298 auto *
Term = findTerminatingInstruction(
F.getEntryBlock());
299 insertDbgVal(*Term,
Term->getIterator());
307 NamedMDNode *NMD = M.getOrInsertNamedMetadata(
"llvm.debugify");
308 auto addDebugifyOperand = [&](
unsigned N) {
312 addDebugifyOperand(NextLine - 1);
313 addDebugifyOperand(NextVar - 1);
315 "llvm.debugify should have exactly 2 operands!");
318 StringRef DIVersionKey =
"Debug Info Version";
319 if (!M.getModuleFlag(DIVersionKey))
328 setDebugLocOriginCollectionForPass(NameOfWrappedPass);
330 auto FuncIt =
F.getIterator();
333 "FunctionDebugify: ",
nullptr);
334 assert(DebugInfoBeforePass &&
"Missing debug info metadata");
336 "FunctionDebugify (original debuginfo)",
343 setDebugLocOriginCollectionForPass(NameOfWrappedPass);
346 "ModuleDebugify: ",
nullptr);
347 assert(DebugInfoBeforePass &&
"Missing debug info metadata");
349 "ModuleDebugify (original debuginfo)",
357 NamedMDNode *DebugifyMD = M.getNamedMetadata(
"llvm.debugify");
359 M.eraseNamedMetadata(DebugifyMD);
363 if (
auto *MIRDebugifyMD = M.getNamedMetadata(
"llvm.mir.debugify")) {
364 M.eraseNamedMetadata(MIRDebugifyMD);
376 "Not all debug info stripped?");
388 for (
MDNode *Flag : Flags) {
390 if (
Key->getString() ==
"Debug Info Version") {
405#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
406 DebugLocKind Kind =
I.getDebugLoc().getKind();
407 return Loc || Kind != DebugLocKind::Normal;
418 LLVM_DEBUG(
dbgs() << Banner <<
": (before) " << NameOfWrappedPass <<
'\n');
420 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
421 dbg() << Banner <<
": Skipping module without debug info\n";
432 if (isFunctionSkipped(
F))
436 if (++FunctionsCnt >= DebugifyFunctionsLimit)
439 auto *SP =
F.getSubprogram();
443 for (
const MDNode *DN : SP->getRetainedNodes()) {
449 if (DebugifyLevel > Level::Locations) {
460 if (DbgVar->getDebugLoc().getInlinedAt())
463 if (DbgVar->isKillLocation())
466 auto *Var = DbgVar->getVariable();
470 HandleDbgVariable(&DVR);
483 StringRef FileNameFromCU,
bool ShouldWriteIntoJSON,
485 bool Preserved =
true;
486 for (
const auto &
F : DIFunctionsAfter) {
489 auto SPIt = DIFunctionsBefore.
find(
F.first);
490 if (SPIt == DIFunctionsBefore.
end()) {
491 if (ShouldWriteIntoJSON)
493 {
"name",
F.first->getName()},
494 {
"action",
"not-generate"}}));
496 dbg() <<
"ERROR: " << NameOfWrappedPass
497 <<
" did not generate DISubprogram for " <<
F.first->getName()
498 <<
" from " << FileNameFromCU <<
'\n';
501 auto SP = SPIt->second;
506 if (ShouldWriteIntoJSON)
508 {
"name",
F.first->getName()},
509 {
"action",
"drop"}}));
511 dbg() <<
"ERROR: " << NameOfWrappedPass <<
" dropped DISubprogram of "
512 <<
F.first->getName() <<
" from " << FileNameFromCU <<
'\n';
523 bool ShouldWriteIntoJSON,
529 collectStackAddresses(
I);
530 auto FnName = Instr->getFunction()->getName();
531 auto BB = Instr->getParent();
532 auto BBName = BB->hasName() ? BB->getName() :
"no-name";
535 auto CreateJSONBugEntry = [&](
const char *Action) {
537 {
"metadata",
"DILocation"},
538 {
"fn-name", FnName.str()},
539 {
"bb-name", BBName.str()},
543#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
544 if (!Instr->getDebugLoc().getOriginStackTraces().empty())
545 BugEntry.
insert({
"origin", symbolizeStackTrace(Instr)});
550 if (ShouldWriteIntoJSON)
551 CreateJSONBugEntry(
"not-generate");
553 dbg() <<
"WARNING: " << NameOfWrappedPass
554 <<
" did not generate DILocation for " << *Instr <<
" (BB: " << BBName
555 <<
", Fn: " << FnName <<
", File: " << FileNameFromCU <<
")\n";
564 bool Preserved =
true;
565 for (
const auto &V : DIVarsBefore) {
566 auto VarIt = DIVarsAfter.
find(V.first);
567 if (VarIt == DIVarsAfter.
end())
570 unsigned NumOfDbgValsAfter = VarIt->second;
572 if (V.second > NumOfDbgValsAfter) {
573 if (ShouldWriteIntoJSON)
575 {{
"metadata",
"dbg-var-intrinsic"},
576 {
"name", V.first->getName()},
577 {
"fn-name", V.first->getScope()->getSubprogram()->getName()},
578 {
"action",
"drop"}}));
580 dbg() <<
"WARNING: " << NameOfWrappedPass
581 <<
" drops dbg.value()/dbg.declare() for " << V.first->getName()
583 <<
"function " << V.first->getScope()->getSubprogram()->getName()
584 <<
" (file " << FileNameFromCU <<
")\n";
600 errs() <<
"Could not open file: " << EC.message() <<
", "
601 << OrigDIVerifyBugsReportFilePath <<
'\n';
605 if (
auto L = OS_FILE.
lock()) {
606 OS_FILE <<
"{\"file\":\"" << FileNameFromCU <<
"\", ";
609 NameOfWrappedPass !=
"" ? NameOfWrappedPass :
"no-name";
610 OS_FILE <<
"\"pass\":\"" <<
PassName <<
"\", ";
613 OS_FILE <<
"\"bugs\": " << BugsToPrint;
624 StringRef OrigDIVerifyBugsReportFilePath) {
625 LLVM_DEBUG(
dbgs() << Banner <<
": (after) " << NameOfWrappedPass <<
'\n');
626 unsetDebugLocOriginCollection();
628 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
629 dbg() << Banner <<
": Skipping module without debug info\n";
636 bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.
empty();
644 bool ResultForInsts =
true;
648 if (isFunctionSkipped(
F))
656 auto *SP =
F.getSubprogram();
661 for (
const MDNode *DN : SP->getRetainedNodes()) {
676 if (DebugifyLevel > Level::Locations) {
681 if (DbgVar->getDebugLoc().getInlinedAt())
684 if (DbgVar->isKillLocation())
687 auto *Var = DbgVar->getVariable();
691 HandleDbgVariable(&DVR);
698 I, NameOfWrappedPass, FileNameFromCU, ShouldWriteIntoJSON, Bugs);
701 ResultForInsts &= InstResult;
706 auto DIFunctionsBefore = DebugInfoBeforePass.
DIFunctions;
707 auto DIFunctionsAfter = DebugInfoAfterPass.
DIFunctions;
711 auto DIVarsBefore = DebugInfoBeforePass.
DIVariables;
715 checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
716 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
718 bool ResultForVars =
checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass,
719 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
721 bool Result = ResultForFunc && ResultForInsts && ResultForVars;
723 StringRef ResultBanner = NameOfWrappedPass !=
"" ? NameOfWrappedPass : Banner;
724 if (ShouldWriteIntoJSON && !Bugs.
empty())
725 writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass,
729 dbg() << ResultBanner <<
": PASS\n";
731 dbg() << ResultBanner <<
": FAIL\n";
736 DebugInfoBeforePass = DebugInfoAfterPass;
744template <
typename DbgValTy>
745bool diagnoseMisSizedDbgValue(
Module &M, DbgValTy *DbgVal) {
754 if (DbgVal->getExpression()->getNumElements())
757 Value *V = DbgVal->getVariableLocationOp(0);
761 Type *Ty = V->getType();
762 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
763 std::optional<uint64_t> DbgVarSize = DbgVal->getFragmentSizeInBits();
764 if (!ValueOperandSize || !DbgVarSize)
767 bool HasBadSize =
false;
768 if (Ty->isIntegerTy()) {
769 auto Signedness = DbgVal->getVariable()->getSignedness();
771 HasBadSize = ValueOperandSize < *DbgVarSize;
773 HasBadSize = ValueOperandSize != *DbgVarSize;
777 dbg() <<
"ERROR: dbg.value operand has size " << ValueOperandSize
778 <<
", but its variable has size " << *DbgVarSize <<
": ";
779 DbgVal->print(dbg());
785bool checkDebugifyMetadata(
Module &M,
790 NamedMDNode *NMD = M.getNamedMetadata(
"llvm.debugify");
791 unsetDebugLocOriginCollection();
793 dbg() << Banner <<
": Skipping module without debugify metadata\n";
797 auto getDebugifyOperand = [&](
unsigned Idx) ->
unsigned {
802 "llvm.debugify should have exactly 2 operands!");
803 unsigned OriginalNumLines = getDebugifyOperand(0);
804 unsigned OriginalNumVars = getDebugifyOperand(1);
805 bool HasErrors =
false;
809 if (StatsMap && !NameOfWrappedPass.
empty())
810 Stats = &StatsMap->operator[](NameOfWrappedPass);
812 BitVector MissingLines{OriginalNumLines,
true};
813 BitVector MissingVars{OriginalNumVars,
true};
815 if (isFunctionSkipped(
F))
820 auto DL =
I.getDebugLoc();
821 if (
DL &&
DL.getLine() != 0) {
822 MissingLines.
reset(
DL.getLine() - 1);
827 dbg() <<
"WARNING: Instruction with empty DebugLoc in function ";
828 dbg() <<
F.getName() <<
" --";
835 auto CheckForMisSized = [&](
auto *DbgVal) {
837 (void)
to_integer(DbgVal->getVariable()->getName(), Var, 10);
838 assert(Var <= OriginalNumVars &&
"Unexpected name for DILocalVariable");
839 bool HasBadSize = diagnoseMisSizedDbgValue(M, DbgVal);
841 MissingVars.
reset(Var - 1);
842 HasErrors |= HasBadSize;
846 if (DVR.isDbgValue() || DVR.isDbgAssign())
847 CheckForMisSized(&DVR);
852 for (
unsigned Idx : MissingLines.
set_bits())
853 dbg() <<
"WARNING: Missing line " << Idx + 1 <<
"\n";
855 for (
unsigned Idx : MissingVars.
set_bits())
856 dbg() <<
"WARNING: Missing variable " << Idx + 1 <<
"\n";
860 Stats->NumDbgLocsExpected += OriginalNumLines;
861 Stats->NumDbgLocsMissing += MissingLines.
count();
862 Stats->NumDbgValuesExpected += OriginalNumVars;
863 Stats->NumDbgValuesMissing += MissingVars.
count();
867 if (!NameOfWrappedPass.
empty())
868 dbg() <<
" [" << NameOfWrappedPass <<
"]";
869 dbg() <<
": " << (HasErrors ?
"FAIL" :
"PASS") <<
'\n';
881struct DebugifyModulePass :
public ModulePass {
882 bool runOnModule(
Module &M)
override {
884 applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass);
889 StringRef NameOfWrappedPass =
"",
890 DebugInfoPerPass *DebugInfoBeforePass =
nullptr)
891 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
892 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
894 void getAnalysisUsage(AnalysisUsage &AU)
const override {
901 StringRef NameOfWrappedPass;
902 DebugInfoPerPass *DebugInfoBeforePass;
915 DebugifyFunctionPass(
917 StringRef NameOfWrappedPass =
"",
918 DebugInfoPerPass *DebugInfoBeforePass =
nullptr)
919 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
920 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
922 void getAnalysisUsage(AnalysisUsage &AU)
const override {
929 StringRef NameOfWrappedPass;
930 DebugInfoPerPass *DebugInfoBeforePass;
936struct CheckDebugifyModulePass :
public ModulePass {
937 bool runOnModule(
Module &M)
override {
940 Result = checkDebugifyMetadata(M,
M.functions(), NameOfWrappedPass,
941 "CheckModuleDebugify", Strip, StatsMap);
944 M,
M.functions(), *DebugInfoBeforePass,
945 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
946 OrigDIVerifyBugsReportFilePath);
951 CheckDebugifyModulePass(
952 bool Strip =
false, StringRef NameOfWrappedPass =
"",
955 DebugInfoPerPass *DebugInfoBeforePass =
nullptr,
956 StringRef OrigDIVerifyBugsReportFilePath =
"")
957 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
958 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
959 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
962 void getAnalysisUsage(AnalysisUsage &AU)
const override {
969 StringRef NameOfWrappedPass;
970 StringRef OrigDIVerifyBugsReportFilePath;
972 DebugInfoPerPass *DebugInfoBeforePass;
982 auto FuncIt =
F.getIterator();
986 NameOfWrappedPass,
"CheckFunctionDebugify",
990 M,
make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
991 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
992 OrigDIVerifyBugsReportFilePath);
997 CheckDebugifyFunctionPass(
998 bool Strip =
false, StringRef NameOfWrappedPass =
"",
1001 DebugInfoPerPass *DebugInfoBeforePass =
nullptr,
1002 StringRef OrigDIVerifyBugsReportFilePath =
"")
1003 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
1004 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
1005 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
1008 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1015 StringRef NameOfWrappedPass;
1016 StringRef OrigDIVerifyBugsReportFilePath;
1018 DebugInfoPerPass *DebugInfoBeforePass;
1029 errs() <<
"Could not open file: " << EC.message() <<
", " << Path <<
'\n';
1033 OS <<
"Pass Name" <<
',' <<
"# of missing debug values" <<
','
1034 <<
"# of missing locations" <<
',' <<
"Missing/Expected value ratio" <<
','
1035 <<
"Missing/Expected location ratio" <<
'\n';
1036 for (
const auto &Entry : Map) {
1040 OS <<
Pass <<
',' <<
Stats.NumDbgValuesMissing <<
','
1041 <<
Stats.NumDbgLocsMissing <<
',' <<
Stats.getMissingValueRatio() <<
','
1042 <<
Stats.getEmptyLocationRatio() <<
'\n';
1050 return new DebugifyModulePass();
1052 return new DebugifyModulePass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
1060 return new DebugifyFunctionPass();
1062 return new DebugifyFunctionPass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
1069 return ApplyToMF(DIB,
F, AM);
1072 "ModuleDebugify: ", ApplyToMFWrapper);
1078 "ModuleDebugify (original debuginfo)",
1092 StringRef OrigDIVerifyBugsReportFilePath) {
1094 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
1096 return new CheckDebugifyModulePass(
false, NameOfWrappedPass,
nullptr,
Mode,
1097 DebugInfoBeforePass,
1098 OrigDIVerifyBugsReportFilePath);
1104 StringRef OrigDIVerifyBugsReportFilePath) {
1106 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
1108 return new CheckDebugifyFunctionPass(
false, NameOfWrappedPass,
nullptr,
Mode,
1109 DebugInfoBeforePass,
1110 OrigDIVerifyBugsReportFilePath);
1116 checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
1117 "CheckModuleDebugify", Strip, StatsMap);
1120 M, M.functions(), *DebugInfoBeforePass,
1121 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
1122 OrigDIVerifyBugsReportFilePath);
1129 "AnalysisManagerProxy",
"PrintFunctionPass",
1130 "PrintModulePass",
"BitcodeWriterPass",
1131 "ThinLTOBitcodeWriterPass",
"VerifierPass"});
1150 MAM.invalidate(M, PA);
1153 PIC.registerAfterPassCallback(
1162 auto It =
F.getIterator();
1164 checkDebugifyMetadata(M,
make_range(It, std::next(It)),
P,
1165 "CheckFunctionDebugify",
true,
1169 *DebugInfoBeforePass,
1170 "CheckModuleDebugify (original debuginfo)",
1171 P, OrigDIVerifyBugsReportFilePath);
1178 checkDebugifyMetadata(M, M.functions(),
P,
"CheckModuleDebugify",
1182 "CheckModuleDebugify (original debuginfo)",
1183 P, OrigDIVerifyBugsReportFilePath);
1184 MAM.invalidate(M, PA);
1189char DebugifyModulePass::ID = 0;
1191 "Attach debug info to everything");
1193char CheckDebugifyModulePass::ID = 0;
1195 CDM(
"check-debugify",
"Check debug info from -debugify");
1197char DebugifyFunctionPass::ID = 0;
1199 "Attach debug info to a function");
1201char CheckDebugifyFunctionPass::ID = 0;
1203 CDF(
"check-debugify-function",
"Check debug info from -debugify-function");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
This file implements the BitVector class.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static RegisterPass< CheckDebugifyModulePass > CDM("check-debugify", "Check debug info from -debugify")
ModulePass * createDebugifyModulePass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
bool hasLoc(const Instruction &I)
FunctionPass * createDebugifyFunctionPass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
static bool isIgnoredPass(StringRef PassID)
static bool applyDebugify(Function &F, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef NameOfWrappedPass="")
static bool checkInstructionCoverage(Instruction &I, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
ModulePass * createCheckDebugifyModulePass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath, StringRef FileNameFromCU, StringRef NameOfWrappedPass, llvm::json::Array &Bugs)
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
static bool checkFunctions(const DebugFnMap &DIFunctionsBefore, const DebugFnMap &DIFunctionsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
static RegisterPass< CheckDebugifyFunctionPass > CDF("check-debugify-function", "Check debug info from -debugify-function")
FunctionPass * createCheckDebugifyFunctionPass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
static bool checkVars(const DebugVarMap &DIVarsBefore, const DebugVarMap &DIVarsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
DebugifyMode
Used to check whether we track synthetic or original debug info.
llvm::MapVector< const llvm::Function *, const llvm::DISubprogram * > DebugFnMap
llvm::MapVector< llvm::StringRef, DebugifyStatistics > DebugifyStatsMap
Map pass names to a per-pass DebugifyStatistics instance.
llvm::MapVector< const llvm::DILocalVariable *, unsigned > DebugVarMap
static bool runOnFunction(Function &F, bool PostInlining)
static SmallString< 128 > getFilename(const DIScope *SP, vfs::FileSystem &VFS)
Extract a filename for a DIScope.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
Legalize the Machine IR a function s Machine IR
block placement Basic Block Placement Stats
Machine Check Debug Module
ModuleAnalysisManager MAM
PassInstrumentationCallbacks PIC
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static const char PassName[]
LLVM_ABI llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
LLVM_ABI llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
LLVM_ABI const CallInst * getTerminatingDeoptimizeCall() const
Returns the call instruction calling @llvm.experimental.deoptimize prior to the terminating return in...
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI const CallInst * getTerminatingMustTailCall() const
Returns the call instruction marked 'musttail' prior to the terminating return instruction of this ba...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BitVector & reset()
Reset all bits in the bitvector.
size_type count() const
Returns the number of bits which are set.
iterator_range< const_set_bits_iterator > set_bits() const
Represents analyses that only rely on functions' control flow.
LLVM_ABI void finalize()
Construct any deferred debug info descriptors.
LLVM_ABI DISubroutineType * createSubroutineType(DITypeArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
LLVM_ABI DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags=DINode::FlagZero, DISubprogram::DISPFlags SPFlags=DISubprogram::SPFlagZero, DITemplateParameterArray TParams=nullptr, DISubprogram *Decl=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName="", bool UseKeyInstructions=false)
Create a new descriptor for the specified subprogram.
LLVM_ABI DbgInstPtr insertDbgValueIntrinsic(llvm::Value *Val, DILocalVariable *VarInfo, DIExpression *Expr, const DILocation *DL, InsertPosition InsertPt)
Insert a new llvm.dbg.value intrinsic call.
LLVM_ABI DITypeArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeArray, create one if required.
LLVM_ABI DIBasicType * createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, DINode::DIFlags Flags=DINode::FlagZero, uint32_t NumExtraInhabitants=0, uint32_t DataSizeInBits=0)
Create debugging information entry for a basic type.
LLVM_ABI DICompileUnit * createCompileUnit(DISourceLanguageName Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, StringRef SplitName=StringRef(), DICompileUnit::DebugEmissionKind Kind=DICompileUnit::DebugEmissionKind::FullDebug, uint64_t DWOId=0, bool SplitDebugInlining=true, bool DebugInfoForProfiling=false, DICompileUnit::DebugNameTableKind NameTableKind=DICompileUnit::DebugNameTableKind::Default, bool RangesBaseAddress=false, StringRef SysRoot={}, StringRef SDK={})
A CompileUnit provides an anchor for all debugging information generated during this instance of comp...
LLVM_ABI DIExpression * createExpression(ArrayRef< uint64_t > Addr={})
Create a new descriptor for the specified variable which has a complex address expression for its add...
LLVM_ABI DILocalVariable * createAutoVariable(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve=false, DINode::DIFlags Flags=DINode::FlagZero, uint32_t AlignInBits=0)
Create a new descriptor for an auto variable.
LLVM_ABI DIFile * createFile(StringRef Filename, StringRef Directory, std::optional< DIFile::ChecksumInfo< StringRef > > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt)
Create a file descriptor to hold debugging information for a file.
Wrapper structure that holds source language identity metadata that includes language name,...
DISPFlags
Debug info subprogram flags.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
DILocation * get() const
Get the underlying DILocation.
static DebugLoc getUnknown()
LLVM_ABI void registerCallbacks(PassInstrumentationCallbacks &PIC, ModuleAnalysisManager &MAM)
FunctionPass class - This class is used to implement most global optimizations.
const Function & getFunction() const
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const char * getOpcodeName() const
This is an important class for using LLVM in a threaded context.
const MDOperand & getOperand(unsigned I) const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
size_type count(const KeyT &Key) const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
@ Warning
Emits a warning if two values disagree.
LLVM_ABI void eraseFromParent()
Drop all references and remove the node from parent module.
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
LLVM_ABI void clearOperands()
Drop all references to this node's operands.
iterator_range< op_iterator > operands()
LLVM_ABI void addOperand(MDNode *M)
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
Pass interface - Implemented by all 'passes'.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
int getNumOccurrences() const
A range adaptor for a pair of iterators.
An Array is a JSON array, which contains heterogeneous JSON values.
void push_back(const Value &E)
An Object is a JSON object, which maps strings to heterogenous JSON values.
std::pair< iterator, bool > insert(KV E)
A Value is an JSON value of unknown type.
A raw_ostream that writes to a file descriptor.
void close()
Manually flush the stream and close the file.
Expected< sys::fs::FileLocker > lock()
Locks the underlying file.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
@ OF_Append
The file should be opened in append mode.
This is an optimization pass for GlobalISel generic memory operations.
T any_cast(const Any &Value)
FormattedString right_justify(StringRef Str, unsigned Width)
right_justify - add spaces before string so total output is Width characters.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI bool stripDebugifyMetadata(Module &M)
Strip out all of the metadata and debug info inserted by debugify.
LLVM_ABI void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map)
LLVM_ABI bool applyDebugifyMetadata(Module &M, iterator_range< Module::iterator > Functions, StringRef Banner, std::function< bool(DIBuilder &, Function &)> ApplyToMF)
Add synthesized debug information to a module.
LLVM_ABI bool collectDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass)
Collect original debug information before a pass.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI bool checkDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass, StringRef OrigDIVerifyBugsReportFilePath)
Check original debug information after a pass.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
LLVM_ABI raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool to_integer(StringRef S, N &Num, unsigned Base=0)
Convert the string S to an integer of the specified type using the radix Base. If Base is 0,...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Used to track the Debug Info Metadata information.
WeakInstValueMap InstToDelete
Track how much debugify information (in the synthetic mode only) has been lost.
RegisterPass<t> template - This template class is used to notify the system that a Pass is available ...