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/IR/DIBuilder.h" 20 #include "llvm/IR/DebugInfo.h" 21 #include "llvm/IR/InstIterator.h" 22 #include "llvm/IR/Instructions.h" 23 #include "llvm/IR/IntrinsicInst.h" 24 #include "llvm/IR/Module.h" 25 #include "llvm/IR/PassInstrumentation.h" 26 #include "llvm/Pass.h" 27 #include "llvm/Support/CommandLine.h" 28 29 #define DEBUG_TYPE "debugify" 30 31 using namespace llvm; 32 33 namespace { 34 35 cl::opt<bool> Quiet("debugify-quiet", 36 cl::desc("Suppress verbose debugify output")); 37 38 enum class Level { 39 Locations, 40 LocationsAndVariables 41 }; 42 43 // Used for the synthetic mode only. 44 cl::opt<Level> DebugifyLevel( 45 "debugify-level", cl::desc("Kind of debug info to add"), 46 cl::values(clEnumValN(Level::Locations, "locations", "Locations only"), 47 clEnumValN(Level::LocationsAndVariables, "location+variables", 48 "Locations and Variables")), 49 cl::init(Level::LocationsAndVariables)); 50 51 raw_ostream &dbg() { return Quiet ? nulls() : errs(); } 52 53 uint64_t getAllocSizeInBits(Module &M, Type *Ty) { 54 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0; 55 } 56 57 bool isFunctionSkipped(Function &F) { 58 return F.isDeclaration() || !F.hasExactDefinition(); 59 } 60 61 /// Find the basic block's terminating instruction. 62 /// 63 /// Special care is needed to handle musttail and deopt calls, as these behave 64 /// like (but are in fact not) terminators. 65 Instruction *findTerminatingInstruction(BasicBlock &BB) { 66 if (auto *I = BB.getTerminatingMustTailCall()) 67 return I; 68 if (auto *I = BB.getTerminatingDeoptimizeCall()) 69 return I; 70 return BB.getTerminator(); 71 } 72 } // end anonymous namespace 73 74 bool llvm::applyDebugifyMetadata( 75 Module &M, iterator_range<Module::iterator> Functions, StringRef Banner, 76 std::function<bool(DIBuilder &DIB, Function &F)> ApplyToMF) { 77 // Skip modules with debug info. 78 if (M.getNamedMetadata("llvm.dbg.cu")) { 79 dbg() << Banner << "Skipping module with debug info\n"; 80 return false; 81 } 82 83 DIBuilder DIB(M); 84 LLVMContext &Ctx = M.getContext(); 85 auto *Int32Ty = Type::getInt32Ty(Ctx); 86 87 // Get a DIType which corresponds to Ty. 88 DenseMap<uint64_t, DIType *> TypeCache; 89 auto getCachedDIType = [&](Type *Ty) -> DIType * { 90 uint64_t Size = getAllocSizeInBits(M, Ty); 91 DIType *&DTy = TypeCache[Size]; 92 if (!DTy) { 93 std::string Name = "ty" + utostr(Size); 94 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned); 95 } 96 return DTy; 97 }; 98 99 unsigned NextLine = 1; 100 unsigned NextVar = 1; 101 auto File = DIB.createFile(M.getName(), "/"); 102 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify", 103 /*isOptimized=*/true, "", 0); 104 105 // Visit each instruction. 106 for (Function &F : Functions) { 107 if (isFunctionSkipped(F)) 108 continue; 109 110 bool InsertedDbgVal = false; 111 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); 112 DISubprogram::DISPFlags SPFlags = 113 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized; 114 if (F.hasPrivateLinkage() || F.hasInternalLinkage()) 115 SPFlags |= DISubprogram::SPFlagLocalToUnit; 116 auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, 117 SPType, NextLine, DINode::FlagZero, SPFlags); 118 F.setSubprogram(SP); 119 120 // Helper that inserts a dbg.value before \p InsertBefore, copying the 121 // location (and possibly the type, if it's non-void) from \p TemplateInst. 122 auto insertDbgVal = [&](Instruction &TemplateInst, 123 Instruction *InsertBefore) { 124 std::string Name = utostr(NextVar++); 125 Value *V = &TemplateInst; 126 if (TemplateInst.getType()->isVoidTy()) 127 V = ConstantInt::get(Int32Ty, 0); 128 const DILocation *Loc = TemplateInst.getDebugLoc().get(); 129 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(), 130 getCachedDIType(V->getType()), 131 /*AlwaysPreserve=*/true); 132 DIB.insertDbgValueIntrinsic(V, LocalVar, DIB.createExpression(), Loc, 133 InsertBefore); 134 }; 135 136 for (BasicBlock &BB : F) { 137 // Attach debug locations. 138 for (Instruction &I : BB) 139 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP)); 140 141 if (DebugifyLevel < Level::LocationsAndVariables) 142 continue; 143 144 // Inserting debug values into EH pads can break IR invariants. 145 if (BB.isEHPad()) 146 continue; 147 148 // Find the terminating instruction, after which no debug values are 149 // attached. 150 Instruction *LastInst = findTerminatingInstruction(BB); 151 assert(LastInst && "Expected basic block with a terminator"); 152 153 // Maintain an insertion point which can't be invalidated when updates 154 // are made. 155 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt(); 156 assert(InsertPt != BB.end() && "Expected to find an insertion point"); 157 Instruction *InsertBefore = &*InsertPt; 158 159 // Attach debug values. 160 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) { 161 // Skip void-valued instructions. 162 if (I->getType()->isVoidTy()) 163 continue; 164 165 // Phis and EH pads must be grouped at the beginning of the block. 166 // Only advance the insertion point when we finish visiting these. 167 if (!isa<PHINode>(I) && !I->isEHPad()) 168 InsertBefore = I->getNextNode(); 169 170 insertDbgVal(*I, InsertBefore); 171 InsertedDbgVal = true; 172 } 173 } 174 // Make sure we emit at least one dbg.value, otherwise MachineDebugify may 175 // not have anything to work with as it goes about inserting DBG_VALUEs. 176 // (It's common for MIR tests to be written containing skeletal IR with 177 // empty functions -- we're still interested in debugifying the MIR within 178 // those tests, and this helps with that.) 179 if (DebugifyLevel == Level::LocationsAndVariables && !InsertedDbgVal) { 180 auto *Term = findTerminatingInstruction(F.getEntryBlock()); 181 insertDbgVal(*Term, Term); 182 } 183 if (ApplyToMF) 184 ApplyToMF(DIB, F); 185 DIB.finalizeSubprogram(SP); 186 } 187 DIB.finalize(); 188 189 // Track the number of distinct lines and variables. 190 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify"); 191 auto addDebugifyOperand = [&](unsigned N) { 192 NMD->addOperand(MDNode::get( 193 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(Int32Ty, N)))); 194 }; 195 addDebugifyOperand(NextLine - 1); // Original number of lines. 196 addDebugifyOperand(NextVar - 1); // Original number of variables. 197 assert(NMD->getNumOperands() == 2 && 198 "llvm.debugify should have exactly 2 operands!"); 199 200 // Claim that this synthetic debug info is valid. 201 StringRef DIVersionKey = "Debug Info Version"; 202 if (!M.getModuleFlag(DIVersionKey)) 203 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION); 204 205 return true; 206 } 207 208 static bool 209 applyDebugify(Function &F, 210 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 211 DebugInfoPerPassMap *DIPreservationMap = nullptr, 212 StringRef NameOfWrappedPass = "") { 213 Module &M = *F.getParent(); 214 auto FuncIt = F.getIterator(); 215 if (Mode == DebugifyMode::SyntheticDebugInfo) 216 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), 217 "FunctionDebugify: ", /*ApplyToMF*/ nullptr); 218 assert(DIPreservationMap); 219 return collectDebugInfoMetadata(M, M.functions(), *DIPreservationMap, 220 "FunctionDebugify (original debuginfo)", 221 NameOfWrappedPass); 222 } 223 224 static bool 225 applyDebugify(Module &M, 226 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 227 DebugInfoPerPassMap *DIPreservationMap = nullptr, 228 StringRef NameOfWrappedPass = "") { 229 if (Mode == DebugifyMode::SyntheticDebugInfo) 230 return applyDebugifyMetadata(M, M.functions(), 231 "ModuleDebugify: ", /*ApplyToMF*/ nullptr); 232 return collectDebugInfoMetadata(M, M.functions(), *DIPreservationMap, 233 "ModuleDebugify (original debuginfo)", 234 NameOfWrappedPass); 235 } 236 237 bool llvm::stripDebugifyMetadata(Module &M) { 238 bool Changed = false; 239 240 // Remove the llvm.debugify module-level named metadata. 241 NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify"); 242 if (DebugifyMD) { 243 M.eraseNamedMetadata(DebugifyMD); 244 Changed = true; 245 } 246 247 // Strip out all debug intrinsics and supporting metadata (subprograms, types, 248 // variables, etc). 249 Changed |= StripDebugInfo(M); 250 251 // Strip out the dead dbg.value prototype. 252 Function *DbgValF = M.getFunction("llvm.dbg.value"); 253 if (DbgValF) { 254 assert(DbgValF->isDeclaration() && DbgValF->use_empty() && 255 "Not all debug info stripped?"); 256 DbgValF->eraseFromParent(); 257 Changed = true; 258 } 259 260 // Strip out the module-level Debug Info Version metadata. 261 // FIXME: There must be an easier way to remove an operand from a NamedMDNode. 262 NamedMDNode *NMD = M.getModuleFlagsMetadata(); 263 if (!NMD) 264 return Changed; 265 SmallVector<MDNode *, 4> Flags(NMD->operands()); 266 NMD->clearOperands(); 267 for (MDNode *Flag : Flags) { 268 MDString *Key = dyn_cast_or_null<MDString>(Flag->getOperand(1)); 269 if (Key->getString() == "Debug Info Version") { 270 Changed = true; 271 continue; 272 } 273 NMD->addOperand(Flag); 274 } 275 // If we left it empty we might as well remove it. 276 if (NMD->getNumOperands() == 0) 277 NMD->eraseFromParent(); 278 279 return Changed; 280 } 281 282 bool llvm::collectDebugInfoMetadata(Module &M, 283 iterator_range<Module::iterator> Functions, 284 DebugInfoPerPassMap &DIPreservationMap, 285 StringRef Banner, 286 StringRef NameOfWrappedPass) { 287 LLVM_DEBUG(dbgs() << Banner << ": (before) " << NameOfWrappedPass << '\n'); 288 289 // Clear the map with the debug info before every single pass. 290 DIPreservationMap.clear(); 291 292 if (!M.getNamedMetadata("llvm.dbg.cu")) { 293 dbg() << Banner << ": Skipping module without debug info\n"; 294 return false; 295 } 296 297 // Visit each instruction. 298 for (Function &F : Functions) { 299 if (isFunctionSkipped(F)) 300 continue; 301 302 // Collect the DISubprogram. 303 auto *SP = F.getSubprogram(); 304 DIPreservationMap[NameOfWrappedPass].DIFunctions.insert({F.getName(), SP}); 305 if (SP) 306 LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n'); 307 308 for (BasicBlock &BB : F) { 309 // Collect debug locations (!dbg). 310 // TODO: Collect dbg.values. 311 for (Instruction &I : BB) { 312 // Skip PHIs. 313 if (isa<PHINode>(I)) 314 continue; 315 316 // Skip debug instructions. 317 if (isa<DbgInfoIntrinsic>(&I)) 318 continue; 319 320 LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n'); 321 DIPreservationMap[NameOfWrappedPass].InstToDelete.insert({&I, &I}); 322 323 const DILocation *Loc = I.getDebugLoc().get(); 324 bool HasLoc = Loc != nullptr; 325 DIPreservationMap[NameOfWrappedPass].DILocations.insert({&I, HasLoc}); 326 } 327 } 328 } 329 330 return true; 331 } 332 333 // This checks the preservation of original debug info attached to functions. 334 static bool checkFunctions(const DebugFnMap &DIFunctionsBefore, 335 const DebugFnMap &DIFunctionsAfter, 336 StringRef NameOfWrappedPass, 337 StringRef FileNameFromCU) { 338 bool Preserved = true; 339 for (const auto &F : DIFunctionsAfter) { 340 if (F.second) 341 continue; 342 auto SPIt = DIFunctionsBefore.find(F.first); 343 if (SPIt == DIFunctionsBefore.end()) { 344 dbg() << "ERROR: " << NameOfWrappedPass 345 << " did not generate DISubprogram for " << F.first << " from " 346 << FileNameFromCU << '\n'; 347 Preserved = false; 348 } else { 349 auto SP = SPIt->second; 350 if (!SP) 351 continue; 352 // If the function had the SP attached before the pass, consider it as 353 // a debug info bug. 354 dbg() << "ERROR: " << NameOfWrappedPass << " dropped DISubprogram of " 355 << F.first << " from " << FileNameFromCU << '\n'; 356 Preserved = false; 357 } 358 } 359 360 return Preserved; 361 } 362 363 // This checks the preservation of the original debug info attached to 364 // instructions. 365 static bool checkInstructions(const DebugInstMap &DILocsBefore, 366 const DebugInstMap &DILocsAfter, 367 const WeakInstValueMap &InstToDelete, 368 StringRef NameOfWrappedPass, 369 StringRef FileNameFromCU) { 370 bool Preserved = true; 371 for (const auto &L : DILocsAfter) { 372 if (L.second) 373 continue; 374 auto Instr = L.first; 375 376 // In order to avoid pointer reuse/recycling, skip the values that might 377 // have been deleted during a pass. 378 auto WeakInstrPtr = InstToDelete.find(Instr); 379 if (WeakInstrPtr != InstToDelete.end() && !WeakInstrPtr->second) 380 continue; 381 382 auto FnName = Instr->getFunction()->getName(); 383 auto BB = Instr->getParent(); 384 auto BBName = BB->hasName() ? BB->getName() : "no-name"; 385 386 auto InstrIt = DILocsBefore.find(Instr); 387 if (InstrIt == DILocsBefore.end()) { 388 dbg() << "WARNING: " << NameOfWrappedPass 389 << " did not generate DILocation for " << *Instr 390 << " (BB: " << BBName << ", Fn: " << FnName 391 << ", File: " << FileNameFromCU << ")\n"; 392 Preserved = false; 393 } else { 394 if (!InstrIt->second) 395 continue; 396 // If the instr had the !dbg attached before the pass, consider it as 397 // a debug info issue. 398 dbg() << "WARNING: " << NameOfWrappedPass << " dropped DILocation of " 399 << *Instr << " (BB: " << BBName << ", Fn: " << FnName 400 << ", File: " << FileNameFromCU << ")\n"; 401 Preserved = false; 402 } 403 } 404 405 return Preserved; 406 } 407 408 bool llvm::checkDebugInfoMetadata(Module &M, 409 iterator_range<Module::iterator> Functions, 410 DebugInfoPerPassMap &DIPreservationMap, 411 StringRef Banner, 412 StringRef NameOfWrappedPass) { 413 LLVM_DEBUG(dbgs() << Banner << ": (after) " << NameOfWrappedPass << '\n'); 414 415 if (!M.getNamedMetadata("llvm.dbg.cu")) { 416 dbg() << Banner << ": Skipping module without debug info\n"; 417 return false; 418 } 419 420 // Map the debug info holding DIs after a pass. 421 DebugInfoPerPassMap DIPreservationAfter; 422 423 // Visit each instruction. 424 for (Function &F : Functions) { 425 if (isFunctionSkipped(F)) 426 continue; 427 428 // TODO: Collect metadata other than DISubprograms. 429 // Collect the DISubprogram. 430 auto *SP = F.getSubprogram(); 431 DIPreservationAfter[NameOfWrappedPass].DIFunctions.insert({F.getName(), SP}); 432 if (SP) 433 LLVM_DEBUG(dbgs() << " Collecting subprogram: " << *SP << '\n'); 434 435 for (BasicBlock &BB : F) { 436 // Collect debug locations (!dbg attachments). 437 // TODO: Collect dbg.values. 438 for (Instruction &I : BB) { 439 // Skip PHIs. 440 if (isa<PHINode>(I)) 441 continue; 442 443 // Skip debug instructions. 444 if (isa<DbgInfoIntrinsic>(&I)) 445 continue; 446 447 LLVM_DEBUG(dbgs() << " Collecting info for inst: " << I << '\n'); 448 449 const DILocation *Loc = I.getDebugLoc().get(); 450 bool HasLoc = Loc != nullptr; 451 452 DIPreservationAfter[NameOfWrappedPass].DILocations.insert({&I, HasLoc}); 453 } 454 } 455 } 456 457 // TODO: The name of the module could be read better? 458 StringRef FileNameFromCU = 459 (cast<DICompileUnit>(M.getNamedMetadata("llvm.dbg.cu")->getOperand(0))) 460 ->getFilename(); 461 462 auto DIFunctionsBefore = DIPreservationMap[NameOfWrappedPass].DIFunctions; 463 auto DIFunctionsAfter = DIPreservationAfter[NameOfWrappedPass].DIFunctions; 464 465 auto DILocsBefore = DIPreservationMap[NameOfWrappedPass].DILocations; 466 auto DILocsAfter = DIPreservationAfter[NameOfWrappedPass].DILocations; 467 468 auto InstToDelete = DIPreservationAfter[NameOfWrappedPass].InstToDelete; 469 470 bool ResultForFunc = checkFunctions(DIFunctionsBefore, DIFunctionsAfter, 471 NameOfWrappedPass, FileNameFromCU); 472 bool ResultForInsts = 473 checkInstructions(DILocsBefore, DILocsAfter, InstToDelete, 474 NameOfWrappedPass, FileNameFromCU); 475 bool Result = ResultForFunc && ResultForInsts; 476 477 StringRef ResultBanner = NameOfWrappedPass != "" ? NameOfWrappedPass : Banner; 478 if (Result) 479 dbg() << ResultBanner << ": PASS\n"; 480 else 481 dbg() << ResultBanner << ": FAIL\n"; 482 483 LLVM_DEBUG(dbgs() << "\n\n"); 484 return Result; 485 } 486 487 namespace { 488 /// Return true if a mis-sized diagnostic is issued for \p DVI. 489 bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) { 490 // The size of a dbg.value's value operand should match the size of the 491 // variable it corresponds to. 492 // 493 // TODO: This, along with a check for non-null value operands, should be 494 // promoted to verifier failures. 495 496 // For now, don't try to interpret anything more complicated than an empty 497 // DIExpression. Eventually we should try to handle OP_deref and fragments. 498 if (DVI->getExpression()->getNumElements()) 499 return false; 500 501 Value *V = DVI->getVariableLocationOp(0); 502 if (!V) 503 return false; 504 505 Type *Ty = V->getType(); 506 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty); 507 Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits(); 508 if (!ValueOperandSize || !DbgVarSize) 509 return false; 510 511 bool HasBadSize = false; 512 if (Ty->isIntegerTy()) { 513 auto Signedness = DVI->getVariable()->getSignedness(); 514 if (Signedness && *Signedness == DIBasicType::Signedness::Signed) 515 HasBadSize = ValueOperandSize < *DbgVarSize; 516 } else { 517 HasBadSize = ValueOperandSize != *DbgVarSize; 518 } 519 520 if (HasBadSize) { 521 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize 522 << ", but its variable has size " << *DbgVarSize << ": "; 523 DVI->print(dbg()); 524 dbg() << "\n"; 525 } 526 return HasBadSize; 527 } 528 529 bool checkDebugifyMetadata(Module &M, 530 iterator_range<Module::iterator> Functions, 531 StringRef NameOfWrappedPass, StringRef Banner, 532 bool Strip, DebugifyStatsMap *StatsMap) { 533 // Skip modules without debugify metadata. 534 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify"); 535 if (!NMD) { 536 dbg() << Banner << ": Skipping module without debugify metadata\n"; 537 return false; 538 } 539 540 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned { 541 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0)) 542 ->getZExtValue(); 543 }; 544 assert(NMD->getNumOperands() == 2 && 545 "llvm.debugify should have exactly 2 operands!"); 546 unsigned OriginalNumLines = getDebugifyOperand(0); 547 unsigned OriginalNumVars = getDebugifyOperand(1); 548 bool HasErrors = false; 549 550 // Track debug info loss statistics if able. 551 DebugifyStatistics *Stats = nullptr; 552 if (StatsMap && !NameOfWrappedPass.empty()) 553 Stats = &StatsMap->operator[](NameOfWrappedPass); 554 555 BitVector MissingLines{OriginalNumLines, true}; 556 BitVector MissingVars{OriginalNumVars, true}; 557 for (Function &F : Functions) { 558 if (isFunctionSkipped(F)) 559 continue; 560 561 // Find missing lines. 562 for (Instruction &I : instructions(F)) { 563 if (isa<DbgValueInst>(&I) || isa<PHINode>(&I)) 564 continue; 565 566 auto DL = I.getDebugLoc(); 567 if (DL && DL.getLine() != 0) { 568 MissingLines.reset(DL.getLine() - 1); 569 continue; 570 } 571 572 if (!DL) { 573 dbg() << "WARNING: Instruction with empty DebugLoc in function "; 574 dbg() << F.getName() << " --"; 575 I.print(dbg()); 576 dbg() << "\n"; 577 } 578 } 579 580 // Find missing variables and mis-sized debug values. 581 for (Instruction &I : instructions(F)) { 582 auto *DVI = dyn_cast<DbgValueInst>(&I); 583 if (!DVI) 584 continue; 585 586 unsigned Var = ~0U; 587 (void)to_integer(DVI->getVariable()->getName(), Var, 10); 588 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable"); 589 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI); 590 if (!HasBadSize) 591 MissingVars.reset(Var - 1); 592 HasErrors |= HasBadSize; 593 } 594 } 595 596 // Print the results. 597 for (unsigned Idx : MissingLines.set_bits()) 598 dbg() << "WARNING: Missing line " << Idx + 1 << "\n"; 599 600 for (unsigned Idx : MissingVars.set_bits()) 601 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n"; 602 603 // Update DI loss statistics. 604 if (Stats) { 605 Stats->NumDbgLocsExpected += OriginalNumLines; 606 Stats->NumDbgLocsMissing += MissingLines.count(); 607 Stats->NumDbgValuesExpected += OriginalNumVars; 608 Stats->NumDbgValuesMissing += MissingVars.count(); 609 } 610 611 dbg() << Banner; 612 if (!NameOfWrappedPass.empty()) 613 dbg() << " [" << NameOfWrappedPass << "]"; 614 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n'; 615 616 // Strip debugify metadata if required. 617 if (Strip) 618 return stripDebugifyMetadata(M); 619 620 return false; 621 } 622 623 /// ModulePass for attaching synthetic debug info to everything, used with the 624 /// legacy module pass manager. 625 struct DebugifyModulePass : public ModulePass { 626 bool runOnModule(Module &M) override { 627 return applyDebugify(M, Mode, DIPreservationMap, NameOfWrappedPass); 628 } 629 630 DebugifyModulePass(enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 631 StringRef NameOfWrappedPass = "", 632 DebugInfoPerPassMap *DIPreservationMap = nullptr) 633 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass), 634 DIPreservationMap(DIPreservationMap), Mode(Mode) {} 635 636 void getAnalysisUsage(AnalysisUsage &AU) const override { 637 AU.setPreservesAll(); 638 } 639 640 static char ID; // Pass identification. 641 642 private: 643 StringRef NameOfWrappedPass; 644 DebugInfoPerPassMap *DIPreservationMap; 645 enum DebugifyMode Mode; 646 }; 647 648 /// FunctionPass for attaching synthetic debug info to instructions within a 649 /// single function, used with the legacy module pass manager. 650 struct DebugifyFunctionPass : public FunctionPass { 651 bool runOnFunction(Function &F) override { 652 return applyDebugify(F, Mode, DIPreservationMap, NameOfWrappedPass); 653 } 654 655 DebugifyFunctionPass( 656 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 657 StringRef NameOfWrappedPass = "", 658 DebugInfoPerPassMap *DIPreservationMap = nullptr) 659 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass), 660 DIPreservationMap(DIPreservationMap), Mode(Mode) {} 661 662 void getAnalysisUsage(AnalysisUsage &AU) const override { 663 AU.setPreservesAll(); 664 } 665 666 static char ID; // Pass identification. 667 668 private: 669 StringRef NameOfWrappedPass; 670 DebugInfoPerPassMap *DIPreservationMap; 671 enum DebugifyMode Mode; 672 }; 673 674 /// ModulePass for checking debug info inserted by -debugify, used with the 675 /// legacy module pass manager. 676 struct CheckDebugifyModulePass : public ModulePass { 677 bool runOnModule(Module &M) override { 678 if (Mode == DebugifyMode::SyntheticDebugInfo) 679 return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass, 680 "CheckModuleDebugify", Strip, StatsMap); 681 return checkDebugInfoMetadata( 682 M, M.functions(), *DIPreservationMap, 683 "CheckModuleDebugify (original debuginfo)", NameOfWrappedPass); 684 } 685 686 CheckDebugifyModulePass( 687 bool Strip = false, StringRef NameOfWrappedPass = "", 688 DebugifyStatsMap *StatsMap = nullptr, 689 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 690 DebugInfoPerPassMap *DIPreservationMap = nullptr) 691 : ModulePass(ID), NameOfWrappedPass(NameOfWrappedPass), 692 StatsMap(StatsMap), DIPreservationMap(DIPreservationMap), Mode(Mode), 693 Strip(Strip) {} 694 695 void getAnalysisUsage(AnalysisUsage &AU) const override { 696 AU.setPreservesAll(); 697 } 698 699 static char ID; // Pass identification. 700 701 private: 702 StringRef NameOfWrappedPass; 703 DebugifyStatsMap *StatsMap; 704 DebugInfoPerPassMap *DIPreservationMap; 705 enum DebugifyMode Mode; 706 bool Strip; 707 }; 708 709 /// FunctionPass for checking debug info inserted by -debugify-function, used 710 /// with the legacy module pass manager. 711 struct CheckDebugifyFunctionPass : public FunctionPass { 712 bool runOnFunction(Function &F) override { 713 Module &M = *F.getParent(); 714 auto FuncIt = F.getIterator(); 715 if (Mode == DebugifyMode::SyntheticDebugInfo) 716 return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), 717 NameOfWrappedPass, "CheckFunctionDebugify", 718 Strip, StatsMap); 719 return checkDebugInfoMetadata( 720 M, make_range(FuncIt, std::next(FuncIt)), *DIPreservationMap, 721 "CheckFunctionDebugify (original debuginfo)", NameOfWrappedPass); 722 } 723 724 CheckDebugifyFunctionPass( 725 bool Strip = false, StringRef NameOfWrappedPass = "", 726 DebugifyStatsMap *StatsMap = nullptr, 727 enum DebugifyMode Mode = DebugifyMode::SyntheticDebugInfo, 728 DebugInfoPerPassMap *DIPreservationMap = nullptr) 729 : FunctionPass(ID), NameOfWrappedPass(NameOfWrappedPass), 730 StatsMap(StatsMap), DIPreservationMap(DIPreservationMap), Mode(Mode), 731 Strip(Strip) {} 732 733 void getAnalysisUsage(AnalysisUsage &AU) const override { 734 AU.setPreservesAll(); 735 } 736 737 static char ID; // Pass identification. 738 739 private: 740 StringRef NameOfWrappedPass; 741 DebugifyStatsMap *StatsMap; 742 DebugInfoPerPassMap *DIPreservationMap; 743 enum DebugifyMode Mode; 744 bool Strip; 745 }; 746 747 } // end anonymous namespace 748 749 void llvm::exportDebugifyStats(StringRef Path, const DebugifyStatsMap &Map) { 750 std::error_code EC; 751 raw_fd_ostream OS{Path, EC}; 752 if (EC) { 753 errs() << "Could not open file: " << EC.message() << ", " << Path << '\n'; 754 return; 755 } 756 757 OS << "Pass Name" << ',' << "# of missing debug values" << ',' 758 << "# of missing locations" << ',' << "Missing/Expected value ratio" << ',' 759 << "Missing/Expected location ratio" << '\n'; 760 for (const auto &Entry : Map) { 761 StringRef Pass = Entry.first; 762 DebugifyStatistics Stats = Entry.second; 763 764 OS << Pass << ',' << Stats.NumDbgValuesMissing << ',' 765 << Stats.NumDbgLocsMissing << ',' << Stats.getMissingValueRatio() << ',' 766 << Stats.getEmptyLocationRatio() << '\n'; 767 } 768 } 769 770 ModulePass *createDebugifyModulePass(enum DebugifyMode Mode, 771 llvm::StringRef NameOfWrappedPass, 772 DebugInfoPerPassMap *DIPreservationMap) { 773 if (Mode == DebugifyMode::SyntheticDebugInfo) 774 return new DebugifyModulePass(); 775 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 776 return new DebugifyModulePass(Mode, NameOfWrappedPass, DIPreservationMap); 777 } 778 779 FunctionPass * 780 createDebugifyFunctionPass(enum DebugifyMode Mode, 781 llvm::StringRef NameOfWrappedPass, 782 DebugInfoPerPassMap *DIPreservationMap) { 783 if (Mode == DebugifyMode::SyntheticDebugInfo) 784 return new DebugifyFunctionPass(); 785 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 786 return new DebugifyFunctionPass(Mode, NameOfWrappedPass, DIPreservationMap); 787 } 788 789 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) { 790 applyDebugifyMetadata(M, M.functions(), 791 "ModuleDebugify: ", /*ApplyToMF*/ nullptr); 792 return PreservedAnalyses::all(); 793 } 794 795 ModulePass *createCheckDebugifyModulePass( 796 bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, 797 enum DebugifyMode Mode, DebugInfoPerPassMap *DIPreservationMap) { 798 if (Mode == DebugifyMode::SyntheticDebugInfo) 799 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap); 800 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 801 return new CheckDebugifyModulePass(false, NameOfWrappedPass, nullptr, Mode, 802 DIPreservationMap); 803 } 804 805 FunctionPass *createCheckDebugifyFunctionPass( 806 bool Strip, StringRef NameOfWrappedPass, DebugifyStatsMap *StatsMap, 807 enum DebugifyMode Mode, DebugInfoPerPassMap *DIPreservationMap) { 808 if (Mode == DebugifyMode::SyntheticDebugInfo) 809 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap); 810 assert(Mode == DebugifyMode::OriginalDebugInfo && "Must be original mode"); 811 return new CheckDebugifyFunctionPass(false, NameOfWrappedPass, nullptr, Mode, 812 DIPreservationMap); 813 } 814 815 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M, 816 ModuleAnalysisManager &) { 817 checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false, 818 nullptr); 819 return PreservedAnalyses::all(); 820 } 821 822 static bool isIgnoredPass(StringRef PassID) { 823 return isSpecialPass(PassID, {"PassManager", "PassAdaptor", 824 "AnalysisManagerProxy", "PrintFunctionPass", 825 "PrintModulePass", "BitcodeWriterPass", 826 "ThinLTOBitcodeWriterPass", "VerifierPass"}); 827 } 828 829 void DebugifyEachInstrumentation::registerCallbacks( 830 PassInstrumentationCallbacks &PIC) { 831 PIC.registerBeforeNonSkippedPassCallback([](StringRef P, Any IR) { 832 if (isIgnoredPass(P)) 833 return; 834 if (any_isa<const Function *>(IR)) 835 applyDebugify(*const_cast<Function *>(any_cast<const Function *>(IR))); 836 else if (any_isa<const Module *>(IR)) 837 applyDebugify(*const_cast<Module *>(any_cast<const Module *>(IR))); 838 }); 839 PIC.registerAfterPassCallback([this](StringRef P, Any IR, 840 const PreservedAnalyses &PassPA) { 841 if (isIgnoredPass(P)) 842 return; 843 if (any_isa<const Function *>(IR)) { 844 auto &F = *const_cast<Function *>(any_cast<const Function *>(IR)); 845 Module &M = *F.getParent(); 846 auto It = F.getIterator(); 847 checkDebugifyMetadata(M, make_range(It, std::next(It)), P, 848 "CheckFunctionDebugify", /*Strip=*/true, &StatsMap); 849 } else if (any_isa<const Module *>(IR)) { 850 auto &M = *const_cast<Module *>(any_cast<const Module *>(IR)); 851 checkDebugifyMetadata(M, M.functions(), P, "CheckModuleDebugify", 852 /*Strip=*/true, &StatsMap); 853 } 854 }); 855 } 856 857 char DebugifyModulePass::ID = 0; 858 static RegisterPass<DebugifyModulePass> DM("debugify", 859 "Attach debug info to everything"); 860 861 char CheckDebugifyModulePass::ID = 0; 862 static RegisterPass<CheckDebugifyModulePass> 863 CDM("check-debugify", "Check debug info from -debugify"); 864 865 char DebugifyFunctionPass::ID = 0; 866 static RegisterPass<DebugifyFunctionPass> DF("debugify-function", 867 "Attach debug info to a function"); 868 869 char CheckDebugifyFunctionPass::ID = 0; 870 static RegisterPass<CheckDebugifyFunctionPass> 871 CDF("check-debugify-function", "Check debug info from -debugify-function"); 872