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