blob: 8f98d81a3d797ddc7f3f2fee21f9e2c7833ad4fd [file] [log] [blame]
Vedant Kumar195dfd12017-12-08 21:57:28 +00001//===- Debugify.cpp - Attach synthetic debug info to everything -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Vedant Kumar195dfd12017-12-08 21:57:28 +00006//
7//===----------------------------------------------------------------------===//
8///
9/// \file This pass attaches synthetic debug info to everything. It can be used
10/// to create targeted tests for debug info preservation.
11///
12//===----------------------------------------------------------------------===//
13
Reid Kleckner4c1a1d32019-11-14 15:15:48 -080014#include "llvm/Transforms/Utils/Debugify.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000015#include "llvm/ADT/BitVector.h"
16#include "llvm/ADT/StringExtras.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000017#include "llvm/IR/DIBuilder.h"
18#include "llvm/IR/DebugInfo.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000019#include "llvm/IR/InstIterator.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000020#include "llvm/IR/Instructions.h"
21#include "llvm/IR/IntrinsicInst.h"
Simon Pilgrim0128b952020-07-24 13:02:33 +010022#include "llvm/IR/Module.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000023#include "llvm/Pass.h"
Reid Kleckner4c1a1d32019-11-14 15:15:48 -080024#include "llvm/Support/CommandLine.h"
Vedant Kumar195dfd12017-12-08 21:57:28 +000025
26using namespace llvm;
27
28namespace {
29
Vedant Kumara9e27312018-06-06 19:05:41 +000030cl::opt<bool> Quiet("debugify-quiet",
31 cl::desc("Suppress verbose debugify output"));
32
Daniel Sanders15f7bc72020-04-03 15:50:11 -070033enum class Level {
34 Locations,
35 LocationsAndVariables
36};
37cl::opt<Level> DebugifyLevel(
38 "debugify-level", cl::desc("Kind of debug info to add"),
39 cl::values(clEnumValN(Level::Locations, "locations", "Locations only"),
40 clEnumValN(Level::LocationsAndVariables, "location+variables",
41 "Locations and Variables")),
42 cl::init(Level::LocationsAndVariables));
43
Vedant Kumara9e27312018-06-06 19:05:41 +000044raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
45
Vedant Kumarb9c1a232018-06-26 22:46:41 +000046uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
47 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
48}
49
Vedant Kumar17d8bba2018-02-15 21:28:38 +000050bool isFunctionSkipped(Function &F) {
51 return F.isDeclaration() || !F.hasExactDefinition();
52}
53
Vedant Kumar6d354ed2018-06-06 19:05:42 +000054/// Find the basic block's terminating instruction.
Vedant Kumar800255f2018-06-05 00:56:07 +000055///
Vedant Kumar6d354ed2018-06-06 19:05:42 +000056/// Special care is needed to handle musttail and deopt calls, as these behave
57/// like (but are in fact not) terminators.
58Instruction *findTerminatingInstruction(BasicBlock &BB) {
Vedant Kumar800255f2018-06-05 00:56:07 +000059 if (auto *I = BB.getTerminatingMustTailCall())
60 return I;
61 if (auto *I = BB.getTerminatingDeoptimizeCall())
62 return I;
63 return BB.getTerminator();
64}
Daniel Sanders1adeeab2020-04-03 16:18:45 -070065} // end anonymous namespace
Vedant Kumar800255f2018-06-05 00:56:07 +000066
Daniel Sanders1adeeab2020-04-03 16:18:45 -070067bool llvm::applyDebugifyMetadata(
68 Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
69 std::function<bool(DIBuilder &DIB, Function &F)> ApplyToMF) {
Vedant Kumar195dfd12017-12-08 21:57:28 +000070 // Skip modules with debug info.
71 if (M.getNamedMetadata("llvm.dbg.cu")) {
Vedant Kumara9e27312018-06-06 19:05:41 +000072 dbg() << Banner << "Skipping module with debug info\n";
Vedant Kumar195dfd12017-12-08 21:57:28 +000073 return false;
74 }
75
76 DIBuilder DIB(M);
77 LLVMContext &Ctx = M.getContext();
Vedant Kumar2a5675f2020-04-13 16:15:37 -070078 auto *Int32Ty = Type::getInt32Ty(Ctx);
Vedant Kumar195dfd12017-12-08 21:57:28 +000079
80 // Get a DIType which corresponds to Ty.
81 DenseMap<uint64_t, DIType *> TypeCache;
82 auto getCachedDIType = [&](Type *Ty) -> DIType * {
Vedant Kumarb9c1a232018-06-26 22:46:41 +000083 uint64_t Size = getAllocSizeInBits(M, Ty);
Vedant Kumar195dfd12017-12-08 21:57:28 +000084 DIType *&DTy = TypeCache[Size];
85 if (!DTy) {
86 std::string Name = "ty" + utostr(Size);
87 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
88 }
89 return DTy;
90 };
91
92 unsigned NextLine = 1;
93 unsigned NextVar = 1;
94 auto File = DIB.createFile(M.getName(), "/");
Vedant Kumarab112b82018-06-05 00:56:07 +000095 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
96 /*isOptimized=*/true, "", 0);
Vedant Kumar195dfd12017-12-08 21:57:28 +000097
98 // Visit each instruction.
Vedant Kumar595ba1d2018-05-15 00:29:27 +000099 for (Function &F : Functions) {
Vedant Kumar17d8bba2018-02-15 21:28:38 +0000100 if (isFunctionSkipped(F))
Vedant Kumar195dfd12017-12-08 21:57:28 +0000101 continue;
102
Vedant Kumar2a5675f2020-04-13 16:15:37 -0700103 bool InsertedDbgVal = false;
Vedant Kumar195dfd12017-12-08 21:57:28 +0000104 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
Paul Robinsoncda54212018-11-19 18:29:28 +0000105 DISubprogram::DISPFlags SPFlags =
106 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
107 if (F.hasPrivateLinkage() || F.hasInternalLinkage())
108 SPFlags |= DISubprogram::SPFlagLocalToUnit;
109 auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
110 SPType, NextLine, DINode::FlagZero, SPFlags);
Vedant Kumar195dfd12017-12-08 21:57:28 +0000111 F.setSubprogram(SP);
Vedant Kumar2a5675f2020-04-13 16:15:37 -0700112
113 // Helper that inserts a dbg.value before \p InsertBefore, copying the
114 // location (and possibly the type, if it's non-void) from \p TemplateInst.
115 auto insertDbgVal = [&](Instruction &TemplateInst,
116 Instruction *InsertBefore) {
117 std::string Name = utostr(NextVar++);
118 Value *V = &TemplateInst;
119 if (TemplateInst.getType()->isVoidTy())
120 V = ConstantInt::get(Int32Ty, 0);
121 const DILocation *Loc = TemplateInst.getDebugLoc().get();
122 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
123 getCachedDIType(V->getType()),
124 /*AlwaysPreserve=*/true);
125 DIB.insertDbgValueIntrinsic(V, LocalVar, DIB.createExpression(), Loc,
126 InsertBefore);
127 };
128
Vedant Kumar195dfd12017-12-08 21:57:28 +0000129 for (BasicBlock &BB : F) {
130 // Attach debug locations.
131 for (Instruction &I : BB)
132 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
133
Daniel Sanders15f7bc72020-04-03 15:50:11 -0700134 if (DebugifyLevel < Level::LocationsAndVariables)
135 continue;
136
Vedant Kumar77f4d4d2018-06-03 22:50:22 +0000137 // Inserting debug values into EH pads can break IR invariants.
138 if (BB.isEHPad())
139 continue;
140
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000141 // Find the terminating instruction, after which no debug values are
142 // attached.
143 Instruction *LastInst = findTerminatingInstruction(BB);
144 assert(LastInst && "Expected basic block with a terminator");
145
146 // Maintain an insertion point which can't be invalidated when updates
147 // are made.
148 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
149 assert(InsertPt != BB.end() && "Expected to find an insertion point");
150 Instruction *InsertBefore = &*InsertPt;
Vedant Kumar7dda2212018-06-04 03:33:01 +0000151
Vedant Kumar195dfd12017-12-08 21:57:28 +0000152 // Attach debug values.
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000153 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
Vedant Kumar195dfd12017-12-08 21:57:28 +0000154 // Skip void-valued instructions.
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000155 if (I->getType()->isVoidTy())
Vedant Kumar195dfd12017-12-08 21:57:28 +0000156 continue;
157
Vedant Kumar6d354ed2018-06-06 19:05:42 +0000158 // Phis and EH pads must be grouped at the beginning of the block.
159 // Only advance the insertion point when we finish visiting these.
160 if (!isa<PHINode>(I) && !I->isEHPad())
161 InsertBefore = I->getNextNode();
Vedant Kumar195dfd12017-12-08 21:57:28 +0000162
Vedant Kumar2a5675f2020-04-13 16:15:37 -0700163 insertDbgVal(*I, InsertBefore);
164 InsertedDbgVal = true;
Vedant Kumar195dfd12017-12-08 21:57:28 +0000165 }
166 }
Vedant Kumar2a5675f2020-04-13 16:15:37 -0700167 // Make sure we emit at least one dbg.value, otherwise MachineDebugify may
168 // not have anything to work with as it goes about inserting DBG_VALUEs.
169 // (It's common for MIR tests to be written containing skeletal IR with
170 // empty functions -- we're still interested in debugifying the MIR within
171 // those tests, and this helps with that.)
172 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
173 auto *Term = findTerminatingInstruction(F.getEntryBlock());
174 insertDbgVal(*Term, Term);
175 }
Daniel Sanders1adeeab2020-04-03 16:18:45 -0700176 if (ApplyToMF)
177 ApplyToMF(DIB, F);
Vedant Kumar195dfd12017-12-08 21:57:28 +0000178 DIB.finalizeSubprogram(SP);
179 }
180 DIB.finalize();
181
182 // Track the number of distinct lines and variables.
183 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
Vedant Kumar195dfd12017-12-08 21:57:28 +0000184 auto addDebugifyOperand = [&](unsigned N) {
185 NMD->addOperand(MDNode::get(
Vedant Kumar2a5675f2020-04-13 16:15:37 -0700186 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N))));
Vedant Kumar195dfd12017-12-08 21:57:28 +0000187 };
188 addDebugifyOperand(NextLine - 1); // Original number of lines.
189 addDebugifyOperand(NextVar - 1); // Original number of variables.
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000190 assert(NMD->getNumOperands() == 2 &&
191 "llvm.debugify should have exactly 2 operands!");
Vedant Kumar4872535e2018-05-24 23:00:23 +0000192
193 // Claim that this synthetic debug info is valid.
194 StringRef DIVersionKey = "Debug Info Version";
195 if (!M.getModuleFlag(DIVersionKey))
196 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
197
Vedant Kumar195dfd12017-12-08 21:57:28 +0000198 return true;
199}
200
Vedant Kumar122a6bf2020-04-10 14:58:13 -0700201bool llvm::stripDebugifyMetadata(Module &M) {
202 bool Changed = false;
203
204 // Remove the llvm.debugify module-level named metadata.
205 NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify");
206 if (DebugifyMD) {
207 M.eraseNamedMetadata(DebugifyMD);
208 Changed = true;
209 }
210
211 // Strip out all debug intrinsics and supporting metadata (subprograms, types,
212 // variables, etc).
213 Changed |= StripDebugInfo(M);
214
215 // Strip out the dead dbg.value prototype.
216 Function *DbgValF = M.getFunction("llvm.dbg.value");
217 if (DbgValF) {
218 assert(DbgValF->isDeclaration() && DbgValF->use_empty() &&
219 "Not all debug info stripped?");
220 DbgValF->eraseFromParent();
221 Changed = true;
222 }
223
224 // Strip out the module-level Debug Info Version metadata.
225 // FIXME: There must be an easier way to remove an operand from a NamedMDNode.
226 NamedMDNode *NMD = M.getModuleFlagsMetadata();
Vedant Kumar2fa656c2020-04-17 17:53:14 -0700227 if (!NMD)
228 return Changed;
Vedant Kumar122a6bf2020-04-10 14:58:13 -0700229 SmallVector<MDNode *, 4> Flags;
230 for (MDNode *Flag : NMD->operands())
231 Flags.push_back(Flag);
232 NMD->clearOperands();
233 for (MDNode *Flag : Flags) {
234 MDString *Key = dyn_cast_or_null<MDString>(Flag->getOperand(1));
235 if (Key->getString() == "Debug Info Version") {
236 Changed = true;
237 continue;
238 }
239 NMD->addOperand(Flag);
240 }
241 // If we left it empty we might as well remove it.
242 if (NMD->getNumOperands() == 0)
243 NMD->eraseFromParent();
244
245 return Changed;
246}
247
Daniel Sanders1adeeab2020-04-03 16:18:45 -0700248namespace {
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000249/// Return true if a mis-sized diagnostic is issued for \p DVI.
250bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
251 // The size of a dbg.value's value operand should match the size of the
252 // variable it corresponds to.
253 //
254 // TODO: This, along with a check for non-null value operands, should be
255 // promoted to verifier failures.
256 Value *V = DVI->getValue();
257 if (!V)
258 return false;
259
260 // For now, don't try to interpret anything more complicated than an empty
261 // DIExpression. Eventually we should try to handle OP_deref and fragments.
262 if (DVI->getExpression()->getNumElements())
263 return false;
264
265 Type *Ty = V->getType();
266 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
Vedant Kumard13536e2018-06-27 00:47:52 +0000267 Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
268 if (!ValueOperandSize || !DbgVarSize)
269 return false;
270
Vedant Kumarba0c8762018-07-06 17:32:40 +0000271 bool HasBadSize = false;
272 if (Ty->isIntegerTy()) {
273 auto Signedness = DVI->getVariable()->getSignedness();
274 if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
275 HasBadSize = ValueOperandSize < *DbgVarSize;
276 } else {
277 HasBadSize = ValueOperandSize != *DbgVarSize;
278 }
279
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000280 if (HasBadSize) {
281 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
Vedant Kumard13536e2018-06-27 00:47:52 +0000282 << ", but its variable has size " << *DbgVarSize << ": ";
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000283 DVI->print(dbg());
284 dbg() << "\n";
285 }
286 return HasBadSize;
287}
288
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000289bool checkDebugifyMetadata(Module &M,
290 iterator_range<Module::iterator> Functions,
Vedant Kumarab112b82018-06-05 00:56:07 +0000291 StringRef NameOfWrappedPass, StringRef Banner,
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000292 bool Strip, DebugifyStatsMap *StatsMap) {
Vedant Kumar195dfd12017-12-08 21:57:28 +0000293 // Skip modules without debugify metadata.
294 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000295 if (!NMD) {
Djordje Todorovic65030822020-05-27 09:42:15 +0200296 dbg() << Banner << ": Skipping module without debugify metadata\n";
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000297 return false;
298 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000299
300 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
301 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
302 ->getZExtValue();
303 };
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000304 assert(NMD->getNumOperands() == 2 &&
305 "llvm.debugify should have exactly 2 operands!");
Vedant Kumar195dfd12017-12-08 21:57:28 +0000306 unsigned OriginalNumLines = getDebugifyOperand(0);
307 unsigned OriginalNumVars = getDebugifyOperand(1);
308 bool HasErrors = false;
309
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000310 // Track debug info loss statistics if able.
311 DebugifyStatistics *Stats = nullptr;
312 if (StatsMap && !NameOfWrappedPass.empty())
313 Stats = &StatsMap->operator[](NameOfWrappedPass);
314
Vedant Kumar195dfd12017-12-08 21:57:28 +0000315 BitVector MissingLines{OriginalNumLines, true};
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000316 BitVector MissingVars{OriginalNumVars, true};
317 for (Function &F : Functions) {
Vedant Kumar17d8bba2018-02-15 21:28:38 +0000318 if (isFunctionSkipped(F))
319 continue;
320
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000321 // Find missing lines.
Vedant Kumar195dfd12017-12-08 21:57:28 +0000322 for (Instruction &I : instructions(F)) {
Pierre-vhf64e4572020-02-27 12:32:51 +0000323 if (isa<DbgValueInst>(&I) || isa<PHINode>(&I))
Vedant Kumar195dfd12017-12-08 21:57:28 +0000324 continue;
325
326 auto DL = I.getDebugLoc();
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000327 if (DL && DL.getLine() != 0) {
Vedant Kumar195dfd12017-12-08 21:57:28 +0000328 MissingLines.reset(DL.getLine() - 1);
329 continue;
330 }
331
Vedant Kumar197e73f2018-06-28 18:21:11 +0000332 if (!DL) {
Vedant Kumarc1cad152020-06-18 14:17:07 -0700333 dbg() << "WARNING: Instruction with empty DebugLoc in function ";
Vedant Kumar197e73f2018-06-28 18:21:11 +0000334 dbg() << F.getName() << " --";
335 I.print(dbg());
336 dbg() << "\n";
Vedant Kumar197e73f2018-06-28 18:21:11 +0000337 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000338 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000339
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000340 // Find missing variables and mis-sized debug values.
Vedant Kumar195dfd12017-12-08 21:57:28 +0000341 for (Instruction &I : instructions(F)) {
342 auto *DVI = dyn_cast<DbgValueInst>(&I);
343 if (!DVI)
344 continue;
345
346 unsigned Var = ~0U;
347 (void)to_integer(DVI->getVariable()->getName(), Var, 10);
348 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
Vedant Kumarb9c1a232018-06-26 22:46:41 +0000349 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
350 if (!HasBadSize)
351 MissingVars.reset(Var - 1);
352 HasErrors |= HasBadSize;
Vedant Kumar195dfd12017-12-08 21:57:28 +0000353 }
354 }
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000355
356 // Print the results.
357 for (unsigned Idx : MissingLines.set_bits())
Vedant Kumara9e27312018-06-06 19:05:41 +0000358 dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000359
Vedant Kumar195dfd12017-12-08 21:57:28 +0000360 for (unsigned Idx : MissingVars.set_bits())
Vedant Kumar2e6c5f92018-06-26 18:54:10 +0000361 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
Vedant Kumar195dfd12017-12-08 21:57:28 +0000362
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000363 // Update DI loss statistics.
364 if (Stats) {
365 Stats->NumDbgLocsExpected += OriginalNumLines;
366 Stats->NumDbgLocsMissing += MissingLines.count();
367 Stats->NumDbgValuesExpected += OriginalNumVars;
368 Stats->NumDbgValuesMissing += MissingVars.count();
369 }
370
Vedant Kumara9e27312018-06-06 19:05:41 +0000371 dbg() << Banner;
Vedant Kumarb70e3562018-05-24 23:00:22 +0000372 if (!NameOfWrappedPass.empty())
Vedant Kumara9e27312018-06-06 19:05:41 +0000373 dbg() << " [" << NameOfWrappedPass << "]";
374 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000375
Vedant Kumar122a6bf2020-04-10 14:58:13 -0700376 // Strip debugify metadata if required.
377 if (Strip)
378 return stripDebugifyMetadata(M);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000379
380 return false;
Vedant Kumar195dfd12017-12-08 21:57:28 +0000381}
382
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000383/// ModulePass for attaching synthetic debug info to everything, used with the
384/// legacy module pass manager.
385struct DebugifyModulePass : public ModulePass {
386 bool runOnModule(Module &M) override {
Daniel Sanders1adeeab2020-04-03 16:18:45 -0700387 return applyDebugifyMetadata(M, M.functions(),
388 "ModuleDebugify: ", /*ApplyToMF*/ nullptr);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000389 }
Vedant Kumar195dfd12017-12-08 21:57:28 +0000390
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000391 DebugifyModulePass() : ModulePass(ID) {}
Vedant Kumar195dfd12017-12-08 21:57:28 +0000392
393 void getAnalysisUsage(AnalysisUsage &AU) const override {
394 AU.setPreservesAll();
395 }
396
397 static char ID; // Pass identification.
398};
399
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000400/// FunctionPass for attaching synthetic debug info to instructions within a
401/// single function, used with the legacy module pass manager.
402struct DebugifyFunctionPass : public FunctionPass {
403 bool runOnFunction(Function &F) override {
404 Module &M = *F.getParent();
405 auto FuncIt = F.getIterator();
406 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
Daniel Sanders1adeeab2020-04-03 16:18:45 -0700407 "FunctionDebugify: ", /*ApplyToMF*/ nullptr);
Vedant Kumar195dfd12017-12-08 21:57:28 +0000408 }
409
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000410 DebugifyFunctionPass() : FunctionPass(ID) {}
Vedant Kumar195dfd12017-12-08 21:57:28 +0000411
412 void getAnalysisUsage(AnalysisUsage &AU) const override {
413 AU.setPreservesAll();
414 }
415
416 static char ID; // Pass identification.
417};
418
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000419/// ModulePass for checking debug info inserted by -debugify, used with the
420/// legacy module pass manager.
421struct CheckDebugifyModulePass : public ModulePass {
422 bool runOnModule(Module &M) override {
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000423 return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000424 "CheckModuleDebugify", Strip, StatsMap);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000425 }
426
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000427 CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "",
428 DebugifyStatsMap *StatsMap = nullptr)
429 : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
430 StatsMap(StatsMap) {}
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000431
Vedant Kumarfb7c7682018-06-04 21:43:28 +0000432 void getAnalysisUsage(AnalysisUsage &AU) const override {
433 AU.setPreservesAll();
434 }
435
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000436 static char ID; // Pass identification.
437
438private:
439 bool Strip;
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000440 StringRef NameOfWrappedPass;
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000441 DebugifyStatsMap *StatsMap;
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000442};
443
444/// FunctionPass for checking debug info inserted by -debugify-function, used
445/// with the legacy module pass manager.
446struct CheckDebugifyFunctionPass : public FunctionPass {
447 bool runOnFunction(Function &F) override {
448 Module &M = *F.getParent();
449 auto FuncIt = F.getIterator();
450 return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
Vedant Kumar4872535e2018-05-24 23:00:23 +0000451 NameOfWrappedPass, "CheckFunctionDebugify",
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000452 Strip, StatsMap);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000453 }
454
Vedant Kumar4872535e2018-05-24 23:00:23 +0000455 CheckDebugifyFunctionPass(bool Strip = false,
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000456 StringRef NameOfWrappedPass = "",
457 DebugifyStatsMap *StatsMap = nullptr)
458 : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
459 StatsMap(StatsMap) {}
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000460
461 void getAnalysisUsage(AnalysisUsage &AU) const override {
462 AU.setPreservesAll();
463 }
464
465 static char ID; // Pass identification.
466
467private:
468 bool Strip;
Anastasis Grammenosb4344c62018-05-15 23:38:05 +0000469 StringRef NameOfWrappedPass;
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000470 DebugifyStatsMap *StatsMap;
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000471};
472
Vedant Kumar195dfd12017-12-08 21:57:28 +0000473} // end anonymous namespace
474
Vedant Kumarab112b82018-06-05 00:56:07 +0000475ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000476
477FunctionPass *createDebugifyFunctionPass() {
478 return new DebugifyFunctionPass();
479}
Vedant Kumar92f7a622018-01-23 20:43:50 +0000480
Vedant Kumar775c7af2018-02-15 21:14:36 +0000481PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
Daniel Sanders1adeeab2020-04-03 16:18:45 -0700482 applyDebugifyMetadata(M, M.functions(),
483 "ModuleDebugify: ", /*ApplyToMF*/ nullptr);
Vedant Kumar775c7af2018-02-15 21:14:36 +0000484 return PreservedAnalyses::all();
485}
486
Vedant Kumar36b89d42018-06-04 00:11:47 +0000487ModulePass *createCheckDebugifyModulePass(bool Strip,
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000488 StringRef NameOfWrappedPass,
489 DebugifyStatsMap *StatsMap) {
490 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000491}
492
Vedant Kumar36b89d42018-06-04 00:11:47 +0000493FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000494 StringRef NameOfWrappedPass,
495 DebugifyStatsMap *StatsMap) {
496 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000497}
Vedant Kumar92f7a622018-01-23 20:43:50 +0000498
Vedant Kumar775c7af2018-02-15 21:14:36 +0000499PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
500 ModuleAnalysisManager &) {
Vedant Kumard6ff43c2018-07-24 00:41:29 +0000501 checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
502 nullptr);
Vedant Kumar775c7af2018-02-15 21:14:36 +0000503 return PreservedAnalyses::all();
504}
505
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000506char DebugifyModulePass::ID = 0;
507static RegisterPass<DebugifyModulePass> DM("debugify",
Vedant Kumar36b89d42018-06-04 00:11:47 +0000508 "Attach debug info to everything");
Vedant Kumar195dfd12017-12-08 21:57:28 +0000509
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000510char CheckDebugifyModulePass::ID = 0;
Vedant Kumar36b89d42018-06-04 00:11:47 +0000511static RegisterPass<CheckDebugifyModulePass>
512 CDM("check-debugify", "Check debug info from -debugify");
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000513
514char DebugifyFunctionPass::ID = 0;
515static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
Vedant Kumar36b89d42018-06-04 00:11:47 +0000516 "Attach debug info to a function");
Vedant Kumar595ba1d2018-05-15 00:29:27 +0000517
518char CheckDebugifyFunctionPass::ID = 0;
Vedant Kumar36b89d42018-06-04 00:11:47 +0000519static RegisterPass<CheckDebugifyFunctionPass>
520 CDF("check-debugify-function", "Check debug info from -debugify-function");