19#include "llvm/Config/llvm-config.h"
33#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
39#define DEBUG_TYPE "debugify"
48 cl::desc(
"Suppress verbose debugify output"));
51 "debugify-func-limit",
52 cl::desc(
"Set max number of processed functions per pass."),
61 "debugify-level",
cl::desc(
"Kind of debug info to add"),
63 clEnumValN(Level::LocationsAndVariables,
"location+variables",
64 "Locations and Variables")),
65 cl::init(Level::LocationsAndVariables));
69#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
72static SymbolizedAddressMap SymbolizedAddrs;
73static AddressSet UnsymbolizedAddrs;
78 if (!UnsymbolizedAddrs.empty()) {
79 sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs);
80 UnsymbolizedAddrs.clear();
82 const DbgLocOrigin::StackTracesTy &OriginStackTraces =
83 I->getDebugLoc().getOriginStackTraces();
86 for (
size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) {
88 OS <<
"========================================\n";
89 auto &[
Depth, StackTrace] = OriginStackTraces[TraceIdx];
90 unsigned VirtualFrameNo = 0;
91 for (
int Frame = 0; Frame <
Depth; ++Frame) {
92 assert(SymbolizedAddrs.contains(StackTrace[Frame]) &&
93 "Expected each address to have been symbolized.");
94 for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) {
96 std::log10(
Depth) + 2)
97 <<
' ' << SymbolizedFrame <<
'\n';
104 auto &OriginStackTraces =
I.getDebugLoc().getOriginStackTraces();
105 for (
auto &[
Depth, StackTrace] : OriginStackTraces) {
106 for (
int Frame = 0; Frame <
Depth; ++Frame) {
107 void *Addr = StackTrace[Frame];
108 if (!SymbolizedAddrs.contains(Addr))
109 UnsymbolizedAddrs.insert(Addr);
118 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
122 return F.isDeclaration() || !
F.hasExactDefinition();
142 if (M.getNamedMetadata(
"llvm.dbg.cu")) {
143 dbg() << Banner <<
"Skipping module with debug info\n";
153 auto getCachedDIType = [&](
Type *Ty) ->
DIType * {
163 unsigned NextLine = 1;
164 unsigned NextVar = 1;
167 "debugify",
true,
"", 0);
171 if (isFunctionSkipped(
F))
174 bool InsertedDbgVal =
false;
177 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
178 if (
F.hasPrivateLinkage() ||
F.hasInternalLinkage())
179 SPFlags |= DISubprogram::SPFlagLocalToUnit;
181 SPType, NextLine, DINode::FlagZero, SPFlags,
182 nullptr,
nullptr,
nullptr,
nullptr,
"",
191 Value *V = &TemplateInst;
193 V = ConstantInt::get(
Int32Ty, 0);
196 getCachedDIType(V->getType()),
205 uint64_t AtomGroup = ApplyAtomGroups ? NextLine : 0;
206 uint8_t AtomRank = ApplyAtomGroups ? 1 : 0;
209 AtomGroup, AtomRank));
212 if (DebugifyLevel < Level::LocationsAndVariables)
221 Instruction *LastInst = findTerminatingInstruction(BB);
222 assert(LastInst &&
"Expected basic block with a terminator");
227 assert(InsertPt != BB.end() &&
"Expected to find an insertion point");
230 InsertPt.setHeadBit(
false);
233 for (
Instruction *
I = &*BB.begin();
I != LastInst;
I =
I->getNextNode()) {
235 if (
I->getType()->isVoidTy())
241 InsertPt = std::next(
I->getIterator());
243 insertDbgVal(*
I, InsertPt);
244 InsertedDbgVal =
true;
252 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
253 auto *
Term = findTerminatingInstruction(
F.getEntryBlock());
254 insertDbgVal(*Term,
Term->getIterator());
262 NamedMDNode *NMD = M.getOrInsertNamedMetadata(
"llvm.debugify");
263 auto addDebugifyOperand = [&](
unsigned N) {
267 addDebugifyOperand(NextLine - 1);
268 addDebugifyOperand(NextVar - 1);
270 "llvm.debugify should have exactly 2 operands!");
273 StringRef DIVersionKey =
"Debug Info Version";
274 if (!M.getModuleFlag(DIVersionKey))
284 auto FuncIt =
F.getIterator();
287 "FunctionDebugify: ",
nullptr);
288 assert(DebugInfoBeforePass &&
"Missing debug info metadata");
290 "FunctionDebugify (original debuginfo)",
299 "ModuleDebugify: ",
nullptr);
300 assert(DebugInfoBeforePass &&
"Missing debug info metadata");
302 "ModuleDebugify (original debuginfo)",
310 NamedMDNode *DebugifyMD = M.getNamedMetadata(
"llvm.debugify");
312 M.eraseNamedMetadata(DebugifyMD);
316 if (
auto *MIRDebugifyMD = M.getNamedMetadata(
"llvm.mir.debugify")) {
317 M.eraseNamedMetadata(MIRDebugifyMD);
329 "Not all debug info stripped?");
341 for (
MDNode *Flag : Flags) {
343 if (
Key->getString() ==
"Debug Info Version") {
358#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
359 DebugLocKind Kind =
I.getDebugLoc().getKind();
360 return Loc || Kind != DebugLocKind::Normal;
371 LLVM_DEBUG(
dbgs() << Banner <<
": (before) " << NameOfWrappedPass <<
'\n');
373 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
374 dbg() << Banner <<
": Skipping module without debug info\n";
385 if (isFunctionSkipped(
F))
389 if (++FunctionsCnt >= DebugifyFunctionsLimit)
392 auto *SP =
F.getSubprogram();
396 for (
const DINode *DN : SP->getRetainedNodes()) {
411 if (DebugifyLevel > Level::Locations) {
416 if (DbgVar->getDebugLoc().getInlinedAt())
419 if (DbgVar->isKillLocation())
422 auto *Var = DbgVar->getVariable();
426 HandleDbgVariable(&DVR);
433 collectStackAddresses(
I);
446 StringRef FileNameFromCU,
bool ShouldWriteIntoJSON,
448 bool Preserved =
true;
449 for (
const auto &
F : DIFunctionsAfter) {
452 auto SPIt = DIFunctionsBefore.
find(
F.first);
453 if (SPIt == DIFunctionsBefore.
end()) {
454 if (ShouldWriteIntoJSON)
456 {
"name",
F.first->getName()},
457 {
"action",
"not-generate"}}));
459 dbg() <<
"ERROR: " << NameOfWrappedPass
460 <<
" did not generate DISubprogram for " <<
F.first->getName()
461 <<
" from " << FileNameFromCU <<
'\n';
464 auto SP = SPIt->second;
469 if (ShouldWriteIntoJSON)
471 {
"name",
F.first->getName()},
472 {
"action",
"drop"}}));
474 dbg() <<
"ERROR: " << NameOfWrappedPass <<
" dropped DISubprogram of "
475 <<
F.first->getName() <<
" from " << FileNameFromCU <<
'\n';
490 bool ShouldWriteIntoJSON,
492 bool Preserved =
true;
493 for (
const auto &L : DILocsAfter) {
496 auto Instr = L.first;
500 auto WeakInstrPtr = InstToDelete.
find(Instr);
501 if (WeakInstrPtr != InstToDelete.
end() && !WeakInstrPtr->second)
504 auto FnName = Instr->getFunction()->getName();
505 auto BB = Instr->getParent();
506 auto BBName = BB->hasName() ? BB->getName() :
"no-name";
509 auto CreateJSONBugEntry = [&](
const char *Action) {
511 {
"metadata",
"DILocation"},
512 {
"fn-name", FnName.str()},
513 {
"bb-name", BBName.str()},
516#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
517 {
"origin", symbolizeStackTrace(Instr)},
522 auto InstrIt = DILocsBefore.
find(Instr);
523 if (InstrIt == DILocsBefore.
end()) {
524 if (ShouldWriteIntoJSON)
525 CreateJSONBugEntry(
"not-generate");
527 dbg() <<
"WARNING: " << NameOfWrappedPass
528 <<
" did not generate DILocation for " << *Instr
529 <<
" (BB: " << BBName <<
", Fn: " << FnName
530 <<
", File: " << FileNameFromCU <<
")\n";
533 if (!InstrIt->second)
537 if (ShouldWriteIntoJSON)
538 CreateJSONBugEntry(
"drop");
540 dbg() <<
"WARNING: " << NameOfWrappedPass <<
" dropped DILocation of "
541 << *Instr <<
" (BB: " << BBName <<
", Fn: " << FnName
542 <<
", File: " << FileNameFromCU <<
")\n";
555 bool Preserved =
true;
556 for (
const auto &V : DIVarsBefore) {
557 auto VarIt = DIVarsAfter.
find(V.first);
558 if (VarIt == DIVarsAfter.
end())
561 unsigned NumOfDbgValsAfter = VarIt->second;
563 if (V.second > NumOfDbgValsAfter) {
564 if (ShouldWriteIntoJSON)
566 {{
"metadata",
"dbg-var-intrinsic"},
567 {
"name", V.first->getName()},
568 {
"fn-name", V.first->getScope()->getSubprogram()->getName()},
569 {
"action",
"drop"}}));
571 dbg() <<
"WARNING: " << NameOfWrappedPass
572 <<
" drops dbg.value()/dbg.declare() for " << V.first->getName()
574 <<
"function " << V.first->getScope()->getSubprogram()->getName()
575 <<
" (file " << FileNameFromCU <<
")\n";
591 errs() <<
"Could not open file: " << EC.message() <<
", "
592 << OrigDIVerifyBugsReportFilePath <<
'\n';
596 if (
auto L = OS_FILE.
lock()) {
597 OS_FILE <<
"{\"file\":\"" << FileNameFromCU <<
"\", ";
600 NameOfWrappedPass !=
"" ? NameOfWrappedPass :
"no-name";
601 OS_FILE <<
"\"pass\":\"" <<
PassName <<
"\", ";
604 OS_FILE <<
"\"bugs\": " << BugsToPrint;
615 StringRef OrigDIVerifyBugsReportFilePath) {
616 LLVM_DEBUG(
dbgs() << Banner <<
": (after) " << NameOfWrappedPass <<
'\n');
618 if (!M.getNamedMetadata(
"llvm.dbg.cu")) {
619 dbg() << Banner <<
": Skipping module without debug info\n";
628 if (isFunctionSkipped(
F))
636 auto *SP =
F.getSubprogram();
641 for (
const DINode *DN : SP->getRetainedNodes()) {
656 if (DebugifyLevel > Level::Locations) {
661 if (DbgVar->getDebugLoc().getInlinedAt())
664 if (DbgVar->isKillLocation())
667 auto *Var = DbgVar->getVariable();
671 HandleDbgVariable(&DVR);
677 collectStackAddresses(
I);
688 auto DIFunctionsBefore = DebugInfoBeforePass.
DIFunctions;
689 auto DIFunctionsAfter = DebugInfoAfterPass.
DIFunctions;
691 auto DILocsBefore = DebugInfoBeforePass.
DILocations;
696 auto DIVarsBefore = DebugInfoBeforePass.
DIVariables;
699 bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.
empty();
703 checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
704 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
706 DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass,
707 FileNameFromCU, ShouldWriteIntoJSON, Bugs);
709#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
713 for (
auto &L : DILocsAfter)
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");
792 dbg() << Banner <<
": Skipping module without debugify metadata\n";
796 auto getDebugifyOperand = [&](
unsigned Idx) ->
unsigned {
801 "llvm.debugify should have exactly 2 operands!");
802 unsigned OriginalNumLines = getDebugifyOperand(0);
803 unsigned OriginalNumVars = getDebugifyOperand(1);
804 bool HasErrors =
false;
808 if (StatsMap && !NameOfWrappedPass.
empty())
809 Stats = &StatsMap->operator[](NameOfWrappedPass);
811 BitVector MissingLines{OriginalNumLines,
true};
812 BitVector MissingVars{OriginalNumVars,
true};
814 if (isFunctionSkipped(
F))
819 auto DL =
I.getDebugLoc();
820 if (
DL &&
DL.getLine() != 0) {
821 MissingLines.
reset(
DL.getLine() - 1);
826 dbg() <<
"WARNING: Instruction with empty DebugLoc in function ";
827 dbg() <<
F.getName() <<
" --";
834 auto CheckForMisSized = [&](
auto *DbgVal) {
836 (void)
to_integer(DbgVal->getVariable()->getName(), Var, 10);
837 assert(Var <= OriginalNumVars &&
"Unexpected name for DILocalVariable");
838 bool HasBadSize = diagnoseMisSizedDbgValue(M, DbgVal);
840 MissingVars.
reset(Var - 1);
841 HasErrors |= HasBadSize;
845 if (DVR.isDbgValue() || DVR.isDbgAssign())
846 CheckForMisSized(&DVR);
851 for (
unsigned Idx : MissingLines.
set_bits())
852 dbg() <<
"WARNING: Missing line " << Idx + 1 <<
"\n";
854 for (
unsigned Idx : MissingVars.
set_bits())
855 dbg() <<
"WARNING: Missing variable " << Idx + 1 <<
"\n";
859 Stats->NumDbgLocsExpected += OriginalNumLines;
860 Stats->NumDbgLocsMissing += MissingLines.
count();
861 Stats->NumDbgValuesExpected += OriginalNumVars;
862 Stats->NumDbgValuesMissing += MissingVars.
count();
866 if (!NameOfWrappedPass.
empty())
867 dbg() <<
" [" << NameOfWrappedPass <<
"]";
868 dbg() <<
": " << (HasErrors ?
"FAIL" :
"PASS") <<
'\n';
880struct DebugifyModulePass :
public ModulePass {
881 bool runOnModule(
Module &M)
override {
883 applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass);
888 StringRef NameOfWrappedPass =
"",
889 DebugInfoPerPass *DebugInfoBeforePass =
nullptr)
890 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
891 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
893 void getAnalysisUsage(AnalysisUsage &AU)
const override {
900 StringRef NameOfWrappedPass;
901 DebugInfoPerPass *DebugInfoBeforePass;
914 DebugifyFunctionPass(
916 StringRef NameOfWrappedPass =
"",
917 DebugInfoPerPass *DebugInfoBeforePass =
nullptr)
918 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
919 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
921 void getAnalysisUsage(AnalysisUsage &AU)
const override {
928 StringRef NameOfWrappedPass;
929 DebugInfoPerPass *DebugInfoBeforePass;
935struct CheckDebugifyModulePass :
public ModulePass {
936 bool runOnModule(
Module &M)
override {
939 Result = checkDebugifyMetadata(M,
M.functions(), NameOfWrappedPass,
940 "CheckModuleDebugify", Strip, StatsMap);
943 M,
M.functions(), *DebugInfoBeforePass,
944 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
945 OrigDIVerifyBugsReportFilePath);
950 CheckDebugifyModulePass(
951 bool Strip =
false, StringRef NameOfWrappedPass =
"",
954 DebugInfoPerPass *DebugInfoBeforePass =
nullptr,
955 StringRef OrigDIVerifyBugsReportFilePath =
"")
956 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
957 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
958 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
961 void getAnalysisUsage(AnalysisUsage &AU)
const override {
968 StringRef NameOfWrappedPass;
969 StringRef OrigDIVerifyBugsReportFilePath;
971 DebugInfoPerPass *DebugInfoBeforePass;
981 auto FuncIt =
F.getIterator();
985 NameOfWrappedPass,
"CheckFunctionDebugify",
989 M,
make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
990 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
991 OrigDIVerifyBugsReportFilePath);
996 CheckDebugifyFunctionPass(
997 bool Strip =
false, StringRef NameOfWrappedPass =
"",
1000 DebugInfoPerPass *DebugInfoBeforePass =
nullptr,
1001 StringRef OrigDIVerifyBugsReportFilePath =
"")
1002 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
1003 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
1004 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
1007 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1014 StringRef NameOfWrappedPass;
1015 StringRef OrigDIVerifyBugsReportFilePath;
1017 DebugInfoPerPass *DebugInfoBeforePass;
1028 errs() <<
"Could not open file: " << EC.message() <<
", " << Path <<
'\n';
1032 OS <<
"Pass Name" <<
',' <<
"# of missing debug values" <<
','
1033 <<
"# of missing locations" <<
',' <<
"Missing/Expected value ratio" <<
','
1034 <<
"Missing/Expected location ratio" <<
'\n';
1035 for (
const auto &Entry : Map) {
1039 OS <<
Pass <<
',' <<
Stats.NumDbgValuesMissing <<
','
1040 <<
Stats.NumDbgLocsMissing <<
',' <<
Stats.getMissingValueRatio() <<
','
1041 <<
Stats.getEmptyLocationRatio() <<
'\n';
1049 return new DebugifyModulePass();
1051 return new DebugifyModulePass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
1059 return new DebugifyFunctionPass();
1061 return new DebugifyFunctionPass(
Mode, NameOfWrappedPass, DebugInfoBeforePass);
1067 "ModuleDebugify: ",
nullptr);
1070 "ModuleDebugify (original debuginfo)",
1081 StringRef OrigDIVerifyBugsReportFilePath) {
1083 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
1085 return new CheckDebugifyModulePass(
false, NameOfWrappedPass,
nullptr,
Mode,
1086 DebugInfoBeforePass,
1087 OrigDIVerifyBugsReportFilePath);
1093 StringRef OrigDIVerifyBugsReportFilePath) {
1095 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
1097 return new CheckDebugifyFunctionPass(
false, NameOfWrappedPass,
nullptr,
Mode,
1098 DebugInfoBeforePass,
1099 OrigDIVerifyBugsReportFilePath);
1105 checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
1106 "CheckModuleDebugify", Strip, StatsMap);
1109 M, M.functions(), *DebugInfoBeforePass,
1110 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
1111 OrigDIVerifyBugsReportFilePath);
1118 "AnalysisManagerProxy",
"PrintFunctionPass",
1119 "PrintModulePass",
"BitcodeWriterPass",
1120 "ThinLTOBitcodeWriterPass",
"VerifierPass"});
1139 MAM.invalidate(M, PA);
1142 PIC.registerAfterPassCallback(
1151 auto It =
F.getIterator();
1153 checkDebugifyMetadata(M,
make_range(It, std::next(It)),
P,
1154 "CheckFunctionDebugify",
true,
1158 *DebugInfoBeforePass,
1159 "CheckModuleDebugify (original debuginfo)",
1160 P, OrigDIVerifyBugsReportFilePath);
1167 checkDebugifyMetadata(M, M.functions(),
P,
"CheckModuleDebugify",
1171 "CheckModuleDebugify (original debuginfo)",
1172 P, OrigDIVerifyBugsReportFilePath);
1173 MAM.invalidate(M, PA);
1178char DebugifyModulePass::ID = 0;
1180 "Attach debug info to everything");
1182char CheckDebugifyModulePass::ID = 0;
1184 CDM(
"check-debugify",
"Check debug info from -debugify");
1186char DebugifyFunctionPass::ID = 0;
1188 "Attach debug info to a function");
1190char CheckDebugifyFunctionPass::ID = 0;
1192 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, 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 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 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 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.
Tagged DWARF-like metadata node.
Wrapper structure that holds a language name and its version.
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 ...