Debugify.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Debugify.h - Attach synthetic debug info to everything -------------===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. ///
  14. /// \file Interface to the `debugify` synthetic debug info testing utility.
  15. ///
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_TRANSFORM_UTILS_DEBUGIFY_H
  18. #define LLVM_TRANSFORM_UTILS_DEBUGIFY_H
  19. #include "llvm/ADT/MapVector.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Bitcode/BitcodeWriterPass.h"
  22. #include "llvm/IR/IRPrintingPasses.h"
  23. #include "llvm/IR/LegacyPassManager.h"
  24. #include "llvm/IR/PassManager.h"
  25. namespace llvm {
  26. class DIBuilder;
  27. /// Add synthesized debug information to a module.
  28. ///
  29. /// \param M The module to add debug information to.
  30. /// \param Functions A range of functions to add debug information to.
  31. /// \param Banner A prefix string to add to debug/error messages.
  32. /// \param ApplyToMF A call back that will add debug information to the
  33. /// MachineFunction for a Function. If nullptr, then the
  34. /// MachineFunction (if any) will not be modified.
  35. bool applyDebugifyMetadata(
  36. Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
  37. std::function<bool(DIBuilder &, Function &)> ApplyToMF);
  38. /// Strip out all of the metadata and debug info inserted by debugify. If no
  39. /// llvm.debugify module-level named metadata is present, this is a no-op.
  40. /// Returns true if any change was made.
  41. bool stripDebugifyMetadata(Module &M);
  42. llvm::ModulePass *createDebugifyModulePass();
  43. llvm::FunctionPass *createDebugifyFunctionPass();
  44. struct NewPMDebugifyPass : public llvm::PassInfoMixin<NewPMDebugifyPass> {
  45. llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
  46. };
  47. /// Track how much `debugify` information has been lost.
  48. struct DebugifyStatistics {
  49. /// Number of missing dbg.values.
  50. unsigned NumDbgValuesMissing = 0;
  51. /// Number of dbg.values expected.
  52. unsigned NumDbgValuesExpected = 0;
  53. /// Number of instructions with empty debug locations.
  54. unsigned NumDbgLocsMissing = 0;
  55. /// Number of instructions expected to have debug locations.
  56. unsigned NumDbgLocsExpected = 0;
  57. /// Get the ratio of missing/expected dbg.values.
  58. float getMissingValueRatio() const {
  59. return float(NumDbgValuesMissing) / float(NumDbgLocsExpected);
  60. }
  61. /// Get the ratio of missing/expected instructions with locations.
  62. float getEmptyLocationRatio() const {
  63. return float(NumDbgLocsMissing) / float(NumDbgLocsExpected);
  64. }
  65. };
  66. /// Map pass names to a per-pass DebugifyStatistics instance.
  67. using DebugifyStatsMap = llvm::MapVector<llvm::StringRef, DebugifyStatistics>;
  68. void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
  69. llvm::ModulePass *
  70. createCheckDebugifyModulePass(bool Strip = false,
  71. llvm::StringRef NameOfWrappedPass = "",
  72. DebugifyStatsMap *StatsMap = nullptr);
  73. llvm::FunctionPass *
  74. createCheckDebugifyFunctionPass(bool Strip = false,
  75. llvm::StringRef NameOfWrappedPass = "",
  76. DebugifyStatsMap *StatsMap = nullptr);
  77. struct NewPMCheckDebugifyPass
  78. : public llvm::PassInfoMixin<NewPMCheckDebugifyPass> {
  79. llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
  80. };
  81. struct DebugifyEachInstrumentation {
  82. DebugifyStatsMap StatsMap;
  83. void registerCallbacks(PassInstrumentationCallbacks &PIC);
  84. };
  85. /// DebugifyCustomPassManager wraps each pass with the debugify passes if
  86. /// needed.
  87. /// NOTE: We support legacy custom pass manager only.
  88. /// TODO: Add New PM support for custom pass manager.
  89. class DebugifyCustomPassManager : public legacy::PassManager {
  90. DebugifyStatsMap DIStatsMap;
  91. bool EnableDebugifyEach = false;
  92. public:
  93. using super = legacy::PassManager;
  94. void add(Pass *P) override {
  95. // Wrap each pass with (-check)-debugify passes if requested, making
  96. // exceptions for passes which shouldn't see -debugify instrumentation.
  97. bool WrapWithDebugify = EnableDebugifyEach && !P->getAsImmutablePass() &&
  98. !isIRPrintingPass(P) && !isBitcodeWriterPass(P);
  99. if (!WrapWithDebugify) {
  100. super::add(P);
  101. return;
  102. }
  103. // Apply -debugify/-check-debugify before/after each pass and collect
  104. // debug info loss statistics.
  105. PassKind Kind = P->getPassKind();
  106. StringRef Name = P->getPassName();
  107. // TODO: Implement Debugify for LoopPass.
  108. switch (Kind) {
  109. case PT_Function:
  110. super::add(createDebugifyFunctionPass());
  111. super::add(P);
  112. super::add(createCheckDebugifyFunctionPass(true, Name, &DIStatsMap));
  113. break;
  114. case PT_Module:
  115. super::add(createDebugifyModulePass());
  116. super::add(P);
  117. super::add(createCheckDebugifyModulePass(true, Name, &DIStatsMap));
  118. break;
  119. default:
  120. super::add(P);
  121. break;
  122. }
  123. }
  124. void enableDebugifyEach() { EnableDebugifyEach = true; }
  125. const DebugifyStatsMap &getDebugifyStatsMap() const { return DIStatsMap; }
  126. };
  127. } // namespace llvm
  128. #endif // LLVM_TRANSFORM_UTILS_DEBUGIFY_H
  129. #ifdef __GNUC__
  130. #pragma GCC diagnostic pop
  131. #endif