Clang] Fix expansion of response files in -Wp after integrated-cc1 change
[llvm-project.git] / llvm / lib / Transforms / Utils / Debugify.cpp
blobb7b4bfa3734d0e140b1c181517ba2a9f38e077d7
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 //===----------------------------------------------------------------------===//
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"
26 using namespace llvm;
28 namespace {
30 cl::opt<bool> Quiet("debugify-quiet",
31 cl::desc("Suppress verbose debugify output"));
33 raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
35 uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
36 return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
39 bool isFunctionSkipped(Function &F) {
40 return F.isDeclaration() || !F.hasExactDefinition();
43 /// Find the basic block's terminating instruction.
44 ///
45 /// Special care is needed to handle musttail and deopt calls, as these behave
46 /// like (but are in fact not) terminators.
47 Instruction *findTerminatingInstruction(BasicBlock &BB) {
48 if (auto *I = BB.getTerminatingMustTailCall())
49 return I;
50 if (auto *I = BB.getTerminatingDeoptimizeCall())
51 return I;
52 return BB.getTerminator();
55 bool applyDebugifyMetadata(Module &M,
56 iterator_range<Module::iterator> Functions,
57 StringRef Banner) {
58 // Skip modules with debug info.
59 if (M.getNamedMetadata("llvm.dbg.cu")) {
60 dbg() << Banner << "Skipping module with debug info\n";
61 return false;
64 DIBuilder DIB(M);
65 LLVMContext &Ctx = M.getContext();
67 // Get a DIType which corresponds to Ty.
68 DenseMap<uint64_t, DIType *> TypeCache;
69 auto getCachedDIType = [&](Type *Ty) -> DIType * {
70 uint64_t Size = getAllocSizeInBits(M, Ty);
71 DIType *&DTy = TypeCache[Size];
72 if (!DTy) {
73 std::string Name = "ty" + utostr(Size);
74 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
76 return DTy;
79 unsigned NextLine = 1;
80 unsigned NextVar = 1;
81 auto File = DIB.createFile(M.getName(), "/");
82 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
83 /*isOptimized=*/true, "", 0);
85 // Visit each instruction.
86 for (Function &F : Functions) {
87 if (isFunctionSkipped(F))
88 continue;
90 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
91 DISubprogram::DISPFlags SPFlags =
92 DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
93 if (F.hasPrivateLinkage() || F.hasInternalLinkage())
94 SPFlags |= DISubprogram::SPFlagLocalToUnit;
95 auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
96 SPType, NextLine, DINode::FlagZero, SPFlags);
97 F.setSubprogram(SP);
98 for (BasicBlock &BB : F) {
99 // Attach debug locations.
100 for (Instruction &I : BB)
101 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
103 // Inserting debug values into EH pads can break IR invariants.
104 if (BB.isEHPad())
105 continue;
107 // Find the terminating instruction, after which no debug values are
108 // attached.
109 Instruction *LastInst = findTerminatingInstruction(BB);
110 assert(LastInst && "Expected basic block with a terminator");
112 // Maintain an insertion point which can't be invalidated when updates
113 // are made.
114 BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
115 assert(InsertPt != BB.end() && "Expected to find an insertion point");
116 Instruction *InsertBefore = &*InsertPt;
118 // Attach debug values.
119 for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
120 // Skip void-valued instructions.
121 if (I->getType()->isVoidTy())
122 continue;
124 // Phis and EH pads must be grouped at the beginning of the block.
125 // Only advance the insertion point when we finish visiting these.
126 if (!isa<PHINode>(I) && !I->isEHPad())
127 InsertBefore = I->getNextNode();
129 std::string Name = utostr(NextVar++);
130 const DILocation *Loc = I->getDebugLoc().get();
131 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
132 getCachedDIType(I->getType()),
133 /*AlwaysPreserve=*/true);
134 DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc,
135 InsertBefore);
138 DIB.finalizeSubprogram(SP);
140 DIB.finalize();
142 // Track the number of distinct lines and variables.
143 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
144 auto *IntTy = Type::getInt32Ty(Ctx);
145 auto addDebugifyOperand = [&](unsigned N) {
146 NMD->addOperand(MDNode::get(
147 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N))));
149 addDebugifyOperand(NextLine - 1); // Original number of lines.
150 addDebugifyOperand(NextVar - 1); // Original number of variables.
151 assert(NMD->getNumOperands() == 2 &&
152 "llvm.debugify should have exactly 2 operands!");
154 // Claim that this synthetic debug info is valid.
155 StringRef DIVersionKey = "Debug Info Version";
156 if (!M.getModuleFlag(DIVersionKey))
157 M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
159 return true;
162 /// Return true if a mis-sized diagnostic is issued for \p DVI.
163 bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
164 // The size of a dbg.value's value operand should match the size of the
165 // variable it corresponds to.
167 // TODO: This, along with a check for non-null value operands, should be
168 // promoted to verifier failures.
169 Value *V = DVI->getValue();
170 if (!V)
171 return false;
173 // For now, don't try to interpret anything more complicated than an empty
174 // DIExpression. Eventually we should try to handle OP_deref and fragments.
175 if (DVI->getExpression()->getNumElements())
176 return false;
178 Type *Ty = V->getType();
179 uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
180 Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
181 if (!ValueOperandSize || !DbgVarSize)
182 return false;
184 bool HasBadSize = false;
185 if (Ty->isIntegerTy()) {
186 auto Signedness = DVI->getVariable()->getSignedness();
187 if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
188 HasBadSize = ValueOperandSize < *DbgVarSize;
189 } else {
190 HasBadSize = ValueOperandSize != *DbgVarSize;
193 if (HasBadSize) {
194 dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
195 << ", but its variable has size " << *DbgVarSize << ": ";
196 DVI->print(dbg());
197 dbg() << "\n";
199 return HasBadSize;
202 bool checkDebugifyMetadata(Module &M,
203 iterator_range<Module::iterator> Functions,
204 StringRef NameOfWrappedPass, StringRef Banner,
205 bool Strip, DebugifyStatsMap *StatsMap) {
206 // Skip modules without debugify metadata.
207 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
208 if (!NMD) {
209 dbg() << Banner << "Skipping module without debugify metadata\n";
210 return false;
213 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
214 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
215 ->getZExtValue();
217 assert(NMD->getNumOperands() == 2 &&
218 "llvm.debugify should have exactly 2 operands!");
219 unsigned OriginalNumLines = getDebugifyOperand(0);
220 unsigned OriginalNumVars = getDebugifyOperand(1);
221 bool HasErrors = false;
223 // Track debug info loss statistics if able.
224 DebugifyStatistics *Stats = nullptr;
225 if (StatsMap && !NameOfWrappedPass.empty())
226 Stats = &StatsMap->operator[](NameOfWrappedPass);
228 BitVector MissingLines{OriginalNumLines, true};
229 BitVector MissingVars{OriginalNumVars, true};
230 for (Function &F : Functions) {
231 if (isFunctionSkipped(F))
232 continue;
234 // Find missing lines.
235 for (Instruction &I : instructions(F)) {
236 if (isa<DbgValueInst>(&I))
237 continue;
239 auto DL = I.getDebugLoc();
240 if (DL && DL.getLine() != 0) {
241 MissingLines.reset(DL.getLine() - 1);
242 continue;
245 if (!DL) {
246 dbg() << "ERROR: Instruction with empty DebugLoc in function ";
247 dbg() << F.getName() << " --";
248 I.print(dbg());
249 dbg() << "\n";
250 HasErrors = true;
254 // Find missing variables and mis-sized debug values.
255 for (Instruction &I : instructions(F)) {
256 auto *DVI = dyn_cast<DbgValueInst>(&I);
257 if (!DVI)
258 continue;
260 unsigned Var = ~0U;
261 (void)to_integer(DVI->getVariable()->getName(), Var, 10);
262 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
263 bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
264 if (!HasBadSize)
265 MissingVars.reset(Var - 1);
266 HasErrors |= HasBadSize;
270 // Print the results.
271 for (unsigned Idx : MissingLines.set_bits())
272 dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
274 for (unsigned Idx : MissingVars.set_bits())
275 dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
277 // Update DI loss statistics.
278 if (Stats) {
279 Stats->NumDbgLocsExpected += OriginalNumLines;
280 Stats->NumDbgLocsMissing += MissingLines.count();
281 Stats->NumDbgValuesExpected += OriginalNumVars;
282 Stats->NumDbgValuesMissing += MissingVars.count();
285 dbg() << Banner;
286 if (!NameOfWrappedPass.empty())
287 dbg() << " [" << NameOfWrappedPass << "]";
288 dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
290 // Strip the Debugify Metadata if required.
291 if (Strip) {
292 StripDebugInfo(M);
293 M.eraseNamedMetadata(NMD);
294 return true;
297 return false;
300 /// ModulePass for attaching synthetic debug info to everything, used with the
301 /// legacy module pass manager.
302 struct DebugifyModulePass : public ModulePass {
303 bool runOnModule(Module &M) override {
304 return applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
307 DebugifyModulePass() : ModulePass(ID) {}
309 void getAnalysisUsage(AnalysisUsage &AU) const override {
310 AU.setPreservesAll();
313 static char ID; // Pass identification.
316 /// FunctionPass for attaching synthetic debug info to instructions within a
317 /// single function, used with the legacy module pass manager.
318 struct DebugifyFunctionPass : public FunctionPass {
319 bool runOnFunction(Function &F) override {
320 Module &M = *F.getParent();
321 auto FuncIt = F.getIterator();
322 return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
323 "FunctionDebugify: ");
326 DebugifyFunctionPass() : FunctionPass(ID) {}
328 void getAnalysisUsage(AnalysisUsage &AU) const override {
329 AU.setPreservesAll();
332 static char ID; // Pass identification.
335 /// ModulePass for checking debug info inserted by -debugify, used with the
336 /// legacy module pass manager.
337 struct CheckDebugifyModulePass : public ModulePass {
338 bool runOnModule(Module &M) override {
339 return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
340 "CheckModuleDebugify", Strip, StatsMap);
343 CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "",
344 DebugifyStatsMap *StatsMap = nullptr)
345 : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
346 StatsMap(StatsMap) {}
348 void getAnalysisUsage(AnalysisUsage &AU) const override {
349 AU.setPreservesAll();
352 static char ID; // Pass identification.
354 private:
355 bool Strip;
356 StringRef NameOfWrappedPass;
357 DebugifyStatsMap *StatsMap;
360 /// FunctionPass for checking debug info inserted by -debugify-function, used
361 /// with the legacy module pass manager.
362 struct CheckDebugifyFunctionPass : public FunctionPass {
363 bool runOnFunction(Function &F) override {
364 Module &M = *F.getParent();
365 auto FuncIt = F.getIterator();
366 return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
367 NameOfWrappedPass, "CheckFunctionDebugify",
368 Strip, StatsMap);
371 CheckDebugifyFunctionPass(bool Strip = false,
372 StringRef NameOfWrappedPass = "",
373 DebugifyStatsMap *StatsMap = nullptr)
374 : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
375 StatsMap(StatsMap) {}
377 void getAnalysisUsage(AnalysisUsage &AU) const override {
378 AU.setPreservesAll();
381 static char ID; // Pass identification.
383 private:
384 bool Strip;
385 StringRef NameOfWrappedPass;
386 DebugifyStatsMap *StatsMap;
389 } // end anonymous namespace
391 ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
393 FunctionPass *createDebugifyFunctionPass() {
394 return new DebugifyFunctionPass();
397 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
398 applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
399 return PreservedAnalyses::all();
402 ModulePass *createCheckDebugifyModulePass(bool Strip,
403 StringRef NameOfWrappedPass,
404 DebugifyStatsMap *StatsMap) {
405 return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
408 FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
409 StringRef NameOfWrappedPass,
410 DebugifyStatsMap *StatsMap) {
411 return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
414 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
415 ModuleAnalysisManager &) {
416 checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
417 nullptr);
418 return PreservedAnalyses::all();
421 char DebugifyModulePass::ID = 0;
422 static RegisterPass<DebugifyModulePass> DM("debugify",
423 "Attach debug info to everything");
425 char CheckDebugifyModulePass::ID = 0;
426 static RegisterPass<CheckDebugifyModulePass>
427 CDM("check-debugify", "Check debug info from -debugify");
429 char DebugifyFunctionPass::ID = 0;
430 static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
431 "Attach debug info to a function");
433 char CheckDebugifyFunctionPass::ID = 0;
434 static RegisterPass<CheckDebugifyFunctionPass>
435 CDF("check-debugify-function", "Check debug info from -debugify-function");