26#define DEBUG_TYPE "dwarfdebug"
32std::optional<DbgVariableLocation>
41 Location.Register =
Instruction.getDebugOperand(0).getReg();
42 Location.FragmentInfo.reset();
58 switch (Op->getOp()) {
59 case dwarf::DW_OP_constu: {
60 int Value = Op->getArg(0);
63 switch (Op->getOp()) {
64 case dwarf::DW_OP_minus:
67 case dwarf::DW_OP_plus:
75 case dwarf::DW_OP_plus_uconst:
79 Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
81 case dwarf::DW_OP_deref:
82 Location.LoadChain.push_back(
Offset);
95 Location.LoadChain.push_back(
Offset);
103 if (M->debug_compile_units().empty())
114 while (!WorkList.
empty()) {
118 if (!Children.empty())
119 WorkList.
append(Children.begin(), Children.end());
125 assert(R.first &&
"InsnRange does not have first instruction!");
126 assert(R.second &&
"InsnRange does not have second instruction!");
136 assert(Label &&
"Didn't insert label before instruction");
154 if (
Tag != dwarf::DW_TAG_member &&
Tag != dwarf::DW_TAG_typedef &&
155 Tag != dwarf::DW_TAG_const_type &&
Tag != dwarf::DW_TAG_volatile_type &&
156 Tag != dwarf::DW_TAG_restrict_type &&
Tag != dwarf::DW_TAG_atomic_type &&
157 Tag != dwarf::DW_TAG_immutable_type)
168 if (
BaseType->getTag() == dwarf::DW_TAG_reference_type ||
169 BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
176 if (isa<DIStringType>(Ty)) {
186 if (
auto *CTy = dyn_cast<DICompositeType>(Ty)) {
187 if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) {
188 if (!(Ty = CTy->getBaseType()))
198 if (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
205 if (
T == dwarf::DW_TAG_pointer_type ||
206 T == dwarf::DW_TAG_ptr_to_member_type ||
207 T == dwarf::DW_TAG_reference_type ||
208 T == dwarf::DW_TAG_rvalue_reference_type)
210 assert(
T == dwarf::DW_TAG_typedef ||
T == dwarf::DW_TAG_const_type ||
211 T == dwarf::DW_TAG_volatile_type ||
212 T == dwarf::DW_TAG_restrict_type ||
T == dwarf::DW_TAG_atomic_type ||
213 T == dwarf::DW_TAG_immutable_type);
214 assert(DTy->getBaseType() &&
"Expected valid base type");
218 auto *BTy = cast<DIBasicType>(Ty);
219 unsigned Encoding = BTy->getEncoding();
220 assert((Encoding == dwarf::DW_ATE_unsigned ||
221 Encoding == dwarf::DW_ATE_unsigned_char ||
222 Encoding == dwarf::DW_ATE_signed ||
223 Encoding == dwarf::DW_ATE_signed_char ||
224 Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
225 Encoding == dwarf::DW_ATE_boolean ||
226 (Ty->
getTag() == dwarf::DW_TAG_unspecified_type &&
227 Ty->
getName() ==
"decltype(nullptr)")) &&
228 "Unsupported encoding");
229 return Encoding == dwarf::DW_ATE_unsigned ||
230 Encoding == dwarf::DW_ATE_unsigned_char ||
231 Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
232 Ty->
getTag() == dwarf::DW_TAG_unspecified_type;
243 auto EK = SP->getUnit()->getEmissionKind();
280 const auto &Entries =
I.second;
286 [](
auto &MO) { return MO.isReg() && MO.getReg(); });
299 Entries.front().getInstr()->getDebugVariable();
302 if (!IsDescribedByReg(Entries.front().getInstr()))
304 if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
306 for (
const auto *
I = Entries.begin();
I != Entries.end(); ++
I) {
307 if (!
I->isDbgValue())
309 const DIExpression *Fragment =
I->getInstr()->getDebugExpression();
310 if (std::any_of(Entries.begin(),
I,
312 return Pred.isDbgValue() &&
313 Fragment->fragmentsOverlap(
314 Pred.getInstr()->getDebugExpression());
321 if (IsDescribedByReg(
I->getInstr()))
328 for (
const auto &Entry : Entries) {
329 if (Entry.isDbgValue())
415 InstOrdering.
clear();
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 MachineModuleInfo *MMI, const MachineFunction *MF)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class is intended to be used as a driving class for all asm writers.
MCSymbol * getFunctionBegin() const
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
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.
dwarf::Tag getTag() const
StringRef getName() const
uint64_t getSizeInBits() const
Specifies a change in a variable's debug value history.
void trimLocationRanges(const MachineFunction &MF, LexicalScopes &LScopes, const InstructionOrdering &Ordering)
Drop location ranges which exist entirely outside each variable's scope.
LLVM_DUMP_METHOD void dump(StringRef FuncName) const
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.
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.
void initialize(const MachineFunction &MF)
LexicalScope - This class is used to track scope information.
SmallVectorImpl< LexicalScope * > & getChildren()
SmallVectorImpl< InsnRange > & getRanges()
bool isAbstractScope() const
void initialize(const MachineFunction &)
initialize - Scan machine function and constuct lexical scope nest, resets the instance if necessary.
bool empty()
empty - Return true if there is any lexical scope information available.
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
MCSymbol * getEndSymbol() const
Returns the MCSymbol marking the end of this basic block.
bool isEntryBlock() const
Returns true if this is the entry block of the function.
bool isEndSection() const
Returns true if this block ends any section.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
const MachineBasicBlock * getParent() const
bool isMetaInstruction(QueryType Type=IgnoreBundle) const
Return true if this instruction doesn't produce any output in the form of executable instructions.
This class contains meta information specific to a module.
const MCContext & getContext() const
bool hasDebugInfo() const
Returns true if valid debug info is present.
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.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
LLVM Value Representation.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
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)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
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.