Debugify.cpp revision 360784
1//===- Debugify.cpp - Attach synthetic debug info to everything -----------===//
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 This pass attaches synthetic debug info to everything. It can be used
10/// to create targeted tests for debug info preservation.
11///
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/Utils/Debugify.h"
15#include "llvm/ADT/BitVector.h"
16#include "llvm/ADT/StringExtras.h"
17#include "llvm/IR/DIBuilder.h"
18#include "llvm/IR/DebugInfo.h"
19#include "llvm/IR/InstIterator.h"
20#include "llvm/IR/Instructions.h"
21#include "llvm/IR/IntrinsicInst.h"
22#include "llvm/IR/Module.h"
23#include "llvm/Pass.h"
24#include "llvm/Support/CommandLine.h"
25
26using namespace llvm;
27
28namespace {
29
30cl::opt<bool> Quiet("debugify-quiet",
31                    cl::desc("Suppress verbose debugify output"));
32
33raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
34
35uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
36  return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
37}
38
39bool isFunctionSkipped(Function &F) {
40  return F.isDeclaration() || !F.hasExactDefinition();
41}
42
43/// Find the basic block's terminating instruction.
44///
45/// Special care is needed to handle musttail and deopt calls, as these behave
46/// like (but are in fact not) terminators.
47Instruction *findTerminatingInstruction(BasicBlock &BB) {
48  if (auto *I = BB.getTerminatingMustTailCall())
49    return I;
50  if (auto *I = BB.getTerminatingDeoptimizeCall())
51    return I;
52  return BB.getTerminator();
53}
54
55bool applyDebugifyMetadata(Module &M,
56                           iterator_range<Module::iterator> Functions,
57                           StringRef Banner) {
58  // Skip modules with debug info.
59  if (M.getNamedMetadata("llvm.dbg.cu")) {
60    dbg() << Banner << "Skipping module with debug info\n";
61    return false;
62  }
63
64  DIBuilder DIB(M);
65  LLVMContext &Ctx = M.getContext();
66
67  // Get a DIType which corresponds to Ty.
68  DenseMap<uint64_t, DIType *> TypeCache;
69  auto getCachedDIType = [&](Type *Ty) -> DIType * {
70    uint64_t Size = getAllocSizeInBits(M, Ty);
71    DIType *&DTy = TypeCache[Size];
72    if (!DTy) {
73      std::string Name = "ty" + utostr(Size);
74      DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
75    }
76    return DTy;
77  };
78
79  unsigned NextLine = 1;
80  unsigned NextVar = 1;
81  auto File = DIB.createFile(M.getName(), "/");
82  auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
83                                  /*isOptimized=*/true, "", 0);
84
85  // Visit each instruction.
86  for (Function &F : Functions) {
87    if (isFunctionSkipped(F))
88      continue;
89
90    auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
91    DISubprogram::DISPFlags SPFlags =
92        DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
93    if (F.hasPrivateLinkage() || F.hasInternalLinkage())
94      SPFlags |= DISubprogram::SPFlagLocalToUnit;
95    auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
96                                 SPType, NextLine, DINode::FlagZero, SPFlags);
97    F.setSubprogram(SP);
98    for (BasicBlock &BB : F) {
99      // Attach debug locations.
100      for (Instruction &I : BB)
101        I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
102
103      // Inserting debug values into EH pads can break IR invariants.
104      if (BB.isEHPad())
105        continue;
106
107      // Find the terminating instruction, after which no debug values are
108      // attached.
109      Instruction *LastInst = findTerminatingInstruction(BB);
110      assert(LastInst && "Expected basic block with a terminator");
111
112      // Maintain an insertion point which can't be invalidated when updates
113      // are made.
114      BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
115      assert(InsertPt != BB.end() && "Expected to find an insertion point");
116      Instruction *InsertBefore = &*InsertPt;
117
118      // Attach debug values.
119      for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
120        // Skip void-valued instructions.
121        if (I->getType()->isVoidTy())
122          continue;
123
124        // Phis and EH pads must be grouped at the beginning of the block.
125        // Only advance the insertion point when we finish visiting these.
126        if (!isa<PHINode>(I) && !I->isEHPad())
127          InsertBefore = I->getNextNode();
128
129        std::string Name = utostr(NextVar++);
130        const DILocation *Loc = I->getDebugLoc().get();
131        auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
132                                               getCachedDIType(I->getType()),
133                                               /*AlwaysPreserve=*/true);
134        DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc,
135                                    InsertBefore);
136      }
137    }
138    DIB.finalizeSubprogram(SP);
139  }
140  DIB.finalize();
141
142  // Track the number of distinct lines and variables.
143  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
144  auto *IntTy = Type::getInt32Ty(Ctx);
145  auto addDebugifyOperand = [&](unsigned N) {
146    NMD->addOperand(MDNode::get(
147        Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N))));
148  };
149  addDebugifyOperand(NextLine - 1); // Original number of lines.
150  addDebugifyOperand(NextVar - 1);  // Original number of variables.
151  assert(NMD->getNumOperands() == 2 &&
152         "llvm.debugify should have exactly 2 operands!");
153
154  // Claim that this synthetic debug info is valid.
155  StringRef DIVersionKey = "Debug Info Version";
156  if (!M.getModuleFlag(DIVersionKey))
157    M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
158
159  return true;
160}
161
162/// Return true if a mis-sized diagnostic is issued for \p DVI.
163bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
164  // The size of a dbg.value's value operand should match the size of the
165  // variable it corresponds to.
166  //
167  // TODO: This, along with a check for non-null value operands, should be
168  // promoted to verifier failures.
169  Value *V = DVI->getValue();
170  if (!V)
171    return false;
172
173  // For now, don't try to interpret anything more complicated than an empty
174  // DIExpression. Eventually we should try to handle OP_deref and fragments.
175  if (DVI->getExpression()->getNumElements())
176    return false;
177
178  Type *Ty = V->getType();
179  uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
180  Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
181  if (!ValueOperandSize || !DbgVarSize)
182    return false;
183
184  bool HasBadSize = false;
185  if (Ty->isIntegerTy()) {
186    auto Signedness = DVI->getVariable()->getSignedness();
187    if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
188      HasBadSize = ValueOperandSize < *DbgVarSize;
189  } else {
190    HasBadSize = ValueOperandSize != *DbgVarSize;
191  }
192
193  if (HasBadSize) {
194    dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
195          << ", but its variable has size " << *DbgVarSize << ": ";
196    DVI->print(dbg());
197    dbg() << "\n";
198  }
199  return HasBadSize;
200}
201
202bool checkDebugifyMetadata(Module &M,
203                           iterator_range<Module::iterator> Functions,
204                           StringRef NameOfWrappedPass, StringRef Banner,
205                           bool Strip, DebugifyStatsMap *StatsMap) {
206  // Skip modules without debugify metadata.
207  NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
208  if (!NMD) {
209    dbg() << Banner << "Skipping module without debugify metadata\n";
210    return false;
211  }
212
213  auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
214    return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
215        ->getZExtValue();
216  };
217  assert(NMD->getNumOperands() == 2 &&
218         "llvm.debugify should have exactly 2 operands!");
219  unsigned OriginalNumLines = getDebugifyOperand(0);
220  unsigned OriginalNumVars = getDebugifyOperand(1);
221  bool HasErrors = false;
222
223  // Track debug info loss statistics if able.
224  DebugifyStatistics *Stats = nullptr;
225  if (StatsMap && !NameOfWrappedPass.empty())
226    Stats = &StatsMap->operator[](NameOfWrappedPass);
227
228  BitVector MissingLines{OriginalNumLines, true};
229  BitVector MissingVars{OriginalNumVars, true};
230  for (Function &F : Functions) {
231    if (isFunctionSkipped(F))
232      continue;
233
234    // Find missing lines.
235    for (Instruction &I : instructions(F)) {
236      if (isa<DbgValueInst>(&I))
237        continue;
238
239      auto DL = I.getDebugLoc();
240      if (DL && DL.getLine() != 0) {
241        MissingLines.reset(DL.getLine() - 1);
242        continue;
243      }
244
245      if (!DL) {
246        dbg() << "ERROR: Instruction with empty DebugLoc in function ";
247        dbg() << F.getName() << " --";
248        I.print(dbg());
249        dbg() << "\n";
250        HasErrors = true;
251      }
252    }
253
254    // Find missing variables and mis-sized debug values.
255    for (Instruction &I : instructions(F)) {
256      auto *DVI = dyn_cast<DbgValueInst>(&I);
257      if (!DVI)
258        continue;
259
260      unsigned Var = ~0U;
261      (void)to_integer(DVI->getVariable()->getName(), Var, 10);
262      assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
263      bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
264      if (!HasBadSize)
265        MissingVars.reset(Var - 1);
266      HasErrors |= HasBadSize;
267    }
268  }
269
270  // Print the results.
271  for (unsigned Idx : MissingLines.set_bits())
272    dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
273
274  for (unsigned Idx : MissingVars.set_bits())
275    dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
276
277  // Update DI loss statistics.
278  if (Stats) {
279    Stats->NumDbgLocsExpected += OriginalNumLines;
280    Stats->NumDbgLocsMissing += MissingLines.count();
281    Stats->NumDbgValuesExpected += OriginalNumVars;
282    Stats->NumDbgValuesMissing += MissingVars.count();
283  }
284
285  dbg() << Banner;
286  if (!NameOfWrappedPass.empty())
287    dbg() << " [" << NameOfWrappedPass << "]";
288  dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
289
290  // Strip the Debugify Metadata if required.
291  if (Strip) {
292    StripDebugInfo(M);
293    M.eraseNamedMetadata(NMD);
294    return true;
295  }
296
297  return false;
298}
299
300/// ModulePass for attaching synthetic debug info to everything, used with the
301/// legacy module pass manager.
302struct DebugifyModulePass : public ModulePass {
303  bool runOnModule(Module &M) override {
304    return applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
305  }
306
307  DebugifyModulePass() : ModulePass(ID) {}
308
309  void getAnalysisUsage(AnalysisUsage &AU) const override {
310    AU.setPreservesAll();
311  }
312
313  static char ID; // Pass identification.
314};
315
316/// FunctionPass for attaching synthetic debug info to instructions within a
317/// single function, used with the legacy module pass manager.
318struct DebugifyFunctionPass : public FunctionPass {
319  bool runOnFunction(Function &F) override {
320    Module &M = *F.getParent();
321    auto FuncIt = F.getIterator();
322    return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
323                                 "FunctionDebugify: ");
324  }
325
326  DebugifyFunctionPass() : FunctionPass(ID) {}
327
328  void getAnalysisUsage(AnalysisUsage &AU) const override {
329    AU.setPreservesAll();
330  }
331
332  static char ID; // Pass identification.
333};
334
335/// ModulePass for checking debug info inserted by -debugify, used with the
336/// legacy module pass manager.
337struct CheckDebugifyModulePass : public ModulePass {
338  bool runOnModule(Module &M) override {
339    return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
340                                 "CheckModuleDebugify", Strip, StatsMap);
341  }
342
343  CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "",
344                          DebugifyStatsMap *StatsMap = nullptr)
345      : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
346        StatsMap(StatsMap) {}
347
348  void getAnalysisUsage(AnalysisUsage &AU) const override {
349    AU.setPreservesAll();
350  }
351
352  static char ID; // Pass identification.
353
354private:
355  bool Strip;
356  StringRef NameOfWrappedPass;
357  DebugifyStatsMap *StatsMap;
358};
359
360/// FunctionPass for checking debug info inserted by -debugify-function, used
361/// with the legacy module pass manager.
362struct CheckDebugifyFunctionPass : public FunctionPass {
363  bool runOnFunction(Function &F) override {
364    Module &M = *F.getParent();
365    auto FuncIt = F.getIterator();
366    return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
367                                 NameOfWrappedPass, "CheckFunctionDebugify",
368                                 Strip, StatsMap);
369  }
370
371  CheckDebugifyFunctionPass(bool Strip = false,
372                            StringRef NameOfWrappedPass = "",
373                            DebugifyStatsMap *StatsMap = nullptr)
374      : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
375        StatsMap(StatsMap) {}
376
377  void getAnalysisUsage(AnalysisUsage &AU) const override {
378    AU.setPreservesAll();
379  }
380
381  static char ID; // Pass identification.
382
383private:
384  bool Strip;
385  StringRef NameOfWrappedPass;
386  DebugifyStatsMap *StatsMap;
387};
388
389} // end anonymous namespace
390
391ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
392
393FunctionPass *createDebugifyFunctionPass() {
394  return new DebugifyFunctionPass();
395}
396
397PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
398  applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
399  return PreservedAnalyses::all();
400}
401
402ModulePass *createCheckDebugifyModulePass(bool Strip,
403                                          StringRef NameOfWrappedPass,
404                                          DebugifyStatsMap *StatsMap) {
405  return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
406}
407
408FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
409                                              StringRef NameOfWrappedPass,
410                                              DebugifyStatsMap *StatsMap) {
411  return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
412}
413
414PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
415                                              ModuleAnalysisManager &) {
416  checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
417                        nullptr);
418  return PreservedAnalyses::all();
419}
420
421char DebugifyModulePass::ID = 0;
422static RegisterPass<DebugifyModulePass> DM("debugify",
423                                           "Attach debug info to everything");
424
425char CheckDebugifyModulePass::ID = 0;
426static RegisterPass<CheckDebugifyModulePass>
427    CDM("check-debugify", "Check debug info from -debugify");
428
429char DebugifyFunctionPass::ID = 0;
430static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
431                                             "Attach debug info to a function");
432
433char CheckDebugifyFunctionPass::ID = 0;
434static RegisterPass<CheckDebugifyFunctionPass>
435    CDF("check-debugify-function", "Check debug info from -debugify-function");
436