Skip to content

Commit

Permalink
[DebugInfo][NFC] Add new MachineOperand type and change DBG_INSTR_REF…
Browse files Browse the repository at this point in the history
… syntax

This patch makes two notable changes to the MIR debug info representation,
which result in different MIR output but identical final DWARF output (NFC
w.r.t. the full compilation). The two changes are:

  * The introduction of a new MachineOperand type, MO_DbgInstrRef, which
    consists of two unsigned numbers that are used to index an instruction
    and an output operand within that instruction, having a meaning
    identical to first two operands of the current DBG_INSTR_REF
    instruction. This operand is only used in DBG_INSTR_REF (see below).
  * A change in syntax for the DBG_INSTR_REF instruction, shuffling the
    operands to make it resemble DBG_VALUE_LIST instead of DBG_VALUE,
    and replacing the first two operands with a single MO_DbgInstrRef-type
    operand.

This patch is the first of a set that will allow DBG_INSTR_REF
instructions to refer to multiple machine locations in the same manner
as DBG_VALUE_LIST.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D129372
  • Loading branch information
SLTozer committed Jan 6, 2023
1 parent bdf7da2 commit e10e936
Show file tree
Hide file tree
Showing 82 changed files with 471 additions and 376 deletions.
23 changes: 19 additions & 4 deletions llvm/docs/MIRLangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ is preferred.
Machine Operands
----------------

There are seventeen different kinds of machine operands, and all of them can be
There are eighteen different kinds of machine operands, and all of them can be
serialized.

Immediate Operands
Expand Down Expand Up @@ -736,6 +736,19 @@ The syntax is:
EH_LABEL <mcsymbol Ltmp1>
Debug Instruction Reference Operands
^^^^^^^^^^^^^^^^^

A debug instruction reference operand is a pair of indices, referring to an
instruction and an operand within that instruction respectively; see
:ref:`Instruction referencing locations <instruction-referencing-locations>`.

The example below uses a reference to Instruction 1, Operand 0:

.. code-block:: text
DBG_INSTR_REF !123, !DIExpression(), dbg-instr-ref(1, 0), debug-location !456
CFIIndex Operands
^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -886,6 +899,8 @@ variable. The second operand (``IsIndirect``) is deprecated and to be deleted.
All additional qualifiers for the variable location should be made through the
expression metadata.

.. _instruction-referencing-locations:

Instruction referencing locations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -898,16 +913,16 @@ instruction number and operand number. Consider the example below:
.. code-block:: text
$rbp = MOV64ri 0, debug-instr-number 1, debug-location !12
DBG_INSTR_REF 1, 0, !123, !DIExpression(), debug-location !456
DBG_INSTR_REF !123, !DIExpression(), dbg-instr-ref(1, 0), debug-location !456
Instruction numbers are directly attached to machine instructions with an
optional ``debug-instr-number`` attachment, before the optional
``debug-location`` attachment. The value defined in ``$rbp`` in the code
above would be identified by the pair ``<1, 0>``.

The first two operands of the ``DBG_INSTR_REF`` above record the instruction
The 3rd operand of the ``DBG_INSTR_REF`` above records the instruction
and operand number ``<1, 0>``, identifying the value defined by the ``MOV64ri``.
The additional operands to ``DBG_INSTR_REF`` are identical to ``DBG_VALUE``,
The first two operands to ``DBG_INSTR_REF`` are identical to ``DBG_VALUE_LIST``,
and the ``DBG_INSTR_REF`` s position records where the variable takes on the
designated value in the same way.

Expand Down
17 changes: 9 additions & 8 deletions llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,17 +661,17 @@ class MachineInstr
/// Returns a range over all operands that are used to determine the variable
/// location for this DBG_VALUE instruction.
iterator_range<mop_iterator> debug_operands() {
assert(isDebugValue() && "Must be a debug value instruction.");
return isDebugValueList()
? make_range(operands_begin() + 2, operands_end())
: make_range(operands_begin(), operands_begin() + 1);
assert((isDebugValueLike()) && "Must be a debug value instruction.");
return isNonListDebugValue()
? make_range(operands_begin(), operands_begin() + 1)
: make_range(operands_begin() + 2, operands_end());
}
/// \copydoc debug_operands()
iterator_range<const_mop_iterator> debug_operands() const {
assert(isDebugValue() && "Must be a debug value instruction.");
return isDebugValueList()
? make_range(operands_begin() + 2, operands_end())
: make_range(operands_begin(), operands_begin() + 1);
assert((isDebugValueLike()) && "Must be a debug value instruction.");
return isNonListDebugValue()
? make_range(operands_begin(), operands_begin() + 1)
: make_range(operands_begin() + 2, operands_end());
}
/// Returns a range over all explicit operands that are register definitions.
/// Implicit definition are not included!
Expand Down Expand Up @@ -1270,6 +1270,7 @@ class MachineInstr
}
bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
bool isDebugRef() const { return getOpcode() == TargetOpcode::DBG_INSTR_REF; }
bool isDebugValueLike() const { return isDebugValue() || isDebugRef(); }
bool isDebugPHI() const { return getOpcode() == TargetOpcode::DBG_PHI; }
bool isDebugInstr() const {
return isDebugValue() || isDebugLabel() || isDebugRef() || isDebugPHI();
Expand Down
23 changes: 4 additions & 19 deletions llvm/include/llvm/CodeGen/MachineInstrBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ class MachineInstrBuilder {

const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
assert((MI->isDebugValue() ? static_cast<bool>(MI->getDebugVariable())
: true) &&
assert((MI->isDebugValueLike() ? static_cast<bool>(MI->getDebugVariable())
: true) &&
"first MDNode argument of a DBG_VALUE not a variable");
assert((MI->isDebugLabel() ? static_cast<bool>(MI->getDebugLabel())
: true) &&
Expand Down Expand Up @@ -484,13 +484,6 @@ MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL,
Register Reg, const MDNode *Variable,
const MDNode *Expr);

/// This version of the builder builds a DBG_VALUE intrinsic
/// for a MachineOperand.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
const MachineOperand &MO, const MDNode *Variable,
const MDNode *Expr);

/// This version of the builder builds a DBG_VALUE or DBG_VALUE_LIST intrinsic
/// for a MachineOperand.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL,
Expand All @@ -507,16 +500,8 @@ MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
Register Reg, const MDNode *Variable,
const MDNode *Expr);

/// This version of the builder builds a DBG_VALUE intrinsic
/// for a machine operand and inserts it at position I.
MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
MachineOperand &MO, const MDNode *Variable,
const MDNode *Expr);

/// This version of the builder builds a DBG_VALUE or DBG_VALUE_LIST intrinsic
/// for a machine operand and inserts it at position I.
/// This version of the builder builds a DBG_VALUE, DBG_INSTR_REF, or
/// DBG_VALUE_LIST intrinsic for a machine operand and inserts it at position I.
MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
Expand Down
39 changes: 38 additions & 1 deletion llvm/include/llvm/CodeGen/MachineOperand.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class MachineOperand {
MO_IntrinsicID, ///< Intrinsic ID for ISel
MO_Predicate, ///< Generic predicate for ISel
MO_ShuffleMask, ///< Other IR Constant for ISel (shuffle masks)
MO_Last = MO_ShuffleMask
MO_DbgInstrRef, ///< Integer indices referring to an instruction+operand
MO_Last = MO_DbgInstrRef
};

private:
Expand Down Expand Up @@ -184,6 +185,11 @@ class MachineOperand {
MachineOperand *Next;
} Reg;

struct { // For MO_DbgInstrRef.
unsigned InstrIdx;
unsigned OpIdx;
} InstrRef;

/// OffsetedInfo - This struct contains the offset and an object identifier.
/// this represent the object as with an optional offset from it.
struct {
Expand Down Expand Up @@ -347,6 +353,7 @@ class MachineOperand {
/// isMetadata - Tests if this is a MO_Metadata operand.
bool isMetadata() const { return OpKind == MO_Metadata; }
bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
bool isDbgInstrRef() const { return OpKind == MO_DbgInstrRef; }
bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
bool isIntrinsicID() const { return OpKind == MO_IntrinsicID; }
bool isPredicate() const { return OpKind == MO_Predicate; }
Expand Down Expand Up @@ -584,6 +591,16 @@ class MachineOperand {
return Contents.Sym;
}

unsigned getInstrRefInstrIndex() const {
assert(isDbgInstrRef() && "Wrong MachineOperand accessor");
return Contents.InstrRef.InstrIdx;
}

unsigned getInstrRefOpIndex() const {
assert(isDbgInstrRef() && "Wrong MachineOperand accessor");
return Contents.InstrRef.OpIdx;
}

unsigned getCFIIndex() const {
assert(isCFIIndex() && "Wrong MachineOperand accessor");
return Contents.CFIIndex;
Expand Down Expand Up @@ -695,6 +712,15 @@ class MachineOperand {
Contents.MD = MD;
}

void setInstrRefInstrIndex(unsigned InstrIdx) {
assert(isDbgInstrRef() && "Wrong MachineOperand mutator");
Contents.InstrRef.InstrIdx = InstrIdx;
}
void setInstrRefOpIndex(unsigned OpIdx) {
assert(isDbgInstrRef() && "Wrong MachineOperand mutator");
Contents.InstrRef.OpIdx = OpIdx;
}

void setMBB(MachineBasicBlock *MBB) {
assert(isMBB() && "Wrong MachineOperand mutator");
Contents.MBB = MBB;
Expand Down Expand Up @@ -763,6 +789,10 @@ class MachineOperand {
void ChangeToTargetIndex(unsigned Idx, int64_t Offset,
unsigned TargetFlags = 0);

/// Replace this operand with an Instruction Reference.
void ChangeToDbgInstrRef(unsigned InstrIdx, unsigned OpIdx,
unsigned TargetFlags = 0);

/// ChangeToRegister - Replace this operand with a new register operand of
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
Expand Down Expand Up @@ -919,6 +949,13 @@ class MachineOperand {
return Op;
}

static MachineOperand CreateDbgInstrRef(unsigned InstrIdx, unsigned OpIdx) {
MachineOperand Op(MachineOperand::MO_DbgInstrRef);
Op.Contents.InstrRef.InstrIdx = InstrIdx;
Op.Contents.InstrRef.OpIdx = OpIdx;
return Op;
}

static MachineOperand CreateCFIIndex(unsigned CFIIndex) {
MachineOperand Op(MachineOperand::MO_CFIIndex);
Op.Contents.CFIIndex = CFIIndex;
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1429,8 +1429,8 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
if (!VTracker && !TTracker)
return false;

unsigned InstNo = MI.getOperand(0).getImm();
unsigned OpNo = MI.getOperand(1).getImm();
unsigned InstNo = MI.getDebugOperand(0).getInstrRefInstrIndex();
unsigned OpNo = MI.getDebugOperand(0).getInstrRefOpIndex();

const DILocalVariable *Var = MI.getDebugVariable();
const DIExpression *Expr = MI.getDebugExpression();
Expand Down Expand Up @@ -2119,7 +2119,7 @@ bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) {
/// \param MI A previously unprocessed debug instruction to analyze for
/// fragment usage.
void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) {
assert(MI.isDebugValue() || MI.isDebugRef());
assert(MI.isDebugValueLike());
DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),
MI.getDebugLoc()->getInlinedAt());
FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
Expand Down Expand Up @@ -2224,7 +2224,7 @@ void InstrRefBasedLDV::produceMLocTransferFunction(
process(MI, nullptr, nullptr);

// Also accumulate fragment map.
if (MI.isDebugValue() || MI.isDebugRef())
if (MI.isDebugValueLike())
accumulateFragmentMap(MI);

// Create a map from the instruction number (if present) to the
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ class VLocTracker {

void defVar(const MachineInstr &MI, const DbgValueProperties &Properties,
const SmallVectorImpl<DbgOpID> &DebugOps) {
assert(MI.isDebugValue() || MI.isDebugRef());
assert(MI.isDebugValueLike());
DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
MI.getDebugLoc()->getInlinedAt());
DbgValue Rec = (DebugOps.size() > 0)
Expand Down
10 changes: 7 additions & 3 deletions llvm/lib/CodeGen/LiveDebugVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,12 +876,16 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {

MachineBasicBlock::iterator LDVImpl::handleDebugInstr(MachineInstr &MI,
SlotIndex Idx) {
assert(MI.isDebugValue() || MI.isDebugRef() || MI.isDebugPHI());
assert(MI.isDebugValueLike() || MI.isDebugPHI());

// In instruction referencing mode, there should be no DBG_VALUE instructions
// that refer to virtual registers. They might still refer to constants.
if (MI.isDebugValue())
assert(!MI.getOperand(0).isReg() || !MI.getOperand(0).getReg().isVirtual());
if (MI.isDebugValueLike())
assert(none_of(MI.debug_operands(),
[](const MachineOperand &MO) {
return MO.isReg() && MO.getReg().isVirtual();
}) &&
"MIs should not refer to Virtual Registers in InstrRef mode.");

// Unlink the instruction, store it in the debug instructions collection.
auto NextInst = std::next(MI.getIterator());
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRParser/MILexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("nofpexcept", MIToken::kw_nofpexcept)
.Case("debug-location", MIToken::kw_debug_location)
.Case("debug-instr-number", MIToken::kw_debug_instr_number)
.Case("dbg-instr-ref", MIToken::kw_dbg_instr_ref)
.Case("same_value", MIToken::kw_cfi_same_value)
.Case("offset", MIToken::kw_cfi_offset)
.Case("rel_offset", MIToken::kw_cfi_rel_offset)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRParser/MILexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct MIToken {
kw_nofpexcept,
kw_debug_location,
kw_debug_instr_number,
kw_dbg_instr_ref,
kw_cfi_same_value,
kw_cfi_offset,
kw_cfi_rel_offset,
Expand Down
34 changes: 34 additions & 0 deletions llvm/lib/CodeGen/MIRParser/MIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ class MIParser {
bool parsePredicateOperand(MachineOperand &Dest);
bool parseShuffleMaskOperand(MachineOperand &Dest);
bool parseTargetIndexOperand(MachineOperand &Dest);
bool parseDbgInstrRefOperand(MachineOperand &Dest);
bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
Expand Down Expand Up @@ -2715,6 +2716,37 @@ bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
return false;
}

bool MIParser::parseDbgInstrRefOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::kw_dbg_instr_ref));

lex();
if (expectAndConsume(MIToken::lparen))
return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");

if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
return error("expected unsigned integer for instruction index");
uint64_t InstrIdx = Token.integerValue().getZExtValue();
assert(InstrIdx <= std::numeric_limits<unsigned>::max() &&
"Instruction reference's instruction index is too large");
lex();

if (expectAndConsume(MIToken::comma))
return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");

if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
return error("expected unsigned integer for operand index");
uint64_t OpIdx = Token.integerValue().getZExtValue();
assert(OpIdx <= std::numeric_limits<unsigned>::max() &&
"Instruction reference's operand index is too large");
lex();

if (expectAndConsume(MIToken::rparen))
return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");

Dest = MachineOperand::CreateDbgInstrRef(InstrIdx, OpIdx);
return false;
}

bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::kw_target_index));
lex();
Expand Down Expand Up @@ -2866,6 +2898,8 @@ bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
return parsePredicateOperand(Dest);
case MIToken::kw_shufflemask:
return parseShuffleMaskOperand(Dest);
case MIToken::kw_dbg_instr_ref:
return parseDbgInstrRefOperand(Dest);
case MIToken::Error:
return true;
case MIToken::Identifier:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
case MachineOperand::MO_IntrinsicID:
case MachineOperand::MO_Predicate:
case MachineOperand::MO_BlockAddress:
case MachineOperand::MO_DbgInstrRef:
case MachineOperand::MO_ShuffleMask: {
unsigned TiedOperandIdx = 0;
if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRVRegNamerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ std::string VRegRenamer::getInstructionOpcodeHash(MachineInstr &MI) {
case MachineOperand::MO_Metadata:
case MachineOperand::MO_MCSymbol:
case MachineOperand::MO_ShuffleMask:
case MachineOperand::MO_DbgInstrRef:
return 0;
}
llvm_unreachable("Unexpected MachineOperandType.");
Expand Down
Loading

0 comments on commit e10e936

Please sign in to comment.