1 //===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp -------*- C++ -*--===//
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 // Common functionality for different debug information format backends.
10 // LLVM currently supports DWARF and CodeView.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/CodeGen/DebugHandlerBase.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/CodeGen/AsmPrinter.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstr.h"
20 #include "llvm/CodeGen/MachineModuleInfo.h"
21 #include "llvm/CodeGen/TargetSubtargetInfo.h"
22 #include "llvm/IR/DebugInfo.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/Support/CommandLine.h"
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "dwarfdebug"
30 
31 /// If true, we drop variable location ranges which exist entirely outside the
32 /// variable's lexical scope instruction ranges.
33 static cl::opt<bool> TrimVarLocs("trim-var-locs", cl::Hidden, cl::init(true));
34 
35 Optional<DbgVariableLocation>
36 DbgVariableLocation::extractFromMachineInstruction(
37     const MachineInstr &Instruction) {
38   DbgVariableLocation Location;
39   if (!Instruction.isDebugValue())
40     return None;
41   if (!Instruction.getDebugOperand(0).isReg())
42     return None;
43   Location.Register = Instruction.getDebugOperand(0).getReg();
44   Location.FragmentInfo.reset();
45   // We only handle expressions generated by DIExpression::appendOffset,
46   // which doesn't require a full stack machine.
47   int64_t Offset = 0;
48   const DIExpression *DIExpr = Instruction.getDebugExpression();
49   auto Op = DIExpr->expr_op_begin();
50   while (Op != DIExpr->expr_op_end()) {
51     switch (Op->getOp()) {
52     case dwarf::DW_OP_constu: {
53       int Value = Op->getArg(0);
54       ++Op;
55       if (Op != DIExpr->expr_op_end()) {
56         switch (Op->getOp()) {
57         case dwarf::DW_OP_minus:
58           Offset -= Value;
59           break;
60         case dwarf::DW_OP_plus:
61           Offset += Value;
62           break;
63         default:
64           continue;
65         }
66       }
67     } break;
68     case dwarf::DW_OP_plus_uconst:
69       Offset += Op->getArg(0);
70       break;
71     case dwarf::DW_OP_LLVM_fragment:
72       Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
73       break;
74     case dwarf::DW_OP_deref:
75       Location.LoadChain.push_back(Offset);
76       Offset = 0;
77       break;
78     default:
79       return None;
80     }
81     ++Op;
82   }
83 
84   // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE
85   // instruction.
86   // FIXME: Replace these with DIExpression.
87   if (Instruction.isIndirectDebugValue())
88     Location.LoadChain.push_back(Offset);
89 
90   return Location;
91 }
92 
93 DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
94 
95 // Each LexicalScope has first instruction and last instruction to mark
96 // beginning and end of a scope respectively. Create an inverse map that list
97 // scopes starts (and ends) with an instruction. One instruction may start (or
98 // end) multiple scopes. Ignore scopes that are not reachable.
99 void DebugHandlerBase::identifyScopeMarkers() {
100   SmallVector<LexicalScope *, 4> WorkList;
101   WorkList.push_back(LScopes.getCurrentFunctionScope());
102   while (!WorkList.empty()) {
103     LexicalScope *S = WorkList.pop_back_val();
104 
105     const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
106     if (!Children.empty())
107       WorkList.append(Children.begin(), Children.end());
108 
109     if (S->isAbstractScope())
110       continue;
111 
112     for (const InsnRange &R : S->getRanges()) {
113       assert(R.first && "InsnRange does not have first instruction!");
114       assert(R.second && "InsnRange does not have second instruction!");
115       requestLabelBeforeInsn(R.first);
116       requestLabelAfterInsn(R.second);
117     }
118   }
119 }
120 
121 // Return Label preceding the instruction.
122 MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) {
123   MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
124   assert(Label && "Didn't insert label before instruction");
125   return Label;
126 }
127 
128 // Return Label immediately following the instruction.
129 MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
130   return LabelsAfterInsn.lookup(MI);
131 }
132 
133 /// If this type is derived from a base type then return base type size.
134 uint64_t DebugHandlerBase::getBaseTypeSize(const DIType *Ty) {
135   assert(Ty);
136   const DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty);
137   if (!DDTy)
138     return Ty->getSizeInBits();
139 
140   unsigned Tag = DDTy->getTag();
141 
142   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
143       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
144       Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
145     return DDTy->getSizeInBits();
146 
147   DIType *BaseType = DDTy->getBaseType();
148 
149   if (!BaseType)
150     return 0;
151 
152   // If this is a derived type, go ahead and get the base type, unless it's a
153   // reference then it's just the size of the field. Pointer types have no need
154   // of this since they're a different type of qualification on the type.
155   if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
156       BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
157     return Ty->getSizeInBits();
158 
159   return getBaseTypeSize(BaseType);
160 }
161 
162 static bool hasDebugInfo(const MachineModuleInfo *MMI,
163                          const MachineFunction *MF) {
164   if (!MMI->hasDebugInfo())
165     return false;
166   auto *SP = MF->getFunction().getSubprogram();
167   if (!SP)
168     return false;
169   assert(SP->getUnit());
170   auto EK = SP->getUnit()->getEmissionKind();
171   if (EK == DICompileUnit::NoDebug)
172     return false;
173   return true;
174 }
175 
176 void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
177   PrevInstBB = nullptr;
178 
179   if (!Asm || !hasDebugInfo(MMI, MF)) {
180     skippedNonDebugFunction();
181     return;
182   }
183 
184   // Grab the lexical scopes for the function, if we don't have any of those
185   // then we're not going to be able to do anything.
186   LScopes.initialize(*MF);
187   if (LScopes.empty()) {
188     beginFunctionImpl(MF);
189     return;
190   }
191 
192   // Make sure that each lexical scope will have a begin/end label.
193   identifyScopeMarkers();
194 
195   // Calculate history for local variables.
196   assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
197   assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
198   calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
199                             DbgValues, DbgLabels);
200   if (TrimVarLocs)
201     DbgValues.trimLocationRanges(*MF, LScopes);
202   LLVM_DEBUG(DbgValues.dump());
203 
204   // Request labels for the full history.
205   for (const auto &I : DbgValues) {
206     const auto &Entries = I.second;
207     if (Entries.empty())
208       continue;
209 
210     auto IsDescribedByReg = [](const MachineInstr *MI) {
211       return MI->getDebugOperand(0).isReg() && MI->getDebugOperand(0).getReg();
212     };
213 
214     // The first mention of a function argument gets the CurrentFnBegin label,
215     // so arguments are visible when breaking at function entry.
216     //
217     // We do not change the label for values that are described by registers,
218     // as that could place them above their defining instructions. We should
219     // ideally not change the labels for constant debug values either, since
220     // doing that violates the ranges that are calculated in the history map.
221     // However, we currently do not emit debug values for constant arguments
222     // directly at the start of the function, so this code is still useful.
223     const DILocalVariable *DIVar =
224         Entries.front().getInstr()->getDebugVariable();
225     if (DIVar->isParameter() &&
226         getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
227       if (!IsDescribedByReg(Entries.front().getInstr()))
228         LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin();
229       if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
230         // Mark all non-overlapping initial fragments.
231         for (auto I = Entries.begin(); I != Entries.end(); ++I) {
232           if (!I->isDbgValue())
233             continue;
234           const DIExpression *Fragment = I->getInstr()->getDebugExpression();
235           if (std::any_of(Entries.begin(), I,
236                           [&](DbgValueHistoryMap::Entry Pred) {
237                             return Pred.isDbgValue() &&
238                                    Fragment->fragmentsOverlap(
239                                        Pred.getInstr()->getDebugExpression());
240                           }))
241             break;
242           // The code that generates location lists for DWARF assumes that the
243           // entries' start labels are monotonically increasing, and since we
244           // don't change the label for fragments that are described by
245           // registers, we must bail out when encountering such a fragment.
246           if (IsDescribedByReg(I->getInstr()))
247             break;
248           LabelsBeforeInsn[I->getInstr()] = Asm->getFunctionBegin();
249         }
250       }
251     }
252 
253     for (const auto &Entry : Entries) {
254       if (Entry.isDbgValue())
255         requestLabelBeforeInsn(Entry.getInstr());
256       else
257         requestLabelAfterInsn(Entry.getInstr());
258     }
259   }
260 
261   // Ensure there is a symbol before DBG_LABEL.
262   for (const auto &I : DbgLabels) {
263     const MachineInstr *MI = I.second;
264     requestLabelBeforeInsn(MI);
265   }
266 
267   PrevInstLoc = DebugLoc();
268   PrevLabel = Asm->getFunctionBegin();
269   beginFunctionImpl(MF);
270 }
271 
272 void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
273   if (!MMI->hasDebugInfo())
274     return;
275 
276   assert(CurMI == nullptr);
277   CurMI = MI;
278 
279   // Insert labels where requested.
280   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
281       LabelsBeforeInsn.find(MI);
282 
283   // No label needed.
284   if (I == LabelsBeforeInsn.end())
285     return;
286 
287   // Label already assigned.
288   if (I->second)
289     return;
290 
291   if (!PrevLabel) {
292     PrevLabel = MMI->getContext().createTempSymbol();
293     Asm->OutStreamer->emitLabel(PrevLabel);
294   }
295   I->second = PrevLabel;
296 }
297 
298 void DebugHandlerBase::endInstruction() {
299   if (!MMI->hasDebugInfo())
300     return;
301 
302   assert(CurMI != nullptr);
303   // Don't create a new label after DBG_VALUE and other instructions that don't
304   // generate code.
305   if (!CurMI->isMetaInstruction()) {
306     PrevLabel = nullptr;
307     PrevInstBB = CurMI->getParent();
308   }
309 
310   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
311       LabelsAfterInsn.find(CurMI);
312   CurMI = nullptr;
313 
314   // No label needed.
315   if (I == LabelsAfterInsn.end())
316     return;
317 
318   // Label already assigned.
319   if (I->second)
320     return;
321 
322   // We need a label after this instruction.
323   if (!PrevLabel) {
324     PrevLabel = MMI->getContext().createTempSymbol();
325     Asm->OutStreamer->emitLabel(PrevLabel);
326   }
327   I->second = PrevLabel;
328 }
329 
330 void DebugHandlerBase::endFunction(const MachineFunction *MF) {
331   if (hasDebugInfo(MMI, MF))
332     endFunctionImpl(MF);
333   DbgValues.clear();
334   DbgLabels.clear();
335   LabelsBeforeInsn.clear();
336   LabelsAfterInsn.clear();
337 }
338 
339 void DebugHandlerBase::beginBasicBlock(const MachineBasicBlock &MBB) {
340   if (!MBB.isBeginSection())
341     return;
342 
343   PrevLabel = MBB.getSymbol();
344 }
345 
346 void DebugHandlerBase::endBasicBlock(const MachineBasicBlock &MBB) {
347   if (!MBB.isEndSection())
348     return;
349 
350   PrevLabel = nullptr;
351 }
352