Commit r331416 breaks the big-endian PPC bot. On the big endian build, we
[llvm-core.git] / tools / opt / Debugify.cpp
blob441fec3676569424e1041e5fb58dd64cb5c2d2b3
1 //===- Debugify.cpp - Attach synthetic debug info to everything -----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file This pass attaches synthetic debug info to everything. It can be used
11 /// to create targeted tests for debug info preservation.
12 ///
13 //===----------------------------------------------------------------------===//
15 #include "PassPrinters.h"
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/IR/BasicBlock.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DIBuilder.h"
21 #include "llvm/IR/DebugInfo.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/GlobalVariable.h"
24 #include "llvm/IR/InstIterator.h"
25 #include "llvm/IR/Instruction.h"
26 #include "llvm/IR/Instructions.h"
27 #include "llvm/IR/IntrinsicInst.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/Pass.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include "llvm/Transforms/IPO.h"
34 using namespace llvm;
36 namespace {
38 bool isFunctionSkipped(Function &F) {
39 return F.isDeclaration() || !F.hasExactDefinition();
42 bool applyDebugifyMetadata(Module &M) {
43 // Skip modules with debug info.
44 if (M.getNamedMetadata("llvm.dbg.cu")) {
45 errs() << "Debugify: Skipping module with debug info\n";
46 return false;
49 DIBuilder DIB(M);
50 LLVMContext &Ctx = M.getContext();
52 // Get a DIType which corresponds to Ty.
53 DenseMap<uint64_t, DIType *> TypeCache;
54 auto getCachedDIType = [&](Type *Ty) -> DIType * {
55 uint64_t Size =
56 Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
57 DIType *&DTy = TypeCache[Size];
58 if (!DTy) {
59 std::string Name = "ty" + utostr(Size);
60 DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
62 return DTy;
65 unsigned NextLine = 1;
66 unsigned NextVar = 1;
67 auto File = DIB.createFile(M.getName(), "/");
68 auto CU =
69 DIB.createCompileUnit(dwarf::DW_LANG_C, DIB.createFile(M.getName(), "/"),
70 "debugify", /*isOptimized=*/true, "", 0);
72 // Visit each instruction.
73 for (Function &F : M) {
74 if (isFunctionSkipped(F))
75 continue;
77 auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
78 bool IsLocalToUnit = F.hasPrivateLinkage() || F.hasInternalLinkage();
79 auto SP =
80 DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, SPType,
81 IsLocalToUnit, /*isDefinition=*/true, NextLine,
82 DINode::FlagZero, /*isOptimized=*/true);
83 F.setSubprogram(SP);
84 for (BasicBlock &BB : F) {
85 // Attach debug locations.
86 for (Instruction &I : BB)
87 I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
89 // Attach debug values.
90 for (Instruction &I : BB) {
91 // Skip void-valued instructions.
92 if (I.getType()->isVoidTy())
93 continue;
95 // Skip the terminator instruction and any just-inserted intrinsics.
96 if (isa<TerminatorInst>(&I) || isa<DbgValueInst>(&I))
97 break;
99 std::string Name = utostr(NextVar++);
100 const DILocation *Loc = I.getDebugLoc().get();
101 auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
102 getCachedDIType(I.getType()),
103 /*AlwaysPreserve=*/true);
104 DIB.insertDbgValueIntrinsic(&I, LocalVar, DIB.createExpression(), Loc,
105 BB.getTerminator());
108 DIB.finalizeSubprogram(SP);
110 DIB.finalize();
112 // Track the number of distinct lines and variables.
113 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
114 auto *IntTy = Type::getInt32Ty(Ctx);
115 auto addDebugifyOperand = [&](unsigned N) {
116 NMD->addOperand(MDNode::get(
117 Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N))));
119 addDebugifyOperand(NextLine - 1); // Original number of lines.
120 addDebugifyOperand(NextVar - 1); // Original number of variables.
121 return true;
124 void checkDebugifyMetadata(Module &M) {
125 // Skip modules without debugify metadata.
126 NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
127 if (!NMD)
128 return;
130 auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
131 return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
132 ->getZExtValue();
134 unsigned OriginalNumLines = getDebugifyOperand(0);
135 unsigned OriginalNumVars = getDebugifyOperand(1);
136 bool HasErrors = false;
138 // Find missing lines.
139 BitVector MissingLines{OriginalNumLines, true};
140 for (Function &F : M) {
141 if (isFunctionSkipped(F))
142 continue;
144 for (Instruction &I : instructions(F)) {
145 if (isa<DbgValueInst>(&I))
146 continue;
148 auto DL = I.getDebugLoc();
149 if (DL) {
150 MissingLines.reset(DL.getLine() - 1);
151 continue;
154 outs() << "ERROR: Instruction with empty DebugLoc -- ";
155 I.print(outs());
156 outs() << "\n";
157 HasErrors = true;
160 for (unsigned Idx : MissingLines.set_bits())
161 outs() << "WARNING: Missing line " << Idx + 1 << "\n";
163 // Find missing variables.
164 BitVector MissingVars{OriginalNumVars, true};
165 for (Function &F : M) {
166 if (isFunctionSkipped(F))
167 continue;
169 for (Instruction &I : instructions(F)) {
170 auto *DVI = dyn_cast<DbgValueInst>(&I);
171 if (!DVI)
172 continue;
174 unsigned Var = ~0U;
175 (void)to_integer(DVI->getVariable()->getName(), Var, 10);
176 assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
177 MissingVars.reset(Var - 1);
180 for (unsigned Idx : MissingVars.set_bits())
181 outs() << "ERROR: Missing variable " << Idx + 1 << "\n";
182 HasErrors |= MissingVars.count() > 0;
184 outs() << "CheckDebugify: " << (HasErrors ? "FAIL" : "PASS") << "\n";
187 /// Attach synthetic debug info to everything.
188 struct DebugifyPass : public ModulePass {
189 bool runOnModule(Module &M) override { return applyDebugifyMetadata(M); }
191 DebugifyPass() : ModulePass(ID) {}
193 void getAnalysisUsage(AnalysisUsage &AU) const override {
194 AU.setPreservesAll();
197 static char ID; // Pass identification.
200 /// Check debug info inserted by -debugify for completeness.
201 struct CheckDebugifyPass : public ModulePass {
202 bool runOnModule(Module &M) override {
203 checkDebugifyMetadata(M);
204 return false;
207 CheckDebugifyPass() : ModulePass(ID) {}
209 void getAnalysisUsage(AnalysisUsage &AU) const override {
210 AU.setPreservesAll();
213 static char ID; // Pass identification.
216 } // end anonymous namespace
218 ModulePass *createDebugifyPass() { return new DebugifyPass(); }
220 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
221 applyDebugifyMetadata(M);
222 return PreservedAnalyses::all();
225 ModulePass *createCheckDebugifyPass() { return new CheckDebugifyPass(); }
227 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
228 ModuleAnalysisManager &) {
229 checkDebugifyMetadata(M);
230 return PreservedAnalyses::all();
233 char DebugifyPass::ID = 0;
234 static RegisterPass<DebugifyPass> X("debugify",
235 "Attach debug info to everything");
237 char CheckDebugifyPass::ID = 0;
238 static RegisterPass<CheckDebugifyPass> Y("check-debugify",
239 "Check debug info from -debugify");