1 //===- 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 
15 #include "Debugify.h"
16 #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 
34 using namespace llvm;
35 
36 namespace {
37 
38 cl::opt<bool> Quiet("debugify-quiet",
39                     cl::desc("Suppress verbose debugify output"));
40 
dbg()41 raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
42 
getAllocSizeInBits(Module & M,Type * Ty)43 uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
44   return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
45 }
46 
isFunctionSkipped(Function & F)47 bool isFunctionSkipped(Function &F) {
48   return F.isDeclaration() || !F.hasExactDefinition();
49 }
50 
51 /// Find the basic block's terminating instruction.
52 ///
53 /// Special care is needed to handle musttail and deopt calls, as these behave
54 /// like (but are in fact not) terminators.
findTerminatingInstruction(BasicBlock & BB)55 Instruction *findTerminatingInstruction(BasicBlock &BB) {
56   if (auto *I = BB.getTerminatingMustTailCall())
57     return I;
58   if (auto *I = BB.getTerminatingDeoptimizeCall())
59     return I;
60   return BB.getTerminator();
61 }
62 
applyDebugifyMetadata(Module & M,iterator_range<Module::iterator> Functions,StringRef Banner)63 bool applyDebugifyMetadata(Module &M,
64                            iterator_range<Module::iterator> Functions,
65                            StringRef Banner) {
66   // Skip modules with debug info.
67   if (M.getNamedMetadata("llvm.dbg.cu")) {
68     dbg() << Banner << "Skipping module with debug info\n";
69     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 * {
78     uint64_t Size = getAllocSizeInBits(M, Ty);
79     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(), "/");
90   auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
91                                   /*isOptimized=*/true, "", 0);
92 
93   // Visit each instruction.
94   for (Function &F : Functions) {
95     if (isFunctionSkipped(F))
96       continue;
97 
98     auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
99     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);
105     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 
111       // Inserting debug values into EH pads can break IR invariants.
112       if (BB.isEHPad())
113         continue;
114 
115       // 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;
125 
126       // Attach debug values.
127       for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
128         // Skip void-valued instructions.
129         if (I->getType()->isVoidTy())
130           continue;
131 
132         // 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();
136 
137         std::string Name = utostr(NextVar++);
138         const DILocation *Loc = I->getDebugLoc().get();
139         auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
140                                                getCachedDIType(I->getType()),
141                                                /*AlwaysPreserve=*/true);
142         DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc,
143                                     InsertBefore);
144       }
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.
159   assert(NMD->getNumOperands() == 2 &&
160          "llvm.debugify should have exactly 2 operands!");
161 
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 
167   return true;
168 }
169 
170 /// Return true if a mis-sized diagnostic is issued for \p DVI.
diagnoseMisSizedDbgValue(Module & M,DbgValueInst * DVI)171 bool 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);
188   Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
189   if (!ValueOperandSize || !DbgVarSize)
190     return false;
191 
192   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 
201   if (HasBadSize) {
202     dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
203           << ", but its variable has size " << *DbgVarSize << ": ";
204     DVI->print(dbg());
205     dbg() << "\n";
206   }
207   return HasBadSize;
208 }
209 
checkDebugifyMetadata(Module & M,iterator_range<Module::iterator> Functions,StringRef NameOfWrappedPass,StringRef Banner,bool Strip,DebugifyStatsMap * StatsMap)210 bool checkDebugifyMetadata(Module &M,
211                            iterator_range<Module::iterator> Functions,
212                            StringRef NameOfWrappedPass, StringRef Banner,
213                            bool Strip, DebugifyStatsMap *StatsMap) {
214   // Skip modules without debugify metadata.
215   NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
216   if (!NMD) {
217     dbg() << Banner << "Skipping module without debugify metadata\n";
218     return false;
219   }
220 
221   auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
222     return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
223         ->getZExtValue();
224   };
225   assert(NMD->getNumOperands() == 2 &&
226          "llvm.debugify should have exactly 2 operands!");
227   unsigned OriginalNumLines = getDebugifyOperand(0);
228   unsigned OriginalNumVars = getDebugifyOperand(1);
229   bool HasErrors = false;
230 
231   // Track debug info loss statistics if able.
232   DebugifyStatistics *Stats = nullptr;
233   if (StatsMap && !NameOfWrappedPass.empty())
234     Stats = &StatsMap->operator[](NameOfWrappedPass);
235 
236   BitVector MissingLines{OriginalNumLines, true};
237   BitVector MissingVars{OriginalNumVars, true};
238   for (Function &F : Functions) {
239     if (isFunctionSkipped(F))
240       continue;
241 
242     // Find missing lines.
243     for (Instruction &I : instructions(F)) {
244       if (isa<DbgValueInst>(&I))
245         continue;
246 
247       auto DL = I.getDebugLoc();
248       if (DL && DL.getLine() != 0) {
249         MissingLines.reset(DL.getLine() - 1);
250         continue;
251       }
252 
253       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       }
260     }
261 
262     // Find missing variables and mis-sized debug values.
263     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");
271       bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
272       if (!HasBadSize)
273         MissingVars.reset(Var - 1);
274       HasErrors |= HasBadSize;
275     }
276   }
277 
278   // Print the results.
279   for (unsigned Idx : MissingLines.set_bits())
280     dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
281 
282   for (unsigned Idx : MissingVars.set_bits())
283     dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
284 
285   // 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 
293   dbg() << Banner;
294   if (!NameOfWrappedPass.empty())
295     dbg() << " [" << NameOfWrappedPass << "]";
296   dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
297 
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;
306 }
307 
308 /// ModulePass for attaching synthetic debug info to everything, used with the
309 /// legacy module pass manager.
310 struct DebugifyModulePass : public ModulePass {
runOnModule__anonfea7d2800111::DebugifyModulePass311   bool runOnModule(Module &M) override {
312     return applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
313   }
314 
DebugifyModulePass__anonfea7d2800111::DebugifyModulePass315   DebugifyModulePass() : ModulePass(ID) {}
316 
getAnalysisUsage__anonfea7d2800111::DebugifyModulePass317   void getAnalysisUsage(AnalysisUsage &AU) const override {
318     AU.setPreservesAll();
319   }
320 
321   static char ID; // Pass identification.
322 };
323 
324 /// FunctionPass for attaching synthetic debug info to instructions within a
325 /// single function, used with the legacy module pass manager.
326 struct DebugifyFunctionPass : public FunctionPass {
runOnFunction__anonfea7d2800111::DebugifyFunctionPass327   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)),
331                                  "FunctionDebugify: ");
332   }
333 
DebugifyFunctionPass__anonfea7d2800111::DebugifyFunctionPass334   DebugifyFunctionPass() : FunctionPass(ID) {}
335 
getAnalysisUsage__anonfea7d2800111::DebugifyFunctionPass336   void getAnalysisUsage(AnalysisUsage &AU) const override {
337     AU.setPreservesAll();
338   }
339 
340   static char ID; // Pass identification.
341 };
342 
343 /// ModulePass for checking debug info inserted by -debugify, used with the
344 /// legacy module pass manager.
345 struct CheckDebugifyModulePass : public ModulePass {
runOnModule__anonfea7d2800111::CheckDebugifyModulePass346   bool runOnModule(Module &M) override {
347     return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
348                                  "CheckModuleDebugify", Strip, StatsMap);
349   }
350 
CheckDebugifyModulePass__anonfea7d2800111::CheckDebugifyModulePass351   CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "",
352                           DebugifyStatsMap *StatsMap = nullptr)
353       : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
354         StatsMap(StatsMap) {}
355 
getAnalysisUsage__anonfea7d2800111::CheckDebugifyModulePass356   void getAnalysisUsage(AnalysisUsage &AU) const override {
357     AU.setPreservesAll();
358   }
359 
360   static char ID; // Pass identification.
361 
362 private:
363   bool Strip;
364   StringRef NameOfWrappedPass;
365   DebugifyStatsMap *StatsMap;
366 };
367 
368 /// FunctionPass for checking debug info inserted by -debugify-function, used
369 /// with the legacy module pass manager.
370 struct CheckDebugifyFunctionPass : public FunctionPass {
runOnFunction__anonfea7d2800111::CheckDebugifyFunctionPass371   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)),
375                                  NameOfWrappedPass, "CheckFunctionDebugify",
376                                  Strip, StatsMap);
377   }
378 
CheckDebugifyFunctionPass__anonfea7d2800111::CheckDebugifyFunctionPass379   CheckDebugifyFunctionPass(bool Strip = false,
380                             StringRef NameOfWrappedPass = "",
381                             DebugifyStatsMap *StatsMap = nullptr)
382       : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
383         StatsMap(StatsMap) {}
384 
getAnalysisUsage__anonfea7d2800111::CheckDebugifyFunctionPass385   void getAnalysisUsage(AnalysisUsage &AU) const override {
386     AU.setPreservesAll();
387   }
388 
389   static char ID; // Pass identification.
390 
391 private:
392   bool Strip;
393   StringRef NameOfWrappedPass;
394   DebugifyStatsMap *StatsMap;
395 };
396 
397 } // end anonymous namespace
398 
exportDebugifyStats(llvm::StringRef Path,const DebugifyStatsMap & Map)399 void 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 
createDebugifyModulePass()420 ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
421 
createDebugifyFunctionPass()422 FunctionPass *createDebugifyFunctionPass() {
423   return new DebugifyFunctionPass();
424 }
425 
run(Module & M,ModuleAnalysisManager &)426 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
427   applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
428   return PreservedAnalyses::all();
429 }
430 
createCheckDebugifyModulePass(bool Strip,StringRef NameOfWrappedPass,DebugifyStatsMap * StatsMap)431 ModulePass *createCheckDebugifyModulePass(bool Strip,
432                                           StringRef NameOfWrappedPass,
433                                           DebugifyStatsMap *StatsMap) {
434   return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
435 }
436 
createCheckDebugifyFunctionPass(bool Strip,StringRef NameOfWrappedPass,DebugifyStatsMap * StatsMap)437 FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
438                                               StringRef NameOfWrappedPass,
439                                               DebugifyStatsMap *StatsMap) {
440   return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
441 }
442 
run(Module & M,ModuleAnalysisManager &)443 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
444                                               ModuleAnalysisManager &) {
445   checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
446                         nullptr);
447   return PreservedAnalyses::all();
448 }
449 
450 char DebugifyModulePass::ID = 0;
451 static RegisterPass<DebugifyModulePass> DM("debugify",
452                                            "Attach debug info to everything");
453 
454 char CheckDebugifyModulePass::ID = 0;
455 static RegisterPass<CheckDebugifyModulePass>
456     CDM("check-debugify", "Check debug info from -debugify");
457 
458 char DebugifyFunctionPass::ID = 0;
459 static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
460                                              "Attach debug info to a function");
461 
462 char CheckDebugifyFunctionPass::ID = 0;
463 static RegisterPass<CheckDebugifyFunctionPass>
464     CDF("check-debugify-function", "Check debug info from -debugify-function");
465