Skip to content

Commit c383f4d

Browse files
committed
[DebugInfo] Allow non-stack_value variadic expressions and use in DBG_INSTR_REF
Prior to this patch, variadic DIExpressions (i.e. ones that contain DW_OP_LLVM_arg) could only be created by salvaging debug values to create stack value expressions, resulting in a DBG_VALUE_LIST being created. As of the previous patch in this patch stack, DBG_INSTR_REF's syntax has been changed to match DBG_VALUE_LIST in preparation for supporting variadic expressions. This patch adds some minor changes needed to allow variadic expressions that aren't stack values to exist, and allows variadic expressions that are trivially reduceable to non-variadic expressions to be handled similarly to non-variadic expressions. Reviewed by: jmorse Differential Revision: https://reviews.llvm.org/D133926
1 parent 2f66c89 commit c383f4d

File tree

64 files changed

+438
-310
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+438
-310
lines changed

llvm/docs/MIRLangRef.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ The example below uses a reference to Instruction 1, Operand 0:
747747

748748
.. code-block:: text
749749
750-
DBG_INSTR_REF !123, !DIExpression(), dbg-instr-ref(1, 0), debug-location !456
750+
DBG_INSTR_REF !123, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !456
751751
752752
CFIIndex Operands
753753
^^^^^^^^^^^^^^^^^
@@ -913,7 +913,7 @@ instruction number and operand number. Consider the example below:
913913
.. code-block:: text
914914
915915
$rbp = MOV64ri 0, debug-instr-number 1, debug-location !12
916-
DBG_INSTR_REF !123, !DIExpression(), dbg-instr-ref(1, 0), debug-location !456
916+
DBG_INSTR_REF !123, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !456
917917
918918
Instruction numbers are directly attached to machine instructions with an
919919
optional ``debug-instr-number`` attachment, before the optional

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,6 +2794,17 @@ class DIExpression : public MDNode {
27942794
/// it cannot be a simple register location.
27952795
bool isComplex() const;
27962796

2797+
/// Return whether the evaluated expression makes use of a single location at
2798+
/// the start of the expression, i.e. if it contains only a single
2799+
/// DW_OP_LLVM_arg op as its first operand, or if it contains none.
2800+
bool isSingleLocationExpression() const;
2801+
2802+
/// If \p Expr is a non-variadic expression (i.e. one that does not contain
2803+
/// DW_OP_LLVM_arg), returns \p Expr converted to variadic form by adding a
2804+
/// leading [DW_OP_LLVM_arg, 0] to the expression; otherwise returns \p Expr.
2805+
static const DIExpression *
2806+
convertToVariadicExpression(const DIExpression *Expr);
2807+
27972808
/// Inserts the elements of \p Expr into \p Ops modified to a canonical form,
27982809
/// which uses DW_OP_LLVM_arg (i.e. is a variadic expression) and folds the
27992810
/// implied derefence from the \p IsIndirect flag into the expression. This

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,10 +1132,16 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
11321132
OS << " <- ";
11331133

11341134
const DIExpression *Expr = MI->getDebugExpression();
1135+
if (Expr->getNumElements() && Expr->isSingleLocationExpression() &&
1136+
Expr->expr_op_begin()->getOp() == dwarf::DW_OP_LLVM_arg) {
1137+
SmallVector<uint64_t> Ops(
1138+
make_range(Expr->elements_begin() + 2, Expr->elements_end()));
1139+
Expr = DIExpression::get(Expr->getContext(), Ops);
1140+
}
11351141
if (Expr->getNumElements()) {
11361142
OS << '[';
11371143
ListSeparator LS;
1138-
for (auto Op : Expr->expr_ops()) {
1144+
for (auto &Op : Expr->expr_ops()) {
11391145
OS << LS << dwarf::OperationEncodingString(Op.getOp());
11401146
for (unsigned I = 0; I < Op.getNumArgs(); ++I)
11411147
OS << ' ' << Op.getArg(I);

llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,7 @@ class DbgValueLoc {
119119
public:
120120
DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
121121
: Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
122-
IsVariadic(true) {
123-
#ifndef NDEBUG
124-
// Currently, DBG_VALUE_VAR expressions must use stack_value.
125-
assert(Expr && Expr->isValid() &&
126-
is_contained(Locs, dwarf::DW_OP_stack_value));
127-
#endif
128-
}
122+
IsVariadic(true) {}
129123

130124
DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
131125
bool IsVariadic)
@@ -136,10 +130,6 @@ class DbgValueLoc {
136130
!any_of(Locs, [](auto LE) { return LE.isLocation(); }));
137131
if (!IsVariadic) {
138132
assert(ValueLocEntries.size() == 1);
139-
} else {
140-
// Currently, DBG_VALUE_VAR expressions must use stack_value.
141-
assert(Expr && Expr->isValid() &&
142-
is_contained(Expr->getElements(), dwarf::DW_OP_stack_value));
143133
}
144134
#endif
145135
}

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ MLocTracker::emitLoc(const SmallVectorImpl<ResolvedDbgOp> &DbgOps,
12621262
// the pointer to the variable loaded off the stack with a deref:
12631263
assert(!Expr->isImplicit());
12641264
OffsetOps.push_back(dwarf::DW_OP_deref);
1265-
} else if (UseDerefSize && !Properties.IsVariadic) {
1265+
} else if (UseDerefSize && Expr->isSingleLocationExpression()) {
12661266
// TODO: Figure out how to handle deref size issues for variadic
12671267
// values.
12681268
// We're loading a value off the stack that's not the same size as the
@@ -1271,7 +1271,7 @@ MLocTracker::emitLoc(const SmallVectorImpl<ResolvedDbgOp> &DbgOps,
12711271
OffsetOps.push_back(dwarf::DW_OP_deref_size);
12721272
OffsetOps.push_back(DerefSizeInBytes);
12731273
StackValue = true;
1274-
} else if (Expr->isComplex()) {
1274+
} else if (Expr->isComplex() || Properties.IsVariadic) {
12751275
// A variable with no size ambiguity, but with extra elements in it's
12761276
// expression. Manually dereference the stack location.
12771277
OffsetOps.push_back(dwarf::DW_OP_deref);
@@ -1590,7 +1590,7 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
15901590
// about it. The rest of this LiveDebugValues implementation acts exactly the
15911591
// same for DBG_INSTR_REFs as DBG_VALUEs (just, the former can refer to values
15921592
// that aren't immediately available).
1593-
DbgValueProperties Properties(Expr, false, false);
1593+
DbgValueProperties Properties(Expr, false, true);
15941594
SmallVector<DbgOpID> DbgOpIDs;
15951595
if (NewID)
15961596
DbgOpIDs.push_back(DbgOpStore.insert(*NewID));
@@ -1634,7 +1634,7 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
16341634
NewID->getInst() > CurInst) {
16351635
SmallVector<DbgOp> UseBeforeDefLocs;
16361636
UseBeforeDefLocs.push_back(*NewID);
1637-
TTracker->addUseBeforeDef(V, {MI.getDebugExpression(), false, false},
1637+
TTracker->addUseBeforeDef(V, {MI.getDebugExpression(), false, true},
16381638
UseBeforeDefLocs, NewID->getInst());
16391639
}
16401640

llvm/lib/CodeGen/LiveDebugVariables.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ class DbgVariableValue {
138138
// Turn this into an undef debug value list; right now, the simplest form
139139
// of this is an expression with one arg, and an undef debug operand.
140140
Expression =
141-
DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0,
142-
dwarf::DW_OP_stack_value});
141+
DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0});
143142
if (auto FragmentInfoOpt = Expr.getFragmentInfo())
144143
Expression = *DIExpression::createFragmentExpression(
145144
Expression, FragmentInfoOpt->OffsetInBits,

llvm/lib/CodeGen/MachineFunction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "llvm/IR/BasicBlock.h"
4545
#include "llvm/IR/Constant.h"
4646
#include "llvm/IR/DataLayout.h"
47+
#include "llvm/IR/DebugInfoMetadata.h"
4748
#include "llvm/IR/DerivedTypes.h"
4849
#include "llvm/IR/Function.h"
4950
#include "llvm/IR/GlobalValue.h"
@@ -1153,6 +1154,10 @@ void MachineFunction::finalizeDebugInstrRefs() {
11531154
MakeUndefDbgValue(MI);
11541155
continue;
11551156
}
1157+
// Only convert Expr to variadic form when we're sure we're emitting a
1158+
// complete instruction reference.
1159+
MI.getDebugExpressionOp().setMetadata(
1160+
DIExpression::convertToVariadicExpression(MI.getDebugExpression()));
11561161

11571162
assert(Reg.isVirtual());
11581163
MachineInstr &DefMI = *RegInfo->def_instr_begin(Reg);

llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
767767
assert(!SD->isVariadic());
768768
SDDbgOperand DbgOperand = SD->getLocationOps()[0];
769769
MDNode *Var = SD->getVariable();
770-
DIExpression *Expr = (DIExpression*)SD->getExpression();
770+
const DIExpression *Expr = (DIExpression *)SD->getExpression();
771771
DebugLoc DL = SD->getDebugLoc();
772772
const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF);
773773

@@ -851,6 +851,10 @@ InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
851851
}
852852
assert(OperandIdx < DefMI->getNumOperands());
853853

854+
// Only convert Expr to variadic form when we're sure we're emitting a
855+
// complete instruction reference.
856+
if (!SD->isVariadic())
857+
Expr = DIExpression::convertToVariadicExpression(Expr);
854858
// Make the DBG_INSTR_REF refer to that instruction, and that operand.
855859
unsigned InstrNum = DefMI->getDebugInstrNum();
856860
SmallVector<MachineOperand, 1> MOs(

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,12 +1358,15 @@ bool DIExpression::isValid() const {
13581358
break;
13591359
}
13601360
case dwarf::DW_OP_LLVM_entry_value: {
1361-
// An entry value operator must appear at the beginning and the number of
1362-
// operations it cover can currently only be 1, because we support only
1363-
// entry values of a simple register location. One reason for this is that
1364-
// we currently can't calculate the size of the resulting DWARF block for
1365-
// other expressions.
1366-
return I->get() == expr_op_begin()->get() && I->getArg(0) == 1;
1361+
// An entry value operator must appear at the beginning or immediately
1362+
// following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
1363+
// currently only be 1, because we support only entry values of a simple
1364+
// register location. One reason for this is that we currently can't
1365+
// calculate the size of the resulting DWARF block for other expressions.
1366+
auto FirstOp = expr_op_begin();
1367+
if (FirstOp->getOp() == dwarf::DW_OP_LLVM_arg && FirstOp->getArg(0) == 0)
1368+
++FirstOp;
1369+
return I->get() == FirstOp->get() && I->getArg(0) == 1;
13671370
}
13681371
case dwarf::DW_OP_LLVM_implicit_pointer:
13691372
case dwarf::DW_OP_LLVM_convert:
@@ -1432,6 +1435,7 @@ bool DIExpression::isComplex() const {
14321435
switch (It.getOp()) {
14331436
case dwarf::DW_OP_LLVM_tag_offset:
14341437
case dwarf::DW_OP_LLVM_fragment:
1438+
case dwarf::DW_OP_LLVM_arg:
14351439
continue;
14361440
default:
14371441
return true;
@@ -1441,6 +1445,36 @@ bool DIExpression::isComplex() const {
14411445
return false;
14421446
}
14431447

1448+
bool DIExpression::isSingleLocationExpression() const {
1449+
if (!isValid())
1450+
return false;
1451+
1452+
if (getNumElements() == 0)
1453+
return true;
1454+
1455+
auto ExprOpBegin = expr_ops().begin();
1456+
auto ExprOpEnd = expr_ops().end();
1457+
if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg)
1458+
++ExprOpBegin;
1459+
1460+
return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) {
1461+
return Op.getOp() == dwarf::DW_OP_LLVM_arg;
1462+
});
1463+
}
1464+
1465+
const DIExpression *
1466+
DIExpression::convertToVariadicExpression(const DIExpression *Expr) {
1467+
if (any_of(Expr->expr_ops(), [](auto ExprOp) {
1468+
return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
1469+
}))
1470+
return Expr;
1471+
SmallVector<uint64_t> NewOps;
1472+
NewOps.reserve(Expr->getNumElements() + 2);
1473+
NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
1474+
NewOps.append(Expr->elements_begin(), Expr->elements_end());
1475+
return DIExpression::get(Expr->getContext(), NewOps);
1476+
}
1477+
14441478
void DIExpression::canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops,
14451479
const DIExpression *Expr,
14461480
bool IsIndirect) {
@@ -1596,10 +1630,21 @@ DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
15961630

15971631
SmallVector<uint64_t, 8> NewOps;
15981632
for (auto Op : Expr->expr_ops()) {
1633+
// A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
1634+
if (StackValue) {
1635+
if (Op.getOp() == dwarf::DW_OP_stack_value)
1636+
StackValue = false;
1637+
else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
1638+
NewOps.push_back(dwarf::DW_OP_stack_value);
1639+
StackValue = false;
1640+
}
1641+
}
15991642
Op.appendToVector(NewOps);
16001643
if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo)
16011644
NewOps.insert(NewOps.end(), Ops.begin(), Ops.end());
16021645
}
1646+
if (StackValue)
1647+
NewOps.push_back(dwarf::DW_OP_stack_value);
16031648

16041649
return DIExpression::get(Expr->getContext(), NewOps);
16051650
}

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,8 +1908,8 @@ void llvm::salvageDebugInfoForDbgValues(
19081908
DII->addVariableLocationOps(AdditionalValues, SalvagedExpr);
19091909
} else {
19101910
// Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is
1911-
// currently only valid for stack value expressions. Do not salvage
1912-
// using DIArgList for dbg.assign yet. FIXME: support this.
1911+
// not currently supported in those instructions. Do not salvage using
1912+
// DIArgList for dbg.assign yet. FIXME: support this.
19131913
// Also do not salvage if the resulting DIArgList would contain an
19141914
// unreasonably large number of values.
19151915
DII->setKillLocation();

0 commit comments

Comments
 (0)