- //===- Debugify.h - Check debug info preservation in optimizations --------===// 
- // 
- // 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/original debug info testing 
- /// utility. 
- /// 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_TRANSFORMS_UTILS_DEBUGIFY_H 
- #define LLVM_TRANSFORMS_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" 
- #include "llvm/IR/ValueHandle.h" 
- #include "llvm/Pass.h" 
-   
- using DebugFnMap = 
-     llvm::MapVector<const llvm::Function *, const llvm::DISubprogram *>; 
- using DebugInstMap = llvm::MapVector<const llvm::Instruction *, bool>; 
- using DebugVarMap = llvm::MapVector<const llvm::DILocalVariable *, unsigned>; 
- using WeakInstValueMap = 
-     llvm::MapVector<const llvm::Instruction *, llvm::WeakVH>; 
-   
- /// Used to track the Debug Info Metadata information. 
- struct DebugInfoPerPass { 
-   // This maps a function name to its associated DISubprogram. 
-   DebugFnMap DIFunctions; 
-   // This maps an instruction and the info about whether it has !dbg attached. 
-   DebugInstMap DILocations; 
-   // This tracks value (instruction) deletion. If an instruction gets deleted, 
-   // WeakVH nulls itself. 
-   WeakInstValueMap InstToDelete; 
-   // Maps variable into dbg users (#dbg values/declares for this variable). 
-   DebugVarMap DIVariables; 
- }; 
-   
- 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); 
-   
- /// Collect original debug information before a pass. 
- /// 
- /// \param M The module to collect debug information from. 
- /// \param Functions A range of functions to collect debug information from. 
- /// \param DebugInfoBeforePass DI metadata before a pass. 
- /// \param Banner A prefix string to add to debug/error messages. 
- /// \param NameOfWrappedPass A name of a pass to add to debug/error messages. 
- bool collectDebugInfoMetadata(Module &M, 
-                               iterator_range<Module::iterator> Functions, 
-                               DebugInfoPerPass &DebugInfoBeforePass, 
-                               StringRef Banner, StringRef NameOfWrappedPass); 
-   
- /// Check original debug information after a pass. 
- /// 
- /// \param M The module to collect debug information from. 
- /// \param Functions A range of functions to collect debug information from. 
- /// \param DebugInfoBeforePass DI metadata before a pass. 
- /// \param Banner A prefix string to add to debug/error messages. 
- /// \param NameOfWrappedPass A name of a pass to add to debug/error messages. 
- bool checkDebugInfoMetadata(Module &M, 
-                             iterator_range<Module::iterator> Functions, 
-                             DebugInfoPerPass &DebugInfoBeforePass, 
-                             StringRef Banner, StringRef NameOfWrappedPass, 
-                             StringRef OrigDIVerifyBugsReportFilePath); 
- } // namespace llvm 
-   
- /// Used to check whether we track synthetic or original debug info. 
- enum class DebugifyMode { NoDebugify, SyntheticDebugInfo, OriginalDebugInfo }; 
-   
- llvm::ModulePass *createDebugifyModulePass( 
-     enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 
-     llvm::StringRef NameOfWrappedPass = "", 
-     DebugInfoPerPass *DebugInfoBeforePass = nullptr); 
- llvm::FunctionPass *createDebugifyFunctionPass( 
-     enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 
-     llvm::StringRef NameOfWrappedPass = "", 
-     DebugInfoPerPass *DebugInfoBeforePass = nullptr); 
-   
- class NewPMDebugifyPass : public llvm::PassInfoMixin<NewPMDebugifyPass> { 
-   llvm::StringRef NameOfWrappedPass; 
-   DebugInfoPerPass *DebugInfoBeforePass = nullptr; 
-   enum DebugifyMode Mode = DebugifyMode::NoDebugify; 
- public: 
-   NewPMDebugifyPass( 
-       enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 
-       llvm::StringRef NameOfWrappedPass = "", 
-       DebugInfoPerPass *DebugInfoBeforePass = nullptr) 
-       : NameOfWrappedPass(NameOfWrappedPass), 
-         DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {} 
-   
-   llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM); 
- }; 
-   
- /// Track how much `debugify` information (in the `synthetic` mode only) 
- /// 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>; 
-   
- llvm::ModulePass *createCheckDebugifyModulePass( 
-     bool Strip = false, llvm::StringRef NameOfWrappedPass = "", 
-     DebugifyStatsMap *StatsMap = nullptr, 
-     enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 
-     DebugInfoPerPass *DebugInfoBeforePass = nullptr, 
-     llvm::StringRef OrigDIVerifyBugsReportFilePath = ""); 
-   
- llvm::FunctionPass *createCheckDebugifyFunctionPass( 
-     bool Strip = false, llvm::StringRef NameOfWrappedPass = "", 
-     DebugifyStatsMap *StatsMap = nullptr, 
-     enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 
-     DebugInfoPerPass *DebugInfoBeforePass = nullptr, 
-     llvm::StringRef OrigDIVerifyBugsReportFilePath = ""); 
-   
- class NewPMCheckDebugifyPass 
-     : public llvm::PassInfoMixin<NewPMCheckDebugifyPass> { 
-   llvm::StringRef NameOfWrappedPass; 
-   llvm::StringRef OrigDIVerifyBugsReportFilePath; 
-   DebugifyStatsMap *StatsMap; 
-   DebugInfoPerPass *DebugInfoBeforePass; 
-   enum DebugifyMode Mode; 
-   bool Strip; 
- public: 
-   NewPMCheckDebugifyPass( 
-       bool Strip = false, llvm::StringRef NameOfWrappedPass = "", 
-       DebugifyStatsMap *StatsMap = nullptr, 
-       enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 
-       DebugInfoPerPass *DebugInfoBeforePass = nullptr, 
-       llvm::StringRef OrigDIVerifyBugsReportFilePath = "") 
-       : NameOfWrappedPass(NameOfWrappedPass), 
-         OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath), 
-         StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode), 
-         Strip(Strip) {} 
-   
-   llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM); 
- }; 
-   
- namespace llvm { 
- void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map); 
-   
- class DebugifyEachInstrumentation { 
-   llvm::StringRef OrigDIVerifyBugsReportFilePath = ""; 
-   DebugInfoPerPass *DebugInfoBeforePass = nullptr; 
-   enum DebugifyMode Mode = DebugifyMode::NoDebugify; 
-   DebugifyStatsMap *DIStatsMap = nullptr; 
-   
- public: 
-   
-   void registerCallbacks(PassInstrumentationCallbacks &PIC); 
-   // Used within DebugifyMode::SyntheticDebugInfo mode. 
-   void setDIStatsMap(DebugifyStatsMap &StatMap) { DIStatsMap = &StatMap; } 
-   const DebugifyStatsMap &getDebugifyStatsMap() const { return *DIStatsMap; } 
-   // Used within DebugifyMode::OriginalDebugInfo mode. 
-   void setDebugInfoBeforePass(DebugInfoPerPass &PerPassMap) { 
-     DebugInfoBeforePass = &PerPassMap; 
-   } 
-   DebugInfoPerPass &getDebugInfoPerPass() { return *DebugInfoBeforePass; } 
-   
-   void setOrigDIVerifyBugsReportFilePath(StringRef BugsReportFilePath) { 
-     OrigDIVerifyBugsReportFilePath = BugsReportFilePath; 
-   } 
-   StringRef getOrigDIVerifyBugsReportFilePath() const { 
-     return OrigDIVerifyBugsReportFilePath; 
-   } 
-   
-   void setDebugifyMode(enum DebugifyMode M) { Mode = M; } 
-   
-   bool isSyntheticDebugInfo() const { 
-     return Mode == DebugifyMode::SyntheticDebugInfo; 
-   } 
-   bool isOriginalDebugInfoMode() const { 
-     return Mode == DebugifyMode::OriginalDebugInfo; 
-   } 
- }; 
-   
- /// 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 { 
-   StringRef OrigDIVerifyBugsReportFilePath; 
-   DebugifyStatsMap *DIStatsMap = nullptr; 
-   DebugInfoPerPass *DebugInfoBeforePass = nullptr; 
-   enum DebugifyMode Mode = DebugifyMode::NoDebugify; 
-   
- 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 = Mode != DebugifyMode::NoDebugify && 
-                             !P->getAsImmutablePass() && !isIRPrintingPass(P) && 
-                             !isBitcodeWriterPass(P); 
-     if (!WrapWithDebugify) { 
-       super::add(P); 
-       return; 
-     } 
-   
-     // Either apply -debugify/-check-debugify before/after each pass and collect 
-     // debug info loss statistics, or collect and check original debug info in 
-     // the optimizations. 
-     PassKind Kind = P->getPassKind(); 
-     StringRef Name = P->getPassName(); 
-   
-     // TODO: Implement Debugify for LoopPass. 
-     switch (Kind) { 
-     case PT_Function: 
-       super::add(createDebugifyFunctionPass(Mode, Name, DebugInfoBeforePass)); 
-       super::add(P); 
-       super::add(createCheckDebugifyFunctionPass( 
-           isSyntheticDebugInfo(), Name, DIStatsMap, Mode, DebugInfoBeforePass, 
-           OrigDIVerifyBugsReportFilePath)); 
-       break; 
-     case PT_Module: 
-       super::add(createDebugifyModulePass(Mode, Name, DebugInfoBeforePass)); 
-       super::add(P); 
-       super::add(createCheckDebugifyModulePass( 
-           isSyntheticDebugInfo(), Name, DIStatsMap, Mode, DebugInfoBeforePass, 
-           OrigDIVerifyBugsReportFilePath)); 
-       break; 
-     default: 
-       super::add(P); 
-       break; 
-     } 
-   } 
-   
-   // Used within DebugifyMode::SyntheticDebugInfo mode. 
-   void setDIStatsMap(DebugifyStatsMap &StatMap) { DIStatsMap = &StatMap; } 
-   // Used within DebugifyMode::OriginalDebugInfo mode. 
-   void setDebugInfoBeforePass(DebugInfoPerPass &PerPassDI) { 
-     DebugInfoBeforePass = &PerPassDI; 
-   } 
-   void setOrigDIVerifyBugsReportFilePath(StringRef BugsReportFilePath) { 
-     OrigDIVerifyBugsReportFilePath = BugsReportFilePath; 
-   } 
-   StringRef getOrigDIVerifyBugsReportFilePath() const { 
-     return OrigDIVerifyBugsReportFilePath; 
-   } 
-   
-   void setDebugifyMode(enum DebugifyMode M) { Mode = M; } 
-   
-   bool isSyntheticDebugInfo() const { 
-     return Mode == DebugifyMode::SyntheticDebugInfo; 
-   } 
-   bool isOriginalDebugInfoMode() const { 
-     return Mode == DebugifyMode::OriginalDebugInfo; 
-   } 
-   
-   const DebugifyStatsMap &getDebugifyStatsMap() const { return *DIStatsMap; } 
-   DebugInfoPerPass &getDebugInfoPerPass() { return *DebugInfoBeforePass; } 
- }; 
- } // namespace llvm 
-   
- #endif // LLVM_TRANSFORMS_UTILS_DEBUGIFY_H 
-