1 //===- Debugify.cpp - Check debug info preservation in optimizations ------===// 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 /// \file In the `synthetic` mode, the `-debugify` attaches synthetic debug info 10 /// to everything. It can be used to create targeted tests for debug info 11 /// preservation. In addition, when using the `original` mode, it can check 12 /// original debug info preservation. The `synthetic` mode is default one. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Transforms/Utils/Debugify.h" 17 #include "llvm/ADT/BitVector.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/Config/llvm-config.h" 20 #include "llvm/IR/DIBuilder.h" 21 #include "llvm/IR/DebugInfo.h" 22 #include "llvm/IR/DebugLoc.h" 23 #include "llvm/IR/InstIterator.h" 24 #include "llvm/IR/Instructions.h" 25 #include "llvm/IR/IntrinsicInst.h" 26 #include "llvm/IR/Module.h" 27 #include "llvm/IR/PassInstrumentation.h" 28 #include "llvm/Pass.h" 29 #include "llvm/Support/CommandLine.h" 30 #include "llvm/Support/FileSystem.h" 31 #include "llvm/Support/JSON.h" 32 #include <optional> 33 #if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN 34 // We need the Signals header to operate on stacktraces if we're using DebugLoc 35 // origin-tracking. 36 #include "llvm/Support/Signals.h" 37 #endif 38 39 #define DEBUG_TYPE "debugify" 40 41 using namespace llvm; 42 43 namespace { 44 45 cl::opt<bool> ApplyAtomGroups("debugify-atoms", cl::init(false)); 46 47 cl::opt<bool> Quiet("debugify-quiet", 48 cl::desc("Suppress verbose debugify output")); 49 50 cl::opt<uint64_t> DebugifyFunctionsLimit( 51 "debugify-func-limit", 52 cl::desc("Set max number of processed functions per pass."), 53 cl::init(UINT_MAX)); 54 55 enum class Level { 56 Locations, 57 LocationsAndVariables 58 }; 59 60 cl::opt<Level> DebugifyLevel( 61 "debugify-level", cl::desc("Kind of debug info to add"), 62 cl::values(clEnumValN(Level::Locations, "locations", "Locations only"), 63 clEnumValN(Level::LocationsAndVariables, "location+variables", 64 "Locations and Variables")), 65 cl::init(Level::LocationsAndVariables)); 66 67 raw_ostream &dbg() { return Quiet ? nulls() : errs(); } 68 69 #if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN 70 // These maps refer to addresses in the current LLVM process, so we can reuse 71 // them everywhere - therefore, we store them at file scope. 72 static SymbolizedAddressMap SymbolizedAddrs; 73 static AddressSet UnsymbolizedAddrs; 74 75 std::string symbolizeStackTrace(const Instruction *I) { 76 // We flush the set of unsymbolized addresses at the latest possible moment, 77 // i.e. now. 78 if (!UnsymbolizedAddrs.empty()) { 79 sys::symbolizeAddresses(UnsymbolizedAddrs, SymbolizedAddrs); 80 UnsymbolizedAddrs.clear(); 81 } 82 const DbgLocOrigin::StackTracesTy &OriginStackTraces = 83 I->getDebugLoc().getOriginStackTraces(); 84 std::string Result; 85 raw_string_ostream OS(Result); 86 for (size_t TraceIdx = 0; TraceIdx < OriginStackTraces.size(); ++TraceIdx) { 87 if (TraceIdx != 0) 88 OS << "========================================\n"; 89 auto &[Depth, StackTrace] = OriginStackTraces[TraceIdx]; 90 unsigned VirtualFrameNo = 0; 91 for (int Frame = 0; Frame < Depth; ++Frame) { 92 assert(SymbolizedAddrs.contains(StackTrace[Frame]) && 93 "Expected each address to have been symbolized."); 94 for (std::string &SymbolizedFrame : SymbolizedAddrs[StackTrace[Frame]]) { 95 OS << right_justify(formatv("#{0}", VirtualFrameNo++).str(), 96 std::log10(Depth) + 2) 97 << ' ' << SymbolizedFrame << '\n'; 98 } 99 } 100 } 101 return Result; 102 } 103 void collectStackAddresses(Instruction &I) { 104 auto &OriginStackTraces = I.getDebugLoc().getOriginStackTraces(); 105 for (auto &[Depth, StackTrace] : OriginStackTraces) { 106 for (int Frame = 0; Frame < Depth; ++Frame) { 107 void *Addr = StackTrace[Frame]; 108 if (!SymbolizedAddrs.contains(Addr)) 109 UnsymbolizedAddrs.insert(Addr); 110 } 111 } 112 } 113 #else 114 void collectStackAddresses(Instruction &I) {} 115 #endif // LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN 116 117 uint64_t getAllocSizeInBits(Module &M, Type *Ty) { 118 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0; 119 } 120 121 bool isFunctionSkipped(Function &F) { 122 return F.isDeclaration() || !F.hasExactDefinition(); 123 } 124 125 /// Find the basic block's terminating instruction. 126 /// 127 /// Special care is needed to handle musttail and deopt calls, as these behave 128 /// like (but are in fact not) terminators. 129 Instruction *findTerminatingInstruction(BasicBlock &BB) { 130 if (auto *I = BB.getTerminatingMustTailCall()) 131 return I; 132 if (auto *I = BB.getTerminatingDeoptimizeCall()) 133 return I; 134 return BB.getTerminator(); 135 } 136 } // end anonymous namespace 137 138 bool llvm::applyDebugifyMetadata( 139 Module &M, iterator_range<Module::iterator> Functions, StringRef Banner, 140 std::function<bool(DIBuilder &DIB, Function &F)> ApplyToMF) { 141 // Skip modules with debug info. 142 if (M.getNamedMetadata("llvm.dbg.cu")) { 143 dbg() << Banner << "Skipping module with debug info\n"; 144 return false; 145 } 146 147 DIBuilder DIB(M); 148 LLVMContext &Ctx = M.getContext(); 149 auto *Int32Ty = Type::getInt32Ty(Ctx); 150 151 // Get a DIType which corresponds to Ty. 152 DenseMap<uint64_t, DIType *> TypeCache; 153 auto getCachedDIType = [&](Type *Ty) -> DIType * { 154 uint64_t Size = getAllocSizeInBits(M, Ty); 155 DIType *&DTy = TypeCache[Size]; 156 if (!DTy) { 157 std::string Name = "ty" + utostr(Size); 158 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned); 159 } 160 return DTy; 161 }; 162 163 unsigned NextLine = 1; 164 unsigned NextVar = 1; 165 auto File = DIB.createFile(M.getName(), "/"); 166 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify", 167 /*isOptimized=*/true, "", 0); 168 169 // Visit each instruction. 170 for (Function &F : Functions) { 171 if (isFunctionSkipped(F)) 172 continue; 173 174 bool InsertedDbgVal = false; 175 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray({})); 176 DISubprogram::DISPFlags SPFlags = 177 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized; 178 if (F.hasPrivateLinkage() || F.hasInternalLinkage()) 179 SPFlags |= DISubprogram::SPFlagLocalToUnit; 180 auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, 181 SPType, NextLine, DINode::FlagZero, SPFlags, 182 nullptr, nullptr, nullptr, nullptr, "", 183 /*UseKeyInstructions*/ ApplyAtomGroups); 184 F.setSubprogram(SP); 185 186 // Helper that inserts a dbg.value before \p InsertBefore, copying the 187 // location (and possibly the type, if it's non-void) from \p TemplateInst. 188 auto insertDbgVal = [&](Instruction &TemplateInst, 189 BasicBlock::iterator InsertPt) { 190 std::string Name = utostr(NextVar++); 191 Value *V = &TemplateInst; 192 if (TemplateInst.getType()->isVoidTy()) 193 V = ConstantInt::get(Int32Ty, 0); 194 const DILocation *Loc = TemplateInst.getDebugLoc().get(); 195 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(), 196 getCachedDIType(V->getType()), 197 /*AlwaysPreserve=*/true); 198 DIB.insertDbgValueIntrinsic(V, LocalVar, DIB.createExpression(), Loc, 199 InsertPt); 200 }; 201 202 for (BasicBlock &BB : F) { 203 // Attach debug locations. 204 for (Instruction &I : BB) { 205 uint64_t AtomGroup = ApplyAtomGroups ? NextLine : 0; 206 uint8_t AtomRank = ApplyAtomGroups ? 1 : 0; 207 uint64_t Line = NextLine++; 208 I.setDebugLoc(DILocation::get(Ctx, Line, 1, SP, nullptr, false, 209 AtomGroup, AtomRank)); 210 } 211 212 if (DebugifyLevel < Level::LocationsAndVariables) 213 continue; 214 215 // Inserting debug values into EH pads can break IR invariants. 216 if (BB.isEHPad()) 217 continue; 218 219 // Find the terminating instruction, after which no debug values are 220 // attached. 221 Instruction *LastInst = findTerminatingInstruction(BB); 222 assert(LastInst && "Expected basic block with a terminator"); 223 224 // Maintain an insertion point which can't be invalidated when updates 225 // are made. 226 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt(); 227 assert(InsertPt != BB.end() && "Expected to find an insertion point"); 228 229 // Insert after existing debug values to preserve order. 230 InsertPt.setHeadBit(false); 231 232 // Attach debug values. 233 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) { 234 // Skip void-valued instructions. 235 if (I->getType()->isVoidTy()) 236 continue; 237 238 // Phis and EH pads must be grouped at the beginning of the block. 239 // Only advance the insertion point when we finish visiting these. 240 if (!isa<PHINode>(I) && !I->isEHPad()) 241 InsertPt = std::next(I->getIterator()); 242 243 insertDbgVal(*I, InsertPt); 244 InsertedDbgVal = true; 245 } 246 } 247 // Make sure we emit at least one dbg.value, otherwise MachineDebugify may 248 // not have anything to work with as it goes about inserting DBG_VALUEs. 249 // (It's common for MIR tests to be written containing skeletal IR with 250 // empty functions -- we're still interested in debugifying the MIR within 251 // those tests, and this helps with that.) 252 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) { 253 auto *Term = findTerminatingInstruction(F.getEntryBlock()); 254 insertDbgVal(*Term, Term->getIterator()); 255 } 256 if (ApplyToMF) 257 ApplyToMF(DIB, F); 258 DIB.finalizeSubprogram(SP); 259 } 260 DIB.finalize(); 261 262 // Track the number of distinct lines and variables. 263 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify"); 264 auto addDebugifyOperand = [&](unsigned N) { 265 NMD->addOperand(MDNode::get( 266 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N)))); 267 }; 268 addDebugifyOperand(NextLine - 1); // Original number of lines. 269 addDebugifyOperand(NextVar - 1); // Original number of variables. 270 assert(NMD->getNumOperands() == 2 && 271 "llvm.debugify should have exactly 2 operands!"); 272 273 // Claim that this synthetic debug info is valid. 274 StringRef DIVersionKey = "Debug Info Version"; 275 if (!M.getModuleFlag(DIVersionKey)) 276 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION); 277 278 return true; 279 } 280 281 static bool applyDebugify(Function &F, enum DebugifyMode Mode, 282 DebugInfoPerPass *DebugInfoBeforePass, 283 StringRef NameOfWrappedPass = "") { 284 Module &M = *F.getParent(); 285 auto FuncIt = F.getIterator(); 286 if (Mode == DebugifyMode::SyntheticDebugInfo) 287 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), 288 "FunctionDebugify: ", /*ApplyToMF*/ nullptr); 289 assert(DebugInfoBeforePass && "Missing debug info metadata"); 290 return collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass, 291 "FunctionDebugify (original debuginfo)", 292 NameOfWrappedPass); 293 } 294 295 static bool applyDebugify(Module &M, enum DebugifyMode Mode, 296 DebugInfoPerPass *DebugInfoBeforePass, 297 StringRef NameOfWrappedPass = "") { 298 if (Mode == DebugifyMode::SyntheticDebugInfo) 299 return applyDebugifyMetadata(M, M.functions(), 300 "ModuleDebugify: ", /*ApplyToMF*/ nullptr); 301 assert(DebugInfoBeforePass && "Missing debug info metadata"); 302 return collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass, 303 "ModuleDebugify (original debuginfo)", 304 NameOfWrappedPass); 305 } 306 307 bool llvm::stripDebugifyMetadata(Module &M) { 308 bool Changed = false; 309 310 // Remove the llvm.debugify and llvm.mir.debugify module-level named metadata. 311 NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify"); 312 if (DebugifyMD) { 313 M.eraseNamedMetadata(DebugifyMD); 314 Changed = true; 315 } 316 317 if (auto *MIRDebugifyMD = M.getNamedMetadata("llvm.mir.debugify")) { 318 M.eraseNamedMetadata(MIRDebugifyMD); 319 Changed = true; 320 } 321 322 // Strip out all debug intrinsics and supporting metadata (subprograms, types, 323 // variables, etc). 324 Changed |= StripDebugInfo(M); 325 326 // Strip out the dead dbg.value prototype. 327 Function *DbgValF = M.getFunction("llvm.dbg.value"); 328 if (DbgValF) { 329 assert(DbgValF->isDeclaration() && DbgValF->use_empty() && 330 "Not all debug info stripped?"); 331 DbgValF->eraseFromParent(); 332 Changed = true; 333 } 334 335 // Strip out the module-level Debug Info Version metadata. 336 // FIXME: There must be an easier way to remove an operand from a NamedMDNode. 337 NamedMDNode *NMD = M.getModuleFlagsMetadata(); 338 if (!NMD) 339 return Changed; 340 SmallVector<MDNode *, 4> Flags(NMD->operands()); 341 NMD->clearOperands(); 342 for (MDNode *Flag : Flags) { 343 auto *Key = cast<MDString>(Flag->getOperand(1)); 344 if (Key->getString() == "Debug Info Version") { 345 Changed = true; 346 continue; 347 } 348 NMD->addOperand(Flag); 349 } 350 // If we left it empty we might as well remove it. 351 if (NMD->getNumOperands() == 0) 352 NMD->eraseFromParent(); 353 354 return Changed; 355 } 356 357 bool hasLoc(const Instruction &I) { 358 const DILocation *Loc = I.getDebugLoc().get(); 359 #if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE 360 DebugLocKind Kind = I.getDebugLoc().getKind(); 361 return Loc || Kind != DebugLocKind::Normal; 362 #else 363 return Loc; 364 #endif 365 } 366 367 bool llvm::collectDebugInfoMetadata(Module &M, 368 iterator_range<Module::iterator> Functions, 369 DebugInfoPerPass &DebugInfoBeforePass, 370 StringRef Banner, 371 StringRef NameOfWrappedPass) { 372 LLVM_DEBUG(dbgs() << Banner << ": (before) " << NameOfWrappedPass << '\n'); 373 374 if (!M.getNamedMetadata("llvm.dbg.cu")) { 375 dbg() << Banner << ": Skipping module without debug info\n"; 376 return false; 377 } 378 379 uint64_t FunctionsCnt = DebugInfoBeforePass.DIFunctions.size(); 380 // Visit each instruction. 381 for (Function &F : Functions) { 382 // Use DI collected after previous Pass (when -debugify-each is used). 383 if (DebugInfoBeforePass.DIFunctions.count(&F)) 384 continue; 385 386 if (isFunctionSkipped(F)) 387 continue; 388 389 // Stop collecting DI if the Functions number reached the limit. 390 if (++FunctionsCnt >= DebugifyFunctionsLimit) 391 break; 392 // Collect the DISubprogram. 393 auto *SP = F.getSubprogram(); 394 DebugInfoBeforePass.DIFunctions.insert({&F, SP}); 395 if (SP) { 396 LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n'); 397 for (const DINode *DN : SP->getRetainedNodes()) { 398 if (const auto *DV = dyn_cast<DILocalVariable>(DN)) { 399 DebugInfoBeforePass.DIVariables[DV] = 0; 400 } 401 } 402 } 403 404 for (BasicBlock &BB : F) { 405 // Collect debug locations (!dbg) and debug variable intrinsics. 406 for (Instruction &I : BB) { 407 // Skip PHIs. 408 if (isa<PHINode>(I)) 409 continue; 410 411 // Cllect dbg.values and dbg.declare. 412 if (DebugifyLevel > Level::Locations) { 413 auto HandleDbgVariable = [&](DbgVariableRecord *DbgVar) { 414 if (!SP) 415 return; 416 // Skip inlined variables. 417 if (DbgVar->getDebugLoc().getInlinedAt()) 418 return; 419 // Skip undef values. 420 if (DbgVar->isKillLocation()) 421 return; 422 423 auto *Var = DbgVar->getVariable(); 424 DebugInfoBeforePass.DIVariables[Var]++; 425 }; 426 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) 427 HandleDbgVariable(&DVR); 428 } 429 430 LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n'); 431 DebugInfoBeforePass.InstToDelete.insert({&I, &I}); 432 433 // Track the addresses to symbolize, if the feature is enabled. 434 collectStackAddresses(I); 435 DebugInfoBeforePass.DILocations.insert({&I, hasLoc(I)}); 436 } 437 } 438 } 439 440 return true; 441 } 442 443 // This checks the preservation of original debug info attached to functions. 444 static bool checkFunctions(const DebugFnMap &DIFunctionsBefore, 445 const DebugFnMap &DIFunctionsAfter, 446 StringRef NameOfWrappedPass, 447 StringRef FileNameFromCU, bool ShouldWriteIntoJSON, 448 llvm::json::Array &Bugs) { 449 bool Preserved = true; 450 for (const auto &F : DIFunctionsAfter) { 451 if (F.second) 452 continue; 453 auto SPIt = DIFunctionsBefore.find(F.first); 454 if (SPIt == DIFunctionsBefore.end()) { 455 if (ShouldWriteIntoJSON) 456 Bugs.push_back(llvm::json::Object({{"metadata", "DISubprogram"}, 457 {"name", F.first->getName()}, 458 {"action", "not-generate"}})); 459 else 460 dbg() << "ERROR: " << NameOfWrappedPass 461 << " did not generate DISubprogram for " << F.first->getName() 462 << " from " << FileNameFromCU << '\n'; 463 Preserved = false; 464 } else { 465 auto SP = SPIt->second; 466 if (!SP) 467 continue; 468 // If the function had the SP attached before the pass, consider it as 469 // a debug info bug. 470 if (ShouldWriteIntoJSON) 471 Bugs.push_back(llvm::json::Object({{"metadata", "DISubprogram"}, 472 {"name", F.first->getName()}, 473 {"action", "drop"}})); 474 else 475 dbg() << "ERROR: " << NameOfWrappedPass << " dropped DISubprogram of " 476 << F.first->getName() << " from " << FileNameFromCU << '\n'; 477 Preserved = false; 478 } 479 } 480 481 return Preserved; 482 } 483 484 // This checks the preservation of the original debug info attached to 485 // instructions. 486 static bool checkInstructions(const DebugInstMap &DILocsBefore, 487 const DebugInstMap &DILocsAfter, 488 const WeakInstValueMap &InstToDelete, 489 StringRef NameOfWrappedPass, 490 StringRef FileNameFromCU, 491 bool ShouldWriteIntoJSON, 492 llvm::json::Array &Bugs) { 493 bool Preserved = true; 494 for (const auto &L : DILocsAfter) { 495 if (L.second) 496 continue; 497 auto Instr = L.first; 498 499 // In order to avoid pointer reuse/recycling, skip the values that might 500 // have been deleted during a pass. 501 auto WeakInstrPtr = InstToDelete.find(Instr); 502 if (WeakInstrPtr != InstToDelete.end() && !WeakInstrPtr->second) 503 continue; 504 505 auto FnName = Instr->getFunction()->getName(); 506 auto BB = Instr->getParent(); 507 auto BBName = BB->hasName() ? BB->getName() : "no-name"; 508 auto InstName = Instruction::getOpcodeName(Instr->getOpcode()); 509 510 auto CreateJSONBugEntry = [&](const char *Action) { 511 Bugs.push_back(llvm::json::Object({ 512 {"metadata", "DILocation"}, 513 {"fn-name", FnName.str()}, 514 {"bb-name", BBName.str()}, 515 {"instr", InstName}, 516 {"action", Action}, 517 #if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN 518 {"origin", symbolizeStackTrace(Instr)}, 519 #endif 520 })); 521 }; 522 523 auto InstrIt = DILocsBefore.find(Instr); 524 if (InstrIt == DILocsBefore.end()) { 525 if (ShouldWriteIntoJSON) 526 CreateJSONBugEntry("not-generate"); 527 else 528 dbg() << "WARNING: " << NameOfWrappedPass 529 << " did not generate DILocation for " << *Instr 530 << " (BB: " << BBName << ", Fn: " << FnName 531 << ", File: " << FileNameFromCU << ")\n"; 532 Preserved = false; 533 } else { 534 if (!InstrIt->second) 535 continue; 536 // If the instr had the !dbg attached before the pass, consider it as 537 // a debug info issue. 538 if (ShouldWriteIntoJSON) 539 CreateJSONBugEntry("drop"); 540 else 541 dbg() << "WARNING: " << NameOfWrappedPass << " dropped DILocation of " 542 << *Instr << " (BB: " << BBName << ", Fn: " << FnName 543 << ", File: " << FileNameFromCU << ")\n"; 544 Preserved = false; 545 } 546 } 547 548 return Preserved; 549 } 550 551 // This checks the preservation of original debug variable intrinsics. 552 static bool checkVars(const DebugVarMap &DIVarsBefore, 553 const DebugVarMap &DIVarsAfter, 554 StringRef NameOfWrappedPass, StringRef FileNameFromCU, 555 bool ShouldWriteIntoJSON, llvm::json::Array &Bugs) { 556 bool Preserved = true; 557 for (const auto &V : DIVarsBefore) { 558 auto VarIt = DIVarsAfter.find(V.first); 559 if (VarIt == DIVarsAfter.end()) 560 continue; 561 562 unsigned NumOfDbgValsAfter = VarIt->second; 563 564 if (V.second > NumOfDbgValsAfter) { 565 if (ShouldWriteIntoJSON) 566 Bugs.push_back(llvm::json::Object( 567 {{"metadata", "dbg-var-intrinsic"}, 568 {"name", V.first->getName()}, 569 {"fn-name", V.first->getScope()->getSubprogram()->getName()}, 570 {"action", "drop"}})); 571 else 572 dbg() << "WARNING: " << NameOfWrappedPass 573 << " drops dbg.value()/dbg.declare() for " << V.first->getName() 574 << " from " 575 << "function " << V.first->getScope()->getSubprogram()->getName() 576 << " (file " << FileNameFromCU << ")\n"; 577 Preserved = false; 578 } 579 } 580 581 return Preserved; 582 } 583 584 // Write the json data into the specifed file. 585 static void writeJSON(StringRef OrigDIVerifyBugsReportFilePath, 586 StringRef FileNameFromCU, StringRef NameOfWrappedPass, 587 llvm::json::Array &Bugs) { 588 std::error_code EC; 589 raw_fd_ostream OS_FILE{OrigDIVerifyBugsReportFilePath, EC, 590 sys::fs::OF_Append | sys::fs::OF_TextWithCRLF}; 591 if (EC) { 592 errs() << "Could not open file: " << EC.message() << ", " 593 << OrigDIVerifyBugsReportFilePath << '\n'; 594 return; 595 } 596 597 if (auto L = OS_FILE.lock()) { 598 OS_FILE << "{\"file\":\"" << FileNameFromCU << "\", "; 599 600 StringRef PassName = 601 NameOfWrappedPass != "" ? NameOfWrappedPass : "no-name"; 602 OS_FILE << "\"pass\":\"" << PassName << "\", "; 603 604 llvm::json::Value BugsToPrint{std::move(Bugs)}; 605 OS_FILE << "\"bugs\": " << BugsToPrint; 606 607 OS_FILE << "}\n"; 608 } 609 OS_FILE.close(); 610 } 611 612 bool llvm::checkDebugInfoMetadata(Module &M, 613 iterator_range<Module::iterator> Functions, 614 DebugInfoPerPass &DebugInfoBeforePass, 615 StringRef Banner, StringRef NameOfWrappedPass, 616 StringRef OrigDIVerifyBugsReportFilePath) { 617 LLVM_DEBUG(dbgs() << Banner << ": (after) " << NameOfWrappedPass << '\n'); 618 619 if (!M.getNamedMetadata("llvm.dbg.cu")) { 620 dbg() << Banner << ": Skipping module without debug info\n"; 621 return false; 622 } 623 624 // Map the debug info holding DIs after a pass. 625 DebugInfoPerPass DebugInfoAfterPass; 626 627 // Visit each instruction. 628 for (Function &F : Functions) { 629 if (isFunctionSkipped(F)) 630 continue; 631 632 // Don't process functions without DI collected before the Pass. 633 if (!DebugInfoBeforePass.DIFunctions.count(&F)) 634 continue; 635 // TODO: Collect metadata other than DISubprograms. 636 // Collect the DISubprogram. 637 auto *SP = F.getSubprogram(); 638 DebugInfoAfterPass.DIFunctions.insert({&F, SP}); 639 640 if (SP) { 641 LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n'); 642 for (const DINode *DN : SP->getRetainedNodes()) { 643 if (const auto *DV = dyn_cast<DILocalVariable>(DN)) { 644 DebugInfoAfterPass.DIVariables[DV] = 0; 645 } 646 } 647 } 648 649 for (BasicBlock &BB : F) { 650 // Collect debug locations (!dbg) and debug variable intrinsics. 651 for (Instruction &I : BB) { 652 // Skip PHIs. 653 if (isa<PHINode>(I)) 654 continue; 655 656 // Collect dbg.values and dbg.declares. 657 if (DebugifyLevel > Level::Locations) { 658 auto HandleDbgVariable = [&](DbgVariableRecord *DbgVar) { 659 if (!SP) 660 return; 661 // Skip inlined variables. 662 if (DbgVar->getDebugLoc().getInlinedAt()) 663 return; 664 // Skip undef values. 665 if (DbgVar->isKillLocation()) 666 return; 667 668 auto *Var = DbgVar->getVariable(); 669 DebugInfoAfterPass.DIVariables[Var]++; 670 }; 671 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) 672 HandleDbgVariable(&DVR); 673 } 674 675 LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n'); 676 677 // Track the addresses to symbolize, if the feature is enabled. 678 collectStackAddresses(I); 679 DebugInfoAfterPass.DILocations.insert({&I, hasLoc(I)}); 680 } 681 } 682 } 683 684 // TODO: The name of the module could be read better? 685 StringRef FileNameFromCU = 686 (cast<DICompileUnit>(M.getNamedMetadata("llvm.dbg.cu")->getOperand(0))) 687 ->getFilename(); 688 689 auto DIFunctionsBefore = DebugInfoBeforePass.DIFunctions; 690 auto DIFunctionsAfter = DebugInfoAfterPass.DIFunctions; 691 692 auto DILocsBefore = DebugInfoBeforePass.DILocations; 693 auto DILocsAfter = DebugInfoAfterPass.DILocations; 694 695 auto InstToDelete = DebugInfoBeforePass.InstToDelete; 696 697 auto DIVarsBefore = DebugInfoBeforePass.DIVariables; 698 auto DIVarsAfter = DebugInfoAfterPass.DIVariables; 699 700 bool ShouldWriteIntoJSON = !OrigDIVerifyBugsReportFilePath.empty(); 701 llvm::json::Array Bugs; 702 703 bool ResultForFunc = 704 checkFunctions(DIFunctionsBefore, DIFunctionsAfter, NameOfWrappedPass, 705 FileNameFromCU, ShouldWriteIntoJSON, Bugs); 706 bool ResultForInsts = checkInstructions( 707 DILocsBefore, DILocsAfter, InstToDelete, NameOfWrappedPass, 708 FileNameFromCU, ShouldWriteIntoJSON, Bugs); 709 710 bool ResultForVars = checkVars(DIVarsBefore, DIVarsAfter, NameOfWrappedPass, 711 FileNameFromCU, ShouldWriteIntoJSON, Bugs); 712 713 bool Result = ResultForFunc && ResultForInsts && ResultForVars; 714 715 StringRef ResultBanner = NameOfWrappedPass != "" ? NameOfWrappedPass : Banner; 716 if (ShouldWriteIntoJSON && !Bugs.empty()) 717 writeJSON(OrigDIVerifyBugsReportFilePath, FileNameFromCU, NameOfWrappedPass, 718 Bugs); 719 720 if (Result) 721 dbg() << ResultBanner << ": PASS\n"; 722 else 723 dbg() << ResultBanner << ": FAIL\n"; 724 725 // In the case of the `debugify-each`, no need to go over all the instructions 726 // again in the collectDebugInfoMetadata(), since as an input we can use 727 // the debugging information from the previous pass. 728 DebugInfoBeforePass = DebugInfoAfterPass; 729 730 LLVM_DEBUG(dbgs() << "\n\n"); 731 return Result; 732 } 733 734 namespace { 735 /// Return true if a mis-sized diagnostic is issued for \p DbgVal. 736 template <typename DbgValTy> 737 bool diagnoseMisSizedDbgValue(Module &M, DbgValTy *DbgVal) { 738 // The size of a dbg.value's value operand should match the size of the 739 // variable it corresponds to. 740 // 741 // TODO: This, along with a check for non-null value operands, should be 742 // promoted to verifier failures. 743 744 // For now, don't try to interpret anything more complicated than an empty 745 // DIExpression. Eventually we should try to handle OP_deref and fragments. 746 if (DbgVal->getExpression()->getNumElements()) 747 return false; 748 749 Value *V = DbgVal->getVariableLocationOp(0); 750 if (!V) 751 return false; 752 753 Type *Ty = V->getType(); 754 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty); 755 std::optional<uint64_t> DbgVarSize = DbgVal->getFragmentSizeInBits(); 756 if (!ValueOperandSize || !DbgVarSize) 757 return false; 758 759 bool HasBadSize = false; 760 if (Ty->isIntegerTy()) { 761 auto Signedness = DbgVal->getVariable()->getSignedness(); 762 if (Signedness == DIBasicType::Signedness::Signed) 763 HasBadSize = ValueOperandSize < *DbgVarSize; 764 } else { 765 HasBadSize = ValueOperandSize != *DbgVarSize; 766 } 767 768 if (HasBadSize) { 769 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize 770 << ", but its variable has size " << *DbgVarSize << ": "; 771 DbgVal->print(dbg()); 772 dbg() << "\n"; 773 } 774 return HasBadSize; 775 } 776 777 bool checkDebugifyMetadata(Module &M, 778 iterator_range<Module::iterator> Functions, 779 StringRef NameOfWrappedPass, StringRef Banner, 780 bool Strip, DebugifyStatsMap *StatsMap) { 781 // Skip modules without debugify metadata. 782 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify"); 783 if (!NMD) { 784 dbg() << Banner << ": Skipping module without debugify metadata\n"; 785 return false; 786 } 787 788 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned { 789 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0)) 790 ->getZExtValue(); 791 }; 792 assert(NMD->getNumOperands() == 2 && 793 "llvm.debugify should have exactly 2 operands!"); 794 unsigned OriginalNumLines = getDebugifyOperand(0); 795 unsigned OriginalNumVars = getDebugifyOperand(1); 796 bool HasErrors = false; 797 798 // Track debug info loss statistics if able. 799 DebugifyStatistics *Stats = nullptr; 800 if (StatsMap && !NameOfWrappedPass.empty()) 801 Stats = &StatsMap->operator[](NameOfWrappedPass); 802 803 BitVector MissingLines{OriginalNumLines, true}; 804 BitVector MissingVars{OriginalNumVars, true}; 805 for (Function &F : Functions) { 806 if (isFunctionSkipped(F)) 807 continue; 808 809 // Find missing lines. 810 for (Instruction &I : instructions(F)) { 811 if (isa<DbgValueInst>(&I)) 812 continue; 813 814 auto DL = I.getDebugLoc(); 815 if (DL && DL.getLine() != 0) { 816 MissingLines.reset(DL.getLine() - 1); 817 continue; 818 } 819 820 if (!isa<PHINode>(&I) && !DL) { 821 dbg() << "WARNING: Instruction with empty DebugLoc in function "; 822 dbg() << F.getName() << " --"; 823 I.print(dbg()); 824 dbg() << "\n"; 825 } 826 } 827 828 // Find missing variables and mis-sized debug values. 829 auto CheckForMisSized = [&](auto *DbgVal) { 830 unsigned Var = ~0U; 831 (void)to_integer(DbgVal->getVariable()->getName(), Var, 10); 832 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable"); 833 bool HasBadSize = diagnoseMisSizedDbgValue(M, DbgVal); 834 if (!HasBadSize) 835 MissingVars.reset(Var - 1); 836 HasErrors |= HasBadSize; 837 }; 838 for (Instruction &I : instructions(F)) { 839 for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) 840 if (DVR.isDbgValue() || DVR.isDbgAssign()) 841 CheckForMisSized(&DVR); 842 auto *DVI = dyn_cast<DbgValueInst>(&I); 843 if (!DVI) 844 continue; 845 CheckForMisSized(DVI); 846 } 847 } 848 849 // Print the results. 850 for (unsigned Idx : MissingLines.set_bits()) 851 dbg() << "WARNING: Missing line " << Idx + 1 << "\n"; 852 853 for (unsigned Idx : MissingVars.set_bits()) 854 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n"; 855 856 // Update DI loss statistics. 857 if (Stats) { 858 Stats->NumDbgLocsExpected += OriginalNumLines; 859 Stats->NumDbgLocsMissing += MissingLines.count(); 860 Stats->NumDbgValuesExpected += OriginalNumVars; 861 Stats->NumDbgValuesMissing += MissingVars.count(); 862 } 863 864 dbg() << Banner; 865 if (!NameOfWrappedPass.empty()) 866 dbg() << " [" << NameOfWrappedPass << "]"; 867 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n'; 868 869 // Strip debugify metadata if required. 870 bool Ret = false; 871 if (Strip) 872 Ret = stripDebugifyMetadata(M); 873 874 return Ret; 875 } 876 877 /// ModulePass for attaching synthetic debug info to everything, used with the 878 /// legacy module pass manager. 879 struct DebugifyModulePass : public ModulePass { 880 bool runOnModule(Module &M) override { 881 bool Result = 882 applyDebugify(M, Mode, DebugInfoBeforePass, NameOfWrappedPass); 883 return Result; 884 } 885 886 DebugifyModulePass(enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 887 StringRef NameOfWrappedPass = "", 888 DebugInfoPerPass *DebugInfoBeforePass = nullptr) 889 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass), 890 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {} 891 892 void getAnalysisUsage(AnalysisUsage &AU) const override { 893 AU.setPreservesAll(); 894 } 895 896 static char ID; // Pass identification. 897 898 private: 899 StringRef NameOfWrappedPass; 900 DebugInfoPerPass *DebugInfoBeforePass; 901 enum DebugifyMode Mode; 902 }; 903 904 /// FunctionPass for attaching synthetic debug info to instructions within a 905 /// single function, used with the legacy module pass manager. 906 struct DebugifyFunctionPass : public FunctionPass { 907 bool runOnFunction(Function &F) override { 908 bool Result = 909 applyDebugify(F, Mode, DebugInfoBeforePass, NameOfWrappedPass); 910 return Result; 911 } 912 913 DebugifyFunctionPass( 914 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 915 StringRef NameOfWrappedPass = "", 916 DebugInfoPerPass *DebugInfoBeforePass = nullptr) 917 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass), 918 DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode) {} 919 920 void getAnalysisUsage(AnalysisUsage &AU) const override { 921 AU.setPreservesAll(); 922 } 923 924 static char ID; // Pass identification. 925 926 private: 927 StringRef NameOfWrappedPass; 928 DebugInfoPerPass *DebugInfoBeforePass; 929 enum DebugifyMode Mode; 930 }; 931 932 /// ModulePass for checking debug info inserted by -debugify, used with the 933 /// legacy module pass manager. 934 struct CheckDebugifyModulePass : public ModulePass { 935 bool runOnModule(Module &M) override { 936 bool Result; 937 if (Mode == DebugifyMode::SyntheticDebugInfo) 938 Result = checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass, 939 "CheckModuleDebugify", Strip, StatsMap); 940 else 941 Result = checkDebugInfoMetadata( 942 M, M.functions(), *DebugInfoBeforePass, 943 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass, 944 OrigDIVerifyBugsReportFilePath); 945 946 return Result; 947 } 948 949 CheckDebugifyModulePass( 950 bool Strip = false, StringRef NameOfWrappedPass = "", 951 DebugifyStatsMap *StatsMap = nullptr, 952 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 953 DebugInfoPerPass *DebugInfoBeforePass = nullptr, 954 StringRef OrigDIVerifyBugsReportFilePath = "") 955 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass), 956 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath), 957 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode), 958 Strip(Strip) {} 959 960 void getAnalysisUsage(AnalysisUsage &AU) const override { 961 AU.setPreservesAll(); 962 } 963 964 static char ID; // Pass identification. 965 966 private: 967 StringRef NameOfWrappedPass; 968 StringRef OrigDIVerifyBugsReportFilePath; 969 DebugifyStatsMap *StatsMap; 970 DebugInfoPerPass *DebugInfoBeforePass; 971 enum DebugifyMode Mode; 972 bool Strip; 973 }; 974 975 /// FunctionPass for checking debug info inserted by -debugify-function, used 976 /// with the legacy module pass manager. 977 struct CheckDebugifyFunctionPass : public FunctionPass { 978 bool runOnFunction(Function &F) override { 979 Module &M = *F.getParent(); 980 auto FuncIt = F.getIterator(); 981 bool Result; 982 if (Mode == DebugifyMode::SyntheticDebugInfo) 983 Result = checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), 984 NameOfWrappedPass, "CheckFunctionDebugify", 985 Strip, StatsMap); 986 else 987 Result = checkDebugInfoMetadata( 988 M, make_range(FuncIt, std::next(FuncIt)), *DebugInfoBeforePass, 989 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass, 990 OrigDIVerifyBugsReportFilePath); 991 992 return Result; 993 } 994 995 CheckDebugifyFunctionPass( 996 bool Strip = false, StringRef NameOfWrappedPass = "", 997 DebugifyStatsMap *StatsMap = nullptr, 998 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 999 DebugInfoPerPass *DebugInfoBeforePass = nullptr, 1000 StringRef OrigDIVerifyBugsReportFilePath = "") 1001 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass), 1002 OrigDIVerifyBugsReportFilePath(OrigDIVerifyBugsReportFilePath), 1003 StatsMap(StatsMap), DebugInfoBeforePass(DebugInfoBeforePass), Mode(Mode), 1004 Strip(Strip) {} 1005 1006 void getAnalysisUsage(AnalysisUsage &AU) const override { 1007 AU.setPreservesAll(); 1008 } 1009 1010 static char ID; // Pass identification. 1011 1012 private: 1013 StringRef NameOfWrappedPass; 1014 StringRef OrigDIVerifyBugsReportFilePath; 1015 DebugifyStatsMap *StatsMap; 1016 DebugInfoPerPass *DebugInfoBeforePass; 1017 enum DebugifyMode Mode; 1018 bool Strip; 1019 }; 1020 1021 } // end anonymous namespace 1022 1023 void llvm::exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map) { 1024 std::error_code EC; 1025 raw_fd_ostream OS{Path, EC}; 1026 if (EC) { 1027 errs() << "Could not open file: " << EC.message() << ", " << Path << '\n'; 1028 return; 1029 } 1030 1031 OS << "Pass Name" << ',' << "# of missing debug values" << ',' 1032 << "# of missing locations" << ',' << "Missing/Expected value ratio" << ',' 1033 << "Missing/Expected location ratio" << '\n'; 1034 for (const auto &Entry : Map) { 1035 StringRef Pass = Entry.first; 1036 DebugifyStatistics Stats = Entry.second; 1037 1038 OS << Pass << ',' << Stats.NumDbgValuesMissing << ',' 1039 << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ',' 1040 << Stats.getEmptyLocationRatio() << '\n'; 1041 } 1042 } 1043 1044 ModulePass *createDebugifyModulePass(enum DebugifyMode Mode, 1045 llvm::StringRef NameOfWrappedPass, 1046 DebugInfoPerPass *DebugInfoBeforePass) { 1047 if (Mode == DebugifyMode::SyntheticDebugInfo) 1048 return new DebugifyModulePass(); 1049 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 1050 return new DebugifyModulePass(Mode, NameOfWrappedPass, DebugInfoBeforePass); 1051 } 1052 1053 FunctionPass * 1054 createDebugifyFunctionPass(enum DebugifyMode Mode, 1055 llvm::StringRef NameOfWrappedPass, 1056 DebugInfoPerPass *DebugInfoBeforePass) { 1057 if (Mode == DebugifyMode::SyntheticDebugInfo) 1058 return new DebugifyFunctionPass(); 1059 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 1060 return new DebugifyFunctionPass(Mode, NameOfWrappedPass, DebugInfoBeforePass); 1061 } 1062 1063 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) { 1064 if (Mode == DebugifyMode::SyntheticDebugInfo) 1065 applyDebugifyMetadata(M, M.functions(), 1066 "ModuleDebugify: ", /*ApplyToMF*/ nullptr); 1067 else 1068 collectDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass, 1069 "ModuleDebugify (original debuginfo)", 1070 NameOfWrappedPass); 1071 1072 PreservedAnalyses PA; 1073 PA.preserveSet<CFGAnalyses>(); 1074 return PA; 1075 } 1076 1077 ModulePass *createCheckDebugifyModulePass( 1078 bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, 1079 enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, 1080 StringRef OrigDIVerifyBugsReportFilePath) { 1081 if (Mode == DebugifyMode::SyntheticDebugInfo) 1082 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap); 1083 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 1084 return new CheckDebugifyModulePass(false, NameOfWrappedPass, nullptr, Mode, 1085 DebugInfoBeforePass, 1086 OrigDIVerifyBugsReportFilePath); 1087 } 1088 1089 FunctionPass *createCheckDebugifyFunctionPass( 1090 bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, 1091 enum DebugifyMode Mode, DebugInfoPerPass *DebugInfoBeforePass, 1092 StringRef OrigDIVerifyBugsReportFilePath) { 1093 if (Mode == DebugifyMode::SyntheticDebugInfo) 1094 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap); 1095 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 1096 return new CheckDebugifyFunctionPass(false, NameOfWrappedPass, nullptr, Mode, 1097 DebugInfoBeforePass, 1098 OrigDIVerifyBugsReportFilePath); 1099 } 1100 1101 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M, 1102 ModuleAnalysisManager &) { 1103 if (Mode == DebugifyMode::SyntheticDebugInfo) 1104 checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass, 1105 "CheckModuleDebugify", Strip, StatsMap); 1106 else 1107 checkDebugInfoMetadata( 1108 M, M.functions(), *DebugInfoBeforePass, 1109 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass, 1110 OrigDIVerifyBugsReportFilePath); 1111 1112 return PreservedAnalyses::all(); 1113 } 1114 1115 static bool isIgnoredPass(StringRef PassID) { 1116 return isSpecialPass(PassID, {"PassManager", "PassAdaptor", 1117 "AnalysisManagerProxy", "PrintFunctionPass", 1118 "PrintModulePass", "BitcodeWriterPass", 1119 "ThinLTOBitcodeWriterPass", "VerifierPass"}); 1120 } 1121 1122 void DebugifyEachInstrumentation::registerCallbacks( 1123 PassInstrumentationCallbacks &PIC, ModuleAnalysisManager &MAM) { 1124 PIC.registerBeforeNonSkippedPassCallback([this, &MAM](StringRef P, Any IR) { 1125 if (isIgnoredPass(P)) 1126 return; 1127 PreservedAnalyses PA; 1128 PA.preserveSet<CFGAnalyses>(); 1129 if (const auto **CF = llvm::any_cast<const Function *>(&IR)) { 1130 Function &F = *const_cast<Function *>(*CF); 1131 applyDebugify(F, Mode, DebugInfoBeforePass, P); 1132 MAM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent()) 1133 .getManager() 1134 .invalidate(F, PA); 1135 } else if (const auto **CM = llvm::any_cast<const Module *>(&IR)) { 1136 Module &M = *const_cast<Module *>(*CM); 1137 applyDebugify(M, Mode, DebugInfoBeforePass, P); 1138 MAM.invalidate(M, PA); 1139 } 1140 }); 1141 PIC.registerAfterPassCallback( 1142 [this, &MAM](StringRef P, Any IR, const PreservedAnalyses &PassPA) { 1143 if (isIgnoredPass(P)) 1144 return; 1145 PreservedAnalyses PA; 1146 PA.preserveSet<CFGAnalyses>(); 1147 if (const auto **CF = llvm::any_cast<const Function *>(&IR)) { 1148 auto &F = *const_cast<Function *>(*CF); 1149 Module &M = *F.getParent(); 1150 auto It = F.getIterator(); 1151 if (Mode == DebugifyMode::SyntheticDebugInfo) 1152 checkDebugifyMetadata(M, make_range(It, std::next(It)), P, 1153 "CheckFunctionDebugify", /*Strip=*/true, 1154 DIStatsMap); 1155 else 1156 checkDebugInfoMetadata(M, make_range(It, std::next(It)), 1157 *DebugInfoBeforePass, 1158 "CheckModuleDebugify (original debuginfo)", 1159 P, OrigDIVerifyBugsReportFilePath); 1160 MAM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent()) 1161 .getManager() 1162 .invalidate(F, PA); 1163 } else if (const auto **CM = llvm::any_cast<const Module *>(&IR)) { 1164 Module &M = *const_cast<Module *>(*CM); 1165 if (Mode == DebugifyMode::SyntheticDebugInfo) 1166 checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify", 1167 /*Strip=*/true, DIStatsMap); 1168 else 1169 checkDebugInfoMetadata(M, M.functions(), *DebugInfoBeforePass, 1170 "CheckModuleDebugify (original debuginfo)", 1171 P, OrigDIVerifyBugsReportFilePath); 1172 MAM.invalidate(M, PA); 1173 } 1174 }); 1175 } 1176 1177 char DebugifyModulePass::ID = 0; 1178 static RegisterPass<DebugifyModulePass> DM("debugify", 1179 "Attach debug info to everything"); 1180 1181 char CheckDebugifyModulePass::ID = 0; 1182 static RegisterPass<CheckDebugifyModulePass> 1183 CDM("check-debugify", "Check debug info from -debugify"); 1184 1185 char DebugifyFunctionPass::ID = 0; 1186 static RegisterPass<DebugifyFunctionPass> DF("debugify-function", 1187 "Attach debug info to a function"); 1188 1189 char CheckDebugifyFunctionPass::ID = 0; 1190 static RegisterPass<CheckDebugifyFunctionPass> 1191 CDF("check-debugify-function", "Check debug info from -debugify-function"); 1192