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