xref: /llvm-project/llvm/lib/Transforms/Utils/Debugify.cpp (revision e03f427196ec67a8a5cfbdd658f9eabe9bce83ce)
1 //===- Debugify.cpp - Check debug info preservation in optimizations ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file In the `synthetic` mode, the `-debugify` attaches synthetic debug info
10 /// to everything. It can be used to create targeted tests for debug info
11 /// preservation. In addition, when using the `original` mode, it can check
12 /// original debug info preservation. The `synthetic` mode is default one.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/Transforms/Utils/Debugify.h"
17 #include "llvm/ADT/BitVector.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/IR/DIBuilder.h"
20 #include "llvm/IR/DebugInfo.h"
21 #include "llvm/IR/InstIterator.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/IntrinsicInst.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/PassInstrumentation.h"
26 #include "llvm/Pass.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/JSON.h"
30 #include <optional>
31 
32 #define DEBUG_TYPE "debugify"
33 
34 using namespace llvm;
35 
36 namespace {
37 
38 cl::opt<bool> Quiet("debugify-quiet",
39                     cl::desc("Suppress verbose debugify output"));
40 
41 cl::opt<uint64_t> DebugifyFunctionsLimit(
42     "debugify-func-limit",
43     cl::desc("Set max number of processed functions per pass."),
44     cl::init(UINT_MAX));
45 
46 enum class Level {
47   Locations,
48   LocationsAndVariables
49 };
50 
51 cl::opt<Level> DebugifyLevel(
52     "debugify-level", cl::desc("Kind of debug info to add"),
53     cl::values(clEnumValN(Level::Locations, "locations", "Locations only"),
54                clEnumValN(Level::LocationsAndVariables, "location+variables",
55                           "Locations and Variables")),
56     cl::init(Level::LocationsAndVariables));
57 
58 raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
59 
60 uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
61   return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
62 }
63 
64 bool isFunctionSkipped(Function &F) {
65   return F.isDeclaration() || !F.hasExactDefinition();
66 }
67 
68 /// Find the basic block's terminating instruction.
69 ///
70 /// Special care is needed to handle musttail and deopt calls, as these behave
71 /// like (but are in fact not) terminators.
72 Instruction *findTerminatingInstruction(BasicBlock &BB) {
73   if (auto *I = BB.getTerminatingMustTailCall())
74     return I;
75   if (auto *I = BB.getTerminatingDeoptimizeCall())
76     return I;
77   return BB.getTerminator();
78 }
79 } // end anonymous namespace
80 
81 bool llvm::applyDebugifyMetadata(
82     Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
83     std::function<bool(DIBuilder &DIB, Function &F)> ApplyToMF) {
84   // Skip modules with debug info.
85   if (M.getNamedMetadata("llvm.dbg.cu")) {
86     dbg() << Banner << "Skipping module with debug info\n";
87     return false;
88   }
89 
90   DIBuilder DIB(M);
91   LLVMContext &Ctx = M.getContext();
92   auto *Int32Ty = Type::getInt32Ty(Ctx);
93 
94   // Get a DIType which corresponds to Ty.
95   DenseMap<uint64_t, DIType *> TypeCache;
96   auto getCachedDIType = [&](Type *Ty) -> DIType * {
97     uint64_t Size = getAllocSizeInBits(M, Ty);
98     DIType *&DTy = TypeCache[Size];
99     if (!DTy) {
100       std::string Name = "ty" + utostr(Size);
101       DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
102     }
103     return DTy;
104   };
105 
106   unsigned NextLine = 1;
107   unsigned NextVar = 1;
108   auto File = DIB.createFile(M.getName(), "/");
109   auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
110                                   /*isOptimized=*/true, "", 0);
111 
112   // Visit each instruction.
113   for (Function &F : Functions) {
114     if (isFunctionSkipped(F))
115       continue;
116 
117     bool InsertedDbgVal = false;
118     auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));
119     DISubprogram::DISPFlags SPFlags =
120         DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
121     if (F.hasPrivateLinkage() || F.hasInternalLinkage())
122       SPFlags |= DISubprogram::SPFlagLocalToUnit;
123     auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
124                                  SPType, NextLine, DINode::FlagZero, SPFlags);
125     F.setSubprogram(SP);
126 
127     // Helper that inserts a dbg.value before \p InsertBefore, copying the
128     // location (and possibly the type, if it's non-void) from \p TemplateInst.
129     auto insertDbgVal = [&](Instruction &TemplateInst,
130                             Instruction *InsertBefore) {
131       std::string Name = utostr(NextVar++);
132       Value *V = &TemplateInst;
133       if (TemplateInst.getType()->isVoidTy())
134         V = ConstantInt::get(Int32Ty, 0);
135       const DILocation *Loc = TemplateInst.getDebugLoc().get();
136       auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
137                                              getCachedDIType(V->getType()),
138                                              /*AlwaysPreserve=*/true);
139       DIB.insertDbgValueIntrinsic(V, LocalVar, DIB.createExpression(), Loc,
140                                   InsertBefore);
141     };
142 
143     for (BasicBlock &BB : F) {
144       // Attach debug locations.
145       for (Instruction &I : BB)
146         I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
147 
148       if (DebugifyLevel < Level::LocationsAndVariables)
149         continue;
150 
151       // Inserting debug values into EH pads can break IR invariants.
152       if (BB.isEHPad())
153         continue;
154 
155       // Find the terminating instruction, after which no debug values are
156       // attached.
157       Instruction *LastInst = findTerminatingInstruction(BB);
158       assert(LastInst && "Expected basic block with a terminator");
159 
160       // Maintain an insertion point which can't be invalidated when updates
161       // are made.
162       BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
163       assert(InsertPt != BB.end() && "Expected to find an insertion point");
164       Instruction *InsertBefore = &*InsertPt;
165 
166       // Attach debug values.
167       for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
168         // Skip void-valued instructions.
169         if (I->getType()->isVoidTy())
170           continue;
171 
172         // Phis and EH pads must be grouped at the beginning of the block.
173         // Only advance the insertion point when we finish visiting these.
174         if (!isa<PHINode>(I) && !I->isEHPad())
175           InsertBefore = I->getNextNode();
176 
177         insertDbgVal(*I, InsertBefore);
178         InsertedDbgVal = true;
179       }
180     }
181     // Make sure we emit at least one dbg.value, otherwise MachineDebugify may
182     // not have anything to work with as it goes about inserting DBG_VALUEs.
183     // (It's common for MIR tests to be written containing skeletal IR with
184     // empty functions -- we're still interested in debugifying the MIR within
185     // those tests, and this helps with that.)
186     if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
187       auto *Term = findTerminatingInstruction(F.getEntryBlock());
188       insertDbgVal(*Term, Term);
189     }
190     if (ApplyToMF)
191       ApplyToMF(DIB, F);
192     DIB.finalizeSubprogram(SP);
193   }
194   DIB.finalize();
195 
196   // Track the number of distinct lines and variables.
197   NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
198   auto addDebugifyOperand = [&](unsigned N) {
199     NMD->addOperand(MDNode::get(
200         Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N))));
201   };
202   addDebugifyOperand(NextLine - 1); // Original number of lines.
203   addDebugifyOperand(NextVar - 1);  // Original number of variables.
204   assert(NMD->getNumOperands() == 2 &&
205          "llvm.debugify should have exactly 2 operands!");
206 
207   // Claim that this synthetic debug info is valid.
208   StringRef DIVersionKey = "Debug Info Version";
209   if (!M.getModuleFlag(DIVersionKey))
210     M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
211 
212   return true;
213 }
214 
215 static bool
216 applyDebugify(Function &F,
217               enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
218               DebugInfoPerPass *DebugInfoBeforePass = nullptr,
219               StringRef NameOfWrappedPass = "") {
220   Module &M = *F.getParent();
221   auto FuncIt = F.getIterator();
222   if (Mode == DebugifyMode::SyntheticDebugInfo)
223     return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
224                                  "FunctionDebugify: ", /*ApplyToMF*/ nullptr);
225   assert(DebugInfoBeforePass);
226   return collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass,
227                                   "FunctionDebugify (original debuginfo)",
228                                   NameOfWrappedPass);
229 }
230 
231 static bool
232 applyDebugify(Module &M,
233               enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
234               DebugInfoPerPass *DebugInfoBeforePass = nullptr,
235               StringRef NameOfWrappedPass = "") {
236   if (Mode == DebugifyMode::SyntheticDebugInfo)
237     return applyDebugifyMetadata(M, M.functions(),
238                                  "ModuleDebugify: ", /*ApplyToMF*/ nullptr);
239   return collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass,
240                                   "ModuleDebugify (original debuginfo)",
241                                   NameOfWrappedPass);
242 }
243 
244 bool llvm::stripDebugifyMetadata(Module &M) {
245   bool Changed = false;
246 
247   // Remove the llvm.debugify and llvm.mir.debugify module-level named metadata.
248   NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify");
249   if (DebugifyMD) {
250     M.eraseNamedMetadata(DebugifyMD);
251     Changed = true;
252   }
253 
254   if (auto *MIRDebugifyMD = M.getNamedMetadata("llvm.mir.debugify")) {
255     M.eraseNamedMetadata(MIRDebugifyMD);
256     Changed = true;
257   }
258 
259   // Strip out all debug intrinsics and supporting metadata (subprograms, types,
260   // variables, etc).
261   Changed |= StripDebugInfo(M);
262 
263   // Strip out the dead dbg.value prototype.
264   Function *DbgValF = M.getFunction("llvm.dbg.value");
265   if (DbgValF) {
266     assert(DbgValF->isDeclaration() && DbgValF->use_empty() &&
267            "Not all debug info stripped?");
268     DbgValF->eraseFromParent();
269     Changed = true;
270   }
271 
272   // Strip out the module-level Debug Info Version metadata.
273   // FIXME: There must be an easier way to remove an operand from a NamedMDNode.
274   NamedMDNode *NMD = M.getModuleFlagsMetadata();
275   if (!NMD)
276     return Changed;
277   SmallVector<MDNode *, 4> Flags(NMD->operands());
278   NMD->clearOperands();
279   for (MDNode *Flag : Flags) {
280     auto *Key = cast<MDString>(Flag->getOperand(1));
281     if (Key->getString() == "Debug Info Version") {
282       Changed = true;
283       continue;
284     }
285     NMD->addOperand(Flag);
286   }
287   // If we left it empty we might as well remove it.
288   if (NMD->getNumOperands() == 0)
289     NMD->eraseFromParent();
290 
291   return Changed;
292 }
293 
294 bool llvm::collectDebugInfoMetadata(Module &M,
295                                     iterator_range<Module::iterator> Functions,
296                                     DebugInfoPerPass &DebugInfoBeforePass,
297                                     StringRef Banner,
298                                     StringRef NameOfWrappedPass) {
299   LLVM_DEBUG(dbgs() << Banner << ": (before) " << NameOfWrappedPass << '\n');
300 
301   if (!M.getNamedMetadata("llvm.dbg.cu")) {
302     dbg() << Banner << ": Skipping module without debug info\n";
303     return false;
304   }
305 
306   uint64_t FunctionsCnt = DebugInfoBeforePass.DIFunctions.size();
307   // Visit each instruction.
308   for (Function &F : Functions) {
309     // Use DI collected after previous Pass (when -debugify-each is used).
310     if (DebugInfoBeforePass.DIFunctions.count(&F))
311       continue;
312 
313     if (isFunctionSkipped(F))
314       continue;
315 
316     // Stop collecting DI if the Functions number reached the limit.
317     if (++FunctionsCnt >= DebugifyFunctionsLimit)
318       break;
319     // Collect the DISubprogram.
320     auto *SP = F.getSubprogram();
321     DebugInfoBeforePass.DIFunctions.insert({&F, SP});
322     if (SP) {
323       LLVM_DEBUG(dbgs() << "  Collecting subprogram: " << *SP << '\n');
324       for (const DINode *DN : SP->getRetainedNodes()) {
325         if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
326           DebugInfoBeforePass.DIVariables[DV] = 0;
327         }
328       }
329     }
330 
331     for (BasicBlock &BB : F) {
332       // Collect debug locations (!dbg) and debug variable intrinsics.
333       for (Instruction &I : BB) {
334         // Skip PHIs.
335         if (isa<PHINode>(I))
336           continue;
337 
338         // Cllect dbg.values and dbg.declare.
339         if (DebugifyLevel > Level::Locations) {
340           auto HandleDbgVariable = [&](auto *DbgVar) {
341             if (!SP)
342               return;
343             // Skip inlined variables.
344             if (DbgVar->getDebugLoc().getInlinedAt())
345               return;
346             // Skip undef values.
347             if (DbgVar->isKillLocation())
348               return;
349 
350             auto *Var = DbgVar->getVariable();
351             DebugInfoBeforePass.DIVariables[Var]++;
352           };
353           for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
354             HandleDbgVariable(&DVR);
355           if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
356             HandleDbgVariable(DVI);
357         }
358 
359         // Skip debug instructions other than dbg.value and dbg.declare.
360         if (isa<DbgInfoIntrinsic>(&I))
361           continue;
362 
363         LLVM_DEBUG(dbgs() << "  Collecting info for inst: " << I << '\n');
364         DebugInfoBeforePass.InstToDelete.insert({&I, &I});
365 
366         const DILocation *Loc = I.getDebugLoc().get();
367         bool HasLoc = Loc != nullptr;
368         DebugInfoBeforePass.DILocations.insert({&I, HasLoc});
369       }
370     }
371   }
372 
373   return true;
374 }
375 
376 // This checks the preservation of original debug info attached to functions.
377 static bool checkFunctions(const DebugFnMap &DIFunctionsBefore,
378                            const DebugFnMap &DIFunctionsAfter,
379                            StringRef NameOfWrappedPass,
380                            StringRef FileNameFromCU, bool ShouldWriteIntoJSON,
381                            llvm::json::Array &Bugs) {
382   bool Preserved = true;
383   for (const auto &F : DIFunctionsAfter) {
384     if (F.second)
385       continue;
386     auto SPIt = DIFunctionsBefore.find(F.first);
387     if (SPIt == DIFunctionsBefore.end()) {
388       if (ShouldWriteIntoJSON)
389         Bugs.push_back(llvm::json::Object({{"metadata", "DISubprogram"},
390                                            {"name", F.first->getName()},
391                                            {"action", "not-generate"}}));
392       else
393         dbg() << "ERROR: " << NameOfWrappedPass
394               << " did not generate DISubprogram for " << F.first->getName()
395               << " from " << FileNameFromCU << '\n';
396       Preserved = false;
397     } else {
398       auto SP = SPIt->second;
399       if (!SP)
400         continue;
401       // If the function had the SP attached before the pass, consider it as
402       // a debug info bug.
403       if (ShouldWriteIntoJSON)
404         Bugs.push_back(llvm::json::Object({{"metadata", "DISubprogram"},
405                                            {"name", F.first->getName()},
406                                            {"action", "drop"}}));
407       else
408         dbg() << "ERROR: " << NameOfWrappedPass << " dropped DISubprogram of "
409               << F.first->getName() << " from " << FileNameFromCU << '\n';
410       Preserved = false;
411     }
412   }
413 
414   return Preserved;
415 }
416 
417 // This checks the preservation of the original debug info attached to
418 // instructions.
419 static bool checkInstructions(const DebugInstMap &DILocsBefore,
420                               const DebugInstMap &DILocsAfter,
421                               const WeakInstValueMap &InstToDelete,
422                               StringRef NameOfWrappedPass,
423                               StringRef FileNameFromCU,
424                               bool ShouldWriteIntoJSON,
425                               llvm::json::Array &Bugs) {
426   bool Preserved = true;
427   for (const auto &L : DILocsAfter) {
428     if (L.second)
429       continue;
430     auto Instr = L.first;
431 
432     // In order to avoid pointer reuse/recycling, skip the values that might
433     // have been deleted during a pass.
434     auto WeakInstrPtr = InstToDelete.find(Instr);
435     if (WeakInstrPtr != InstToDelete.end() && !WeakInstrPtr->second)
436       continue;
437 
438     auto FnName = Instr->getFunction()->getName();
439     auto BB = Instr->getParent();
440     auto BBName = BB->hasName() ? BB->getName() : "no-name";
441     auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
442 
443     auto InstrIt = DILocsBefore.find(Instr);
444     if (InstrIt == DILocsBefore.end()) {
445       if (ShouldWriteIntoJSON)
446         Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
447                                            {"fn-name", FnName.str()},
448                                            {"bb-name", BBName.str()},
449                                            {"instr", InstName},
450                                            {"action", "not-generate"}}));
451       else
452         dbg() << "WARNING: " << NameOfWrappedPass
453               << " did not generate DILocation for " << *Instr
454               << " (BB: " << BBName << ", Fn: " << FnName
455               << ", File: " << FileNameFromCU << ")\n";
456       Preserved = false;
457     } else {
458       if (!InstrIt->second)
459         continue;
460       // If the instr had the !dbg attached before the pass, consider it as
461       // a debug info issue.
462       if (ShouldWriteIntoJSON)
463         Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
464                                            {"fn-name", FnName.str()},
465                                            {"bb-name", BBName.str()},
466                                            {"instr", InstName},
467                                            {"action", "drop"}}));
468       else
469         dbg() << "WARNING: " << NameOfWrappedPass << " dropped DILocation of "
470               << *Instr << " (BB: " << BBName << ", Fn: " << FnName
471               << ", File: " << FileNameFromCU << ")\n";
472       Preserved = false;
473     }
474   }
475 
476   return Preserved;
477 }
478 
479 // This checks the preservation of original debug variable intrinsics.
480 static bool checkVars(const DebugVarMap &DIVarsBefore,
481                       const DebugVarMap &DIVarsAfter,
482                       StringRef NameOfWrappedPass, StringRef FileNameFromCU,
483                       bool ShouldWriteIntoJSON, llvm::json::Array &Bugs) {
484   bool Preserved = true;
485   for (const auto &V : DIVarsBefore) {
486     auto VarIt = DIVarsAfter.find(V.first);
487     if (VarIt == DIVarsAfter.end())
488       continue;
489 
490     unsigned NumOfDbgValsAfter = VarIt->second;
491 
492     if (V.second > NumOfDbgValsAfter) {
493       if (ShouldWriteIntoJSON)
494         Bugs.push_back(llvm::json::Object(
495             {{"metadata", "dbg-var-intrinsic"},
496              {"name", V.first->getName()},
497              {"fn-name", V.first->getScope()->getSubprogram()->getName()},
498              {"action", "drop"}}));
499       else
500         dbg() << "WARNING: " << NameOfWrappedPass
501               << " drops dbg.value()/dbg.declare() for " << V.first->getName()
502               << " from "
503               << "function " << V.first->getScope()->getSubprogram()->getName()
504               << " (file " << FileNameFromCU << ")\n";
505       Preserved = false;
506     }
507   }
508 
509   return Preserved;
510 }
511 
512 // Write the json data into the specifed file.
513 static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath,
514                       StringRef FileNameFromCU, StringRef NameOfWrappedPass,
515                       llvm::json::Array &Bugs) {
516   std::error_code EC;
517   raw_fd_ostream OS_FILE{OrigDIVerifyBugsReportFilePath, EC,
518                          sys::fs::OF_Append | sys::fs::OF_TextWithCRLF};
519   if (EC) {
520     errs() << "Could not open file: " << EC.message() << ", "
521            << OrigDIVerifyBugsReportFilePath << '\n';
522     return;
523   }
524 
525   if (auto L = OS_FILE.lock()) {
526     OS_FILE << "{\"file\":\"" << FileNameFromCU << "\", ";
527 
528     StringRef PassName =
529         NameOfWrappedPass != "" ? NameOfWrappedPass : "no-name";
530     OS_FILE << "\"pass\":\"" << PassName << "\", ";
531 
532     llvm::json::Value BugsToPrint{std::move(Bugs)};
533     OS_FILE << "\"bugs\": " << BugsToPrint;
534 
535     OS_FILE << "}\n";
536   }
537   OS_FILE.close();
538 }
539 
540 bool llvm::checkDebugInfoMetadata(Module &M,
541                                   iterator_range<Module::iterator> Functions,
542                                   DebugInfoPerPass &DebugInfoBeforePass,
543                                   StringRef Banner, StringRef NameOfWrappedPass,
544                                   StringRef OrigDIVerifyBugsReportFilePath) {
545   LLVM_DEBUG(dbgs() << Banner << ": (after) " << NameOfWrappedPass << '\n');
546 
547   if (!M.getNamedMetadata("llvm.dbg.cu")) {
548     dbg() << Banner << ": Skipping module without debug info\n";
549     return false;
550   }
551 
552   // Map the debug info holding DIs after a pass.
553   DebugInfoPerPass DebugInfoAfterPass;
554 
555   // Visit each instruction.
556   for (Function &F : Functions) {
557     if (isFunctionSkipped(F))
558       continue;
559 
560     // Don't process functions without DI collected before the Pass.
561     if (!DebugInfoBeforePass.DIFunctions.count(&F))
562       continue;
563     // TODO: Collect metadata other than DISubprograms.
564     // Collect the DISubprogram.
565     auto *SP = F.getSubprogram();
566     DebugInfoAfterPass.DIFunctions.insert({&F, SP});
567 
568     if (SP) {
569       LLVM_DEBUG(dbgs() << "  Collecting subprogram: " << *SP << '\n');
570       for (const DINode *DN : SP->getRetainedNodes()) {
571         if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
572           DebugInfoAfterPass.DIVariables[DV] = 0;
573         }
574       }
575     }
576 
577     for (BasicBlock &BB : F) {
578       // Collect debug locations (!dbg) and debug variable intrinsics.
579       for (Instruction &I : BB) {
580         // Skip PHIs.
581         if (isa<PHINode>(I))
582           continue;
583 
584         // Collect dbg.values and dbg.declares.
585         if (DebugifyLevel > Level::Locations) {
586           auto HandleDbgVariable = [&](auto *DbgVar) {
587             if (!SP)
588               return;
589             // Skip inlined variables.
590             if (DbgVar->getDebugLoc().getInlinedAt())
591               return;
592             // Skip undef values.
593             if (DbgVar->isKillLocation())
594               return;
595 
596             auto *Var = DbgVar->getVariable();
597             DebugInfoAfterPass.DIVariables[Var]++;
598           };
599           for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
600             HandleDbgVariable(&DVR);
601           if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
602             HandleDbgVariable(DVI);
603         }
604 
605         // Skip debug instructions other than dbg.value and dbg.declare.
606         if (isa<DbgInfoIntrinsic>(&I))
607           continue;
608 
609         LLVM_DEBUG(dbgs() << "  Collecting info for inst: " << I << '\n');
610 
611         const DILocation *Loc = I.getDebugLoc().get();
612         bool HasLoc = Loc != nullptr;
613 
614         DebugInfoAfterPass.DILocations.insert({&I, HasLoc});
615       }
616     }
617   }
618 
619   // TODO: The name of the module could be read better?
620   StringRef FileNameFromCU =
621       (cast<DICompileUnit>(M.getNamedMetadata("llvm.dbg.cu")->getOperand(0)))
622           ->getFilename();
623 
624   auto DIFunctionsBefore = DebugInfoBeforePass.DIFunctions;
625   auto DIFunctionsAfter = DebugInfoAfterPass.DIFunctions;
626 
627   auto DILocsBefore = DebugInfoBeforePass.DILocations;
628   auto DILocsAfter = DebugInfoAfterPass.DILocations;
629 
630   auto InstToDelete = DebugInfoBeforePass.InstToDelete;
631 
632   auto DIVarsBefore = DebugInfoBeforePass.DIVariables;
633   auto DIVarsAfter = DebugInfoAfterPass.DIVariables;
634 
635   bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.empty();
636   llvm::json::Array Bugs;
637 
638   bool ResultForFunc =
639       checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
640                      FileNameFromCU, ShouldWriteIntoJSON, Bugs);
641   bool ResultForInsts = checkInstructions(
642       DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass,
643       FileNameFromCU, ShouldWriteIntoJSON, Bugs);
644 
645   bool ResultForVars = checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass,
646                                  FileNameFromCU, ShouldWriteIntoJSON, Bugs);
647 
648   bool Result = ResultForFunc && ResultForInsts && ResultForVars;
649 
650   StringRef ResultBanner = NameOfWrappedPass != "" ? NameOfWrappedPass : Banner;
651   if (ShouldWriteIntoJSON && !Bugs.empty())
652     writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass,
653               Bugs);
654 
655   if (Result)
656     dbg() << ResultBanner << ": PASS\n";
657   else
658     dbg() << ResultBanner << ": FAIL\n";
659 
660   // In the case of the `debugify-each`, no need to go over all the instructions
661   // again in the collectDebugInfoMetadata(), since as an input we can use
662   // the debugging information from the previous pass.
663   DebugInfoBeforePass = DebugInfoAfterPass;
664 
665   LLVM_DEBUG(dbgs() << "\n\n");
666   return Result;
667 }
668 
669 namespace {
670 /// Return true if a mis-sized diagnostic is issued for \p DbgVal.
671 template <typename DbgValTy>
672 bool diagnoseMisSizedDbgValue(Module &M, DbgValTy *DbgVal) {
673   // The size of a dbg.value's value operand should match the size of the
674   // variable it corresponds to.
675   //
676   // TODO: This, along with a check for non-null value operands, should be
677   // promoted to verifier failures.
678 
679   // For now, don't try to interpret anything more complicated than an empty
680   // DIExpression. Eventually we should try to handle OP_deref and fragments.
681   if (DbgVal->getExpression()->getNumElements())
682     return false;
683 
684   Value *V = DbgVal->getVariableLocationOp(0);
685   if (!V)
686     return false;
687 
688   Type *Ty = V->getType();
689   uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
690   std::optional<uint64_t> DbgVarSize = DbgVal->getFragmentSizeInBits();
691   if (!ValueOperandSize || !DbgVarSize)
692     return false;
693 
694   bool HasBadSize = false;
695   if (Ty->isIntegerTy()) {
696     auto Signedness = DbgVal->getVariable()->getSignedness();
697     if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
698       HasBadSize = ValueOperandSize < *DbgVarSize;
699   } else {
700     HasBadSize = ValueOperandSize != *DbgVarSize;
701   }
702 
703   if (HasBadSize) {
704     dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
705           << ", but its variable has size " << *DbgVarSize << ": ";
706     DbgVal->print(dbg());
707     dbg() << "\n";
708   }
709   return HasBadSize;
710 }
711 
712 bool checkDebugifyMetadata(Module &M,
713                            iterator_range<Module::iterator> Functions,
714                            StringRef NameOfWrappedPass, StringRef Banner,
715                            bool Strip, DebugifyStatsMap *StatsMap) {
716   // Skip modules without debugify metadata.
717   NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
718   if (!NMD) {
719     dbg() << Banner << ": Skipping module without debugify metadata\n";
720     return false;
721   }
722 
723   auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
724     return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
725         ->getZExtValue();
726   };
727   assert(NMD->getNumOperands() == 2 &&
728          "llvm.debugify should have exactly 2 operands!");
729   unsigned OriginalNumLines = getDebugifyOperand(0);
730   unsigned OriginalNumVars = getDebugifyOperand(1);
731   bool HasErrors = false;
732 
733   // Track debug info loss statistics if able.
734   DebugifyStatistics *Stats = nullptr;
735   if (StatsMap && !NameOfWrappedPass.empty())
736     Stats = &StatsMap->operator[](NameOfWrappedPass);
737 
738   BitVector MissingLines{OriginalNumLines, true};
739   BitVector MissingVars{OriginalNumVars, true};
740   for (Function &F : Functions) {
741     if (isFunctionSkipped(F))
742       continue;
743 
744     // Find missing lines.
745     for (Instruction &I : instructions(F)) {
746       if (isa<DbgValueInst>(&I))
747         continue;
748 
749       auto DL = I.getDebugLoc();
750       if (DL && DL.getLine() != 0) {
751         MissingLines.reset(DL.getLine() - 1);
752         continue;
753       }
754 
755       if (!isa<PHINode>(&I) && !DL) {
756         dbg() << "WARNING: Instruction with empty DebugLoc in function ";
757         dbg() << F.getName() << " --";
758         I.print(dbg());
759         dbg() << "\n";
760       }
761     }
762 
763     // Find missing variables and mis-sized debug values.
764     auto CheckForMisSized = [&](auto *DbgVal) {
765       unsigned Var = ~0U;
766       (void)to_integer(DbgVal->getVariable()->getName(), Var, 10);
767       assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
768       bool HasBadSize = diagnoseMisSizedDbgValue(M, DbgVal);
769       if (!HasBadSize)
770         MissingVars.reset(Var - 1);
771       HasErrors |= HasBadSize;
772     };
773     for (Instruction &I : instructions(F)) {
774       for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
775         if (DVR.isDbgValue() || DVR.isDbgAssign())
776           CheckForMisSized(&DVR);
777       auto *DVI = dyn_cast<DbgValueInst>(&I);
778       if (!DVI)
779         continue;
780       CheckForMisSized(DVI);
781     }
782   }
783 
784   // Print the results.
785   for (unsigned Idx : MissingLines.set_bits())
786     dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
787 
788   for (unsigned Idx : MissingVars.set_bits())
789     dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
790 
791   // Update DI loss statistics.
792   if (Stats) {
793     Stats->NumDbgLocsExpected += OriginalNumLines;
794     Stats->NumDbgLocsMissing += MissingLines.count();
795     Stats->NumDbgValuesExpected += OriginalNumVars;
796     Stats->NumDbgValuesMissing += MissingVars.count();
797   }
798 
799   dbg() << Banner;
800   if (!NameOfWrappedPass.empty())
801     dbg() << " [" << NameOfWrappedPass << "]";
802   dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
803 
804   // Strip debugify metadata if required.
805   bool Ret = false;
806   if (Strip)
807     Ret = stripDebugifyMetadata(M);
808 
809   return Ret;
810 }
811 
812 /// ModulePass for attaching synthetic debug info to everything, used with the
813 /// legacy module pass manager.
814 struct DebugifyModulePass : public ModulePass {
815   bool runOnModule(Module &M) override {
816     bool Result =
817         applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass);
818     return Result;
819   }
820 
821   DebugifyModulePass(enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
822                      StringRef NameOfWrappedPass = "",
823                      DebugInfoPerPass *DebugInfoBeforePass = nullptr)
824       : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
825         DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
826 
827   void getAnalysisUsage(AnalysisUsage &AU) const override {
828     AU.setPreservesAll();
829   }
830 
831   static char ID; // Pass identification.
832 
833 private:
834   StringRef NameOfWrappedPass;
835   DebugInfoPerPass *DebugInfoBeforePass;
836   enum DebugifyMode Mode;
837 };
838 
839 /// FunctionPass for attaching synthetic debug info to instructions within a
840 /// single function, used with the legacy module pass manager.
841 struct DebugifyFunctionPass : public FunctionPass {
842   bool runOnFunction(Function &F) override {
843     bool Result =
844         applyDebugify(F, Mode, DebugInfoBeforePass, NameOfWrappedPass);
845     return Result;
846   }
847 
848   DebugifyFunctionPass(
849       enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
850       StringRef NameOfWrappedPass = "",
851       DebugInfoPerPass *DebugInfoBeforePass = nullptr)
852       : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
853         DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
854 
855   void getAnalysisUsage(AnalysisUsage &AU) const override {
856     AU.setPreservesAll();
857   }
858 
859   static char ID; // Pass identification.
860 
861 private:
862   StringRef NameOfWrappedPass;
863   DebugInfoPerPass *DebugInfoBeforePass;
864   enum DebugifyMode Mode;
865 };
866 
867 /// ModulePass for checking debug info inserted by -debugify, used with the
868 /// legacy module pass manager.
869 struct CheckDebugifyModulePass : public ModulePass {
870   bool runOnModule(Module &M) override {
871     bool Result;
872     if (Mode == DebugifyMode::SyntheticDebugInfo)
873       Result = checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
874                                    "CheckModuleDebugify", Strip, StatsMap);
875     else
876       Result = checkDebugInfoMetadata(
877         M, M.functions(), *DebugInfoBeforePass,
878         "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
879         OrigDIVerifyBugsReportFilePath);
880 
881     return Result;
882   }
883 
884   CheckDebugifyModulePass(
885       bool Strip = false, StringRef NameOfWrappedPass = "",
886       DebugifyStatsMap *StatsMap = nullptr,
887       enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
888       DebugInfoPerPass *DebugInfoBeforePass = nullptr,
889       StringRef OrigDIVerifyBugsReportFilePath = "")
890       : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
891         OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
892         StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
893         Strip(Strip) {}
894 
895   void getAnalysisUsage(AnalysisUsage &AU) const override {
896     AU.setPreservesAll();
897   }
898 
899   static char ID; // Pass identification.
900 
901 private:
902   StringRef NameOfWrappedPass;
903   StringRef OrigDIVerifyBugsReportFilePath;
904   DebugifyStatsMap *StatsMap;
905   DebugInfoPerPass *DebugInfoBeforePass;
906   enum DebugifyMode Mode;
907   bool Strip;
908 };
909 
910 /// FunctionPass for checking debug info inserted by -debugify-function, used
911 /// with the legacy module pass manager.
912 struct CheckDebugifyFunctionPass : public FunctionPass {
913   bool runOnFunction(Function &F) override {
914     Module &M = *F.getParent();
915     auto FuncIt = F.getIterator();
916     bool Result;
917     if (Mode == DebugifyMode::SyntheticDebugInfo)
918       Result = checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
919                                    NameOfWrappedPass, "CheckFunctionDebugify",
920                                    Strip, StatsMap);
921     else
922       Result = checkDebugInfoMetadata(
923         M, make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
924         "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
925         OrigDIVerifyBugsReportFilePath);
926 
927     return Result;
928   }
929 
930   CheckDebugifyFunctionPass(
931       bool Strip = false, StringRef NameOfWrappedPass = "",
932       DebugifyStatsMap *StatsMap = nullptr,
933       enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
934       DebugInfoPerPass *DebugInfoBeforePass = nullptr,
935       StringRef OrigDIVerifyBugsReportFilePath = "")
936       : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
937         OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
938         StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
939         Strip(Strip) {}
940 
941   void getAnalysisUsage(AnalysisUsage &AU) const override {
942     AU.setPreservesAll();
943   }
944 
945   static char ID; // Pass identification.
946 
947 private:
948   StringRef NameOfWrappedPass;
949   StringRef OrigDIVerifyBugsReportFilePath;
950   DebugifyStatsMap *StatsMap;
951   DebugInfoPerPass *DebugInfoBeforePass;
952   enum DebugifyMode Mode;
953   bool Strip;
954 };
955 
956 } // end anonymous namespace
957 
958 void llvm::exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map) {
959   std::error_code EC;
960   raw_fd_ostream OS{Path, EC};
961   if (EC) {
962     errs() << "Could not open file: " << EC.message() << ", " << Path << '\n';
963     return;
964   }
965 
966   OS << "Pass Name" << ',' << "# of missing debug values" << ','
967      << "# of missing locations" << ',' << "Missing/Expected value ratio" << ','
968      << "Missing/Expected location ratio" << '\n';
969   for (const auto &Entry : Map) {
970     StringRef Pass = Entry.first;
971     DebugifyStatistics Stats = Entry.second;
972 
973     OS << Pass << ',' << Stats.NumDbgValuesMissing << ','
974        << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ','
975        << Stats.getEmptyLocationRatio() << '\n';
976   }
977 }
978 
979 ModulePass *createDebugifyModulePass(enum DebugifyMode Mode,
980                                      llvm::StringRef NameOfWrappedPass,
981                                      DebugInfoPerPass *DebugInfoBeforePass) {
982   if (Mode == DebugifyMode::SyntheticDebugInfo)
983     return new DebugifyModulePass();
984   assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
985   return new DebugifyModulePass(Mode, NameOfWrappedPass, DebugInfoBeforePass);
986 }
987 
988 FunctionPass *
989 createDebugifyFunctionPass(enum DebugifyMode Mode,
990                            llvm::StringRef NameOfWrappedPass,
991                            DebugInfoPerPass *DebugInfoBeforePass) {
992   if (Mode == DebugifyMode::SyntheticDebugInfo)
993     return new DebugifyFunctionPass();
994   assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
995   return new DebugifyFunctionPass(Mode, NameOfWrappedPass, DebugInfoBeforePass);
996 }
997 
998 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
999   if (Mode == DebugifyMode::SyntheticDebugInfo)
1000     applyDebugifyMetadata(M, M.functions(),
1001                           "ModuleDebugify: ", /*ApplyToMF*/ nullptr);
1002   else
1003     collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass,
1004                              "ModuleDebugify (original debuginfo)",
1005                               NameOfWrappedPass);
1006 
1007   PreservedAnalyses PA;
1008   PA.preserveSet<CFGAnalyses>();
1009   return PA;
1010 }
1011 
1012 ModulePass *createCheckDebugifyModulePass(
1013     bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap,
1014     enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass,
1015     StringRef OrigDIVerifyBugsReportFilePath) {
1016   if (Mode == DebugifyMode::SyntheticDebugInfo)
1017     return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
1018   assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
1019   return new CheckDebugifyModulePass(false, NameOfWrappedPass, nullptr, Mode,
1020                                      DebugInfoBeforePass,
1021                                      OrigDIVerifyBugsReportFilePath);
1022 }
1023 
1024 FunctionPass *createCheckDebugifyFunctionPass(
1025     bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap,
1026     enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass,
1027     StringRef OrigDIVerifyBugsReportFilePath) {
1028   if (Mode == DebugifyMode::SyntheticDebugInfo)
1029     return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
1030   assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
1031   return new CheckDebugifyFunctionPass(false, NameOfWrappedPass, nullptr, Mode,
1032                                        DebugInfoBeforePass,
1033                                        OrigDIVerifyBugsReportFilePath);
1034 }
1035 
1036 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
1037                                               ModuleAnalysisManager &) {
1038   if (Mode == DebugifyMode::SyntheticDebugInfo)
1039     checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
1040                                    "CheckModuleDebugify", Strip, StatsMap);
1041   else
1042     checkDebugInfoMetadata(
1043       M, M.functions(), *DebugInfoBeforePass,
1044       "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
1045       OrigDIVerifyBugsReportFilePath);
1046 
1047   return PreservedAnalyses::all();
1048 }
1049 
1050 static bool isIgnoredPass(StringRef PassID) {
1051   return isSpecialPass(PassID, {"PassManager", "PassAdaptor",
1052                                 "AnalysisManagerProxy", "PrintFunctionPass",
1053                                 "PrintModulePass", "BitcodeWriterPass",
1054                                 "ThinLTOBitcodeWriterPass", "VerifierPass"});
1055 }
1056 
1057 void DebugifyEachInstrumentation::registerCallbacks(
1058     PassInstrumentationCallbacks &PIC, ModuleAnalysisManager &MAM) {
1059   PIC.registerBeforeNonSkippedPassCallback([this, &MAM](StringRef P, Any IR) {
1060     if (isIgnoredPass(P))
1061       return;
1062     PreservedAnalyses PA;
1063     PA.preserveSet<CFGAnalyses>();
1064     if (const auto **CF = llvm::any_cast<const Function *>(&IR)) {
1065       Function &F = *const_cast<Function *>(*CF);
1066       applyDebugify(F, Mode, DebugInfoBeforePass, P);
1067       MAM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent())
1068           .getManager()
1069           .invalidate(F, PA);
1070     } else if (const auto **CM = llvm::any_cast<const Module *>(&IR)) {
1071       Module &M = *const_cast<Module *>(*CM);
1072       applyDebugify(M, Mode, DebugInfoBeforePass, P);
1073       MAM.invalidate(M, PA);
1074     }
1075   });
1076   PIC.registerAfterPassCallback(
1077       [this, &MAM](StringRef P, Any IR, const PreservedAnalyses &PassPA) {
1078         if (isIgnoredPass(P))
1079           return;
1080         PreservedAnalyses PA;
1081         PA.preserveSet<CFGAnalyses>();
1082         if (const auto **CF = llvm::any_cast<const Function *>(&IR)) {
1083           auto &F = *const_cast<Function *>(*CF);
1084           Module &M = *F.getParent();
1085           auto It = F.getIterator();
1086           if (Mode == DebugifyMode::SyntheticDebugInfo)
1087             checkDebugifyMetadata(M, make_range(It, std::next(It)), P,
1088                                   "CheckFunctionDebugify", /*Strip=*/true,
1089                                   DIStatsMap);
1090           else
1091             checkDebugInfoMetadata(M, make_range(It, std::next(It)),
1092                                    *DebugInfoBeforePass,
1093                                    "CheckModuleDebugify (original debuginfo)",
1094                                    P, OrigDIVerifyBugsReportFilePath);
1095           MAM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent())
1096               .getManager()
1097               .invalidate(F, PA);
1098         } else if (const auto **CM = llvm::any_cast<const Module *>(&IR)) {
1099           Module &M = *const_cast<Module *>(*CM);
1100           if (Mode == DebugifyMode::SyntheticDebugInfo)
1101             checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify",
1102                                   /*Strip=*/true, DIStatsMap);
1103           else
1104             checkDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass,
1105                                    "CheckModuleDebugify (original debuginfo)",
1106                                    P, OrigDIVerifyBugsReportFilePath);
1107           MAM.invalidate(M, PA);
1108         }
1109       });
1110 }
1111 
1112 char DebugifyModulePass::ID = 0;
1113 static RegisterPass<DebugifyModulePass> DM("debugify",
1114                                            "Attach debug info to everything");
1115 
1116 char CheckDebugifyModulePass::ID = 0;
1117 static RegisterPass<CheckDebugifyModulePass>
1118     CDM("check-debugify", "Check debug info from -debugify");
1119 
1120 char DebugifyFunctionPass::ID = 0;
1121 static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
1122                                              "Attach debug info to a function");
1123 
1124 char CheckDebugifyFunctionPass::ID = 0;
1125 static RegisterPass<CheckDebugifyFunctionPass>
1126     CDF("check-debugify-function", "Check debug info from -debugify-function");
1127