LLVM: lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
24
25using namespace llvm;
26
27#define DEBUG_TYPE "dwarfdebug"
28
29
30
32
33std::optional
37
38 if (Instruction.getNumDebugOperands() != 1)
39 return std::nullopt;
40 if (.getDebugOperand(0).isReg())
41 return std::nullopt;
43 Location.FragmentInfo.reset();
44
45
49
50
52 if (Instruction.getNumDebugOperands() == 1 &&
55 else
56 return std::nullopt;
57 }
59 switch (Op->getOp()) {
60 case dwarf::DW_OP_constu: {
64 switch (Op->getOp()) {
65 case dwarf::DW_OP_minus:
67 break;
68 case dwarf::DW_OP_plus:
70 break;
71 default:
72 continue;
73 }
74 }
75 } break;
76 case dwarf::DW_OP_plus_uconst:
78 break;
80 Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
81 break;
82 case dwarf::DW_OP_deref:
83 Location.LoadChain.push_back(Offset);
85 break;
86 default:
87 return std::nullopt;
88 }
90 }
91
92
93
94
96 Location.LoadChain.push_back(Offset);
97
98 return Location;
99}
100
102
104
106 if (M->debug_compile_units().empty())
107 Asm = nullptr;
108 else
110}
111
112
113
114
115
119 while (!WorkList.empty()) {
121
123 if (!Children.empty())
124 WorkList.append(Children.begin(), Children.end());
125
127 continue;
128
130 assert(R.first && "InsnRange does not have first instruction!");
131 assert(R.second && "InsnRange does not have second instruction!");
134 }
135 }
136}
137
138
141 assert(Label && "Didn't insert label before instruction");
142 return Label;
143}
144
145
149
150
153
154 unsigned Tag = Ty->getTag();
155
156 if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
157 Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
158 Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type &&
159 Tag != dwarf::DW_TAG_immutable_type &&
160 Tag != dwarf::DW_TAG_template_alias)
161 return Ty->getSizeInBits();
162
165 BaseType = DDTy->getBaseType();
167 BaseType = SRTy->getBaseType();
168
170 return 0;
171
172
173
174
175 if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
176 BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
177 return Ty->getSizeInBits();
178
180}
181
184
185
186
187
188
189
190 return true;
191 }
192
194 Ty = SRTy->getBaseType();
195 if (!Ty)
196 return false;
197 }
198
200 if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) {
201 if (!(Ty = CTy->getBaseType()))
202
203
204 return false;
205 } else
206
207
208 return true;
209 }
210
213
214
215
216
217
218 if (T == dwarf::DW_TAG_pointer_type ||
219 T == dwarf::DW_TAG_ptr_to_member_type ||
220 T == dwarf::DW_TAG_reference_type ||
221 T == dwarf::DW_TAG_rvalue_reference_type)
222 return true;
223 assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
224 T == dwarf::DW_TAG_volatile_type ||
225 T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type ||
226 T == dwarf::DW_TAG_immutable_type ||
227 T == dwarf::DW_TAG_template_alias);
228 assert(DTy->getBaseType() && "Expected valid base type");
230 }
231
233 unsigned Encoding = BTy->getEncoding();
234 assert((Encoding == dwarf::DW_ATE_unsigned ||
235 Encoding == dwarf::DW_ATE_unsigned_char ||
236 Encoding == dwarf::DW_ATE_signed ||
237 Encoding == dwarf::DW_ATE_signed_char ||
238 Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
239 Encoding == dwarf::DW_ATE_boolean ||
240 Encoding == dwarf::DW_ATE_complex_float ||
241 Encoding == dwarf::DW_ATE_signed_fixed ||
242 Encoding == dwarf::DW_ATE_unsigned_fixed ||
245 (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
246 Ty->getName() == "decltype(nullptr)")) &&
247 "Unsupported encoding");
248 return Encoding == dwarf::DW_ATE_unsigned ||
249 Encoding == dwarf::DW_ATE_unsigned_char ||
250 Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
251 Encoding == llvm::dwarf::DW_ATE_unsigned_fixed ||
252 Ty->getTag() == dwarf::DW_TAG_unspecified_type;
253}
254
257 if (!SP)
258 return false;
259 assert(SP->getUnit());
260 auto EK = SP->getUnit()->getEmissionKind();
262 return false;
263 return true;
264}
265
268
271 return;
272 }
273
274
275
276 LScopes.scanFunction(*MF);
279 return;
280 }
281
282
284
285
286 assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
287 assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
290 InstOrdering.initialize(*MF);
294
295
297 const auto &Entries = I.second;
298 if (Entries.empty())
299 continue;
300
302 return any_of(MI->debug_operands(),
303 [](auto &MO) { return MO.isReg() && MO.getReg(); });
304 };
305
306
307
308
309
310
311
312
313
314
316 Entries.front().getInstr()->getDebugVariable();
319 if (!IsDescribedByReg(Entries.front().getInstr()))
321 if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
322
323 for (const auto *I = Entries.begin(); I != Entries.end(); ++I) {
324 if (->isDbgValue())
325 continue;
326 const DIExpression *Fragment = I->getInstr()->getDebugExpression();
327 if (std::any_of(Entries.begin(), I,
329 return Pred.isDbgValue() &&
330 Fragment->fragmentsOverlap(
331 Pred.getInstr()->getDebugExpression());
332 }))
333 break;
334
335
336
337
338 if (IsDescribedByReg(I->getInstr()))
339 break;
341 }
342 }
343 }
344
345 for (const auto &Entry : Entries) {
346 if (Entry.isDbgValue())
348 else
350 }
351 }
352
353
357 }
358
362}
363
365 if ( ||
->hasDebugInfo())
366 return;
367
370
371
374
375
377 return;
378
379
380 if (I->second)
381 return;
382
384 PrevLabel = MMI->getContext().createTempSymbol();
386 }
388}
389
391 if ( ||
->hasDebugInfo())
392 return;
393
395
396
397 if (->isMetaInstruction()) {
400 }
401
404
405
408 return;
409 }
410
411
412
413
414
415 if (CurMI->getParent()->isEndSection() && CurMI->getNextNode() == nullptr) {
418 PrevLabel = MMI->getContext().createTempSymbol();
420 }
423}
424
432 InstOrdering.clear();
433}
434
437 if (.isEntryBlock())
439}
440
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static cl::opt< bool > TrimVarLocs("trim-var-locs", cl::Hidden, cl::init(true))
If true, we drop variable location ranges which exist entirely outside the variable's lexical scope i...
static bool hasDebugInfo(const MachineFunction *MF)
Definition DebugHandlerBase.cpp:255
Module.h This file contains the declarations for the Module class.
This class is intended to be used as a driving class for all asm writers.
expr_op_iterator expr_op_begin() const
Visit the elements via ExprOperand wrappers.
expr_op_iterator expr_op_end() const
DILocalScope * getScope() const
Get the local scope for this variable.
Specifies a change in a variable's debug value history.
static bool isUnsignedDIType(const DIType *Ty)
Return true if type encoding is unsigned.
Definition DebugHandlerBase.cpp:182
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
virtual void endFunctionImpl(const MachineFunction *MF)=0
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
Definition DebugHandlerBase.cpp:139
MachineModuleInfo * MMI
Collected machine module information.
void endBasicBlockSection(const MachineBasicBlock &MBB) override
Process the end of a basic-block-section within a function.
Definition DebugHandlerBase.cpp:441
void identifyScopeMarkers()
Indentify instructions that are marking the beginning of or ending of a scope.
Definition DebugHandlerBase.cpp:116
virtual void skippedNonDebugFunction()
void endFunction(const MachineFunction *MF) override
Gather post-function debug information.
Definition DebugHandlerBase.cpp:425
DebugLoc PrevInstLoc
Previous instruction's location information.
void beginFunction(const MachineFunction *MF) override
Gather pre-function debug information.
Definition DebugHandlerBase.cpp:266
void endInstruction() override
Process end of an instruction.
Definition DebugHandlerBase.cpp:390
~DebugHandlerBase() override
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
Definition DebugHandlerBase.cpp:146
DebugHandlerBase(AsmPrinter *A)
Definition DebugHandlerBase.cpp:101
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
Definition DebugHandlerBase.cpp:364
const MachineBasicBlock * PrevInstBB
virtual void beginFunctionImpl(const MachineFunction *MF)=0
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
void beginBasicBlockSection(const MachineBasicBlock &MBB) override
Process the beginning of a new basic-block-section within a function.
Definition DebugHandlerBase.cpp:435
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
DenseMap< const MachineInstr *, MCSymbol * > LabelsBeforeInsn
Maps instruction with label emitted before instruction.
void beginModule(Module *M) override
Definition DebugHandlerBase.cpp:105
DenseMap< const MachineInstr *, MCSymbol * > LabelsAfterInsn
Maps instruction with label emitted after instruction.
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before MI.
const MachineBasicBlock * EpilogBeginBlock
This block includes epilogue instructions.
static uint64_t getBaseTypeSize(const DIType *Ty)
If this type is derived from a base type then return base type size.
Definition DebugHandlerBase.cpp:151
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
DISubprogram * getSubprogram() const
Get the attached subprogram.
This class is used to track scope information.
SmallVectorImpl< LexicalScope * > & getChildren()
SmallVectorImpl< InsnRange > & getRanges()
bool isAbstractScope() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
A Module instance is used to store all the information related to an LLVM module.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
initializer< Ty > init(const Ty &Val)
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
This is an optimization pass for GlobalISel generic memory operations.
void calculateDbgEntityHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &DbgValues, DbgLabelInstrMap &DbgLabels)
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
This is used to track range of instructions with identical lexical scope.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
Represents the location at which a variable is stored.
static std::optional< DbgVariableLocation > extractFromMachineInstruction(const MachineInstr &Instruction)
Extract a VariableLocation from a MachineInstr.
Definition DebugHandlerBase.cpp:34
MCRegister Register
Base register.