27#define DEBUG_TYPE "dwarfdebug"
35 if (
Op.isNonEmitting())
45 else if (
Value == std::numeric_limits<uint64_t>::max()) {
51 emitOp(dwarf::DW_OP_constu);
57 assert(DwarfReg >= 0 &&
"invalid negative dwarf register number");
59 "location description already locked down");
62 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
64 emitOp(dwarf::DW_OP_regx, Comment);
70 assert(DwarfReg >= 0 &&
"invalid negative dwarf register number");
73 emitOp(dwarf::DW_OP_breg0 + DwarfReg);
75 emitOp(dwarf::DW_OP_bregx);
82 emitOp(dwarf::DW_OP_fbreg);
90 const unsigned SizeOfByte = 8;
92 emitOp(dwarf::DW_OP_bit_piece);
96 emitOp(dwarf::DW_OP_piece);
97 unsigned ByteSize = SizeInBits / SizeOfByte;
100 this->OffsetInBits += SizeInBits;
122 int64_t Reg =
TRI.getDwarfRegNumForVirtReg(MachineReg,
false);
130 int64_t Reg =
TRI.getDwarfRegNum(MachineReg,
false);
148 Reg =
TRI.getDwarfRegNum(SR,
false);
150 unsigned Idx =
TRI.getSubRegIndex(SR, MachineReg);
151 unsigned Size =
TRI.getSubRegIdxSize(Idx);
152 unsigned RegOffset =
TRI.getSubRegIdxOffset(Idx);
173 unsigned Idx =
TRI.getSubRegIndex(MachineReg, SR);
174 unsigned Size =
TRI.getSubRegIdxSize(Idx);
175 unsigned Offset =
TRI.getSubRegIdxOffset(Idx);
176 Reg =
TRI.getDwarfRegNum(SR,
false);
191 -1,
Offset - CurPos,
"no DWARF register encoding"));
196 Reg, std::min<unsigned>(
Size, MaxSize -
Offset),
"sub-register"));
208 -1,
RegSize - CurPos,
"no DWARF register encoding"));
214 emitOp(dwarf::DW_OP_stack_value);
221 emitOp(dwarf::DW_OP_lit0);
223 emitOp(dwarf::DW_OP_lit1);
229 emitOp(dwarf::DW_OP_consts);
244 const uint64_t *
Data =
Value.getRawData();
267 "implicit value must be byte-sized");
269 emitOp(dwarf::DW_OP_implicit_value);
277 for (
unsigned I = 0;
I < NumBytes; ++
I)
285 if (NumBytes == 4 || NumBytes == 8 ) {
287 emitOp(dwarf::DW_OP_implicit_value);
296 for (
int i = 0; i < NumBytes; ++i) {
304 dbgs() <<
"Skipped DW_OP_implicit_value creation for ConstantFP of size: "
311 unsigned FragmentOffsetInBits) {
348 if (Reg.DwarfRegNo >= 0)
349 addReg(Reg.DwarfRegNo, Reg.Comment);
362 emitOp(dwarf::DW_OP_stack_value);
376 return Op.getOp() == dwarf::DW_OP_stack_value;
386 LLVM_DEBUG(
dbgs() <<
"TODO: giving up on debug information due to "
387 "multi-register usage.\n");
396 while (
auto Op = ExprCursor.
peek()) {
404 auto Op = ExprCursor.
peek();
406 int SignedOffset = 0;
407 assert(!Reg.isSubRegister() &&
"full register expected");
411 const uint64_t IntMax =
412 static_cast<uint64_t
>(std::numeric_limits<int>::max());
426 if (
N &&
N->getOp() == dwarf::DW_OP_plus &&
Offset <= IntMax) {
429 }
else if (
N &&
N->getOp() == dwarf::DW_OP_minus &&
431 SignedOffset = -
static_cast<int64_t
>(
Offset);
440 addBReg(Reg.DwarfRegNo, SignedOffset);
453 if (
Loc.isIndirect())
459 if (
Loc.isIndirect())
468 auto Op = ExprCursor.
take();
473 "Can currently only emit entry values covering a single operation");
486 emitOp(
CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
507 "Began emitting entry value block before cancelling entry value");
517 unsigned I = 0, E =
CU.ExprRefedBaseTypes.size();
519 if (
CU.ExprRefedBaseTypes[
I].BitSize == BitSize &&
520 CU.ExprRefedBaseTypes[
I].Encoding == Encoding)
524 CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
532 auto Op = ExprCursor.
take();
533 switch (
Op->getOp()) {
534 case dwarf::DW_OP_deref:
548 "unhandled opcode found in expression");
559 std::optional<DIExpression::ConvertOp> PrevConvertOp;
562 auto Op = ExprCursor.take();
563 uint64_t OpNum =
Op->getOp();
565 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
568 }
else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
569 addBReg(OpNum - dwarf::DW_OP_breg0,
Op->getArg(0));
582 unsigned SizeInBits =
Fragment.getSizeInBits();
583 unsigned FragmentOffset =
Fragment.getOffsetInBits();
614 unsigned SizeInBits = Extract.getSizeInBits();
615 unsigned BitOffset = Extract.getOffsetInBits();
616 bool IsSigned = Extract.isSigned();
617 unsigned DerefSize = 0;
620 unsigned PtrSizeInBytes =
CU.getAsmPrinter()->MAI.getCodePointerSize();
626 DerefSize =
alignTo(BitOffset + SizeInBits, 8) / 8;
627 if (DerefSize == PtrSizeInBytes) {
628 emitOp(dwarf::DW_OP_deref);
630 emitOp(dwarf::DW_OP_deref_size);
638 if (!IsSigned && BitOffset == 0) {
639 if (8 * DerefSize == SizeInBits) {
643 emitOp(dwarf::DW_OP_constu);
651 unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);
652 unsigned RightShift = LeftShift + BitOffset;
654 emitOp(dwarf::DW_OP_constu);
659 emitOp(dwarf::DW_OP_constu);
661 emitOp(IsSigned ? dwarf::DW_OP_shra : dwarf::DW_OP_shr);
670 case dwarf::DW_OP_plus_uconst:
672 emitOp(dwarf::DW_OP_plus_uconst);
675 case dwarf::DW_OP_plus:
676 case dwarf::DW_OP_minus:
677 case dwarf::DW_OP_mul:
678 case dwarf::DW_OP_div:
679 case dwarf::DW_OP_mod:
680 case dwarf::DW_OP_or:
681 case dwarf::DW_OP_and:
682 case dwarf::DW_OP_xor:
683 case dwarf::DW_OP_shl:
684 case dwarf::DW_OP_shr:
685 case dwarf::DW_OP_shra:
686 case dwarf::DW_OP_lit0:
687 case dwarf::DW_OP_not:
688 case dwarf::DW_OP_dup:
689 case dwarf::DW_OP_push_object_address:
690 case dwarf::DW_OP_over:
691 case dwarf::DW_OP_rot:
692 case dwarf::DW_OP_eq:
693 case dwarf::DW_OP_ne:
694 case dwarf::DW_OP_gt:
695 case dwarf::DW_OP_ge:
696 case dwarf::DW_OP_lt:
697 case dwarf::DW_OP_le:
698 case dwarf::DW_OP_neg:
699 case dwarf::DW_OP_abs:
702 case dwarf::DW_OP_deref:
709 emitOp(dwarf::DW_OP_deref);
711 case dwarf::DW_OP_constu:
715 case dwarf::DW_OP_consts:
717 emitOp(dwarf::DW_OP_consts);
722 unsigned BitSize = Convert.getBitSize();
726 emitOp(dwarf::DW_OP_convert);
735 if (PrevConvertOp && PrevConvertOp->getBitSize() < BitSize) {
736 if (Encoding == dwarf::DW_ATE_signed)
738 else if (Encoding == dwarf::DW_ATE_unsigned)
740 PrevConvertOp = std::nullopt;
742 PrevConvertOp = Convert;
747 case dwarf::DW_OP_stack_value:
750 case dwarf::DW_OP_swap:
752 emitOp(dwarf::DW_OP_swap);
754 case dwarf::DW_OP_xderef:
756 emitOp(dwarf::DW_OP_xderef);
758 case dwarf::DW_OP_deref_size:
759 emitOp(dwarf::DW_OP_deref_size);
765 case dwarf::DW_OP_regx:
766 emitOp(dwarf::DW_OP_regx);
769 case dwarf::DW_OP_bregx:
770 emitOp(dwarf::DW_OP_bregx);
822 "overlapping or duplicate fragments");
831 emitOp(dwarf::DW_OP_constu);
834 emitOp(dwarf::DW_OP_lit0);
837 emitOp(dwarf::DW_OP_constu);
846 if (FromBits / 7 < 1+1+1+1+1) {
848 emitOp(dwarf::DW_OP_constu);
856 emitOp(dwarf::DW_OP_lit1);
857 emitOp(dwarf::DW_OP_constu);
860 emitOp(dwarf::DW_OP_lit1);
861 emitOp(dwarf::DW_OP_minus);
893 const MCSymbol *Sym =
CU.getAsmPrinter()->getSymbol(GV);
896 : dwarf::DW_OP_GNU_addr_index);
899 emitOp(dwarf::DW_OP_addr);
907 emitOp(dwarf::DW_OP_plus_uconst);
911 emitOp(dwarf::DW_OP_plus);
917 emitOp(dwarf::DW_OP_WASM_location);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isRemainingExpressionComplex(const DIExpressionCursor &ExprCursor)
Return whether the rest of the expression needs the complex register path.
static bool isMemoryLocation(DIExpressionCursor ExprCursor)
Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?
This file contains constants used for implementing Dwarf debug support.
Register const TargetRegisterInfo * TRI
This file implements the SmallBitVector class.
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
LLVM_ABI APInt byteSwap() const
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
This class is intended to be used as a driving class for all asm writers.
const DataLayout & getDataLayout() const
Return information about data layout.
This is an important base class in LLVM.
Holds a DIExpression and keeps track of how many operands have been consumed so far.
std::optional< DIExpression::ExprOperand > peekNext() const
Return the next operation.
std::optional< DIExpression::FragmentInfo > getFragmentInfo() const
Retrieve the fragment information, if any.
std::optional< DIExpression::ExprOperand > peek() const
Return the current operation.
void consume(unsigned N)
Consume N operations.
std::optional< DIExpression::ExprOperand > take()
Consume one operation.
A lightweight wrapper around an expression operand.
LLVM_ABI 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.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
Collects and handles dwarf debug information.
AddressPool & getAddressPool()
virtual void emitRelocatedAddress(const MCSymbol *Sym)
Emit a relocated address operand.
void addAnd(unsigned Mask)
Emit a bitwise and dwarf operation.
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
bool canAddGlobalAddress() const
Whether addGlobalAddress() can spell a global's address at all.
virtual void emitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
bool isUnknownLocation() const
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
uint64_t OffsetInBits
Current Fragment Offset in Bits.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, llvm::Register MachineReg)=0
Return whether the given machine register is the frame register in the current function.
bool addGlobalAddress(const GlobalValue *GV, int64_t Offset)
Emit the address of GV displaced by Offset as an implicit location description, i....
void finalize()
This needs to be called last to commit any pending changes.
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...
void emitLegacySExt(unsigned FromBits)
void cancelEntryValue()
Cancel the emission of an entry value.
bool isRegisterLocation() const
void setMemoryLocationKind()
Lock this down to become a memory location description.
virtual void emitBaseTypeRef(uint64_t Idx)=0
virtual void emitData1(uint8_t Value)=0
bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
unsigned SavedLocationKind
bool addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
std::optional< uint8_t > TagOffset
bool isImplicitLocation() const
virtual bool supportsRelocatedAddress() const
Whether a relocated address operand, as needed by DW_OP_addr, can be emitted into this output form.
virtual void emitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
void maskSubRegister()
Emit shift/mask operations for the pending subregister.
SmallVector< Register, 2 > DwarfRegs
The register location, if any.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addStackValue()
Emit a DW_OP_stack_value, if supported.
bool usesAddressPool() const
Whether a global's address is spelled through the address pool, whose index is plain data,...
void finalizeEntryValue()
Finalize an entry value by emitting its size operand, and committing the DWARF block which has been e...
bool isMemoryLocation() const
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
unsigned SubRegisterSizeInBits
Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
void addFBReg(int64_t Offset)
Emit DW_OP_fbreg <Offset>.
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.
bool isEntryValue() const
unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding)
Return the index of a base type with the given properties and create one if necessary.
void addImplicitValue(const APInt &Value, const AsmPrinter &AP)
Emit an implicit value.
void addSignedConstant(int64_t Value)
Emit a signed constant.
void emitLegacyZExt(unsigned FromBits)
bool IsEmittingEntryValue
Whether we are currently emitting an entry value operation.
virtual void emitSigned(int64_t Value)=0
Emit a raw signed value.
void addReg(int64_t DwarfReg, const char *Comment=nullptr)
Emit a DW_OP_reg operation.
unsigned SubRegisterOffsetInBits
void setEntryValueFlags(const MachineLocation &Loc)
Lock this down to become an entry value location.
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
void addShr(unsigned ShiftBy)
Emit a shift-right dwarf operation.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
void emitConstu(uint64_t Value)
Emit a normalized unsigned constant.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
void addBReg(int64_t DwarfReg, int64_t Offset)
Emit a DW_OP_breg operation.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool subsetOf(const SmallBitVector &RHS) const
Check if This is a subset of RHS.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
MCRegisterClass TargetRegisterClass
Holds information about all subregisters comprising a register location.
static Register createRegister(int64_t RegNo, const char *Comment)
Create a full register, no extra DW_OP_piece operators necessary.
static Register createSubRegister(int64_t RegNo, unsigned SizeInBits, const char *Comment)
Create a subregister that needs a DW_OP_piece operator with SizeInBits.