1 //===- Debugify.cpp - Attach synthetic debug info to everything -----------===// 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 This pass attaches synthetic debug info to everything. It can be used 10 /// to create targeted tests for debug info preservation. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Utils/Debugify.h" 15 #include "llvm/ADT/BitVector.h" 16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/IR/DIBuilder.h" 18 #include "llvm/IR/DebugInfo.h" 19 #include "llvm/IR/InstIterator.h" 20 #include "llvm/IR/Instructions.h" 21 #include "llvm/IR/IntrinsicInst.h" 22 #include "llvm/IR/Module.h" 23 #include "llvm/Pass.h" 24 #include "llvm/Support/CommandLine.h" 25 26 using namespace llvm; 27 28 namespace { 29 30 cl::opt<bool> Quiet("debugify-quiet", 31 cl::desc("Suppress verbose debugify output")); 32 33 enum class Level { 34 Locations, 35 LocationsAndVariables 36 }; 37 cl::opt<Level> DebugifyLevel( 38 "debugify-level", cl::desc("Kind of debug info to add"), 39 cl::values(clEnumValN(Level::Locations, "locations", "Locations only"), 40 clEnumValN(Level::LocationsAndVariables, "location+variables", 41 "Locations and Variables")), 42 cl::init(Level::LocationsAndVariables)); 43 44 raw_ostream &dbg() { return Quiet ? nulls() : errs(); } 45 46 uint64_t getAllocSizeInBits(Module &M, Type *Ty) { 47 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0; 48 } 49 50 bool isFunctionSkipped(Function &F) { 51 return F.isDeclaration() || !F.hasExactDefinition(); 52 } 53 54 /// Find the basic block's terminating instruction. 55 /// 56 /// Special care is needed to handle musttail and deopt calls, as these behave 57 /// like (but are in fact not) terminators. 58 Instruction *findTerminatingInstruction(BasicBlock &BB) { 59 if (auto *I = BB.getTerminatingMustTailCall()) 60 return I; 61 if (auto *I = BB.getTerminatingDeoptimizeCall()) 62 return I; 63 return BB.getTerminator(); 64 } 65 } // end anonymous namespace 66 67 bool llvm::applyDebugifyMetadata( 68 Module &M, iterator_range<Module::iterator> Functions, StringRef Banner, 69 std::function<bool(DIBuilder &DIB, Function &F)> ApplyToMF) { 70 // Skip modules with debug info. 71 if (M.getNamedMetadata("llvm.dbg.cu")) { 72 dbg() << Banner << "Skipping module with debug info\n"; 73 return false; 74 } 75 76 DIBuilder DIB(M); 77 LLVMContext &Ctx = M.getContext(); 78 79 // Get a DIType which corresponds to Ty. 80 DenseMap<uint64_t, DIType *> TypeCache; 81 auto getCachedDIType = [&](Type *Ty) -> DIType * { 82 uint64_t Size = getAllocSizeInBits(M, Ty); 83 DIType *&DTy = TypeCache[Size]; 84 if (!DTy) { 85 std::string Name = "ty" + utostr(Size); 86 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned); 87 } 88 return DTy; 89 }; 90 91 unsigned NextLine = 1; 92 unsigned NextVar = 1; 93 auto File = DIB.createFile(M.getName(), "/"); 94 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify", 95 /*isOptimized=*/true, "", 0); 96 97 // Visit each instruction. 98 for (Function &F : Functions) { 99 if (isFunctionSkipped(F)) 100 continue; 101 102 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); 103 DISubprogram::DISPFlags SPFlags = 104 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized; 105 if (F.hasPrivateLinkage() || F.hasInternalLinkage()) 106 SPFlags |= DISubprogram::SPFlagLocalToUnit; 107 auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, 108 SPType, NextLine, DINode::FlagZero, SPFlags); 109 F.setSubprogram(SP); 110 for (BasicBlock &BB : F) { 111 // Attach debug locations. 112 for (Instruction &I : BB) 113 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP)); 114 115 if (DebugifyLevel < Level::LocationsAndVariables) 116 continue; 117 118 // Inserting debug values into EH pads can break IR invariants. 119 if (BB.isEHPad()) 120 continue; 121 122 // Find the terminating instruction, after which no debug values are 123 // attached. 124 Instruction *LastInst = findTerminatingInstruction(BB); 125 assert(LastInst && "Expected basic block with a terminator"); 126 127 // Maintain an insertion point which can't be invalidated when updates 128 // are made. 129 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt(); 130 assert(InsertPt != BB.end() && "Expected to find an insertion point"); 131 Instruction *InsertBefore = &*InsertPt; 132 133 // Attach debug values. 134 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) { 135 // Skip void-valued instructions. 136 if (I->getType()->isVoidTy()) 137 continue; 138 139 // Phis and EH pads must be grouped at the beginning of the block. 140 // Only advance the insertion point when we finish visiting these. 141 if (!isa<PHINode>(I) && !I->isEHPad()) 142 InsertBefore = I->getNextNode(); 143 144 std::string Name = utostr(NextVar++); 145 const DILocation *Loc = I->getDebugLoc().get(); 146 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(), 147 getCachedDIType(I->getType()), 148 /*AlwaysPreserve=*/true); 149 DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc, 150 InsertBefore); 151 } 152 } 153 if (ApplyToMF) 154 ApplyToMF(DIB, F); 155 DIB.finalizeSubprogram(SP); 156 } 157 DIB.finalize(); 158 159 // Track the number of distinct lines and variables. 160 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify"); 161 auto *IntTy = Type::getInt32Ty(Ctx); 162 auto addDebugifyOperand = [&](unsigned N) { 163 NMD->addOperand(MDNode::get( 164 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N)))); 165 }; 166 addDebugifyOperand(NextLine - 1); // Original number of lines. 167 addDebugifyOperand(NextVar - 1); // Original number of variables. 168 assert(NMD->getNumOperands() == 2 && 169 "llvm.debugify should have exactly 2 operands!"); 170 171 // Claim that this synthetic debug info is valid. 172 StringRef DIVersionKey = "Debug Info Version"; 173 if (!M.getModuleFlag(DIVersionKey)) 174 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION); 175 176 return true; 177 } 178 179 namespace { 180 /// Return true if a mis-sized diagnostic is issued for \p DVI. 181 bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) { 182 // The size of a dbg.value's value operand should match the size of the 183 // variable it corresponds to. 184 // 185 // TODO: This, along with a check for non-null value operands, should be 186 // promoted to verifier failures. 187 Value *V = DVI->getValue(); 188 if (!V) 189 return false; 190 191 // For now, don't try to interpret anything more complicated than an empty 192 // DIExpression. Eventually we should try to handle OP_deref and fragments. 193 if (DVI->getExpression()->getNumElements()) 194 return false; 195 196 Type *Ty = V->getType(); 197 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty); 198 Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits(); 199 if (!ValueOperandSize || !DbgVarSize) 200 return false; 201 202 bool HasBadSize = false; 203 if (Ty->isIntegerTy()) { 204 auto Signedness = DVI->getVariable()->getSignedness(); 205 if (Signedness && *Signedness == DIBasicType::Signedness::Signed) 206 HasBadSize = ValueOperandSize < *DbgVarSize; 207 } else { 208 HasBadSize = ValueOperandSize != *DbgVarSize; 209 } 210 211 if (HasBadSize) { 212 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize 213 << ", but its variable has size " << *DbgVarSize << ": "; 214 DVI->print(dbg()); 215 dbg() << "\n"; 216 } 217 return HasBadSize; 218 } 219 220 bool checkDebugifyMetadata(Module &M, 221 iterator_range<Module::iterator> Functions, 222 StringRef NameOfWrappedPass, StringRef Banner, 223 bool Strip, DebugifyStatsMap *StatsMap) { 224 // Skip modules without debugify metadata. 225 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify"); 226 if (!NMD) { 227 dbg() << Banner << "Skipping module without debugify metadata\n"; 228 return false; 229 } 230 231 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned { 232 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0)) 233 ->getZExtValue(); 234 }; 235 assert(NMD->getNumOperands() == 2 && 236 "llvm.debugify should have exactly 2 operands!"); 237 unsigned OriginalNumLines = getDebugifyOperand(0); 238 unsigned OriginalNumVars = getDebugifyOperand(1); 239 bool HasErrors = false; 240 241 // Track debug info loss statistics if able. 242 DebugifyStatistics *Stats = nullptr; 243 if (StatsMap && !NameOfWrappedPass.empty()) 244 Stats = &StatsMap->operator[](NameOfWrappedPass); 245 246 BitVector MissingLines{OriginalNumLines, true}; 247 BitVector MissingVars{OriginalNumVars, true}; 248 for (Function &F : Functions) { 249 if (isFunctionSkipped(F)) 250 continue; 251 252 // Find missing lines. 253 for (Instruction &I : instructions(F)) { 254 if (isa<DbgValueInst>(&I) || isa<PHINode>(&I)) 255 continue; 256 257 auto DL = I.getDebugLoc(); 258 if (DL && DL.getLine() != 0) { 259 MissingLines.reset(DL.getLine() - 1); 260 continue; 261 } 262 263 if (!DL) { 264 dbg() << "ERROR: Instruction with empty DebugLoc in function "; 265 dbg() << F.getName() << " --"; 266 I.print(dbg()); 267 dbg() << "\n"; 268 HasErrors = true; 269 } 270 } 271 272 // Find missing variables and mis-sized debug values. 273 for (Instruction &I : instructions(F)) { 274 auto *DVI = dyn_cast<DbgValueInst>(&I); 275 if (!DVI) 276 continue; 277 278 unsigned Var = ~0U; 279 (void)to_integer(DVI->getVariable()->getName(), Var, 10); 280 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable"); 281 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI); 282 if (!HasBadSize) 283 MissingVars.reset(Var - 1); 284 HasErrors |= HasBadSize; 285 } 286 } 287 288 // Print the results. 289 for (unsigned Idx : MissingLines.set_bits()) 290 dbg() << "WARNING: Missing line " << Idx + 1 << "\n"; 291 292 for (unsigned Idx : MissingVars.set_bits()) 293 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n"; 294 295 // Update DI loss statistics. 296 if (Stats) { 297 Stats->NumDbgLocsExpected += OriginalNumLines; 298 Stats->NumDbgLocsMissing += MissingLines.count(); 299 Stats->NumDbgValuesExpected += OriginalNumVars; 300 Stats->NumDbgValuesMissing += MissingVars.count(); 301 } 302 303 dbg() << Banner; 304 if (!NameOfWrappedPass.empty()) 305 dbg() << " [" << NameOfWrappedPass << "]"; 306 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n'; 307 308 // Strip the Debugify Metadata if required. 309 if (Strip) { 310 StripDebugInfo(M); 311 M.eraseNamedMetadata(NMD); 312 return true; 313 } 314 315 return false; 316 } 317 318 /// ModulePass for attaching synthetic debug info to everything, used with the 319 /// legacy module pass manager. 320 struct DebugifyModulePass : public ModulePass { 321 bool runOnModule(Module &M) override { 322 return applyDebugifyMetadata(M, M.functions(), 323 "ModuleDebugify: ", /*ApplyToMF*/ nullptr); 324 } 325 326 DebugifyModulePass() : ModulePass(ID) {} 327 328 void getAnalysisUsage(AnalysisUsage &AU) const override { 329 AU.setPreservesAll(); 330 } 331 332 static char ID; // Pass identification. 333 }; 334 335 /// FunctionPass for attaching synthetic debug info to instructions within a 336 /// single function, used with the legacy module pass manager. 337 struct DebugifyFunctionPass : public FunctionPass { 338 bool runOnFunction(Function &F) override { 339 Module &M = *F.getParent(); 340 auto FuncIt = F.getIterator(); 341 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), 342 "FunctionDebugify: ", /*ApplyToMF*/ nullptr); 343 } 344 345 DebugifyFunctionPass() : FunctionPass(ID) {} 346 347 void getAnalysisUsage(AnalysisUsage &AU) const override { 348 AU.setPreservesAll(); 349 } 350 351 static char ID; // Pass identification. 352 }; 353 354 /// ModulePass for checking debug info inserted by -debugify, used with the 355 /// legacy module pass manager. 356 struct CheckDebugifyModulePass : public ModulePass { 357 bool runOnModule(Module &M) override { 358 return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass, 359 "CheckModuleDebugify", Strip, StatsMap); 360 } 361 362 CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "", 363 DebugifyStatsMap *StatsMap = nullptr) 364 : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass), 365 StatsMap(StatsMap) {} 366 367 void getAnalysisUsage(AnalysisUsage &AU) const override { 368 AU.setPreservesAll(); 369 } 370 371 static char ID; // Pass identification. 372 373 private: 374 bool Strip; 375 StringRef NameOfWrappedPass; 376 DebugifyStatsMap *StatsMap; 377 }; 378 379 /// FunctionPass for checking debug info inserted by -debugify-function, used 380 /// with the legacy module pass manager. 381 struct CheckDebugifyFunctionPass : public FunctionPass { 382 bool runOnFunction(Function &F) override { 383 Module &M = *F.getParent(); 384 auto FuncIt = F.getIterator(); 385 return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)), 386 NameOfWrappedPass, "CheckFunctionDebugify", 387 Strip, StatsMap); 388 } 389 390 CheckDebugifyFunctionPass(bool Strip = false, 391 StringRef NameOfWrappedPass = "", 392 DebugifyStatsMap *StatsMap = nullptr) 393 : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass), 394 StatsMap(StatsMap) {} 395 396 void getAnalysisUsage(AnalysisUsage &AU) const override { 397 AU.setPreservesAll(); 398 } 399 400 static char ID; // Pass identification. 401 402 private: 403 bool Strip; 404 StringRef NameOfWrappedPass; 405 DebugifyStatsMap *StatsMap; 406 }; 407 408 } // end anonymous namespace 409 410 ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); } 411 412 FunctionPass *createDebugifyFunctionPass() { 413 return new DebugifyFunctionPass(); 414 } 415 416 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) { 417 applyDebugifyMetadata(M, M.functions(), 418 "ModuleDebugify: ", /*ApplyToMF*/ nullptr); 419 return PreservedAnalyses::all(); 420 } 421 422 ModulePass *createCheckDebugifyModulePass(bool Strip, 423 StringRef NameOfWrappedPass, 424 DebugifyStatsMap *StatsMap) { 425 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap); 426 } 427 428 FunctionPass *createCheckDebugifyFunctionPass(bool Strip, 429 StringRef NameOfWrappedPass, 430 DebugifyStatsMap *StatsMap) { 431 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap); 432 } 433 434 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M, 435 ModuleAnalysisManager &) { 436 checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false, 437 nullptr); 438 return PreservedAnalyses::all(); 439 } 440 441 char DebugifyModulePass::ID = 0; 442 static RegisterPass<DebugifyModulePass> DM("debugify", 443 "Attach debug info to everything"); 444 445 char CheckDebugifyModulePass::ID = 0; 446 static RegisterPass<CheckDebugifyModulePass> 447 CDM("check-debugify", "Check debug info from -debugify"); 448 449 char DebugifyFunctionPass::ID = 0; 450 static RegisterPass<DebugifyFunctionPass> DF("debugify-function", 451 "Attach debug info to a function"); 452 453 char CheckDebugifyFunctionPass::ID = 0; 454 static RegisterPass<CheckDebugifyFunctionPass> 455 CDF("check-debugify-function", "Check debug info from -debugify-function"); 456