blob: 54ff00849b0456ea9ed165a46450696781f63fb4 [file] [log] [blame]
Vedant Kumar195dfd12017-12-08 21:57:28 +00001//===- Debugify.cpp - Attach synthetic debug info to everything -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file This pass attaches synthetic debug info to everything. It can be used
11/// to create targeted tests for debug info preservation.
12///
13//===----------------------------------------------------------------------===//
14
Vedant Kumar775c7af2018-02-15 21:14:36 +000015#include "PassPrinters.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000016#include "llvm/ADT/BitVector.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/IR/BasicBlock.h"
19#include "llvm/IR/Constants.h"
20#include "llvm/IR/DIBuilder.h"
21#include "llvm/IR/DebugInfo.h"
22#include "llvm/IR/Function.h"
23#include "llvm/IR/GlobalVariable.h"
24#include "llvm/IR/InstIterator.h"
25#include "llvm/IR/Instruction.h"
26#include "llvm/IR/Instructions.h"
27#include "llvm/IR/IntrinsicInst.h"
28#include "llvm/IR/Module.h"
29#include "llvm/IR/Type.h"
30#include "llvm/Pass.h"
31#include "llvm/Support/raw_ostream.h"
32#include "llvm/Transforms/IPO.h"
33
34using namespace llvm;
35
36namespace {
37
Vedant Kumara9e27312018-06-06 19:05:41 +000038cl::opt<bool> Quiet("debugify-quiet",
39 cl::desc("Suppress verbose debugify output"));
40
41raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
42
Vedant Kumarb9c1a232018-06-26 22:46:41 +000043uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
44 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
45}
46
Vedant Kumar17d8bba2018-02-15 21:28:38 +000047bool isFunctionSkipped(Function &F) {
48 return F.isDeclaration() || !F.hasExactDefinition();
49}
50
Vedant Kumar6d354ed2018-06-06 19:05:42 +000051/// Find the basic block's terminating instruction.
Vedant Kumar800255f2018-06-05 00:56:07 +000052///
Vedant Kumar6d354ed2018-06-06 19:05:42 +000053/// Special care is needed to handle musttail and deopt calls, as these behave
54/// like (but are in fact not) terminators.
55Instruction *findTerminatingInstruction(BasicBlock &BB) {
Vedant Kumar800255f2018-06-05 00:56:07 +000056 if (auto *I = BB.getTerminatingMustTailCall())
57 return I;
58 if (auto *I = BB.getTerminatingDeoptimizeCall())
59 return I;
60 return BB.getTerminator();
61}
62
Vedant Kumar595ba1d2018-05-15 00:29:27 +000063bool applyDebugifyMetadata(Module &M,
64 iterator_range<Module::iterator> Functions,
65 StringRef Banner) {
Vedant Kumar195dfd12017-12-08 21:57:28 +000066 // Skip modules with debug info.
67 if (M.getNamedMetadata("llvm.dbg.cu")) {
Vedant Kumara9e27312018-06-06 19:05:41 +000068 dbg() << Banner << "Skipping module with debug info\n";
Vedant Kumar195dfd12017-12-08 21:57:28 +000069 return false;
70 }
71
72 DIBuilder DIB(M);
73 LLVMContext &Ctx = M.getContext();
74
75 // Get a DIType which corresponds to Ty.
76 DenseMap<uint64_t, DIType *> TypeCache;
77 auto getCachedDIType = [&](Type *Ty) -> DIType * {
Vedant Kumarb9c1a232018-06-26 22:46:41 +000078 uint64_t Size = getAllocSizeInBits(M, Ty);
Vedant Kumar195dfd12017-12-08 21:57:28 +000079 DIType *&DTy = TypeCache[Size];
80 if (!DTy) {
81 std::string Name = "ty" + utostr(Size);
82 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
83 }
84 return DTy;
85 };
86
87 unsigned NextLine = 1;
88 unsigned NextVar = 1;
89 auto File = DIB.createFile(M.getName(), "/");
Vedant Kumarab112b82018-06-05 00:56:07 +000090 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
91 /*isOptimized=*/true, "", 0);
Vedant Kumar195dfd12017-12-08 21:57:28 +000092
93 // Visit each instruction.
Vedant Kumar595ba1d2018-05-15 00:29:27 +000094 for (Function &F : Functions) {
Vedant Kumar17d8bba2018-02-15 21:28:38 +000095 if (isFunctionSkipped(F))
Vedant Kumar195dfd12017-12-08 21:57:28 +000096 continue;
97
98 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
99 bool IsLocalToUnit = F.hasPrivateLinkage() || F.hasInternalLinkage();
100 auto SP =
101 DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, SPType,
Vedant Kumar16276322018-02-13 18:15:27 +0000102 IsLocalToUnit, /*isDefinition=*/true, NextLine,
Vedant Kumar195dfd12017-12-08 21:57:28 +0000103 DINode::FlagZero, /*isOptimized=*/true);
104 F.setSubprogram(SP);
105 for (BasicBlock &BB : F) {
106 // Attach debug locations.
107 for (Instruction &I : BB)
108 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
109
Vedant Kumar77f4d4d2018-06-03 22:50:22 +0000110 // Inserting debug values into EH pads can break IR invariants.
111 if (BB.isEHPad())
112 continue;
113
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000114 // Find the terminating instruction, after which no debug values are
115 // attached.
116 Instruction *LastInst = findTerminatingInstruction(BB);
117 assert(LastInst && "Expected basic block with a terminator");
118
119 // Maintain an insertion point which can't be invalidated when updates
120 // are made.
121 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
122 assert(InsertPt != BB.end() && "Expected to find an insertion point");
123 Instruction *InsertBefore = &*InsertPt;
Vedant Kumar7dda2212018-06-04 03:33:01 +0000124
Vedant Kumar195dfd12017-12-08 21:57:28 +0000125 // Attach debug values.
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000126 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
Vedant Kumar195dfd12017-12-08 21:57:28 +0000127 // Skip void-valued instructions.
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000128 if (I->getType()->isVoidTy())
Vedant Kumar195dfd12017-12-08 21:57:28 +0000129 continue;
130
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000131 // Phis and EH pads must be grouped at the beginning of the block.
132 // Only advance the insertion point when we finish visiting these.
133 if (!isa<PHINode>(I) && !I->isEHPad())
134 InsertBefore = I->getNextNode();
Vedant Kumar195dfd12017-12-08 21:57:28 +0000135
136 std::string Name = utostr(NextVar++);
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000137 const DILocation *Loc = I->getDebugLoc().get();
Vedant Kumar195dfd12017-12-08 21:57:28 +0000138 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000139 getCachedDIType(I->getType()),
Vedant Kumar195dfd12017-12-08 21:57:28 +0000140 /*AlwaysPreserve=*/true);
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000141 DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc,
142 InsertBefore);
Vedant Kumar195dfd12017-12-08 21:57:28 +0000143 }
144 }
145 DIB.finalizeSubprogram(SP);
146 }
147 DIB.finalize();
148
149 // Track the number of distinct lines and variables.
150 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
151 auto *IntTy = Type::getInt32Ty(Ctx);
152 auto addDebugifyOperand = [&](unsigned N) {
153 NMD->addOperand(MDNode::get(
154 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N))));
155 };
156 addDebugifyOperand(NextLine - 1); // Original number of lines.
157 addDebugifyOperand(NextVar - 1); // Original number of variables.
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000158 assert(NMD->getNumOperands() == 2 &&
159 "llvm.debugify should have exactly 2 operands!");
Vedant Kumar4872535e2018-05-24 23:00:23 +0000160
161 // Claim that this synthetic debug info is valid.
162 StringRef DIVersionKey = "Debug Info Version";
163 if (!M.getModuleFlag(DIVersionKey))
164 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
165
Vedant Kumar195dfd12017-12-08 21:57:28 +0000166 return true;
167}
168
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000169/// Return true if a mis-sized diagnostic is issued for \p DVI.
170bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
171 // The size of a dbg.value's value operand should match the size of the
172 // variable it corresponds to.
173 //
174 // TODO: This, along with a check for non-null value operands, should be
175 // promoted to verifier failures.
176 Value *V = DVI->getValue();
177 if (!V)
178 return false;
179
180 // For now, don't try to interpret anything more complicated than an empty
181 // DIExpression. Eventually we should try to handle OP_deref and fragments.
182 if (DVI->getExpression()->getNumElements())
183 return false;
184
185 Type *Ty = V->getType();
186 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
187 uint64_t DbgVarSize = *DVI->getFragmentSizeInBits();
188 bool HasBadSize = Ty->isIntegerTy() ? (ValueOperandSize < DbgVarSize)
189 : (ValueOperandSize != DbgVarSize);
190 if (HasBadSize) {
191 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
192 << ", but its variable has size " << DbgVarSize << ": ";
193 DVI->print(dbg());
194 dbg() << "\n";
195 }
196 return HasBadSize;
197}
198
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000199bool checkDebugifyMetadata(Module &M,
200 iterator_range<Module::iterator> Functions,
Vedant Kumarab112b82018-06-05 00:56:07 +0000201 StringRef NameOfWrappedPass, StringRef Banner,
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000202 bool Strip) {
Vedant Kumar195dfd12017-12-08 21:57:28 +0000203 // Skip modules without debugify metadata.
204 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000205 if (!NMD) {
Vedant Kumara9e27312018-06-06 19:05:41 +0000206 dbg() << Banner << "Skipping module without debugify metadata\n";
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000207 return false;
208 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000209
210 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
211 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
212 ->getZExtValue();
213 };
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000214 assert(NMD->getNumOperands() == 2 &&
215 "llvm.debugify should have exactly 2 operands!");
Vedant Kumar195dfd12017-12-08 21:57:28 +0000216 unsigned OriginalNumLines = getDebugifyOperand(0);
217 unsigned OriginalNumVars = getDebugifyOperand(1);
218 bool HasErrors = false;
219
Vedant Kumar195dfd12017-12-08 21:57:28 +0000220 BitVector MissingLines{OriginalNumLines, true};
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000221 BitVector MissingVars{OriginalNumVars, true};
222 for (Function &F : Functions) {
Vedant Kumar17d8bba2018-02-15 21:28:38 +0000223 if (isFunctionSkipped(F))
224 continue;
225
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000226 // Find missing lines.
Vedant Kumar195dfd12017-12-08 21:57:28 +0000227 for (Instruction &I : instructions(F)) {
228 if (isa<DbgValueInst>(&I))
229 continue;
230
231 auto DL = I.getDebugLoc();
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000232 if (DL && DL.getLine() != 0) {
Vedant Kumar195dfd12017-12-08 21:57:28 +0000233 MissingLines.reset(DL.getLine() - 1);
234 continue;
235 }
236
Vedant Kumara9e27312018-06-06 19:05:41 +0000237 dbg() << "ERROR: Instruction with empty DebugLoc in function ";
238 dbg() << F.getName() << " --";
239 I.print(dbg());
240 dbg() << "\n";
Vedant Kumar195dfd12017-12-08 21:57:28 +0000241 HasErrors = true;
242 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000243
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000244 // Find missing variables and mis-sized debug values.
Vedant Kumar195dfd12017-12-08 21:57:28 +0000245 for (Instruction &I : instructions(F)) {
246 auto *DVI = dyn_cast<DbgValueInst>(&I);
247 if (!DVI)
248 continue;
249
250 unsigned Var = ~0U;
251 (void)to_integer(DVI->getVariable()->getName(), Var, 10);
252 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000253 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
254 if (!HasBadSize)
255 MissingVars.reset(Var - 1);
256 HasErrors |= HasBadSize;
Vedant Kumar195dfd12017-12-08 21:57:28 +0000257 }
258 }
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000259
260 // Print the results.
261 for (unsigned Idx : MissingLines.set_bits())
Vedant Kumara9e27312018-06-06 19:05:41 +0000262 dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000263
Vedant Kumar195dfd12017-12-08 21:57:28 +0000264 for (unsigned Idx : MissingVars.set_bits())
Vedant Kumar2e6c5f92018-06-26 18:54:10 +0000265 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
Vedant Kumar195dfd12017-12-08 21:57:28 +0000266
Vedant Kumara9e27312018-06-06 19:05:41 +0000267 dbg() << Banner;
Vedant Kumarb70e3562018-05-24 23:00:22 +0000268 if (!NameOfWrappedPass.empty())
Vedant Kumara9e27312018-06-06 19:05:41 +0000269 dbg() << " [" << NameOfWrappedPass << "]";
270 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000271
272 // Strip the Debugify Metadata if required.
273 if (Strip) {
274 StripDebugInfo(M);
275 M.eraseNamedMetadata(NMD);
276 return true;
277 }
278
279 return false;
Vedant Kumar195dfd12017-12-08 21:57:28 +0000280}
281
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000282/// ModulePass for attaching synthetic debug info to everything, used with the
283/// legacy module pass manager.
284struct DebugifyModulePass : public ModulePass {
285 bool runOnModule(Module &M) override {
286 return applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
287 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000288
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000289 DebugifyModulePass() : ModulePass(ID) {}
Vedant Kumar195dfd12017-12-08 21:57:28 +0000290
291 void getAnalysisUsage(AnalysisUsage &AU) const override {
292 AU.setPreservesAll();
293 }
294
295 static char ID; // Pass identification.
296};
297
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000298/// FunctionPass for attaching synthetic debug info to instructions within a
299/// single function, used with the legacy module pass manager.
300struct DebugifyFunctionPass : public FunctionPass {
301 bool runOnFunction(Function &F) override {
302 Module &M = *F.getParent();
303 auto FuncIt = F.getIterator();
304 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
Vedant Kumarab112b82018-06-05 00:56:07 +0000305 "FunctionDebugify: ");
Vedant Kumar195dfd12017-12-08 21:57:28 +0000306 }
307
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000308 DebugifyFunctionPass() : FunctionPass(ID) {}
Vedant Kumar195dfd12017-12-08 21:57:28 +0000309
310 void getAnalysisUsage(AnalysisUsage &AU) const override {
311 AU.setPreservesAll();
312 }
313
314 static char ID; // Pass identification.
315};
316
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000317/// ModulePass for checking debug info inserted by -debugify, used with the
318/// legacy module pass manager.
319struct CheckDebugifyModulePass : public ModulePass {
320 bool runOnModule(Module &M) override {
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000321 return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
322 "CheckModuleDebugify", Strip);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000323 }
324
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000325 CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "")
326 : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass) {}
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000327
Vedant Kumarfb7c7682018-06-04 21:43:28 +0000328 void getAnalysisUsage(AnalysisUsage &AU) const override {
329 AU.setPreservesAll();
330 }
331
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000332 static char ID; // Pass identification.
333
334private:
335 bool Strip;
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000336 StringRef NameOfWrappedPass;
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000337};
338
339/// FunctionPass for checking debug info inserted by -debugify-function, used
340/// with the legacy module pass manager.
341struct CheckDebugifyFunctionPass : public FunctionPass {
342 bool runOnFunction(Function &F) override {
343 Module &M = *F.getParent();
344 auto FuncIt = F.getIterator();
345 return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
Vedant Kumar4872535e2018-05-24 23:00:23 +0000346 NameOfWrappedPass, "CheckFunctionDebugify",
347 Strip);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000348 }
349
Vedant Kumar4872535e2018-05-24 23:00:23 +0000350 CheckDebugifyFunctionPass(bool Strip = false,
351 StringRef NameOfWrappedPass = "")
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000352 : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass) {}
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000353
354 void getAnalysisUsage(AnalysisUsage &AU) const override {
355 AU.setPreservesAll();
356 }
357
358 static char ID; // Pass identification.
359
360private:
361 bool Strip;
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000362 StringRef NameOfWrappedPass;
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000363};
364
Vedant Kumar195dfd12017-12-08 21:57:28 +0000365} // end anonymous namespace
366
Vedant Kumarab112b82018-06-05 00:56:07 +0000367ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000368
369FunctionPass *createDebugifyFunctionPass() {
370 return new DebugifyFunctionPass();
371}
Vedant Kumar92f7a622018-01-23 20:43:50 +0000372
Vedant Kumar775c7af2018-02-15 21:14:36 +0000373PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000374 applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
Vedant Kumar775c7af2018-02-15 21:14:36 +0000375 return PreservedAnalyses::all();
376}
377
Vedant Kumar36b89d42018-06-04 00:11:47 +0000378ModulePass *createCheckDebugifyModulePass(bool Strip,
379 StringRef NameOfWrappedPass) {
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000380 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000381}
382
Vedant Kumar36b89d42018-06-04 00:11:47 +0000383FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
384 StringRef NameOfWrappedPass) {
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000385 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000386}
Vedant Kumar92f7a622018-01-23 20:43:50 +0000387
Vedant Kumar775c7af2018-02-15 21:14:36 +0000388PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
389 ModuleAnalysisManager &) {
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000390 checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false);
Vedant Kumar775c7af2018-02-15 21:14:36 +0000391 return PreservedAnalyses::all();
392}
393
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000394char DebugifyModulePass::ID = 0;
395static RegisterPass<DebugifyModulePass> DM("debugify",
Vedant Kumar36b89d42018-06-04 00:11:47 +0000396 "Attach debug info to everything");
Vedant Kumar195dfd12017-12-08 21:57:28 +0000397
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000398char CheckDebugifyModulePass::ID = 0;
Vedant Kumar36b89d42018-06-04 00:11:47 +0000399static RegisterPass<CheckDebugifyModulePass>
400 CDM("check-debugify", "Check debug info from -debugify");
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000401
402char DebugifyFunctionPass::ID = 0;
403static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
Vedant Kumar36b89d42018-06-04 00:11:47 +0000404 "Attach debug info to a function");
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000405
406char CheckDebugifyFunctionPass::ID = 0;
Vedant Kumar36b89d42018-06-04 00:11:47 +0000407static RegisterPass<CheckDebugifyFunctionPass>
408 CDF("check-debugify-function", "Check debug info from -debugify-function");