1//===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp -------*- C++ -*--===//
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
7//===----------------------------------------------------------------------===//
9// Common functionality for different debug information format backends.
10// LLVM currently supports DWARF and CodeView.
12//===----------------------------------------------------------------------===//
27 #define DEBUG_TYPE "dwarfdebug"
29/// If true, we drop variable location ranges which exist entirely outside the
30/// variable's lexical scope instruction ranges.
33std::optional<DbgVariableLocation>
37 // Variables calculated from multiple locations can't be represented here.
43 Location.FragmentInfo.reset();
44 // We only handle expressions generated by DIExpression::appendOffset,
45 // which doesn't require a full stack machine.
49 // We can handle a DBG_VALUE_LIST iff it has exactly one location operand that
50 // appears exactly once at the start of the expression.
59 switch (
Op->getOp()) {
60 case dwarf::DW_OP_constu: {
64 switch (
Op->getOp()) {
65 case dwarf::DW_OP_minus:
68 case dwarf::DW_OP_plus:
76 case dwarf::DW_OP_plus_uconst:
80 Location.FragmentInfo = {
Op->getArg(1),
Op->getArg(0)};
82 case dwarf::DW_OP_deref:
83 Location.LoadChain.push_back(
Offset);
92 // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE
94 // FIXME: Replace these with DIExpression.
96 Location.LoadChain.push_back(
Offset);
106 if (M->debug_compile_units().empty())
112// Each LexicalScope has first instruction and last instruction to mark
113// beginning and end of a scope respectively. Create an inverse map that list
114// scopes starts (and ends) with an instruction. One instruction may start (or
115// end) multiple scopes. Ignore scopes that are not reachable.
119 while (!WorkList.
empty()) {
123 if (!Children.empty())
124 WorkList.
append(Children.begin(), Children.end());
130 assert(R.first &&
"InsnRange does not have first instruction!");
131 assert(R.second &&
"InsnRange does not have second instruction!");
138// Return Label preceding the instruction.
141 assert(Label &&
"Didn't insert label before instruction");
145// Return Label immediately following the instruction.
150/// If this type is derived from a base type then return base type size.
154 unsigned Tag = Ty->getTag();
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();
172 // If this is a derived type, go ahead and get the base type, unless it's a
173 // reference then it's just the size of the field. Pointer types have no need
174 // of this since they're a different type of qualification on the type.
175 if (
BaseType->getTag() == dwarf::DW_TAG_reference_type ||
176 BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
177 return Ty->getSizeInBits();
184 // Some transformations (e.g. instcombine) may decide to turn a Fortran
185 // character object into an integer, and later ones (e.g. SROA) may
186 // further inject a constant integer in a llvm.dbg.value call to track
187 // the object's value. Here we trust the transformations are doing the
188 // right thing, and treat the constant as unsigned to preserve that value
189 // (i.e. avoid sign extension).
194 Ty = SRTy->getBaseType();
200 if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) {
201 if (!(Ty = CTy->getBaseType()))
202 // FIXME: Enums without a fixed underlying type have unknown signedness
203 // here, leading to incorrectly emitted constants.
206 // (Pieces of) aggregate types that get hacked apart by SROA may be
207 // represented by a constant. Encode them as unsigned bytes.
213 // Encode pointer constants as unsigned bytes. This is used at least for
214 // null pointer constant emission.
215 // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed
216 // here, but accept them for now due to a bug in SROA producing bogus
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)
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");
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;
260 auto EK = SP->getUnit()->getEmissionKind();
274 // Grab the lexical scopes for the function, if we don't have any of those
275 // then we're not going to be able to do anything.
282 // Make sure that each lexical scope will have a begin/end label.
285 // Calculate history for local variables.
290 InstOrdering.initialize(*MF);
295 // Request labels for the full history.
297 const auto &Entries =
I.second;
303 [](
auto &MO) { return MO.isReg() && MO.getReg(); });
306 // The first mention of a function argument gets the CurrentFnBegin label,
307 // so arguments are visible when breaking at function entry.
309 // We do not change the label for values that are described by registers,
310 // as that could place them above their defining instructions. We should
311 // ideally not change the labels for constant debug values either, since
312 // doing that violates the ranges that are calculated in the history map.
313 // However, we currently do not emit debug values for constant arguments
314 // directly at the start of the function, so this code is still useful.
316 Entries.front().getInstr()->getDebugVariable();
319 if (!IsDescribedByReg(Entries.front().getInstr()))
321 if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
322 // Mark all non-overlapping initial fragments.
323 for (
const auto *
I = Entries.begin();
I != Entries.end(); ++
I) {
324 if (!
I->isDbgValue())
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());
334 // The code that generates location lists for DWARF assumes that the
335 // entries' start labels are monotonically increasing, and since we
336 // don't change the label for fragments that are described by
337 // registers, we must bail out when encountering such a fragment.
338 if (IsDescribedByReg(
I->getInstr()))
345 for (
const auto &Entry : Entries) {
346 if (Entry.isDbgValue())
353 // Ensure there is a symbol before DBG_LABEL.
365 if (!
Asm || !
Asm->hasDebugInfo())
371 // Insert labels where requested.
379 // Label already assigned.
391 if (!
Asm || !
Asm->hasDebugInfo())
395 // Don't create a new label after DBG_VALUE and other instructions that don't
397 if (!
CurMI->isMetaInstruction()) {
405 // No label needed or label already assigned.
411 // We need a label after this instruction. With basic block sections, just
412 // use the end symbol of the section if this is the last instruction of the
413 // section. This reduces the need for an additional label and also helps
415 if (
CurMI->getParent()->isEndSection() &&
CurMI->getNextNode() ==
nullptr) {
432 InstOrdering.clear();
437 if (!
MBB.isEntryBlock())
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)
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.
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.
MachineModuleInfo * MMI
Collected machine module information.
void endBasicBlockSection(const MachineBasicBlock &MBB) override
Process the end of a basic-block-section within a function.
void identifyScopeMarkers()
Indentify instructions that are marking the beginning of or ending of a scope.
virtual void skippedNonDebugFunction()
void endFunction(const MachineFunction *MF) override
Gather post-function debug information.
DebugLoc PrevInstLoc
Previous instruction's location information.
void beginFunction(const MachineFunction *MF) override
Gather pre-function debug information.
void endInstruction() override
Process end of an instruction.
~DebugHandlerBase() override
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
DebugHandlerBase(AsmPrinter *A)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
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.
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
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.
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<X> - 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<X> - 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<X> - 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.
MCRegister Register
Base register.