27#define DEBUG_TYPE "dwarfdebug"
33std::optional<DbgVariableLocation>
43 Location.FragmentInfo.reset();
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:
81 Location.FragmentInfo = {Fragment.getSizeInBits(),
82 Fragment.getOffsetInBits()};
85 case dwarf::DW_OP_deref:
86 Location.LoadChain.push_back(
Offset);
99 Location.LoadChain.push_back(
Offset);
109 if (M->debug_compile_units().empty())
122 while (!WorkList.
empty()) {
126 if (!Children.empty())
127 WorkList.
append(Children.begin(), Children.end());
133 assert(R.first &&
"InsnRange does not have first instruction!");
134 assert(R.second &&
"InsnRange does not have second instruction!");
144 assert(Label &&
"Didn't insert label before instruction");
157 unsigned Tag = Ty->getTag();
159 if (
Tag != dwarf::DW_TAG_member &&
Tag != dwarf::DW_TAG_typedef &&
160 Tag != dwarf::DW_TAG_const_type &&
Tag != dwarf::DW_TAG_volatile_type &&
161 Tag != dwarf::DW_TAG_restrict_type &&
Tag != dwarf::DW_TAG_atomic_type &&
162 Tag != dwarf::DW_TAG_immutable_type &&
163 Tag != dwarf::DW_TAG_template_alias)
164 return Ty->getSizeInBits();
178 if (
BaseType->getTag() == dwarf::DW_TAG_reference_type ||
179 BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
180 return Ty->getSizeInBits();
197 Ty = SRTy->getBaseType();
203 if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) {
204 if (!(Ty = CTy->getBaseType()))
221 if (
T == dwarf::DW_TAG_pointer_type ||
222 T == dwarf::DW_TAG_ptr_to_member_type ||
223 T == dwarf::DW_TAG_reference_type ||
224 T == dwarf::DW_TAG_rvalue_reference_type)
226 assert(
T == dwarf::DW_TAG_typedef ||
T == dwarf::DW_TAG_const_type ||
227 T == dwarf::DW_TAG_volatile_type ||
228 T == dwarf::DW_TAG_restrict_type ||
T == dwarf::DW_TAG_atomic_type ||
229 T == dwarf::DW_TAG_immutable_type ||
230 T == dwarf::DW_TAG_template_alias);
231 assert(DTy->getBaseType() &&
"Expected valid base type");
236 unsigned Encoding = BTy->getEncoding();
237 assert((Encoding == dwarf::DW_ATE_unsigned ||
238 Encoding == dwarf::DW_ATE_unsigned_char ||
239 Encoding == dwarf::DW_ATE_signed ||
240 Encoding == dwarf::DW_ATE_signed_char ||
241 Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
242 Encoding == dwarf::DW_ATE_boolean ||
243 Encoding == dwarf::DW_ATE_complex_float ||
244 Encoding == dwarf::DW_ATE_signed_fixed ||
245 Encoding == dwarf::DW_ATE_unsigned_fixed ||
248 (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
249 Ty->getName() ==
"decltype(nullptr)")) &&
250 "Unsupported encoding");
251 return Encoding == dwarf::DW_ATE_unsigned ||
252 Encoding == dwarf::DW_ATE_unsigned_char ||
253 Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
254 Encoding == llvm::dwarf::DW_ATE_unsigned_fixed ||
255 Ty->getTag() == dwarf::DW_TAG_unspecified_type;
263 auto EK = SP->getUnit()->getEmissionKind();
293 InstOrdering.initialize(*MF);
300 const auto &Entries =
I.second;
306 [](
auto &MO) { return MO.isReg() && MO.getReg(); });
319 Entries.front().getInstr()->getDebugVariable();
322 if (!IsDescribedByReg(Entries.front().getInstr()))
324 if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
326 for (
const auto *
I = Entries.begin();
I != Entries.end(); ++
I) {
327 if (!
I->isDbgValue())
329 const DIExpression *Fragment =
I->getInstr()->getDebugExpression();
330 if (std::any_of(Entries.begin(),
I,
332 return Pred.isDbgValue() &&
333 Fragment->fragmentsOverlap(
334 Pred.getInstr()->getDebugExpression());
341 if (IsDescribedByReg(
I->getInstr()))
348 for (
const auto &Entry : Entries) {
349 if (Entry.isDbgValue())
368 if (!
Asm || !
Asm->hasDebugInfo())
393 if (!
Asm || !
Asm->hasDebugInfo())
399 if (!
CurMI->isMetaInstruction()) {
416 if (
CurMI->getParent()->isEndSection() &&
CurMI->getNextNode() ==
nullptr) {
433 InstOrdering.clear();
438 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.
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.
LLVM_ABI 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 LLVM_ABI std::optional< DbgVariableLocation > extractFromMachineInstruction(const MachineInstr &Instruction)
Extract a VariableLocation from a MachineInstr.
MCRegister Register
Base register.