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