LLVM  15.0.0git
Debugify.cpp
Go to the documentation of this file.
1 //===- Debugify.cpp - Check debug info preservation in optimizations ------===//
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 In the `synthetic` mode, the `-debugify` attaches synthetic debug info
10 /// to everything. It can be used to create targeted tests for debug info
11 /// preservation. In addition, when using the `original` mode, it can check
12 /// original debug info preservation. The `synthetic` mode is default one.
13 ///
14 //===----------------------------------------------------------------------===//
15 
17 #include "llvm/ADT/BitVector.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/IR/DIBuilder.h"
20 #include "llvm/IR/DebugInfo.h"
21 #include "llvm/IR/InstIterator.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/IntrinsicInst.h"
24 #include "llvm/IR/Module.h"
26 #include "llvm/Pass.h"
29 #include "llvm/Support/JSON.h"
30 
31 #define DEBUG_TYPE "debugify"
32 
33 using namespace llvm;
34 
35 namespace {
36 
37 cl::opt<bool> Quiet("debugify-quiet",
38  cl::desc("Suppress verbose debugify output"));
39 
40 cl::opt<uint64_t> DebugifyFunctionsLimit(
41  "debugify-func-limit",
42  cl::desc("Set max number of processed functions per pass."),
43  cl::init(UINT_MAX));
44 
45 enum class Level {
46  Locations,
47  LocationsAndVariables
48 };
49 
50 cl::opt<Level> DebugifyLevel(
51  "debugify-level", cl::desc("Kind of debug info to add"),
52  cl::values(clEnumValN(Level::Locations, "locations", "Locations only"),
53  clEnumValN(Level::LocationsAndVariables, "location+variables",
54  "Locations and Variables")),
55  cl::init(Level::LocationsAndVariables));
56 
57 raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
58 
59 uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
60  return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
61 }
62 
63 bool isFunctionSkipped(Function &F) {
64  return F.isDeclaration() || !F.hasExactDefinition();
65 }
66 
67 /// Find the basic block's terminating instruction.
68 ///
69 /// Special care is needed to handle musttail and deopt calls, as these behave
70 /// like (but are in fact not) terminators.
71 Instruction *findTerminatingInstruction(BasicBlock &BB) {
72  if (auto *I = BB.getTerminatingMustTailCall())
73  return I;
74  if (auto *I = BB.getTerminatingDeoptimizeCall())
75  return I;
76  return BB.getTerminator();
77 }
78 } // end anonymous namespace
79 
82  std::function<bool(DIBuilder &DIB, Function &F)> ApplyToMF) {
83  // Skip modules with debug info.
84  if (M.getNamedMetadata("llvm.dbg.cu")) {
85  dbg() << Banner << "Skipping module with debug info\n";
86  return false;
87  }
88 
89  DIBuilder DIB(M);
90  LLVMContext &Ctx = M.getContext();
91  auto *Int32Ty = Type::getInt32Ty(Ctx);
92 
93  // Get a DIType which corresponds to Ty.
95  auto getCachedDIType = [&](Type *Ty) -> DIType * {
96  uint64_t Size = getAllocSizeInBits(M, Ty);
97  DIType *&DTy = TypeCache[Size];
98  if (!DTy) {
99  std::string Name = "ty" + utostr(Size);
100  DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
101  }
102  return DTy;
103  };
104 
105  unsigned NextLine = 1;
106  unsigned NextVar = 1;
107  auto File = DIB.createFile(M.getName(), "/");
108  auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
109  /*isOptimized=*/true, "", 0);
110 
111  // Visit each instruction.
112  for (Function &F : Functions) {
113  if (isFunctionSkipped(F))
114  continue;
115 
116  bool InsertedDbgVal = false;
117  auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
118  DISubprogram::DISPFlags SPFlags =
119  DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
120  if (F.hasPrivateLinkage() || F.hasInternalLinkage())
121  SPFlags |= DISubprogram::SPFlagLocalToUnit;
122  auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
123  SPType, NextLine, DINode::FlagZero, SPFlags);
124  F.setSubprogram(SP);
125 
126  // Helper that inserts a dbg.value before \p InsertBefore, copying the
127  // location (and possibly the type, if it's non-void) from \p TemplateInst.
128  auto insertDbgVal = [&](Instruction &TemplateInst,
129  Instruction *InsertBefore) {
130  std::string Name = utostr(NextVar++);
131  Value *V = &TemplateInst;
132  if (TemplateInst.getType()->isVoidTy())
133  V = ConstantInt::get(Int32Ty, 0);
134  const DILocation *Loc = TemplateInst.getDebugLoc().get();
135  auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
136  getCachedDIType(V->getType()),
137  /*AlwaysPreserve=*/true);
138  DIB.insertDbgValueIntrinsic(V, LocalVar, DIB.createExpression(), Loc,
139  InsertBefore);
140  };
141 
142  for (BasicBlock &BB : F) {
143  // Attach debug locations.
144  for (Instruction &I : BB)
145  I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
146 
147  if (DebugifyLevel < Level::LocationsAndVariables)
148  continue;
149 
150  // Inserting debug values into EH pads can break IR invariants.
151  if (BB.isEHPad())
152  continue;
153 
154  // Find the terminating instruction, after which no debug values are
155  // attached.
156  Instruction *LastInst = findTerminatingInstruction(BB);
157  assert(LastInst && "Expected basic block with a terminator");
158 
159  // Maintain an insertion point which can't be invalidated when updates
160  // are made.
161  BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
162  assert(InsertPt != BB.end() && "Expected to find an insertion point");
163  Instruction *InsertBefore = &*InsertPt;
164 
165  // Attach debug values.
166  for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
167  // Skip void-valued instructions.
168  if (I->getType()->isVoidTy())
169  continue;
170 
171  // Phis and EH pads must be grouped at the beginning of the block.
172  // Only advance the insertion point when we finish visiting these.
173  if (!isa<PHINode>(I) && !I->isEHPad())
174  InsertBefore = I->getNextNode();
175 
176  insertDbgVal(*I, InsertBefore);
177  InsertedDbgVal = true;
178  }
179  }
180  // Make sure we emit at least one dbg.value, otherwise MachineDebugify may
181  // not have anything to work with as it goes about inserting DBG_VALUEs.
182  // (It's common for MIR tests to be written containing skeletal IR with
183  // empty functions -- we're still interested in debugifying the MIR within
184  // those tests, and this helps with that.)
185  if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) {
186  auto *Term = findTerminatingInstruction(F.getEntryBlock());
187  insertDbgVal(*Term, Term);
188  }
189  if (ApplyToMF)
190  ApplyToMF(DIB, F);
191  DIB.finalizeSubprogram(SP);
192  }
193  DIB.finalize();
194 
195  // Track the number of distinct lines and variables.
196  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
197  auto addDebugifyOperand = [&](unsigned N) {
198  NMD->addOperand(MDNode::get(
200  };
201  addDebugifyOperand(NextLine - 1); // Original number of lines.
202  addDebugifyOperand(NextVar - 1); // Original number of variables.
203  assert(NMD->getNumOperands() == 2 &&
204  "llvm.debugify should have exactly 2 operands!");
205 
206  // Claim that this synthetic debug info is valid.
207  StringRef DIVersionKey = "Debug Info Version";
208  if (!M.getModuleFlag(DIVersionKey))
209  M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
210 
211  return true;
212 }
213 
214 static bool
217  DebugInfoPerPass *DebugInfoBeforePass = nullptr,
218  StringRef NameOfWrappedPass = "") {
219  Module &M = *F.getParent();
220  auto FuncIt = F.getIterator();
222  return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
223  "FunctionDebugify: ", /*ApplyToMF*/ nullptr);
224  assert(DebugInfoBeforePass);
225  return collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass,
226  "FunctionDebugify (original debuginfo)",
227  NameOfWrappedPass);
228 }
229 
230 static bool
233  DebugInfoPerPass *DebugInfoBeforePass = nullptr,
234  StringRef NameOfWrappedPass = "") {
236  return applyDebugifyMetadata(M, M.functions(),
237  "ModuleDebugify: ", /*ApplyToMF*/ nullptr);
238  return collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass,
239  "ModuleDebugify (original debuginfo)",
240  NameOfWrappedPass);
241 }
242 
244  bool Changed = false;
245 
246  // Remove the llvm.debugify module-level named metadata.
247  NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify");
248  if (DebugifyMD) {
249  M.eraseNamedMetadata(DebugifyMD);
250  Changed = true;
251  }
252 
253  // Strip out all debug intrinsics and supporting metadata (subprograms, types,
254  // variables, etc).
255  Changed |= StripDebugInfo(M);
256 
257  // Strip out the dead dbg.value prototype.
258  Function *DbgValF = M.getFunction("llvm.dbg.value");
259  if (DbgValF) {
260  assert(DbgValF->isDeclaration() && DbgValF->use_empty() &&
261  "Not all debug info stripped?");
262  DbgValF->eraseFromParent();
263  Changed = true;
264  }
265 
266  // Strip out the module-level Debug Info Version metadata.
267  // FIXME: There must be an easier way to remove an operand from a NamedMDNode.
268  NamedMDNode *NMD = M.getModuleFlagsMetadata();
269  if (!NMD)
270  return Changed;
271  SmallVector<MDNode *, 4> Flags(NMD->operands());
272  NMD->clearOperands();
273  for (MDNode *Flag : Flags) {
274  auto *Key = cast<MDString>(Flag->getOperand(1));
275  if (Key->getString() == "Debug Info Version") {
276  Changed = true;
277  continue;
278  }
279  NMD->addOperand(Flag);
280  }
281  // If we left it empty we might as well remove it.
282  if (NMD->getNumOperands() == 0)
283  NMD->eraseFromParent();
284 
285  return Changed;
286 }
287 
290  DebugInfoPerPass &DebugInfoBeforePass,
291  StringRef Banner,
292  StringRef NameOfWrappedPass) {
293  LLVM_DEBUG(dbgs() << Banner << ": (before) " << NameOfWrappedPass << '\n');
294 
295  if (!M.getNamedMetadata("llvm.dbg.cu")) {
296  dbg() << Banner << ": Skipping module without debug info\n";
297  return false;
298  }
299 
300  uint64_t FunctionsCnt = DebugInfoBeforePass.DIFunctions.size();
301  // Visit each instruction.
302  for (Function &F : Functions) {
303  // Use DI collected after previous Pass (when -debugify-each is used).
304  if (DebugInfoBeforePass.DIFunctions.count(&F))
305  continue;
306 
307  if (isFunctionSkipped(F))
308  continue;
309 
310  // Stop collecting DI if the Functions number reached the limit.
311  if (++FunctionsCnt >= DebugifyFunctionsLimit)
312  break;
313  // Collect the DISubprogram.
314  auto *SP = F.getSubprogram();
315  DebugInfoBeforePass.DIFunctions.insert({&F, SP});
316  if (SP) {
317  LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n');
318  for (const DINode *DN : SP->getRetainedNodes()) {
319  if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
320  DebugInfoBeforePass.DIVariables[DV] = 0;
321  }
322  }
323  }
324 
325  for (BasicBlock &BB : F) {
326  // Collect debug locations (!dbg) and debug variable intrinsics.
327  for (Instruction &I : BB) {
328  // Skip PHIs.
329  if (isa<PHINode>(I))
330  continue;
331 
332  // Cllect dbg.values and dbg.declare.
333  if (DebugifyLevel > Level::Locations) {
334  if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
335  if (!SP)
336  continue;
337  // Skip inlined variables.
338  if (I.getDebugLoc().getInlinedAt())
339  continue;
340  // Skip undef values.
341  if (DVI->isUndef())
342  continue;
343 
344  auto *Var = DVI->getVariable();
345  DebugInfoBeforePass.DIVariables[Var]++;
346  continue;
347  }
348  }
349 
350  // Skip debug instructions other than dbg.value and dbg.declare.
351  if (isa<DbgInfoIntrinsic>(&I))
352  continue;
353 
354  LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
355  DebugInfoBeforePass.InstToDelete.insert({&I, &I});
356 
357  const DILocation *Loc = I.getDebugLoc().get();
358  bool HasLoc = Loc != nullptr;
359  DebugInfoBeforePass.DILocations.insert({&I, HasLoc});
360  }
361  }
362  }
363 
364  return true;
365 }
366 
367 // This checks the preservation of original debug info attached to functions.
368 static bool checkFunctions(const DebugFnMap &DIFunctionsBefore,
369  const DebugFnMap &DIFunctionsAfter,
370  StringRef NameOfWrappedPass,
371  StringRef FileNameFromCU, bool ShouldWriteIntoJSON,
372  llvm::json::Array &Bugs) {
373  bool Preserved = true;
374  for (const auto &F : DIFunctionsAfter) {
375  if (F.second)
376  continue;
377  auto SPIt = DIFunctionsBefore.find(F.first);
378  if (SPIt == DIFunctionsBefore.end()) {
379  if (ShouldWriteIntoJSON)
380  Bugs.push_back(llvm::json::Object({{"metadata", "DISubprogram"},
381  {"name", F.first->getName()},
382  {"action", "not-generate"}}));
383  else
384  dbg() << "ERROR: " << NameOfWrappedPass
385  << " did not generate DISubprogram for " << F.first->getName()
386  << " from " << FileNameFromCU << '\n';
387  Preserved = false;
388  } else {
389  auto SP = SPIt->second;
390  if (!SP)
391  continue;
392  // If the function had the SP attached before the pass, consider it as
393  // a debug info bug.
394  if (ShouldWriteIntoJSON)
395  Bugs.push_back(llvm::json::Object({{"metadata", "DISubprogram"},
396  {"name", F.first->getName()},
397  {"action", "drop"}}));
398  else
399  dbg() << "ERROR: " << NameOfWrappedPass << " dropped DISubprogram of "
400  << F.first->getName() << " from " << FileNameFromCU << '\n';
401  Preserved = false;
402  }
403  }
404 
405  return Preserved;
406 }
407 
408 // This checks the preservation of the original debug info attached to
409 // instructions.
410 static bool checkInstructions(const DebugInstMap &DILocsBefore,
411  const DebugInstMap &DILocsAfter,
412  const WeakInstValueMap &InstToDelete,
413  StringRef NameOfWrappedPass,
414  StringRef FileNameFromCU,
415  bool ShouldWriteIntoJSON,
416  llvm::json::Array &Bugs) {
417  bool Preserved = true;
418  for (const auto &L : DILocsAfter) {
419  if (L.second)
420  continue;
421  auto Instr = L.first;
422 
423  // In order to avoid pointer reuse/recycling, skip the values that might
424  // have been deleted during a pass.
425  auto WeakInstrPtr = InstToDelete.find(Instr);
426  if (WeakInstrPtr != InstToDelete.end() && !WeakInstrPtr->second)
427  continue;
428 
429  auto FnName = Instr->getFunction()->getName();
430  auto BB = Instr->getParent();
431  auto BBName = BB->hasName() ? BB->getName() : "no-name";
432  auto InstName = Instruction::getOpcodeName(Instr->getOpcode());
433 
434  auto InstrIt = DILocsBefore.find(Instr);
435  if (InstrIt == DILocsBefore.end()) {
436  if (ShouldWriteIntoJSON)
437  Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
438  {"fn-name", FnName.str()},
439  {"bb-name", BBName.str()},
440  {"instr", InstName},
441  {"action", "not-generate"}}));
442  else
443  dbg() << "WARNING: " << NameOfWrappedPass
444  << " did not generate DILocation for " << *Instr
445  << " (BB: " << BBName << ", Fn: " << FnName
446  << ", File: " << FileNameFromCU << ")\n";
447  Preserved = false;
448  } else {
449  if (!InstrIt->second)
450  continue;
451  // If the instr had the !dbg attached before the pass, consider it as
452  // a debug info issue.
453  if (ShouldWriteIntoJSON)
454  Bugs.push_back(llvm::json::Object({{"metadata", "DILocation"},
455  {"fn-name", FnName.str()},
456  {"bb-name", BBName.str()},
457  {"instr", InstName},
458  {"action", "drop"}}));
459  else
460  dbg() << "WARNING: " << NameOfWrappedPass << " dropped DILocation of "
461  << *Instr << " (BB: " << BBName << ", Fn: " << FnName
462  << ", File: " << FileNameFromCU << ")\n";
463  Preserved = false;
464  }
465  }
466 
467  return Preserved;
468 }
469 
470 // This checks the preservation of original debug variable intrinsics.
471 static bool checkVars(const DebugVarMap &DIVarsBefore,
472  const DebugVarMap &DIVarsAfter,
473  StringRef NameOfWrappedPass, StringRef FileNameFromCU,
474  bool ShouldWriteIntoJSON, llvm::json::Array &Bugs) {
475  bool Preserved = true;
476  for (const auto &V : DIVarsBefore) {
477  auto VarIt = DIVarsAfter.find(V.first);
478  if (VarIt == DIVarsAfter.end())
479  continue;
480 
481  unsigned NumOfDbgValsAfter = VarIt->second;
482 
483  if (V.second > NumOfDbgValsAfter) {
484  if (ShouldWriteIntoJSON)
486  {{"metadata", "dbg-var-intrinsic"},
487  {"name", V.first->getName()},
488  {"fn-name", V.first->getScope()->getSubprogram()->getName()},
489  {"action", "drop"}}));
490  else
491  dbg() << "WARNING: " << NameOfWrappedPass
492  << " drops dbg.value()/dbg.declare() for " << V.first->getName()
493  << " from "
494  << "function " << V.first->getScope()->getSubprogram()->getName()
495  << " (file " << FileNameFromCU << ")\n";
496  Preserved = false;
497  }
498  }
499 
500  return Preserved;
501 }
502 
503 // Write the json data into the specifed file.
504 static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath,
505  StringRef FileNameFromCU, StringRef NameOfWrappedPass,
506  llvm::json::Array &Bugs) {
507  std::error_code EC;
508  raw_fd_ostream OS_FILE{OrigDIVerifyBugsReportFilePath, EC,
510  if (EC) {
511  errs() << "Could not open file: " << EC.message() << ", "
512  << OrigDIVerifyBugsReportFilePath << '\n';
513  return;
514  }
515 
516  OS_FILE << "{\"file\":\"" << FileNameFromCU << "\", ";
517 
518  StringRef PassName = NameOfWrappedPass != "" ? NameOfWrappedPass : "no-name";
519  OS_FILE << "\"pass\":\"" << PassName << "\", ";
520 
521  llvm::json::Value BugsToPrint{std::move(Bugs)};
522  OS_FILE << "\"bugs\": " << BugsToPrint;
523 
524  OS_FILE << "}\n";
525 }
526 
529  DebugInfoPerPass &DebugInfoBeforePass,
530  StringRef Banner, StringRef NameOfWrappedPass,
531  StringRef OrigDIVerifyBugsReportFilePath) {
532  LLVM_DEBUG(dbgs() << Banner << ": (after) " << NameOfWrappedPass << '\n');
533 
534  if (!M.getNamedMetadata("llvm.dbg.cu")) {
535  dbg() << Banner << ": Skipping module without debug info\n";
536  return false;
537  }
538 
539  // Map the debug info holding DIs after a pass.
540  DebugInfoPerPass DebugInfoAfterPass;
541 
542  // Visit each instruction.
543  for (Function &F : Functions) {
544  if (isFunctionSkipped(F))
545  continue;
546 
547  // Don't process functions without DI collected before the Pass.
548  if (!DebugInfoBeforePass.DIFunctions.count(&F))
549  continue;
550  // TODO: Collect metadata other than DISubprograms.
551  // Collect the DISubprogram.
552  auto *SP = F.getSubprogram();
553  DebugInfoAfterPass.DIFunctions.insert({&F, SP});
554 
555  if (SP) {
556  LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n');
557  for (const DINode *DN : SP->getRetainedNodes()) {
558  if (const auto *DV = dyn_cast<DILocalVariable>(DN)) {
559  DebugInfoAfterPass.DIVariables[DV] = 0;
560  }
561  }
562  }
563 
564  for (BasicBlock &BB : F) {
565  // Collect debug locations (!dbg) and debug variable intrinsics.
566  for (Instruction &I : BB) {
567  // Skip PHIs.
568  if (isa<PHINode>(I))
569  continue;
570 
571  // Collect dbg.values and dbg.declares.
572  if (DebugifyLevel > Level::Locations) {
573  if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
574  if (!SP)
575  continue;
576  // Skip inlined variables.
577  if (I.getDebugLoc().getInlinedAt())
578  continue;
579  // Skip undef values.
580  if (DVI->isUndef())
581  continue;
582 
583  auto *Var = DVI->getVariable();
584  DebugInfoAfterPass.DIVariables[Var]++;
585  continue;
586  }
587  }
588 
589  // Skip debug instructions other than dbg.value and dbg.declare.
590  if (isa<DbgInfoIntrinsic>(&I))
591  continue;
592 
593  LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n');
594 
595  const DILocation *Loc = I.getDebugLoc().get();
596  bool HasLoc = Loc != nullptr;
597 
598  DebugInfoAfterPass.DILocations.insert({&I, HasLoc});
599  }
600  }
601  }
602 
603  // TODO: The name of the module could be read better?
604  StringRef FileNameFromCU =
605  (cast<DICompileUnit>(M.getNamedMetadata("llvm.dbg.cu")->getOperand(0)))
606  ->getFilename();
607 
608  auto DIFunctionsBefore = DebugInfoBeforePass.DIFunctions;
609  auto DIFunctionsAfter = DebugInfoAfterPass.DIFunctions;
610 
611  auto DILocsBefore = DebugInfoBeforePass.DILocations;
612  auto DILocsAfter = DebugInfoAfterPass.DILocations;
613 
614  auto InstToDelete = DebugInfoBeforePass.InstToDelete;
615 
616  auto DIVarsBefore = DebugInfoBeforePass.DIVariables;
617  auto DIVarsAfter = DebugInfoAfterPass.DIVariables;
618 
619  bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.empty();
620  llvm::json::Array Bugs;
621 
622  bool ResultForFunc =
623  checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass,
624  FileNameFromCU, ShouldWriteIntoJSON, Bugs);
625  bool ResultForInsts = checkInstructions(
626  DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass,
627  FileNameFromCU, ShouldWriteIntoJSON, Bugs);
628 
629  bool ResultForVars = checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass,
630  FileNameFromCU, ShouldWriteIntoJSON, Bugs);
631 
632  bool Result = ResultForFunc && ResultForInsts && ResultForVars;
633 
634  StringRef ResultBanner = NameOfWrappedPass != "" ? NameOfWrappedPass : Banner;
635  if (ShouldWriteIntoJSON && !Bugs.empty())
636  writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass,
637  Bugs);
638 
639  if (Result)
640  dbg() << ResultBanner << ": PASS\n";
641  else
642  dbg() << ResultBanner << ": FAIL\n";
643 
644  // In the case of the `debugify-each`, no need to go over all the instructions
645  // again in the collectDebugInfoMetadata(), since as an input we can use
646  // the debugging information from the previous pass.
647  DebugInfoBeforePass = DebugInfoAfterPass;
648 
649  LLVM_DEBUG(dbgs() << "\n\n");
650  return Result;
651 }
652 
653 namespace {
654 /// Return true if a mis-sized diagnostic is issued for \p DVI.
655 bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
656  // The size of a dbg.value's value operand should match the size of the
657  // variable it corresponds to.
658  //
659  // TODO: This, along with a check for non-null value operands, should be
660  // promoted to verifier failures.
661 
662  // For now, don't try to interpret anything more complicated than an empty
663  // DIExpression. Eventually we should try to handle OP_deref and fragments.
664  if (DVI->getExpression()->getNumElements())
665  return false;
666 
667  Value *V = DVI->getVariableLocationOp(0);
668  if (!V)
669  return false;
670 
671  Type *Ty = V->getType();
672  uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
673  Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
674  if (!ValueOperandSize || !DbgVarSize)
675  return false;
676 
677  bool HasBadSize = false;
678  if (Ty->isIntegerTy()) {
679  auto Signedness = DVI->getVariable()->getSignedness();
680  if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
681  HasBadSize = ValueOperandSize < *DbgVarSize;
682  } else {
683  HasBadSize = ValueOperandSize != *DbgVarSize;
684  }
685 
686  if (HasBadSize) {
687  dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
688  << ", but its variable has size " << *DbgVarSize << ": ";
689  DVI->print(dbg());
690  dbg() << "\n";
691  }
692  return HasBadSize;
693 }
694 
695 bool checkDebugifyMetadata(Module &M,
697  StringRef NameOfWrappedPass, StringRef Banner,
698  bool Strip, DebugifyStatsMap *StatsMap) {
699  // Skip modules without debugify metadata.
700  NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
701  if (!NMD) {
702  dbg() << Banner << ": Skipping module without debugify metadata\n";
703  return false;
704  }
705 
706  auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
707  return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
708  ->getZExtValue();
709  };
710  assert(NMD->getNumOperands() == 2 &&
711  "llvm.debugify should have exactly 2 operands!");
712  unsigned OriginalNumLines = getDebugifyOperand(0);
713  unsigned OriginalNumVars = getDebugifyOperand(1);
714  bool HasErrors = false;
715 
716  // Track debug info loss statistics if able.
717  DebugifyStatistics *Stats = nullptr;
718  if (StatsMap && !NameOfWrappedPass.empty())
719  Stats = &StatsMap->operator[](NameOfWrappedPass);
720 
721  BitVector MissingLines{OriginalNumLines, true};
722  BitVector MissingVars{OriginalNumVars, true};
723  for (Function &F : Functions) {
724  if (isFunctionSkipped(F))
725  continue;
726 
727  // Find missing lines.
728  for (Instruction &I : instructions(F)) {
729  if (isa<DbgValueInst>(&I))
730  continue;
731 
732  auto DL = I.getDebugLoc();
733  if (DL && DL.getLine() != 0) {
734  MissingLines.reset(DL.getLine() - 1);
735  continue;
736  }
737 
738  if (!isa<PHINode>(&I) && !DL) {
739  dbg() << "WARNING: Instruction with empty DebugLoc in function ";
740  dbg() << F.getName() << " --";
741  I.print(dbg());
742  dbg() << "\n";
743  }
744  }
745 
746  // Find missing variables and mis-sized debug values.
747  for (Instruction &I : instructions(F)) {
748  auto *DVI = dyn_cast<DbgValueInst>(&I);
749  if (!DVI)
750  continue;
751 
752  unsigned Var = ~0U;
753  (void)to_integer(DVI->getVariable()->getName(), Var, 10);
754  assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
755  bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
756  if (!HasBadSize)
757  MissingVars.reset(Var - 1);
758  HasErrors |= HasBadSize;
759  }
760  }
761 
762  // Print the results.
763  for (unsigned Idx : MissingLines.set_bits())
764  dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
765 
766  for (unsigned Idx : MissingVars.set_bits())
767  dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
768 
769  // Update DI loss statistics.
770  if (Stats) {
771  Stats->NumDbgLocsExpected += OriginalNumLines;
772  Stats->NumDbgLocsMissing += MissingLines.count();
773  Stats->NumDbgValuesExpected += OriginalNumVars;
774  Stats->NumDbgValuesMissing += MissingVars.count();
775  }
776 
777  dbg() << Banner;
778  if (!NameOfWrappedPass.empty())
779  dbg() << " [" << NameOfWrappedPass << "]";
780  dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
781 
782  // Strip debugify metadata if required.
783  if (Strip)
784  return stripDebugifyMetadata(M);
785 
786  return false;
787 }
788 
789 /// ModulePass for attaching synthetic debug info to everything, used with the
790 /// legacy module pass manager.
791 struct DebugifyModulePass : public ModulePass {
792  bool runOnModule(Module &M) override {
793  return applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass);
794  }
795 
796  DebugifyModulePass(enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
797  StringRef NameOfWrappedPass = "",
798  DebugInfoPerPass *DebugInfoBeforePass = nullptr)
799  : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
800  DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
801 
802  void getAnalysisUsage(AnalysisUsage &AU) const override {
803  AU.setPreservesAll();
804  }
805 
806  static char ID; // Pass identification.
807 
808 private:
809  StringRef NameOfWrappedPass;
810  DebugInfoPerPass *DebugInfoBeforePass;
811  enum DebugifyMode Mode;
812 };
813 
814 /// FunctionPass for attaching synthetic debug info to instructions within a
815 /// single function, used with the legacy module pass manager.
816 struct DebugifyFunctionPass : public FunctionPass {
817  bool runOnFunction(Function &F) override {
818  return applyDebugify(F, Mode, DebugInfoBeforePass, NameOfWrappedPass);
819  }
820 
821  DebugifyFunctionPass(
823  StringRef NameOfWrappedPass = "",
824  DebugInfoPerPass *DebugInfoBeforePass = nullptr)
825  : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
826  DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
827 
828  void getAnalysisUsage(AnalysisUsage &AU) const override {
829  AU.setPreservesAll();
830  }
831 
832  static char ID; // Pass identification.
833 
834 private:
835  StringRef NameOfWrappedPass;
836  DebugInfoPerPass *DebugInfoBeforePass;
837  enum DebugifyMode Mode;
838 };
839 
840 /// ModulePass for checking debug info inserted by -debugify, used with the
841 /// legacy module pass manager.
842 struct CheckDebugifyModulePass : public ModulePass {
843  bool runOnModule(Module &M) override {
845  return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
846  "CheckModuleDebugify", Strip, StatsMap);
847  return checkDebugInfoMetadata(
848  M, M.functions(), *DebugInfoBeforePass,
849  "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
850  OrigDIVerifyBugsReportFilePath);
851  }
852 
853  CheckDebugifyModulePass(
854  bool Strip = false, StringRef NameOfWrappedPass = "",
855  DebugifyStatsMap *StatsMap = nullptr,
857  DebugInfoPerPass *DebugInfoBeforePass = nullptr,
858  StringRef OrigDIVerifyBugsReportFilePath = "")
859  : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass),
860  OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
861  StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
862  Strip(Strip) {}
863 
864  void getAnalysisUsage(AnalysisUsage &AU) const override {
865  AU.setPreservesAll();
866  }
867 
868  static char ID; // Pass identification.
869 
870 private:
871  StringRef NameOfWrappedPass;
872  StringRef OrigDIVerifyBugsReportFilePath;
873  DebugifyStatsMap *StatsMap;
874  DebugInfoPerPass *DebugInfoBeforePass;
875  enum DebugifyMode Mode;
876  bool Strip;
877 };
878 
879 /// FunctionPass for checking debug info inserted by -debugify-function, used
880 /// with the legacy module pass manager.
881 struct CheckDebugifyFunctionPass : public FunctionPass {
882  bool runOnFunction(Function &F) override {
883  Module &M = *F.getParent();
884  auto FuncIt = F.getIterator();
886  return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
887  NameOfWrappedPass, "CheckFunctionDebugify",
888  Strip, StatsMap);
889  return checkDebugInfoMetadata(
890  M, make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass,
891  "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass,
892  OrigDIVerifyBugsReportFilePath);
893  }
894 
895  CheckDebugifyFunctionPass(
896  bool Strip = false, StringRef NameOfWrappedPass = "",
897  DebugifyStatsMap *StatsMap = nullptr,
899  DebugInfoPerPass *DebugInfoBeforePass = nullptr,
900  StringRef OrigDIVerifyBugsReportFilePath = "")
901  : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass),
902  OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
903  StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
904  Strip(Strip) {}
905 
906  void getAnalysisUsage(AnalysisUsage &AU) const override {
907  AU.setPreservesAll();
908  }
909 
910  static char ID; // Pass identification.
911 
912 private:
913  StringRef NameOfWrappedPass;
914  StringRef OrigDIVerifyBugsReportFilePath;
915  DebugifyStatsMap *StatsMap;
916  DebugInfoPerPass *DebugInfoBeforePass;
917  enum DebugifyMode Mode;
918  bool Strip;
919 };
920 
921 } // end anonymous namespace
922 
924  std::error_code EC;
925  raw_fd_ostream OS{Path, EC};
926  if (EC) {
927  errs() << "Could not open file: " << EC.message() << ", " << Path << '\n';
928  return;
929  }
930 
931  OS << "Pass Name" << ',' << "# of missing debug values" << ','
932  << "# of missing locations" << ',' << "Missing/Expected value ratio" << ','
933  << "Missing/Expected location ratio" << '\n';
934  for (const auto &Entry : Map) {
935  StringRef Pass = Entry.first;
936  DebugifyStatistics Stats = Entry.second;
937 
938  OS << Pass << ',' << Stats.NumDbgValuesMissing << ','
939  << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ','
940  << Stats.getEmptyLocationRatio() << '\n';
941  }
942 }
943 
945  llvm::StringRef NameOfWrappedPass,
946  DebugInfoPerPass *DebugInfoBeforePass) {
948  return new DebugifyModulePass();
949  assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
950  return new DebugifyModulePass(Mode, NameOfWrappedPass, DebugInfoBeforePass);
951 }
952 
953 FunctionPass *
955  llvm::StringRef NameOfWrappedPass,
956  DebugInfoPerPass *DebugInfoBeforePass) {
958  return new DebugifyFunctionPass();
959  assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
960  return new DebugifyFunctionPass(Mode, NameOfWrappedPass, DebugInfoBeforePass);
961 }
962 
964  applyDebugifyMetadata(M, M.functions(),
965  "ModuleDebugify: ", /*ApplyToMF*/ nullptr);
966  return PreservedAnalyses::all();
967 }
968 
970  bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap,
971  enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass,
972  StringRef OrigDIVerifyBugsReportFilePath) {
974  return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
975  assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
976  return new CheckDebugifyModulePass(false, NameOfWrappedPass, nullptr, Mode,
977  DebugInfoBeforePass,
978  OrigDIVerifyBugsReportFilePath);
979 }
980 
982  bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap,
983  enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass,
984  StringRef OrigDIVerifyBugsReportFilePath) {
986  return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
987  assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode");
988  return new CheckDebugifyFunctionPass(false, NameOfWrappedPass, nullptr, Mode,
989  DebugInfoBeforePass,
990  OrigDIVerifyBugsReportFilePath);
991 }
992 
995  checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
996  nullptr);
997  return PreservedAnalyses::all();
998 }
999 
1000 static bool isIgnoredPass(StringRef PassID) {
1001  return isSpecialPass(PassID, {"PassManager", "PassAdaptor",
1002  "AnalysisManagerProxy", "PrintFunctionPass",
1003  "PrintModulePass", "BitcodeWriterPass",
1004  "ThinLTOBitcodeWriterPass", "VerifierPass"});
1005 }
1006 
1010  if (isIgnoredPass(P))
1011  return;
1012  if (any_isa<const Function *>(IR))
1013  applyDebugify(*const_cast<Function *>(any_cast<const Function *>(IR)));
1014  else if (any_isa<const Module *>(IR))
1015  applyDebugify(*const_cast<Module *>(any_cast<const Module *>(IR)));
1016  });
1018  const PreservedAnalyses &PassPA) {
1019  if (isIgnoredPass(P))
1020  return;
1021  if (any_isa<const Function *>(IR)) {
1022  auto &F = *const_cast<Function *>(any_cast<const Function *>(IR));
1023  Module &M = *F.getParent();
1024  auto It = F.getIterator();
1025  checkDebugifyMetadata(M, make_range(It, std::next(It)), P,
1026  "CheckFunctionDebugify", /*Strip=*/true, &StatsMap);
1027  } else if (any_isa<const Module *>(IR)) {
1028  auto &M = *const_cast<Module *>(any_cast<const Module *>(IR));
1029  checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify",
1030  /*Strip=*/true, &StatsMap);
1031  }
1032  });
1033 }
1034 
1035 char DebugifyModulePass::ID = 0;
1036 static RegisterPass<DebugifyModulePass> DM("debugify",
1037  "Attach debug info to everything");
1038 
1041  CDM("check-debugify", "Check debug info from -debugify");
1042 
1043 char DebugifyFunctionPass::ID = 0;
1044 static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
1045  "Attach debug info to a function");
1046 
1049  CDF("check-debugify-function", "Check debug info from -debugify-function");
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::RegisterPass
RegisterPass<t> template - This template class is used to notify the system that a Pass is available ...
Definition: PassSupport.h:94
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
Int32Ty
IntegerType * Int32Ty
Definition: NVVMIntrRange.cpp:67
llvm::DbgVariableIntrinsic::getExpression
DIExpression * getExpression() const
Definition: IntrinsicInst.h:258
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:264
CDF
static RegisterPass< CheckDebugifyFunctionPass > CDF("check-debugify-function", "Check debug info from -debugify-function")
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm::StripDebugInfo
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
Definition: DebugInfo.cpp:474
llvm::json::Value
A Value is an JSON value of unknown type.
Definition: JSON.h:290
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::DIType
Base class for types.
Definition: DebugInfoMetadata.h:658
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::DIBuilder::getOrCreateTypeArray
DITypeRefArray getOrCreateTypeArray(ArrayRef< Metadata * > Elements)
Get a DITypeRefArray, create one if required.
Definition: DIBuilder.cpp:685
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::NamedMDNode
A tuple of MDNodes.
Definition: Metadata.h:1488
llvm::DIBuilder::finalize
void finalize()
Construct any deferred debug info descriptors.
Definition: DIBuilder.cpp:79
DebugifyMode
DebugifyMode
Used to check whether we track synthetic or original debug info.
Definition: Debugify.h:93
FileSystem.h
llvm::NamedMDNode::getNumOperands
unsigned getNumOperands() const
Definition: Metadata.cpp:1150
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:87
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
IntrinsicInst.h
llvm::DIBuilder
Definition: DIBuilder.h:41
InstIterator.h
Debugify.h
llvm::Function
Definition: Function.h:60
llvm::DIBuilder::finalizeSubprogram
void finalizeSubprogram(DISubprogram *SP)
Finalize a specific subprogram - no new variables may be added to this subprogram afterwards.
Definition: DIBuilder.cpp:59
llvm::json::Array::empty
bool empty() const
Definition: JSON.h:186
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
Pass.h
checkFunctions
static bool checkFunctions(const DebugFnMap &DIFunctionsBefore, const DebugFnMap &DIFunctionsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
Definition: Debugify.cpp:368
DM
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
llvm::PassInstrumentationCallbacks::registerBeforeNonSkippedPassCallback
void registerBeforeNonSkippedPassCallback(CallableT C)
Definition: PassInstrumentation.h:106
llvm::lltok::LocalVar
@ LocalVar
Definition: LLToken.h:418
llvm::Function::eraseFromParent
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Function.cpp:364
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
DebugInfoPerPass::DIVariables
DebugVarMap DIVariables
Definition: Debugify.h:43
createDebugifyFunctionPass
FunctionPass * createDebugifyFunctionPass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
Definition: Debugify.cpp:954
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1557
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
createDebugifyModulePass
ModulePass * createDebugifyModulePass(enum DebugifyMode Mode, llvm::StringRef NameOfWrappedPass, DebugInfoPerPass *DebugInfoBeforePass)
Definition: Debugify.cpp:944
PIC
PassInstrumentationCallbacks PIC
Definition: PassBuilderBindings.cpp:55
llvm::DbgVariableIntrinsic::getVariable
DILocalVariable * getVariable() const
Definition: IntrinsicInst.h:254
llvm::Optional< uint64_t >
llvm::MapVector< const llvm::Function *, const llvm::DISubprogram * >
NewPMDebugifyPass::run
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
Definition: Debugify.cpp:963
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::applyDebugifyMetadata
bool applyDebugifyMetadata(Module &M, iterator_range< Module::iterator > Functions, StringRef Banner, std::function< bool(DIBuilder &, Function &)> ApplyToMF)
Add synthesized debug information to a module.
llvm::DIBuilder::createSubroutineType
DISubroutineType * createSubroutineType(DITypeRefArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
Definition: DIBuilder.cpp:544
checkInstructions
static bool checkInstructions(const DebugInstMap &DILocsBefore, const DebugInstMap &DILocsAfter, const WeakInstValueMap &InstToDelete, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
Definition: Debugify.cpp:410
llvm::nulls
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
Definition: raw_ostream.cpp:900
llvm::json::Array::push_back
void push_back(const Value &E)
Definition: JSON.h:191
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
llvm::DbgVariableIntrinsic::getVariableLocationOp
Value * getVariableLocationOp(unsigned OpIdx) const
Definition: IntrinsicInst.cpp:58
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::DIBuilder::createFile
DIFile * createFile(StringRef Filename, StringRef Directory, Optional< DIFile::ChecksumInfo< StringRef >> Checksum=None, Optional< StringRef > Source=None)
Create a file descriptor to hold debugging information for a file.
Definition: DIBuilder.cpp:229
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1300
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
DebugifyMode::SyntheticDebugInfo
@ SyntheticDebugInfo
llvm::DIBuilder::createAutoVariable
DILocalVariable * createAutoVariable(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve=false, DINode::DIFlags Flags=DINode::FlagZero, uint32_t AlignInBits=0)
Create a new descriptor for an auto variable.
Definition: DIBuilder.cpp:795
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::NamedMDNode::addOperand
void addOperand(MDNode *M)
Definition: Metadata.cpp:1160
CommandLine.h
llvm::GlobalValue::isDeclaration
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:264
applyDebugify
static bool applyDebugify(Function &F, enum DebugifyMode Mode=DebugifyMode::SyntheticDebugInfo, DebugInfoPerPass *DebugInfoBeforePass=nullptr, StringRef NameOfWrappedPass="")
Definition: Debugify.cpp:215
isIgnoredPass
static bool isIgnoredPass(StringRef PassID)
Definition: Debugify.cpp:1000
llvm::DbgValueInst
This represents the llvm.dbg.value instruction.
Definition: IntrinsicInst.h:348
llvm::collectDebugInfoMetadata
bool collectDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass)
Collect original debug information before a pass.
Definition: Debugify.cpp:288
DebugInfoPerPass::DIFunctions
DebugFnMap DIFunctions
Definition: Debugify.h:36
PassInstrumentation.h
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::DISubprogram::DISPFlags
DISPFlags
Debug info subprogram flags.
Definition: DebugInfoMetadata.h:1818
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:486
llvm::isSpecialPass
bool isSpecialPass(StringRef PassID, const std::vector< StringRef > &Specials)
Definition: PassInstrumentation.cpp:33
llvm::Instruction::getOpcodeName
const char * getOpcodeName() const
Definition: Instruction.h:159
llvm::Instruction
Definition: Instruction.h:42
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
llvm::NamedMDNode::eraseFromParent
void eraseFromParent()
Drop all references and remove the node from parent module.
Definition: Metadata.cpp:1167
llvm::json::Array
An Array is a JSON array, which contains heterogeneous JSON values.
Definition: JSON.h:157
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
BitVector.h
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:928
IR
Statically lint checks LLVM IR
Definition: Lint.cpp:751
JSON.h
llvm::exportDebugifyStats
void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map)
Definition: Debugify.cpp:923
llvm::BitVector
Definition: BitVector.h:75
DebugInfoPerPass::InstToDelete
WeakInstValueMap InstToDelete
Definition: Debugify.h:41
llvm::stripDebugifyMetadata
bool stripDebugifyMetadata(Module &M)
Strip out all of the metadata and debug info inserted by debugify.
Definition: Debugify.cpp:243
llvm::DEBUG_METADATA_VERSION
@ DEBUG_METADATA_VERSION
Definition: Metadata.h:52
llvm::None
const NoneType None
Definition: None.h:24
getFilename
static SmallString< 128 > getFilename(const DISubprogram *SP)
Extract a filename for a DISubprogram.
Definition: GCOVProfiling.cpp:212
llvm::Value::use_empty
bool use_empty() const
Definition: Value.h:344
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::DIBasicType::Signedness::Signed
@ Signed
llvm::sys::fs::OF_TextWithCRLF
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
Definition: FileSystem.h:770
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:191
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1204
createCheckDebugifyFunctionPass
FunctionPass * createCheckDebugifyFunctionPass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
Definition: Debugify.cpp:981
llvm::cl::opt< bool >
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
DebugInfoPerPass
Used to track the Debug Info Metadata information.
Definition: Debugify.h:34
llvm::cl::values
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:685
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::MapVector::find
iterator find(const KeyT &Key)
Definition: MapVector.h:148
uint64_t
llvm::DebugifyEachInstrumentation::StatsMap
DebugifyStatsMap StatsMap
Definition: Debugify.h:160
llvm::DIBuilder::createExpression
DIExpression * createExpression(ArrayRef< uint64_t > Addr=None)
Create a new descriptor for the specified variable which has a complex address expression for its add...
Definition: DIBuilder.cpp:833
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::DenseMap
Definition: DenseMap.h:716
DebugInfo.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::DebugLoc::get
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:20
llvm::M68kBeads::Term
@ Term
Definition: M68kBaseInfo.h:71
StringExtras.h
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
DIBuilder.h
getSubprogram
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)
Definition: DIBuilder.cpp:838
llvm::Value::print
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4590
llvm::checkDebugInfoMetadata
bool checkDebugInfoMetadata(Module &M, iterator_range< Module::iterator > Functions, DebugInfoPerPass &DebugInfoBeforePass, StringRef Banner, StringRef NameOfWrappedPass, StringRef OrigDIVerifyBugsReportFilePath)
Check original debug information after a pass.
Definition: Debugify.cpp:527
llvm::NamedMDNode::getOperand
MDNode * getOperand(unsigned i) const
Definition: Metadata.cpp:1154
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DebugifyStatistics
Track how much debugify information (in the synthetic mode only) has been lost.
Definition: Debugify.h:110
Mode
SI Whole Quad Mode
Definition: SIWholeQuadMode.cpp:262
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MDNode
Metadata node.
Definition: Metadata.h:937
DebugifyMode::OriginalDebugInfo
@ OriginalDebugInfo
llvm::DIVariable::getName
StringRef getName() const
Definition: DebugInfoMetadata.h:2504
llvm::DIVariable::getSignedness
Optional< DIBasicType::Signedness > getSignedness() const
Return the signedness of this variable's type, or None if this type is neither signed nor unsigned.
Definition: DebugInfoMetadata.h:2514
llvm::MapVector::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: MapVector.h:118
llvm::Module::Warning
@ Warning
Emits a warning if two values disagree.
Definition: Module.h:122
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::DINode
Tagged DWARF-like metadata node.
Definition: DebugInfoMetadata.h:129
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
clEnumValN
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:660
llvm::ValueAsMetadata::getConstant
static ConstantAsMetadata * getConstant(Value *C)
Definition: Metadata.h:367
llvm::PICLevel::Level
Level
Definition: CodeGen.h:33
llvm::DbgVariableIntrinsic::getFragmentSizeInBits
Optional< uint64_t > getFragmentSizeInBits() const
Get the size (in bits) of the variable, or fragment of the variable that is described.
Definition: IntrinsicInst.cpp:136
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:305
llvm::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:444
llvm::NamedMDNode::operands
iterator_range< op_iterator > operands()
Definition: Metadata.h:1584
llvm::MapVector::end
iterator end()
Definition: MapVector.h:72
llvm::DIBuilder::createCompileUnit
DICompileUnit * createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, StringRef SplitName=StringRef(), DICompileUnit::DebugEmissionKind Kind=DICompileUnit::DebugEmissionKind::FullDebug, uint64_t DWOId=0, bool SplitDebugInlining=true, bool DebugInfoForProfiling=false, DICompileUnit::DebugNameTableKind NameTableKind=DICompileUnit::DebugNameTableKind::Default, bool RangesBaseAddress=false, StringRef SysRoot={}, StringRef SDK={})
A CompileUnit provides an anchor for all debugging information generated during this instance of comp...
Definition: DIBuilder.cpp:149
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::Any
Definition: Any.h:28
llvm::MapVector::count
size_type count(const KeyT &Key) const
Definition: MapVector.h:143
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
Stats
block placement Basic Block Placement Stats
Definition: MachineBlockPlacement.cpp:3656
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
DebugInfoPerPass::DILocations
DebugInstMap DILocations
Definition: Debugify.h:38
NewPMCheckDebugifyPass::run
llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM)
Definition: Debugify.cpp:993
llvm::MapVector::size
size_type size() const
Definition: MapVector.h:61
CDM
static RegisterPass< CheckDebugifyModulePass > CDM("check-debugify", "Check debug info from -debugify")
writeJSON
static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath, StringRef FileNameFromCU, StringRef NameOfWrappedPass, llvm::json::Array &Bugs)
Definition: Debugify.cpp:504
llvm::PassInstrumentationCallbacks::registerAfterPassCallback
void registerAfterPassCallback(CallableT C)
Definition: PassInstrumentation.h:110
llvm::DIBuilder::createFunction
DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags=DINode::FlagZero, DISubprogram::DISPFlags SPFlags=DISubprogram::SPFlagZero, DITemplateParameterArray TParams=nullptr, DISubprogram *Decl=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName="")
Create a new descriptor for the specified subprogram.
Definition: DIBuilder.cpp:844
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
Instructions.h
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:367
llvm::PassInstrumentationCallbacks
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
Definition: PassInstrumentation.h:66
N
#define N
createCheckDebugifyModulePass
ModulePass * createCheckDebugifyModulePass(bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, StringRef OrigDIVerifyBugsReportFilePath)
Definition: Debugify.cpp:969
llvm::sys::fs::OF_Append
@ OF_Append
The file should be opened in append mode.
Definition: FileSystem.h:773
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::DIExpression::getNumElements
unsigned getNumElements() const
Definition: DebugInfoMetadata.h:2584
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::DIBuilder::createBasicType
DIBasicType * createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding, DINode::DIFlags Flags=DINode::FlagZero)
Create debugging information entry for a basic type.
Definition: DIBuilder.cpp:281
llvm::DebugifyEachInstrumentation::registerCallbacks
void registerCallbacks(PassInstrumentationCallbacks &PIC)
Definition: Debugify.cpp:1007
llvm::cl::desc
Definition: CommandLine.h:405
llvm::ARMBuildAttrs::File
@ File
Definition: ARMBuildAttributes.h:36
llvm::json::Object
An Object is a JSON object, which maps strings to heterogenous JSON values.
Definition: JSON.h:91
llvm::NamedMDNode::clearOperands
void clearOperands()
Drop all references to this node's operands.
Definition: Metadata.cpp:1169
CU
Definition: AArch64AsmBackend.cpp:504
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
PassName
static const char PassName[]
Definition: X86LowerAMXIntrinsics.cpp:671
checkVars
static bool checkVars(const DebugVarMap &DIVarsBefore, const DebugVarMap &DIVarsAfter, StringRef NameOfWrappedPass, StringRef FileNameFromCU, bool ShouldWriteIntoJSON, llvm::json::Array &Bugs)
Definition: Debugify.cpp:471
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38