19#include "llvm/Config/llvm-config.h"
32#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
38#define DEBUG_TYPE "debugify"
47 cl::desc(
"Suppress verbose debugify output"));
50 "debugify-func-limit",
51 cl::desc(
"Set max number of processed functions per pass."),
60 "debugify-level",
cl::desc(
"Kind of debug info to add"),
62 clEnumValN(Level::LocationsAndVariables,
"location+variables",
63 "Locations and Variables")),
64 cl::init(Level::LocationsAndVariables));
68#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
71static SymbolizedAddressMap SymbolizedAddrs;
72static AddressSet UnsymbolizedAddrs;
77 if (!UnsymbolizedAddrs.empty()) {
78 sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
79 UnsymbolizedAddrs.clear();
81 const DbgLocOrigin::StackTracesTy &OriginStackTraces =
82 I->getDebugLoc().getOriginStackTraces();
85 for (
size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
87 OS <<
"========================================\n";
88 auto &[
Depth, StackTrace] = OriginStackTraces[TraceIdx];
89 unsigned VirtualFrameNo = 0;
90 for (
int Frame = 0; Frame <
Depth; ++Frame) {
91 assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
92 "Expected each address to have been symbolized.");
93 for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
95 std::log10(
Depth) + 2)
96 <<
' ' << SymbolizedFrame <<
'\n';
103 auto &OriginStackTraces =
I.getDebugLoc().getOriginStackTraces();
104 for (
auto &[
Depth, StackTrace] : OriginStackTraces) {
105 for (
int Frame = 0; Frame <
Depth; ++Frame) {
106 void *Addr = StackTrace[Frame];
107 if (!SymbolizedAddrs.contains(Addr))
108 UnsymbolizedAddrs.insert(Addr);
117 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
121 return F.isDeclaration() || !
F.hasExactDefinition();
141 if (M.getNamedMetadata(
"llvm.dbg.cu")) {
142 dbg() << Banner <<
"Skipping module with debug info\n";
152 auto getCachedDIType = [&](
Type *Ty) ->
DIType * {
162 unsigned NextLine = 1;
163 unsigned NextVar = 1;
170 if (isFunctionSkipped(
F))
173 bool InsertedDbgVal =
false;
176 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
177 if (
F.hasPrivateLinkage() ||
F.hasInternalLinkage())
178 SPFlags |= DISubprogram::SPFlagLocalToUnit;
180 SPType, NextLine, DINode::FlagZero, SPFlags,
181 nullptr,
nullptr,
nullptr,
nullptr,
"",
190 Value *V = &TemplateInst;
192 V = ConstantInt::get(
Int32Ty, 0);
195 getCachedDIType(V->getType()),
204 uint64_t AtomGroup = ApplyAtomGroups ? NextLine : 0;
205 uint8_t AtomRank = ApplyAtomGroups ? 1 : 0;
208 AtomGroup, AtomRank));
211 if (DebugifyLevel < Level::LocationsAndVariables)
220 Instruction *LastInst = findTerminatingInstruction(BB);
221 assert(LastInst &&
"Expected basic block with a terminator");
226 assert(InsertPt != BB.end() &&
"Expected to find an insertion point");
229 InsertPt.setHeadBit(
false);
232 for (
Instruction *
I = &*BB.begin();
I != LastInst;
I =
I->getNextNode()) {
234 if (
I->getType()->isVoidTy())
240 InsertPt = std::next(
I->getIterator());
242 insertDbgVal(*
I, InsertPt);
243 InsertedDbgVal =
true;
251 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
252 auto *
Term = findTerminatingInstruction(
F.getEntryBlock());
253 insertDbgVal(*Term,
Term->getIterator());
261 NamedMDNode *NMD = M.getOrInsertNamedMetadata(
"llvm.debugify");
262 auto addDebugifyOperand = [&](
unsigned N) {
266 addDebugifyOperand(NextLine - 1);
267 addDebugifyOperand(NextVar - 1);
269 "llvm.debugify should have exactly 2 operands!");
272 StringRef DIVersionKey =
"Debug Info Version";
273 if (!M.getModuleFlag(DIVersionKey))
283 auto FuncIt =
F.getIterator();
286 "FunctionDebugify: ",
nullptr);
287 assert(DebugInfoBeforePass &&
"Missing debug info metadata");
289 "FunctionDebugify (original debuginfo)",
298 "ModuleDebugify: ",
nullptr);
299 assert(DebugInfoBeforePass &&
"Missing debug info metadata");
301 "ModuleDebugify (original debuginfo)",
309 NamedMDNode *DebugifyMD = M.getNamedMetadata(
"llvm.debugify");
311 M.eraseNamedMetadata(DebugifyMD);
315 if (
auto *MIRDebugifyMD = M.getNamedMetadata(
"llvm.mir.debugify")) {
316 M.eraseNamedMetadata(MIRDebugifyMD);
328 "Not all debug info stripped?");
340 for (
MDNode *Flag : Flags) {
342 if (
Key->getString() ==
"Debug Info Version") {
357#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
358 DebugLocKind Kind =
I.getDebugLoc().getKind();
359 return Loc || Kind != DebugLocKind::Normal;
370 LLVM_DEBUG(
dbgs() << Banner <<
": (before) " << NameOfWrappedPass <<
'\n');
372 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
373 dbg() << Banner <<
": Skipping module without debug info\n";
384 if (isFunctionSkipped(
F))
388 if (++FunctionsCnt >= DebugifyFunctionsLimit)
391 auto *SP =
F.getSubprogram();
395 for (
const DINode *DN : SP->getRetainedNodes()) {
410 if (DebugifyLevel > Level::Locations) {
415 if (DbgVar->getDebugLoc().getInlinedAt())
418 if (DbgVar->isKillLocation())
421 auto *Var = DbgVar->getVariable();
425 HandleDbgVariable(&DVR);
432 collectStackAddresses(
I);
445 StringRef FileNameFromCU,
bool ShouldWriteIntoJSON,
447 bool Preserved =
true;
448 for (
const auto &
F : DIFunctionsAfter) {
451 auto SPIt = DIFunctionsBefore.
find(
F.first);
452 if (SPIt == DIFunctionsBefore.
end()) {
453 if (ShouldWriteIntoJSON)
455 {
"name",
F.first->getName()},
456 {
"action",
"not-generate"}}));
458 dbg() <<
"ERROR: " << NameOfWrappedPass
459 <<
" did not generate DISubprogram for " <<
F.first->getName()
460 <<
" from " << FileNameFromCU <<
'\n';
463 auto SP = SPIt->second;
468 if (ShouldWriteIntoJSON)
470 {
"name",
F.first->getName()},
471 {
"action",
"drop"}}));
473 dbg() <<
"ERROR: " << NameOfWrappedPass <<
" dropped DISubprogram of "
474 <<
F.first->getName() <<
" from " << FileNameFromCU <<
'\n';
489 bool ShouldWriteIntoJSON,
491 bool Preserved =
true;
492 for (
const auto &L : DILocsAfter) {
495 auto Instr = L.first;
499 auto WeakInstrPtr = InstToDelete.
find(Instr);
500 if (WeakInstrPtr != InstToDelete.
end() && !WeakInstrPtr->second)
503 auto FnName = Instr->getFunction()->getName();
504 auto BB = Instr->getParent();
505 auto BBName = BB->hasName() ? BB->getName() :
"no-name";
508 auto CreateJSONBugEntry = [&](
const char *Action) {
510 {
"metadata",
"DILocation"},
511 {
"fn-name", FnName.str()},
512 {
"bb-name", BBName.str()},
515#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
516 {
"origin", symbolizeStackTrace(Instr)},
521 auto InstrIt = DILocsBefore.
find(Instr);
522 if (InstrIt == DILocsBefore.
end()) {
523 if (ShouldWriteIntoJSON)
524 CreateJSONBugEntry(
"not-generate");
526 dbg() <<
"WARNING: " << NameOfWrappedPass
527 <<
" did not generate DILocation for " << *Instr
528 <<
" (BB: " << BBName <<
", Fn: " << FnName
529 <<
", File: " << FileNameFromCU <<
")\n";
532 if (!InstrIt->second)
536 if (ShouldWriteIntoJSON)
537 CreateJSONBugEntry(
"drop");
539 dbg() <<
"WARNING: " << NameOfWrappedPass <<
" dropped DILocation of "
540 << *Instr <<
" (BB: " << BBName <<
", Fn: " << FnName
541 <<
", File: " << FileNameFromCU <<
")\n";
554 bool Preserved =
true;
555 for (
const auto &V : DIVarsBefore) {
556 auto VarIt = DIVarsAfter.
find(V.first);
557 if (VarIt == DIVarsAfter.
end())
560 unsigned NumOfDbgValsAfter = VarIt->second;
562 if (V.second > NumOfDbgValsAfter) {
563 if (ShouldWriteIntoJSON)
565 {{
"metadata",
"dbg-var-intrinsic"},
566 {
"name", V.first->getName()},
567 {
"fn-name", V.first->getScope()->getSubprogram()->getName()},
568 {
"action",
"drop"}}));
570 dbg() <<
"WARNING: " << NameOfWrappedPass
571 <<
" drops dbg.value()/dbg.declare() for " << V.first->getName()
573 <<
"function " << V.first->getScope()->getSubprogram()->getName()
574 <<
" (file " << FileNameFromCU <<
")\n";
590 errs() <<
"Could not open file: " << EC.message() <<
", "
591 << OrigDIVerifyBugsReportFilePath <<
'\n';
595 if (
auto L = OS_FILE.
lock()) {
596 OS_FILE <<
"{\"file\":\"" << FileNameFromCU <<
"\", ";
599 NameOfWrappedPass !=
"" ? NameOfWrappedPass :
"no-name";
600 OS_FILE <<
"\"pass\":\"" <<
PassName <<
"\", ";
603 OS_FILE <<
"\"bugs\": " << BugsToPrint;
614 StringRef OrigDIVerifyBugsReportFilePath) {
615 LLVM_DEBUG(
dbgs() << Banner <<
": (after) " << NameOfWrappedPass <<
'\n');
617 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
618 dbg() << Banner <<
": Skipping module without debug info\n";
627 if (isFunctionSkipped(
F))
635 auto *SP =
F.getSubprogram();
640 for (
const DINode *DN : SP->getRetainedNodes()) {
655 if (DebugifyLevel > Level::Locations) {
660 if (DbgVar->getDebugLoc().getInlinedAt())
663 if (DbgVar->isKillLocation())
666 auto *Var = DbgVar->getVariable();
670 HandleDbgVariable(&DVR);
676 collectStackAddresses(
I);
687 auto DIFunctionsBefore = DebugInfoBeforePass.
DIFunctions;
688 auto DIFunctionsAfter = DebugInfoAfterPass.
DIFunctions;
690 auto DILocsBefore = DebugInfoBeforePass.
DILocations;
695 auto DIVarsBefore = DebugInfoBeforePass.
DIVariables;
698 bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.
empty();
702 checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
703 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
705 DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass,
706 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
708#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
712 for (
auto &L : DILocsAfter)
717 bool ResultForVars =
checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass,
718 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
720 bool Result = ResultForFunc && ResultForInsts && ResultForVars;
722 StringRef ResultBanner = NameOfWrappedPass !=
"" ? NameOfWrappedPass : Banner;
723 if (ShouldWriteIntoJSON && !Bugs.
empty())
724 writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass,
728 dbg() << ResultBanner <<
": PASS\n";
730 dbg() << ResultBanner <<
": FAIL\n";
735 DebugInfoBeforePass = DebugInfoAfterPass;
743template <
typename DbgValTy>
744bool diagnoseMisSizedDbgValue(
Module &M, DbgValTy *DbgVal) {
753 if (DbgVal->getExpression()->getNumElements())
756 Value *V = DbgVal->getVariableLocationOp(0);
760 Type *Ty = V->getType();
761 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
762 std::optional<uint64_t> DbgVarSize = DbgVal->getFragmentSizeInBits();
763 if (!ValueOperandSize || !DbgVarSize)
766 bool HasBadSize =
false;
767 if (Ty->isIntegerTy()) {
768 auto Signedness = DbgVal->getVariable()->getSignedness();
770 HasBadSize = ValueOperandSize < *DbgVarSize;
772 HasBadSize = ValueOperandSize != *DbgVarSize;
776 dbg() <<
"ERROR: dbg.value operand has size " << ValueOperandSize
777 <<
", but its variable has size " << *DbgVarSize <<
": ";
778 DbgVal->print(dbg());
784bool checkDebugifyMetadata(
Module &M,
789 NamedMDNode *NMD = M.getNamedMetadata(
"llvm.debugify");
791 dbg() << Banner <<
": Skipping module without debugify metadata\n";
795 auto getDebugifyOperand = [&](
unsigned Idx) ->
unsigned {
800 "llvm.debugify should have exactly 2 operands!");
801 unsigned OriginalNumLines = getDebugifyOperand(0);
802 unsigned OriginalNumVars = getDebugifyOperand(1);
803 bool HasErrors =
false;
807 if (StatsMap && !NameOfWrappedPass.
empty())
808 Stats = &StatsMap->operator[](NameOfWrappedPass);
810 BitVector MissingLines{OriginalNumLines,
true};
811 BitVector MissingVars{OriginalNumVars,
true};
813 if (isFunctionSkipped(
F))
818 auto DL =
I.getDebugLoc();
819 if (
DL &&
DL.getLine() != 0) {
820 MissingLines.
reset(
DL.getLine() - 1);
825 dbg() <<
"WARNING: Instruction with empty DebugLoc in function ";
826 dbg() <<
F.getName() <<
" --";
833 auto CheckForMisSized = [&](
auto *DbgVal) {
835 (void)
to_integer(DbgVal->getVariable()->getName(), Var, 10);
836 assert(Var <= OriginalNumVars &&
"Unexpected name for DILocalVariable");
837 bool HasBadSize = diagnoseMisSizedDbgValue(M, DbgVal);
839 MissingVars.
reset(Var - 1);
840 HasErrors |= HasBadSize;
844 if (DVR.isDbgValue() || DVR.isDbgAssign())
845 CheckForMisSized(&DVR);
850 for (
unsigned Idx : MissingLines.
set_bits())
851 dbg() <<
"WARNING: Missing line " << Idx + 1 <<
"\n";
853 for (
unsigned Idx : MissingVars.
set_bits())
854 dbg() <<
"WARNING: Missing variable " << Idx + 1 <<
"\n";
858 Stats->NumDbgLocsExpected += OriginalNumLines;
859 Stats->NumDbgLocsMissing += MissingLines.
count();
860 Stats->NumDbgValuesExpected += OriginalNumVars;
861 Stats->NumDbgValuesMissing += MissingVars.
count();
865 if (!NameOfWrappedPass.
empty())
866 dbg() <<
" [" << NameOfWrappedPass <<
"]";
867 dbg() <<
": " << (HasErrors ?
"FAIL" :
"PASS") <<
'\n';
879struct DebugifyModulePass :
public ModulePass {
880 bool runOnModule(
Module &M)
override {
882 applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass);
887 StringRef NameOfWrappedPass =
"",
888 DebugInfoPerPass *DebugInfoBeforePass =
nullptr)
889 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
890 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
892 void getAnalysisUsage(AnalysisUsage &AU)
const override {
899 StringRef NameOfWrappedPass;
900 DebugInfoPerPass *DebugInfoBeforePass;
913 DebugifyFunctionPass(
915 StringRef NameOfWrappedPass =
"",
916 DebugInfoPerPass *DebugInfoBeforePass =
nullptr)
917 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
918 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
920 void getAnalysisUsage(AnalysisUsage &AU)
const override {
927 StringRef NameOfWrappedPass;
928 DebugInfoPerPass *DebugInfoBeforePass;
934struct CheckDebugifyModulePass :
public ModulePass {
935 bool runOnModule(
Module &M)
override {
938 Result = checkDebugifyMetadata(M,
M.functions(), NameOfWrappedPass,
939 "CheckModuleDebugify", Strip, StatsMap);
942 M,
M.functions(), *DebugInfoBeforePass,
943 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
944 OrigDIVerifyBugsReportFilePath);
949 CheckDebugifyModulePass(
950 bool Strip =
false, StringRef NameOfWrappedPass =
"",
953 DebugInfoPerPass *DebugInfoBeforePass =
nullptr,
954 StringRef OrigDIVerifyBugsReportFilePath =
"")
955 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
956 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
957 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
960 void getAnalysisUsage(AnalysisUsage &AU)
const override {
967 StringRef NameOfWrappedPass;
968 StringRef OrigDIVerifyBugsReportFilePath;
970 DebugInfoPerPass *DebugInfoBeforePass;
980 auto FuncIt =
F.getIterator();
984 NameOfWrappedPass,
"CheckFunctionDebugify",
988 M,
make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
989 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
990 OrigDIVerifyBugsReportFilePath);
995 CheckDebugifyFunctionPass(
996 bool Strip =
false, StringRef NameOfWrappedPass =
"",
999 DebugInfoPerPass *DebugInfoBeforePass =
nullptr,
1000 StringRef OrigDIVerifyBugsReportFilePath =
"")
1001 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
1002 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
1003 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
1006 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1013 StringRef NameOfWrappedPass;
1014 StringRef OrigDIVerifyBugsReportFilePath;
1016 DebugInfoPerPass *DebugInfoBeforePass;
1027 errs() <<
"Could not open file: " << EC.message() <<
", " << Path <<
'\n';
1031 OS <<
"Pass Name" <<
',' <<
"# of missing debug values" <<
','
1032 <<
"# of missing locations" <<
',' <<
"Missing/Expected value ratio" <<
','
1033 <<
"Missing/Expected location ratio" <<
'\n';
1034 for (
const auto &Entry : Map) {
1038 OS <<
Pass <<
',' <<
Stats.NumDbgValuesMissing <<
','
1039 <<
Stats.NumDbgLocsMissing <<
',' <<
Stats.getMissingValueRatio() <<
','
1040 <<
Stats.getEmptyLocationRatio() <<
'\n';
1048 return new DebugifyModulePass();
1050 return new DebugifyModulePass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
1058 return new DebugifyFunctionPass();
1060 return new DebugifyFunctionPass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
1066 "ModuleDebugify: ",
nullptr);
1069 "ModuleDebugify (original debuginfo)",
1080 StringRef OrigDIVerifyBugsReportFilePath) {
1082 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
1084 return new CheckDebugifyModulePass(
false, NameOfWrappedPass,
nullptr,
Mode,
1085 DebugInfoBeforePass,
1086 OrigDIVerifyBugsReportFilePath);
1092 StringRef OrigDIVerifyBugsReportFilePath) {
1094 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
1096 return new CheckDebugifyFunctionPass(
false, NameOfWrappedPass,
nullptr,
Mode,
1097 DebugInfoBeforePass,
1098 OrigDIVerifyBugsReportFilePath);
1104 checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
1105 "CheckModuleDebugify", Strip, StatsMap);
1108 M, M.functions(), *DebugInfoBeforePass,
1109 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
1110 OrigDIVerifyBugsReportFilePath);
1117 "AnalysisManagerProxy",
"PrintFunctionPass",
1118 "PrintModulePass",
"BitcodeWriterPass",
1119 "ThinLTOBitcodeWriterPass",
"VerifierPass"});
1138 MAM.invalidate(M, PA);
1141 PIC.registerAfterPassCallback(
1150 auto It =
F.getIterator();
1152 checkDebugifyMetadata(M,
make_range(It, std::next(It)),
P,
1153 "CheckFunctionDebugify",
true,
1157 *DebugInfoBeforePass,
1158 "CheckModuleDebugify (original debuginfo)",
1159 P, OrigDIVerifyBugsReportFilePath);
1166 checkDebugifyMetadata(M, M.functions(),
P,
"CheckModuleDebugify",
1170 "CheckModuleDebugify (original debuginfo)",
1171 P, OrigDIVerifyBugsReportFilePath);
1172 MAM.invalidate(M, PA);
1177char DebugifyModulePass::ID = 0;
1179 "Attach debug info to everything");
1181char CheckDebugifyModulePass::ID = 0;
1183 CDM(
"check-debugify",
"Check debug info from -debugify");
1185char DebugifyFunctionPass::ID = 0;
1187 "Attach debug info to a function");
1189char CheckDebugifyFunctionPass::ID = 0;
1191 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="")
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)
static bool checkInstructions(const DebugInstMap &DILocsBefore, const DebugInstMap &DILocsAfter, const WeakInstValueMap &InstToDelete, 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::Instruction *, bool > DebugInstMap
llvm::MapVector< const llvm::Instruction *, llvm::WeakVH > WeakInstValueMap
llvm::MapVector< const llvm::DILocalVariable *, unsigned > DebugVarMap
static bool runOnFunction(Function &F, bool PostInlining)
static SmallString< 128 > getFilename(const DIScope *SP)
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 if the block is well formed or null if the block is not well forme...
size_type count() const
count - 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(DITypeRefArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
LLVM_ABI DICompileUnit * createCompileUnit(unsigned 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 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 DIBasicType * createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, DINode::DIFlags Flags=DINode::FlagZero, uint32_t NumExtraInhabitants=0)
Create debugging information entry for a basic type.
LLVM_ABI DITypeRefArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeRefArray, create one if required.
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.
Tagged DWARF-like metadata node.
DISPFlags
Debug info subprogram flags.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI 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)
size_type count(const KeyT &Key) const
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - 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.
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.
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
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 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 ...