123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- Debugify.h - Attach synthetic debug info to everything -------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file Interface to the `debugify` synthetic debug info testing utility.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_TRANSFORM_UTILS_DEBUGIFY_H
- #define LLVM_TRANSFORM_UTILS_DEBUGIFY_H
- #include "llvm/ADT/MapVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Bitcode/BitcodeWriterPass.h"
- #include "llvm/IR/IRPrintingPasses.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/IR/PassManager.h"
- namespace llvm {
- class DIBuilder;
- /// Add synthesized debug information to a module.
- ///
- /// \param M The module to add debug information to.
- /// \param Functions A range of functions to add debug information to.
- /// \param Banner A prefix string to add to debug/error messages.
- /// \param ApplyToMF A call back that will add debug information to the
- /// MachineFunction for a Function. If nullptr, then the
- /// MachineFunction (if any) will not be modified.
- bool applyDebugifyMetadata(
- Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
- std::function<bool(DIBuilder &, Function &)> ApplyToMF);
- /// Strip out all of the metadata and debug info inserted by debugify. If no
- /// llvm.debugify module-level named metadata is present, this is a no-op.
- /// Returns true if any change was made.
- bool stripDebugifyMetadata(Module &M);
- llvm::ModulePass *createDebugifyModulePass();
- llvm::FunctionPass *createDebugifyFunctionPass();
- struct NewPMDebugifyPass : public llvm::PassInfoMixin<NewPMDebugifyPass> {
- llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
- };
- /// Track how much `debugify` information has been lost.
- struct DebugifyStatistics {
- /// Number of missing dbg.values.
- unsigned NumDbgValuesMissing = 0;
- /// Number of dbg.values expected.
- unsigned NumDbgValuesExpected = 0;
- /// Number of instructions with empty debug locations.
- unsigned NumDbgLocsMissing = 0;
- /// Number of instructions expected to have debug locations.
- unsigned NumDbgLocsExpected = 0;
- /// Get the ratio of missing/expected dbg.values.
- float getMissingValueRatio() const {
- return float(NumDbgValuesMissing) / float(NumDbgLocsExpected);
- }
- /// Get the ratio of missing/expected instructions with locations.
- float getEmptyLocationRatio() const {
- return float(NumDbgLocsMissing) / float(NumDbgLocsExpected);
- }
- };
- /// Map pass names to a per-pass DebugifyStatistics instance.
- using DebugifyStatsMap = llvm::MapVector<llvm::StringRef, DebugifyStatistics>;
- void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
- llvm::ModulePass *
- createCheckDebugifyModulePass(bool Strip = false,
- llvm::StringRef NameOfWrappedPass = "",
- DebugifyStatsMap *StatsMap = nullptr);
- llvm::FunctionPass *
- createCheckDebugifyFunctionPass(bool Strip = false,
- llvm::StringRef NameOfWrappedPass = "",
- DebugifyStatsMap *StatsMap = nullptr);
- struct NewPMCheckDebugifyPass
- : public llvm::PassInfoMixin<NewPMCheckDebugifyPass> {
- llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
- };
- struct DebugifyEachInstrumentation {
- DebugifyStatsMap StatsMap;
- void registerCallbacks(PassInstrumentationCallbacks &PIC);
- };
- /// DebugifyCustomPassManager wraps each pass with the debugify passes if
- /// needed.
- /// NOTE: We support legacy custom pass manager only.
- /// TODO: Add New PM support for custom pass manager.
- class DebugifyCustomPassManager : public legacy::PassManager {
- DebugifyStatsMap DIStatsMap;
- bool EnableDebugifyEach = false;
- public:
- using super = legacy::PassManager;
- void add(Pass *P) override {
- // Wrap each pass with (-check)-debugify passes if requested, making
- // exceptions for passes which shouldn't see -debugify instrumentation.
- bool WrapWithDebugify = EnableDebugifyEach && !P->getAsImmutablePass() &&
- !isIRPrintingPass(P) && !isBitcodeWriterPass(P);
- if (!WrapWithDebugify) {
- super::add(P);
- return;
- }
- // Apply -debugify/-check-debugify before/after each pass and collect
- // debug info loss statistics.
- PassKind Kind = P->getPassKind();
- StringRef Name = P->getPassName();
- // TODO: Implement Debugify for LoopPass.
- switch (Kind) {
- case PT_Function:
- super::add(createDebugifyFunctionPass());
- super::add(P);
- super::add(createCheckDebugifyFunctionPass(true, Name, &DIStatsMap));
- break;
- case PT_Module:
- super::add(createDebugifyModulePass());
- super::add(P);
- super::add(createCheckDebugifyModulePass(true, Name, &DIStatsMap));
- break;
- default:
- super::add(P);
- break;
- }
- }
- void enableDebugifyEach() { EnableDebugifyEach = true; }
- const DebugifyStatsMap &getDebugifyStatsMap() const { return DIStatsMap; }
- };
- } // namespace llvm
- #endif // LLVM_TRANSFORM_UTILS_DEBUGIFY_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|