MachineCheckDebugify.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //===- MachineCheckDebugify.cpp - Check debug info ------------------------===//
  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 checks debug info after mir-debugify (+ pass-to-test). Currently
  10. /// it simply checks the integrity of line info in DILocation and
  11. /// DILocalVariable which mir-debugifiy generated before.
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/CodeGen/MachineFunctionPass.h"
  14. #include "llvm/CodeGen/MachineModuleInfo.h"
  15. #include "llvm/CodeGen/Passes.h"
  16. #include "llvm/IR/DebugInfo.h"
  17. #include "llvm/InitializePasses.h"
  18. #include "llvm/Support/CommandLine.h"
  19. #include "llvm/Transforms/Utils/Debugify.h"
  20. #define DEBUG_TYPE "mir-check-debugify"
  21. using namespace llvm;
  22. namespace {
  23. struct CheckDebugMachineModule : public ModulePass {
  24. bool runOnModule(Module &M) override {
  25. MachineModuleInfo &MMI =
  26. getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
  27. NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
  28. if (!NMD) {
  29. errs() << "WARNING: Please run mir-debugify to generate "
  30. "llvm.mir.debugify metadata first.\n";
  31. return false;
  32. }
  33. auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
  34. return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
  35. ->getZExtValue();
  36. };
  37. assert(NMD->getNumOperands() == 2 &&
  38. "llvm.mir.debugify should have exactly 2 operands!");
  39. unsigned NumLines = getDebugifyOperand(0);
  40. unsigned NumVars = getDebugifyOperand(1);
  41. BitVector MissingLines{NumLines, true};
  42. BitVector MissingVars{NumVars, true};
  43. for (Function &F : M.functions()) {
  44. MachineFunction *MF = MMI.getMachineFunction(F);
  45. if (!MF)
  46. continue;
  47. for (MachineBasicBlock &MBB : *MF) {
  48. // Find missing lines.
  49. // TODO: Avoid meta instructions other than dbg_val.
  50. for (MachineInstr &MI : MBB) {
  51. if (MI.isDebugValue())
  52. continue;
  53. const DebugLoc DL = MI.getDebugLoc();
  54. if (DL && DL.getLine() != 0) {
  55. MissingLines.reset(DL.getLine() - 1);
  56. continue;
  57. }
  58. if (!DL) {
  59. errs() << "WARNING: Instruction with empty DebugLoc in function ";
  60. errs() << F.getName() << " --";
  61. MI.print(errs());
  62. }
  63. }
  64. // Find missing variables.
  65. // TODO: Handle DBG_INSTR_REF which is under an experimental option now.
  66. for (MachineInstr &MI : MBB) {
  67. if (!MI.isDebugValue())
  68. continue;
  69. const DILocalVariable *LocalVar = MI.getDebugVariable();
  70. unsigned Var = ~0U;
  71. (void)to_integer(LocalVar->getName(), Var, 10);
  72. assert(Var <= NumVars && "Unexpected name for DILocalVariable");
  73. MissingVars.reset(Var - 1);
  74. }
  75. }
  76. }
  77. bool Fail = false;
  78. for (unsigned Idx : MissingLines.set_bits()) {
  79. errs() << "WARNING: Missing line " << Idx + 1 << "\n";
  80. Fail = true;
  81. }
  82. for (unsigned Idx : MissingVars.set_bits()) {
  83. errs() << "WARNING: Missing variable " << Idx + 1 << "\n";
  84. Fail = true;
  85. }
  86. errs() << "Machine IR debug info check: ";
  87. errs() << (Fail ? "FAIL" : "PASS") << "\n";
  88. return false;
  89. }
  90. CheckDebugMachineModule() : ModulePass(ID) {}
  91. void getAnalysisUsage(AnalysisUsage &AU) const override {
  92. AU.addRequired<MachineModuleInfoWrapperPass>();
  93. AU.addPreserved<MachineModuleInfoWrapperPass>();
  94. AU.setPreservesCFG();
  95. }
  96. static char ID; // Pass identification.
  97. };
  98. char CheckDebugMachineModule::ID = 0;
  99. } // end anonymous namespace
  100. INITIALIZE_PASS_BEGIN(CheckDebugMachineModule, DEBUG_TYPE,
  101. "Machine Check Debug Module", false, false)
  102. INITIALIZE_PASS_END(CheckDebugMachineModule, DEBUG_TYPE,
  103. "Machine Check Debug Module", false, false)
  104. ModulePass *llvm::createCheckDebugMachineModulePass() {
  105. return new CheckDebugMachineModule();
  106. }