LostDebugLocObserver.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //===----- llvm/CodeGen/GlobalISel/LostDebugLocObserver.cpp -----*- C++ -*-===//
  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. /// Tracks DebugLocs between checkpoints and verifies that they are transferred.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
  13. using namespace llvm;
  14. #define LOC_DEBUG(X) DEBUG_WITH_TYPE(DebugType.str().c_str(), X)
  15. void LostDebugLocObserver::analyzeDebugLocations() {
  16. if (LostDebugLocs.empty()) {
  17. LOC_DEBUG(dbgs() << ".. No debug info was present\n");
  18. return;
  19. }
  20. if (PotentialMIsForDebugLocs.empty()) {
  21. LOC_DEBUG(
  22. dbgs() << ".. No instructions to carry debug info (dead code?)\n");
  23. return;
  24. }
  25. LOC_DEBUG(dbgs() << ".. Searching " << PotentialMIsForDebugLocs.size()
  26. << " instrs for " << LostDebugLocs.size() << " locations\n");
  27. SmallPtrSet<MachineInstr *, 4> FoundIn;
  28. for (MachineInstr *MI : PotentialMIsForDebugLocs) {
  29. if (!MI->getDebugLoc())
  30. continue;
  31. // Check this first in case there's a matching line-0 location on both input
  32. // and output.
  33. if (MI->getDebugLoc().getLine() == 0) {
  34. LOC_DEBUG(
  35. dbgs() << ".. Assuming line-0 location covers remainder (if any)\n");
  36. return;
  37. }
  38. if (LostDebugLocs.erase(MI->getDebugLoc())) {
  39. LOC_DEBUG(dbgs() << ".. .. found " << MI->getDebugLoc() << " in " << *MI);
  40. FoundIn.insert(MI);
  41. continue;
  42. }
  43. }
  44. if (LostDebugLocs.empty())
  45. return;
  46. NumLostDebugLocs += LostDebugLocs.size();
  47. LOC_DEBUG({
  48. dbgs() << ".. Lost locations:\n";
  49. for (const DebugLoc &Loc : LostDebugLocs) {
  50. dbgs() << ".. .. ";
  51. Loc.print(dbgs());
  52. dbgs() << "\n";
  53. }
  54. dbgs() << ".. MIs with matched locations:\n";
  55. for (MachineInstr *MI : FoundIn)
  56. if (PotentialMIsForDebugLocs.erase(MI))
  57. dbgs() << ".. .. " << *MI;
  58. dbgs() << ".. Remaining MIs with unmatched/no locations:\n";
  59. for (const MachineInstr *MI : PotentialMIsForDebugLocs)
  60. dbgs() << ".. .. " << *MI;
  61. });
  62. }
  63. void LostDebugLocObserver::checkpoint(bool CheckDebugLocs) {
  64. if (CheckDebugLocs)
  65. analyzeDebugLocations();
  66. PotentialMIsForDebugLocs.clear();
  67. LostDebugLocs.clear();
  68. }
  69. void LostDebugLocObserver::createdInstr(MachineInstr &MI) {
  70. PotentialMIsForDebugLocs.insert(&MI);
  71. }
  72. static bool irTranslatorNeverAddsLocations(unsigned Opcode) {
  73. switch (Opcode) {
  74. default:
  75. return false;
  76. case TargetOpcode::G_CONSTANT:
  77. case TargetOpcode::G_FCONSTANT:
  78. case TargetOpcode::G_IMPLICIT_DEF:
  79. case TargetOpcode::G_GLOBAL_VALUE:
  80. return true;
  81. }
  82. }
  83. void LostDebugLocObserver::erasingInstr(MachineInstr &MI) {
  84. if (irTranslatorNeverAddsLocations(MI.getOpcode()))
  85. return;
  86. PotentialMIsForDebugLocs.erase(&MI);
  87. if (MI.getDebugLoc())
  88. LostDebugLocs.insert(MI.getDebugLoc());
  89. }
  90. void LostDebugLocObserver::changingInstr(MachineInstr &MI) {
  91. if (irTranslatorNeverAddsLocations(MI.getOpcode()))
  92. return;
  93. PotentialMIsForDebugLocs.erase(&MI);
  94. if (MI.getDebugLoc())
  95. LostDebugLocs.insert(MI.getDebugLoc());
  96. }
  97. void LostDebugLocObserver::changedInstr(MachineInstr &MI) {
  98. PotentialMIsForDebugLocs.insert(&MI);
  99. }