blob: 3b1effba1592226f2500ff806e03c05be06fd515 [file] [log] [blame]
Vedant Kumar2cac1082017-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 Kumara4afd1f2018-07-24 00:41:28 +000015#include "Debugify.h"
Vedant Kumar2cac1082017-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 Kumarf0c081c2018-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 Kumaracc97932018-06-26 22:46:41 +000043uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
44 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
45}
46
Vedant Kumarda3c20c2018-02-15 21:28:38 +000047bool isFunctionSkipped(Function &F) {
48 return F.isDeclaration() || !F.hasExactDefinition();
49}
50
Vedant Kumara9595242018-06-06 19:05:42 +000051/// Find the basic block's terminating instruction.
Vedant Kumar0e9833d2018-06-05 00:56:07 +000052///
Vedant Kumara9595242018-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 Kumar0e9833d2018-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 Kumarb12dd1f2018-05-15 00:29:27 +000063bool applyDebugifyMetadata(Module &M,
64 iterator_range<Module::iterator> Functions,
65 StringRef Banner) {
Vedant Kumar2cac1082017-12-08 21:57:28 +000066 // Skip modules with debug info.
67 if (M.getNamedMetadata("llvm.dbg.cu")) {
Vedant Kumarf0c081c2018-06-06 19:05:41 +000068 dbg() << Banner << "Skipping module with debug info\n";
Vedant Kumar2cac1082017-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 Kumaracc97932018-06-26 22:46:41 +000078 uint64_t Size = getAllocSizeInBits(M, Ty);
Vedant Kumar2cac1082017-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 Kumar61b411c2018-06-05 00:56:07 +000090 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
91 /*isOptimized=*/true, "", 0);
Vedant Kumar2cac1082017-12-08 21:57:28 +000092
93 // Visit each instruction.
Vedant Kumarb12dd1f2018-05-15 00:29:27 +000094 for (Function &F : Functions) {
Vedant Kumarda3c20c2018-02-15 21:28:38 +000095 if (isFunctionSkipped(F))
Vedant Kumar2cac1082017-12-08 21:57:28 +000096 continue;
97
98 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
Paul Robinsoneaa73532018-11-19 18:29:28 +000099 DISubprogram::DISPFlags SPFlags =
100 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
101 if (F.hasPrivateLinkage() || F.hasInternalLinkage())
102 SPFlags |= DISubprogram::SPFlagLocalToUnit;
103 auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
104 SPType, NextLine, DINode::FlagZero, SPFlags);
Vedant Kumar2cac1082017-12-08 21:57:28 +0000105 F.setSubprogram(SP);
106 for (BasicBlock &BB : F) {
107 // Attach debug locations.
108 for (Instruction &I : BB)
109 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
110
Vedant Kumar23738502018-06-03 22:50:22 +0000111 // Inserting debug values into EH pads can break IR invariants.
112 if (BB.isEHPad())
113 continue;
114
Vedant Kumara9595242018-06-06 19:05:42 +0000115 // Find the terminating instruction, after which no debug values are
116 // attached.
117 Instruction *LastInst = findTerminatingInstruction(BB);
118 assert(LastInst && "Expected basic block with a terminator");
119
120 // Maintain an insertion point which can't be invalidated when updates
121 // are made.
122 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
123 assert(InsertPt != BB.end() && "Expected to find an insertion point");
124 Instruction *InsertBefore = &*InsertPt;
Vedant Kumar4f55de62018-06-04 03:33:01 +0000125
Vedant Kumar2cac1082017-12-08 21:57:28 +0000126 // Attach debug values.
Vedant Kumara9595242018-06-06 19:05:42 +0000127 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
Vedant Kumar2cac1082017-12-08 21:57:28 +0000128 // Skip void-valued instructions.
Vedant Kumara9595242018-06-06 19:05:42 +0000129 if (I->getType()->isVoidTy())
Vedant Kumar2cac1082017-12-08 21:57:28 +0000130 continue;
131
Vedant Kumara9595242018-06-06 19:05:42 +0000132 // Phis and EH pads must be grouped at the beginning of the block.
133 // Only advance the insertion point when we finish visiting these.
134 if (!isa<PHINode>(I) && !I->isEHPad())
135 InsertBefore = I->getNextNode();
Vedant Kumar2cac1082017-12-08 21:57:28 +0000136
137 std::string Name = utostr(NextVar++);
Vedant Kumara9595242018-06-06 19:05:42 +0000138 const DILocation *Loc = I->getDebugLoc().get();
Vedant Kumar2cac1082017-12-08 21:57:28 +0000139 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
Vedant Kumara9595242018-06-06 19:05:42 +0000140 getCachedDIType(I->getType()),
Vedant Kumar2cac1082017-12-08 21:57:28 +0000141 /*AlwaysPreserve=*/true);
Vedant Kumara9595242018-06-06 19:05:42 +0000142 DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc,
143 InsertBefore);
Vedant Kumar2cac1082017-12-08 21:57:28 +0000144 }
145 }
146 DIB.finalizeSubprogram(SP);
147 }
148 DIB.finalize();
149
150 // Track the number of distinct lines and variables.
151 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
152 auto *IntTy = Type::getInt32Ty(Ctx);
153 auto addDebugifyOperand = [&](unsigned N) {
154 NMD->addOperand(MDNode::get(
155 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N))));
156 };
157 addDebugifyOperand(NextLine - 1); // Original number of lines.
158 addDebugifyOperand(NextVar - 1); // Original number of variables.
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000159 assert(NMD->getNumOperands() == 2 &&
160 "llvm.debugify should have exactly 2 operands!");
Vedant Kumar646a7362018-05-24 23:00:23 +0000161
162 // Claim that this synthetic debug info is valid.
163 StringRef DIVersionKey = "Debug Info Version";
164 if (!M.getModuleFlag(DIVersionKey))
165 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
166
Vedant Kumar2cac1082017-12-08 21:57:28 +0000167 return true;
168}
169
Vedant Kumaracc97932018-06-26 22:46:41 +0000170/// Return true if a mis-sized diagnostic is issued for \p DVI.
171bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
172 // The size of a dbg.value's value operand should match the size of the
173 // variable it corresponds to.
174 //
175 // TODO: This, along with a check for non-null value operands, should be
176 // promoted to verifier failures.
177 Value *V = DVI->getValue();
178 if (!V)
179 return false;
180
181 // For now, don't try to interpret anything more complicated than an empty
182 // DIExpression. Eventually we should try to handle OP_deref and fragments.
183 if (DVI->getExpression()->getNumElements())
184 return false;
185
186 Type *Ty = V->getType();
187 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
Vedant Kumar3dbfeaf2018-06-27 00:47:52 +0000188 Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
189 if (!ValueOperandSize || !DbgVarSize)
190 return false;
191
Vedant Kumard3643492018-07-06 17:32:40 +0000192 bool HasBadSize = false;
193 if (Ty->isIntegerTy()) {
194 auto Signedness = DVI->getVariable()->getSignedness();
195 if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
196 HasBadSize = ValueOperandSize < *DbgVarSize;
197 } else {
198 HasBadSize = ValueOperandSize != *DbgVarSize;
199 }
200
Vedant Kumaracc97932018-06-26 22:46:41 +0000201 if (HasBadSize) {
202 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
Vedant Kumar3dbfeaf2018-06-27 00:47:52 +0000203 << ", but its variable has size " << *DbgVarSize << ": ";
Vedant Kumaracc97932018-06-26 22:46:41 +0000204 DVI->print(dbg());
205 dbg() << "\n";
206 }
207 return HasBadSize;
208}
209
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000210bool checkDebugifyMetadata(Module &M,
211 iterator_range<Module::iterator> Functions,
Vedant Kumar61b411c2018-06-05 00:56:07 +0000212 StringRef NameOfWrappedPass, StringRef Banner,
Vedant Kumar499e3df2018-07-24 00:41:29 +0000213 bool Strip, DebugifyStatsMap *StatsMap) {
Vedant Kumar2cac1082017-12-08 21:57:28 +0000214 // Skip modules without debugify metadata.
215 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000216 if (!NMD) {
Vedant Kumarf0c081c2018-06-06 19:05:41 +0000217 dbg() << Banner << "Skipping module without debugify metadata\n";
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000218 return false;
219 }
Vedant Kumar2cac1082017-12-08 21:57:28 +0000220
221 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
222 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
223 ->getZExtValue();
224 };
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000225 assert(NMD->getNumOperands() == 2 &&
226 "llvm.debugify should have exactly 2 operands!");
Vedant Kumar2cac1082017-12-08 21:57:28 +0000227 unsigned OriginalNumLines = getDebugifyOperand(0);
228 unsigned OriginalNumVars = getDebugifyOperand(1);
229 bool HasErrors = false;
230
Vedant Kumar499e3df2018-07-24 00:41:29 +0000231 // Track debug info loss statistics if able.
232 DebugifyStatistics *Stats = nullptr;
233 if (StatsMap && !NameOfWrappedPass.empty())
234 Stats = &StatsMap->operator[](NameOfWrappedPass);
235
Vedant Kumar2cac1082017-12-08 21:57:28 +0000236 BitVector MissingLines{OriginalNumLines, true};
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000237 BitVector MissingVars{OriginalNumVars, true};
238 for (Function &F : Functions) {
Vedant Kumarda3c20c2018-02-15 21:28:38 +0000239 if (isFunctionSkipped(F))
240 continue;
241
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000242 // Find missing lines.
Vedant Kumar2cac1082017-12-08 21:57:28 +0000243 for (Instruction &I : instructions(F)) {
244 if (isa<DbgValueInst>(&I))
245 continue;
246
247 auto DL = I.getDebugLoc();
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000248 if (DL && DL.getLine() != 0) {
Vedant Kumar2cac1082017-12-08 21:57:28 +0000249 MissingLines.reset(DL.getLine() - 1);
250 continue;
251 }
252
Vedant Kumar3d7cc9e2018-06-28 18:21:11 +0000253 if (!DL) {
254 dbg() << "ERROR: Instruction with empty DebugLoc in function ";
255 dbg() << F.getName() << " --";
256 I.print(dbg());
257 dbg() << "\n";
258 HasErrors = true;
259 }
Vedant Kumar2cac1082017-12-08 21:57:28 +0000260 }
Vedant Kumar2cac1082017-12-08 21:57:28 +0000261
Vedant Kumaracc97932018-06-26 22:46:41 +0000262 // Find missing variables and mis-sized debug values.
Vedant Kumar2cac1082017-12-08 21:57:28 +0000263 for (Instruction &I : instructions(F)) {
264 auto *DVI = dyn_cast<DbgValueInst>(&I);
265 if (!DVI)
266 continue;
267
268 unsigned Var = ~0U;
269 (void)to_integer(DVI->getVariable()->getName(), Var, 10);
270 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
Vedant Kumaracc97932018-06-26 22:46:41 +0000271 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
272 if (!HasBadSize)
273 MissingVars.reset(Var - 1);
274 HasErrors |= HasBadSize;
Vedant Kumar2cac1082017-12-08 21:57:28 +0000275 }
276 }
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000277
278 // Print the results.
279 for (unsigned Idx : MissingLines.set_bits())
Vedant Kumarf0c081c2018-06-06 19:05:41 +0000280 dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000281
Vedant Kumar2cac1082017-12-08 21:57:28 +0000282 for (unsigned Idx : MissingVars.set_bits())
Vedant Kumar92533692018-06-26 18:54:10 +0000283 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
Vedant Kumar2cac1082017-12-08 21:57:28 +0000284
Vedant Kumar499e3df2018-07-24 00:41:29 +0000285 // Update DI loss statistics.
286 if (Stats) {
287 Stats->NumDbgLocsExpected += OriginalNumLines;
288 Stats->NumDbgLocsMissing += MissingLines.count();
289 Stats->NumDbgValuesExpected += OriginalNumVars;
290 Stats->NumDbgValuesMissing += MissingVars.count();
291 }
292
Vedant Kumarf0c081c2018-06-06 19:05:41 +0000293 dbg() << Banner;
Vedant Kumar951e6052018-05-24 23:00:22 +0000294 if (!NameOfWrappedPass.empty())
Vedant Kumarf0c081c2018-06-06 19:05:41 +0000295 dbg() << " [" << NameOfWrappedPass << "]";
296 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000297
298 // Strip the Debugify Metadata if required.
299 if (Strip) {
300 StripDebugInfo(M);
301 M.eraseNamedMetadata(NMD);
302 return true;
303 }
304
305 return false;
Vedant Kumar2cac1082017-12-08 21:57:28 +0000306}
307
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000308/// ModulePass for attaching synthetic debug info to everything, used with the
309/// legacy module pass manager.
310struct DebugifyModulePass : public ModulePass {
311 bool runOnModule(Module &M) override {
312 return applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
313 }
Vedant Kumar2cac1082017-12-08 21:57:28 +0000314
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000315 DebugifyModulePass() : ModulePass(ID) {}
Vedant Kumar2cac1082017-12-08 21:57:28 +0000316
317 void getAnalysisUsage(AnalysisUsage &AU) const override {
318 AU.setPreservesAll();
319 }
320
321 static char ID; // Pass identification.
322};
323
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000324/// FunctionPass for attaching synthetic debug info to instructions within a
325/// single function, used with the legacy module pass manager.
326struct DebugifyFunctionPass : public FunctionPass {
327 bool runOnFunction(Function &F) override {
328 Module &M = *F.getParent();
329 auto FuncIt = F.getIterator();
330 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
Vedant Kumar61b411c2018-06-05 00:56:07 +0000331 "FunctionDebugify: ");
Vedant Kumar2cac1082017-12-08 21:57:28 +0000332 }
333
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000334 DebugifyFunctionPass() : FunctionPass(ID) {}
Vedant Kumar2cac1082017-12-08 21:57:28 +0000335
336 void getAnalysisUsage(AnalysisUsage &AU) const override {
337 AU.setPreservesAll();
338 }
339
340 static char ID; // Pass identification.
341};
342
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000343/// ModulePass for checking debug info inserted by -debugify, used with the
344/// legacy module pass manager.
345struct CheckDebugifyModulePass : public ModulePass {
346 bool runOnModule(Module &M) override {
Anastasis Grammenosd1460232018-05-15 23:38:05 +0000347 return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
Vedant Kumar499e3df2018-07-24 00:41:29 +0000348 "CheckModuleDebugify", Strip, StatsMap);
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000349 }
350
Vedant Kumar499e3df2018-07-24 00:41:29 +0000351 CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "",
352 DebugifyStatsMap *StatsMap = nullptr)
353 : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
354 StatsMap(StatsMap) {}
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000355
Vedant Kumar8c3bbfc2018-06-04 21:43:28 +0000356 void getAnalysisUsage(AnalysisUsage &AU) const override {
357 AU.setPreservesAll();
358 }
359
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000360 static char ID; // Pass identification.
361
362private:
363 bool Strip;
Anastasis Grammenosd1460232018-05-15 23:38:05 +0000364 StringRef NameOfWrappedPass;
Vedant Kumar499e3df2018-07-24 00:41:29 +0000365 DebugifyStatsMap *StatsMap;
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000366};
367
368/// FunctionPass for checking debug info inserted by -debugify-function, used
369/// with the legacy module pass manager.
370struct CheckDebugifyFunctionPass : public FunctionPass {
371 bool runOnFunction(Function &F) override {
372 Module &M = *F.getParent();
373 auto FuncIt = F.getIterator();
374 return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
Vedant Kumar646a7362018-05-24 23:00:23 +0000375 NameOfWrappedPass, "CheckFunctionDebugify",
Vedant Kumar499e3df2018-07-24 00:41:29 +0000376 Strip, StatsMap);
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000377 }
378
Vedant Kumar646a7362018-05-24 23:00:23 +0000379 CheckDebugifyFunctionPass(bool Strip = false,
Vedant Kumar499e3df2018-07-24 00:41:29 +0000380 StringRef NameOfWrappedPass = "",
381 DebugifyStatsMap *StatsMap = nullptr)
382 : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
383 StatsMap(StatsMap) {}
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000384
385 void getAnalysisUsage(AnalysisUsage &AU) const override {
386 AU.setPreservesAll();
387 }
388
389 static char ID; // Pass identification.
390
391private:
392 bool Strip;
Anastasis Grammenosd1460232018-05-15 23:38:05 +0000393 StringRef NameOfWrappedPass;
Vedant Kumar499e3df2018-07-24 00:41:29 +0000394 DebugifyStatsMap *StatsMap;
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000395};
396
Vedant Kumar2cac1082017-12-08 21:57:28 +0000397} // end anonymous namespace
398
Vedant Kumar499e3df2018-07-24 00:41:29 +0000399void exportDebugifyStats(llvm::StringRef Path, const DebugifyStatsMap &Map) {
400 std::error_code EC;
401 raw_fd_ostream OS{Path, EC};
402 if (EC) {
403 errs() << "Could not open file: " << EC.message() << ", " << Path << '\n';
404 return;
405 }
406
407 OS << "Pass Name" << ',' << "# of missing debug values" << ','
408 << "# of missing locations" << ',' << "Missing/Expected value ratio" << ','
409 << "Missing/Expected location ratio" << '\n';
410 for (const auto &Entry : Map) {
411 StringRef Pass = Entry.first;
412 DebugifyStatistics Stats = Entry.second;
413
414 OS << Pass << ',' << Stats.NumDbgValuesMissing << ','
415 << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ','
416 << Stats.getEmptyLocationRatio() << '\n';
417 }
418}
419
Vedant Kumar61b411c2018-06-05 00:56:07 +0000420ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000421
422FunctionPass *createDebugifyFunctionPass() {
423 return new DebugifyFunctionPass();
424}
Vedant Kumar48c582c2018-01-23 20:43:50 +0000425
Vedant Kumarb8c067b2018-02-15 21:14:36 +0000426PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000427 applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
Vedant Kumarb8c067b2018-02-15 21:14:36 +0000428 return PreservedAnalyses::all();
429}
430
Vedant Kumar63a0fe22018-06-04 00:11:47 +0000431ModulePass *createCheckDebugifyModulePass(bool Strip,
Vedant Kumar499e3df2018-07-24 00:41:29 +0000432 StringRef NameOfWrappedPass,
433 DebugifyStatsMap *StatsMap) {
434 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000435}
436
Vedant Kumar63a0fe22018-06-04 00:11:47 +0000437FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
Vedant Kumar499e3df2018-07-24 00:41:29 +0000438 StringRef NameOfWrappedPass,
439 DebugifyStatsMap *StatsMap) {
440 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000441}
Vedant Kumar48c582c2018-01-23 20:43:50 +0000442
Vedant Kumarb8c067b2018-02-15 21:14:36 +0000443PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
444 ModuleAnalysisManager &) {
Vedant Kumar499e3df2018-07-24 00:41:29 +0000445 checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
446 nullptr);
Vedant Kumarb8c067b2018-02-15 21:14:36 +0000447 return PreservedAnalyses::all();
448}
449
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000450char DebugifyModulePass::ID = 0;
451static RegisterPass<DebugifyModulePass> DM("debugify",
Vedant Kumar63a0fe22018-06-04 00:11:47 +0000452 "Attach debug info to everything");
Vedant Kumar2cac1082017-12-08 21:57:28 +0000453
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000454char CheckDebugifyModulePass::ID = 0;
Vedant Kumar63a0fe22018-06-04 00:11:47 +0000455static RegisterPass<CheckDebugifyModulePass>
456 CDM("check-debugify", "Check debug info from -debugify");
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000457
458char DebugifyFunctionPass::ID = 0;
459static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
Vedant Kumar63a0fe22018-06-04 00:11:47 +0000460 "Attach debug info to a function");
Vedant Kumarb12dd1f2018-05-15 00:29:27 +0000461
462char CheckDebugifyFunctionPass::ID = 0;
Vedant Kumar63a0fe22018-06-04 00:11:47 +0000463static RegisterPass<CheckDebugifyFunctionPass>
464 CDF("check-debugify-function", "Check debug info from -debugify-function");