File indexing completed on 2026-05-10 08:44:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_TRANSFORMS_UTILS_DEBUGIFY_H
0015 #define LLVM_TRANSFORMS_UTILS_DEBUGIFY_H
0016
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/Bitcode/BitcodeWriterPass.h"
0020 #include "llvm/IR/IRPrintingPasses.h"
0021 #include "llvm/IR/LegacyPassManager.h"
0022 #include "llvm/IR/Module.h"
0023 #include "llvm/IR/PassInstrumentation.h"
0024 #include "llvm/IR/PassManager.h"
0025 #include "llvm/IR/ValueHandle.h"
0026 #include "llvm/Pass.h"
0027
0028 using DebugFnMap =
0029 llvm::MapVector<const llvm::Function *, const llvm::DISubprogram *>;
0030 using DebugInstMap = llvm::MapVector<const llvm::Instruction *, bool>;
0031 using DebugVarMap = llvm::MapVector<const llvm::DILocalVariable *, unsigned>;
0032 using WeakInstValueMap =
0033 llvm::MapVector<const llvm::Instruction *, llvm::WeakVH>;
0034
0035
0036 struct DebugInfoPerPass {
0037
0038 DebugFnMap DIFunctions;
0039
0040 DebugInstMap DILocations;
0041
0042
0043 WeakInstValueMap InstToDelete;
0044
0045 DebugVarMap DIVariables;
0046 };
0047
0048 namespace llvm {
0049 class DIBuilder;
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 bool applyDebugifyMetadata(
0060 Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
0061 std::function<bool(DIBuilder &, Function &)> ApplyToMF);
0062
0063
0064
0065
0066 bool stripDebugifyMetadata(Module &M);
0067
0068
0069
0070
0071
0072
0073
0074
0075 bool collectDebugInfoMetadata(Module &M,
0076 iterator_range<Module::iterator> Functions,
0077 DebugInfoPerPass &DebugInfoBeforePass,
0078 StringRef Banner, StringRef NameOfWrappedPass);
0079
0080
0081
0082
0083
0084
0085
0086
0087 bool checkDebugInfoMetadata(Module &M,
0088 iterator_range<Module::iterator> Functions,
0089 DebugInfoPerPass &DebugInfoBeforePass,
0090 StringRef Banner, StringRef NameOfWrappedPass,
0091 StringRef OrigDIVerifyBugsReportFilePath);
0092 }
0093
0094
0095 enum class DebugifyMode { NoDebugify, SyntheticDebugInfo, OriginalDebugInfo };
0096
0097 llvm::ModulePass *createDebugifyModulePass(
0098 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
0099 llvm::StringRef NameOfWrappedPass = "",
0100 DebugInfoPerPass *DebugInfoBeforePass = nullptr);
0101 llvm::FunctionPass *createDebugifyFunctionPass(
0102 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
0103 llvm::StringRef NameOfWrappedPass = "",
0104 DebugInfoPerPass *DebugInfoBeforePass = nullptr);
0105
0106 class NewPMDebugifyPass : public llvm::PassInfoMixin<NewPMDebugifyPass> {
0107 llvm::StringRef NameOfWrappedPass;
0108 DebugInfoPerPass *DebugInfoBeforePass = nullptr;
0109 enum DebugifyMode Mode = DebugifyMode::NoDebugify;
0110 public:
0111 NewPMDebugifyPass(
0112 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
0113 llvm::StringRef NameOfWrappedPass = "",
0114 DebugInfoPerPass *DebugInfoBeforePass = nullptr)
0115 : NameOfWrappedPass(NameOfWrappedPass),
0116 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {}
0117
0118 llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
0119 };
0120
0121
0122
0123 struct DebugifyStatistics {
0124
0125 unsigned NumDbgValuesMissing = 0;
0126
0127
0128 unsigned NumDbgValuesExpected = 0;
0129
0130
0131 unsigned NumDbgLocsMissing = 0;
0132
0133
0134 unsigned NumDbgLocsExpected = 0;
0135
0136
0137 float getMissingValueRatio() const {
0138 return float(NumDbgValuesMissing) / float(NumDbgLocsExpected);
0139 }
0140
0141
0142 float getEmptyLocationRatio() const {
0143 return float(NumDbgLocsMissing) / float(NumDbgLocsExpected);
0144 }
0145 };
0146
0147
0148 using DebugifyStatsMap = llvm::MapVector<llvm::StringRef, DebugifyStatistics>;
0149
0150 llvm::ModulePass *createCheckDebugifyModulePass(
0151 bool Strip = false, llvm::StringRef NameOfWrappedPass = "",
0152 DebugifyStatsMap *StatsMap = nullptr,
0153 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
0154 DebugInfoPerPass *DebugInfoBeforePass = nullptr,
0155 llvm::StringRef OrigDIVerifyBugsReportFilePath = "");
0156
0157 llvm::FunctionPass *createCheckDebugifyFunctionPass(
0158 bool Strip = false, llvm::StringRef NameOfWrappedPass = "",
0159 DebugifyStatsMap *StatsMap = nullptr,
0160 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
0161 DebugInfoPerPass *DebugInfoBeforePass = nullptr,
0162 llvm::StringRef OrigDIVerifyBugsReportFilePath = "");
0163
0164 class NewPMCheckDebugifyPass
0165 : public llvm::PassInfoMixin<NewPMCheckDebugifyPass> {
0166 llvm::StringRef NameOfWrappedPass;
0167 llvm::StringRef OrigDIVerifyBugsReportFilePath;
0168 DebugifyStatsMap *StatsMap;
0169 DebugInfoPerPass *DebugInfoBeforePass;
0170 enum DebugifyMode Mode;
0171 bool Strip;
0172 public:
0173 NewPMCheckDebugifyPass(
0174 bool Strip = false, llvm::StringRef NameOfWrappedPass = "",
0175 DebugifyStatsMap *StatsMap = nullptr,
0176 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo,
0177 DebugInfoPerPass *DebugInfoBeforePass = nullptr,
0178 llvm::StringRef OrigDIVerifyBugsReportFilePath = "")
0179 : NameOfWrappedPass(NameOfWrappedPass),
0180 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath),
0181 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode),
0182 Strip(Strip) {}
0183
0184 llvm::PreservedAnalyses run(llvm::Module &M, llvm::ModuleAnalysisManager &AM);
0185 };
0186
0187 namespace llvm {
0188 void exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map);
0189
0190 class DebugifyEachInstrumentation {
0191 llvm::StringRef OrigDIVerifyBugsReportFilePath = "";
0192 DebugInfoPerPass *DebugInfoBeforePass = nullptr;
0193 enum DebugifyMode Mode = DebugifyMode::NoDebugify;
0194 DebugifyStatsMap *DIStatsMap = nullptr;
0195
0196 public:
0197 void registerCallbacks(PassInstrumentationCallbacks &PIC,
0198 ModuleAnalysisManager &MAM);
0199
0200 void setDIStatsMap(DebugifyStatsMap &StatMap) { DIStatsMap = &StatMap; }
0201 const DebugifyStatsMap &getDebugifyStatsMap() const { return *DIStatsMap; }
0202
0203 void setDebugInfoBeforePass(DebugInfoPerPass &PerPassMap) {
0204 DebugInfoBeforePass = &PerPassMap;
0205 }
0206 DebugInfoPerPass &getDebugInfoPerPass() { return *DebugInfoBeforePass; }
0207
0208 void setOrigDIVerifyBugsReportFilePath(StringRef BugsReportFilePath) {
0209 OrigDIVerifyBugsReportFilePath = BugsReportFilePath;
0210 }
0211 StringRef getOrigDIVerifyBugsReportFilePath() const {
0212 return OrigDIVerifyBugsReportFilePath;
0213 }
0214
0215 void setDebugifyMode(enum DebugifyMode M) { Mode = M; }
0216
0217 bool isSyntheticDebugInfo() const {
0218 return Mode == DebugifyMode::SyntheticDebugInfo;
0219 }
0220 bool isOriginalDebugInfoMode() const {
0221 return Mode == DebugifyMode::OriginalDebugInfo;
0222 }
0223 };
0224
0225
0226
0227
0228
0229 class DebugifyCustomPassManager : public legacy::PassManager {
0230 StringRef OrigDIVerifyBugsReportFilePath;
0231 DebugifyStatsMap *DIStatsMap = nullptr;
0232 DebugInfoPerPass *DebugInfoBeforePass = nullptr;
0233 enum DebugifyMode Mode = DebugifyMode::NoDebugify;
0234
0235 public:
0236 using super = legacy::PassManager;
0237
0238 void add(Pass *P) override {
0239
0240
0241 bool WrapWithDebugify = Mode != DebugifyMode::NoDebugify &&
0242 !P->getAsImmutablePass() && !isIRPrintingPass(P) &&
0243 !isBitcodeWriterPass(P);
0244 if (!WrapWithDebugify) {
0245 super::add(P);
0246 return;
0247 }
0248
0249
0250
0251
0252 PassKind Kind = P->getPassKind();
0253 StringRef Name = P->getPassName();
0254
0255
0256 switch (Kind) {
0257 case PT_Function:
0258 super::add(createDebugifyFunctionPass(Mode, Name, DebugInfoBeforePass));
0259 super::add(P);
0260 super::add(createCheckDebugifyFunctionPass(
0261 isSyntheticDebugInfo(), Name, DIStatsMap, Mode, DebugInfoBeforePass,
0262 OrigDIVerifyBugsReportFilePath));
0263 break;
0264 case PT_Module:
0265 super::add(createDebugifyModulePass(Mode, Name, DebugInfoBeforePass));
0266 super::add(P);
0267 super::add(createCheckDebugifyModulePass(
0268 isSyntheticDebugInfo(), Name, DIStatsMap, Mode, DebugInfoBeforePass,
0269 OrigDIVerifyBugsReportFilePath));
0270 break;
0271 default:
0272 super::add(P);
0273 break;
0274 }
0275 }
0276
0277
0278 void setDIStatsMap(DebugifyStatsMap &StatMap) { DIStatsMap = &StatMap; }
0279
0280 void setDebugInfoBeforePass(DebugInfoPerPass &PerPassDI) {
0281 DebugInfoBeforePass = &PerPassDI;
0282 }
0283 void setOrigDIVerifyBugsReportFilePath(StringRef BugsReportFilePath) {
0284 OrigDIVerifyBugsReportFilePath = BugsReportFilePath;
0285 }
0286 StringRef getOrigDIVerifyBugsReportFilePath() const {
0287 return OrigDIVerifyBugsReportFilePath;
0288 }
0289
0290 void setDebugifyMode(enum DebugifyMode M) { Mode = M; }
0291
0292 bool isSyntheticDebugInfo() const {
0293 return Mode == DebugifyMode::SyntheticDebugInfo;
0294 }
0295 bool isOriginalDebugInfoMode() const {
0296 return Mode == DebugifyMode::OriginalDebugInfo;
0297 }
0298
0299 const DebugifyStatsMap &getDebugifyStatsMap() const { return *DIStatsMap; }
0300 DebugInfoPerPass &getDebugInfoPerPass() { return *DebugInfoBeforePass; }
0301 };
0302 }
0303
0304 #endif