Go to the documentation of this file.
26 #define DEBUG_TYPE "dwarfdebug"
37 emitOp(dwarf::DW_OP_constu);
43 assert(DwarfReg >= 0 &&
"invalid negative dwarf register number");
45 "location description already locked down");
48 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
50 emitOp(dwarf::DW_OP_regx, Comment);
56 assert(DwarfReg >= 0 &&
"invalid negative dwarf register number");
59 emitOp(dwarf::DW_OP_breg0 + DwarfReg);
61 emitOp(dwarf::DW_OP_bregx);
68 emitOp(dwarf::DW_OP_fbreg);
76 const unsigned SizeOfByte = 8;
78 emitOp(dwarf::DW_OP_bit_piece);
82 emitOp(dwarf::DW_OP_piece);
83 unsigned ByteSize = SizeInBits / SizeOfByte;
86 this->OffsetInBits += SizeInBits;
156 CurSubReg.
set(Offset, Offset + Size);
160 if (Offset < MaxSize && CurSubReg.
test(Coverage)) {
164 -1, Offset - CurPos,
"no DWARF register encoding"));
165 if (Offset == 0 && Size >= MaxSize)
169 Reg, std::min<unsigned>(Size, MaxSize - Offset),
"sub-register"));
172 Coverage.
set(Offset, Offset + Size);
173 CurPos = Offset + Size;
181 -1,
RegSize - CurPos,
"no DWARF register encoding"));
187 emitOp(dwarf::DW_OP_stack_value);
193 emitOp(dwarf::DW_OP_consts);
207 unsigned Size =
Value.getBitWidth();
213 while (Offset < Size) {
215 if (Offset == 0 && Size <= 64)
227 if (NumBytes == 4 || NumBytes == 8 ) {
229 emitOp(dwarf::DW_OP_implicit_value);
238 for (
int i = 0;
i < NumBytes; ++
i) {
246 dbgs() <<
"Skipped DW_OP_implicit_value creation for ConstantFP of size: "
253 unsigned FragmentOffsetInBits) {
255 if (!
addMachineReg(
TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
260 bool HasComplexExpression =
false;
261 auto Op = ExprCursor.
peek();
263 HasComplexExpression =
true;
294 if (
Reg.DwarfRegNo >= 0)
297 if (
RegSize > FragmentInfo->SizeInBits)
309 emitOp(dwarf::DW_OP_stack_value);
315 auto NextOp = ExprCursor.
peek();
325 return Op.getOp() == dwarf::DW_OP_stack_value;
335 LLVM_DEBUG(
dbgs() <<
"TODO: giving up on debug information due to "
336 "multi-register usage.\n");
344 int SignedOffset = 0;
345 assert(!
Reg.isSubRegister() &&
"full register expected");
349 if (
Op && (
Op->getOp() == dwarf::DW_OP_plus_uconst)) {
352 if (Offset <= IntMax) {
353 SignedOffset = Offset;
361 if (
Op &&
Op->getOp() == dwarf::DW_OP_constu) {
365 if (
N &&
N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
366 SignedOffset = Offset;
368 }
else if (
N &&
N->getOp() == dwarf::DW_OP_minus &&
370 SignedOffset = -
static_cast<int64_t
>(Offset);
383 auto NextOp = ExprCursor.
peek();
408 auto Op = ExprCursor.
take();
413 "Can currently only emit entry values covering a single operation");
425 emitOp(
CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
446 "Began emitting entry value block before cancelling entry value");
456 unsigned I = 0,
E =
CU.ExprRefedBaseTypes.size();
458 if (
CU.ExprRefedBaseTypes[
I].BitSize == BitSize &&
459 CU.ExprRefedBaseTypes[
I].Encoding == Encoding)
463 CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
471 auto Op = ExprCursor.
take();
472 switch (
Op->getOp()) {
473 case dwarf::DW_OP_deref:
500 auto Op = ExprCursor.take();
503 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
506 }
else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
507 addBReg(OpNum - dwarf::DW_OP_breg0,
Op->getArg(0));
513 if (!InsertArg(
Op->getArg(0), ExprCursor)) {
519 unsigned SizeInBits =
Op->getArg(1);
520 unsigned FragmentOffset =
Op->getArg(0);
548 case dwarf::DW_OP_plus_uconst:
550 emitOp(dwarf::DW_OP_plus_uconst);
553 case dwarf::DW_OP_plus:
554 case dwarf::DW_OP_minus:
555 case dwarf::DW_OP_mul:
556 case dwarf::DW_OP_div:
557 case dwarf::DW_OP_mod:
558 case dwarf::DW_OP_or:
559 case dwarf::DW_OP_and:
560 case dwarf::DW_OP_xor:
561 case dwarf::DW_OP_shl:
562 case dwarf::DW_OP_shr:
563 case dwarf::DW_OP_shra:
564 case dwarf::DW_OP_lit0:
565 case dwarf::DW_OP_not:
566 case dwarf::DW_OP_dup:
567 case dwarf::DW_OP_push_object_address:
568 case dwarf::DW_OP_over:
571 case dwarf::DW_OP_deref:
578 emitOp(dwarf::DW_OP_deref);
580 case dwarf::DW_OP_constu:
584 case dwarf::DW_OP_consts:
586 emitOp(dwarf::DW_OP_consts);
590 unsigned BitSize =
Op->getArg(0);
593 emitOp(dwarf::DW_OP_convert);
602 if (PrevConvertOp && PrevConvertOp->
getArg(0) < BitSize) {
603 if (Encoding == dwarf::DW_ATE_signed)
605 else if (Encoding == dwarf::DW_ATE_unsigned)
607 PrevConvertOp =
None;
614 case dwarf::DW_OP_stack_value:
617 case dwarf::DW_OP_swap:
619 emitOp(dwarf::DW_OP_swap);
621 case dwarf::DW_OP_xderef:
623 emitOp(dwarf::DW_OP_xderef);
625 case dwarf::DW_OP_deref_size:
626 emitOp(dwarf::DW_OP_deref_size);
632 case dwarf::DW_OP_regx:
633 emitOp(dwarf::DW_OP_regx);
636 case dwarf::DW_OP_bregx:
637 emitOp(dwarf::DW_OP_bregx);
679 "overlapping or duplicate fragments");
688 emitOp(dwarf::DW_OP_constu);
691 emitOp(dwarf::DW_OP_lit0);
694 emitOp(dwarf::DW_OP_constu);
703 if (FromBits / 7 < 1+1+1+1+1) {
705 emitOp(dwarf::DW_OP_constu);
713 emitOp(dwarf::DW_OP_lit1);
714 emitOp(dwarf::DW_OP_constu);
717 emitOp(dwarf::DW_OP_lit1);
718 emitOp(dwarf::DW_OP_minus);
724 emitOp(dwarf::DW_OP_WASM_location);
unsigned SubRegisterSizeInBits
Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
void addFBReg(int Offset)
Emit DW_OP_fbreg <Offset>.
This is an optimization pass for GlobalISel generic memory operations.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void emitConstu(uint64_t Value)
Emit a normalized unsigned constant.
void addShr(unsigned ShiftBy)
Emit a shift-right dwarf operation.
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
virtual void emitSigned(int64_t Value)=0
Emit a raw signed value.
int getDwarfRegNum(MCRegister RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
Reg
All possible values of the reg field in the ModR/M byte.
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Optional< uint8_t > TagOffset
unsigned getBitWidth() const
Return the number of bits in the APInt.
A lightweight wrapper around an expression operand.
SmallVector< Register, 2 > DwarfRegs
The register location, if any.
Optional< DIExpression::FragmentInfo > getFragmentInfo() const
Retrieve the fragment information, if any.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
bool test(unsigned Idx) const
unsigned const TargetRegisterInfo * TRI
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
void finalizeEntryValue()
Finalize an entry value by emitting its size operand, and committing the DWARF block which has been e...
bool isMemoryLocation() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isImplicitLocation() const
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits)
Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed to represent a subregister.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, llvm::Register MachineReg)=0
Return whether the given machine register is the frame register in the current function.
virtual void emitData1(uint8_t Value)=0
void setEntryValueFlags(const MachineLocation &Loc)
Lock this down to become an entry value location.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
uint64_t getArg(unsigned I) const
Get an argument to the operand.
unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding)
Return the index of a base type with the given properties and create one if necessary.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
void emitLegacySExt(unsigned FromBits)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
void finalize()
This needs to be called last to commit any pending changes.
uint64_t OffsetInBits
Current Fragment Offset in Bits.
static bool isMemoryLocation(DIExpressionCursor ExprCursor)
Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void consume(unsigned N)
Consume N operations.
unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
void setMemoryLocationKind()
Lock this down to become a memory location description.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
uint64_t getZExtValue() const
Get zero extended value.
APInt bitcastToAPInt() const
void cancelEntryValue()
Cancel the emission of an entry value.
unsigned SavedLocationKind
An efficient, type-erasing, non-owning reference to a callable.
virtual void emitBaseTypeRef(uint64_t Idx)=0
@ DW_OP_LLVM_entry_value
Only used in LLVM metadata.
virtual void emitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
void maskSubRegister()
Add masking operations to stencil out a subregister.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSuperRegIterator enumerates all super-registers of Reg.
void addBReg(int DwarfReg, int Offset)
Emit a DW_OP_breg operation.
void addSignedConstant(int64_t Value)
Emit a signed constant.
Class for arbitrary precision integers.
bool isUnknownLocation() const
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
bool isEntryValue() const
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
Optional< DIExpression::ExprOperand > peekNext() const
Return the next operation.
static Register createRegister(int RegNo, const char *Comment)
Create a full register, no extra DW_OP_piece operators necessary.
Optional< DIExpression::ExprOperand > peek() const
Return the current operation.
Wrapper class representing virtual and physical registers.
static Optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
bool IsEmittingEntryValue
Whether we are currently emitting an entry value operation.
bool isRegisterLocation() const
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
bool isFragment() const
Return whether this is a piece of an aggregate variable.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
virtual void emitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
This class is intended to be used as a driving class for all asm writers.
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
static Register createSubRegister(int RegNo, unsigned SizeInBits, const char *Comment)
Create a subregister that needs a DW_OP_piece operator with SizeInBits.
MCSubRegIterator enumerates all sub-registers of Reg.
void addAnd(unsigned Mask)
Emit a bitwise and dwarf operation.
Holds a DIExpression and keeps track of how many operands have been consumed so far.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
void emitLegacyZExt(unsigned FromBits)
Align max(MaybeAlign Lhs, Align Rhs)
const DataLayout & getDataLayout() const
Return information about data layout.
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
LLVM Value Representation.
void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
void addStackValue()
Emit a DW_OP_stack_value, if supported.
void addReg(int DwarfReg, const char *Comment=nullptr)
Emit a DW_OP_reg operation.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
Optional< DIExpression::ExprOperand > take()
Consume one operation.
unsigned SubRegisterOffsetInBits
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.