Skip to content

Commit 9525af7

Browse files
committed
[DebugInfo] Support representation of multiple location operands in SDDbgValue
This patch modifies the class that represents debug values during ISel, SDDbgValue, to support multiple location operands (to represent a dbg.value that uses a DIArgList). Part of this class's functionality has been split off into a new class, SDDbgOperand. The new class SDDbgOperand represents a single value, corresponding to an SSA value or MachineOperand in the IR and MIR respectively. Members of SDDbgValue that were previously related to that specific value (as opposed to the variable or DIExpression), such as the Kind enum, have been moved to SDDbgOperand. SDDbgValue now contains an array of SDDbgOperand instead, allowing it to hold more than one of these values. All changes outside SDDbgValue are simply updates to use the new interface. Differential Revision: https://reviews.llvm.org/D88585
1 parent 7cdcb4a commit 9525af7

File tree

5 files changed

+187
-93
lines changed

5 files changed

+187
-93
lines changed

llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -701,11 +701,12 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
701701
if (auto *InstrRef = EmitDbgInstrRef(SD, VRBaseMap))
702702
return InstrRef;
703703

704-
if (SD->getKind() == SDDbgValue::FRAMEIX) {
704+
SDDbgOperand SDOperand = SD->getLocationOps()[0];
705+
if (SDOperand.getKind() == SDDbgOperand::FRAMEIX) {
705706
// Stack address; this needs to be lowered in target-dependent fashion.
706707
// EmitTargetCodeForFrameDebugValue is responsible for allocation.
707708
auto FrameMI = BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE))
708-
.addFrameIndex(SD->getFrameIx());
709+
.addFrameIndex(SDOperand.getFrameIx());
709710
if (SD->isIndirect())
710711
// Push [fi + 0] onto the DIExpression stack.
711712
FrameMI.addImm(0);
@@ -717,9 +718,9 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
717718
// Otherwise, we're going to create an instruction here.
718719
const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
719720
MachineInstrBuilder MIB = BuildMI(*MF, DL, II);
720-
if (SD->getKind() == SDDbgValue::SDNODE) {
721-
SDNode *Node = SD->getSDNode();
722-
SDValue Op = SDValue(Node, SD->getResNo());
721+
if (SDOperand.getKind() == SDDbgOperand::SDNODE) {
722+
SDNode *Node = SDOperand.getSDNode();
723+
SDValue Op = SDValue(Node, SDOperand.getResNo());
723724
// It's possible we replaced this SDNode with other(s) and therefore
724725
// didn't generate code for it. It's better to catch these cases where
725726
// they happen and transfer the debug info, but trying to guarantee that
@@ -731,10 +732,10 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
731732
else
732733
AddOperand(MIB, Op, (*MIB).getNumOperands(), &II, VRBaseMap,
733734
/*IsDebug=*/true, /*IsClone=*/false, /*IsCloned=*/false);
734-
} else if (SD->getKind() == SDDbgValue::VREG) {
735-
MIB.addReg(SD->getVReg(), RegState::Debug);
736-
} else if (SD->getKind() == SDDbgValue::CONST) {
737-
const Value *V = SD->getConst();
735+
} else if (SDOperand.getKind() == SDDbgOperand::VREG) {
736+
MIB.addReg(SDOperand.getVReg(), RegState::Debug);
737+
} else if (SDOperand.getKind() == SDDbgOperand::CONST) {
738+
const Value *V = SDOperand.getConst();
738739
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
739740
if (CI->getBitWidth() > 64)
740741
MIB.addCImm(CI);
@@ -770,14 +771,18 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
770771
MachineInstr *
771772
InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
772773
DenseMap<SDValue, Register> &VRBaseMap) {
774+
// No support for instruction references for variadic values yet.
775+
if (SD->isVariadic())
776+
return nullptr;
777+
SDDbgOperand DbgOperand = SD->getLocationOps()[0];
773778
// Instruction referencing is still in a prototype state: for now we're only
774779
// going to support SDNodes within a block. Copies are not supported, they
775780
// don't actually define a value.
776-
if (SD->getKind() != SDDbgValue::SDNODE)
781+
if (DbgOperand.getKind() != SDDbgOperand::SDNODE)
777782
return nullptr;
778783

779-
SDNode *Node = SD->getSDNode();
780-
SDValue Op = SDValue(Node, SD->getResNo());
784+
SDNode *Node = DbgOperand.getSDNode();
785+
SDValue Op = SDValue(Node, DbgOperand.getResNo());
781786
DenseMap<SDValue, Register>::iterator I = VRBaseMap.find(Op);
782787
if (I==VRBaseMap.end())
783788
return nullptr; // undef value: let EmitDbgValue produce a DBG_VALUE $noreg.

llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h

Lines changed: 119 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,94 +25,161 @@ class SDNode;
2525
class Value;
2626
class raw_ostream;
2727

28-
/// Holds the information from a dbg_value node through SDISel.
29-
/// We do not use SDValue here to avoid including its header.
30-
class SDDbgValue {
28+
/// Holds the information for a single machine location through SDISel; either
29+
/// an SDNode, a constant, a stack location, or a virtual register.
30+
class SDDbgOperand {
3131
public:
32-
enum DbgValueKind {
33-
SDNODE = 0, ///< Value is the result of an expression.
34-
CONST = 1, ///< Value is a constant.
35-
FRAMEIX = 2, ///< Value is contents of a stack location.
36-
VREG = 3 ///< Value is a virtual register.
32+
enum Kind {
33+
SDNODE = 0, ///< Value is the result of an expression.
34+
CONST = 1, ///< Value is a constant.
35+
FRAMEIX = 2, ///< Value is contents of a stack location.
36+
VREG = 3 ///< Value is a virtual register.
3737
};
38+
Kind getKind() const { return kind; }
39+
40+
/// Returns the SDNode* for a register ref
41+
SDNode *getSDNode() const {
42+
assert(kind == SDNODE);
43+
return u.s.Node;
44+
}
45+
46+
/// Returns the ResNo for a register ref
47+
unsigned getResNo() const {
48+
assert(kind == SDNODE);
49+
return u.s.ResNo;
50+
}
51+
52+
/// Returns the Value* for a constant
53+
const Value *getConst() const {
54+
assert(kind == CONST);
55+
return u.Const;
56+
}
57+
58+
/// Returns the FrameIx for a stack object
59+
unsigned getFrameIx() const {
60+
assert(kind == FRAMEIX);
61+
return u.FrameIx;
62+
}
63+
64+
/// Returns the Virtual Register for a VReg
65+
unsigned getVReg() const {
66+
assert(kind == VREG);
67+
return u.VReg;
68+
}
69+
70+
static SDDbgOperand fromNode(SDNode *Node, unsigned ResNo) {
71+
return SDDbgOperand(Node, ResNo);
72+
}
73+
static SDDbgOperand fromFrameIdx(unsigned FrameIdx) {
74+
return SDDbgOperand(FrameIdx, FRAMEIX);
75+
}
76+
static SDDbgOperand fromVReg(unsigned VReg) {
77+
return SDDbgOperand(VReg, VREG);
78+
}
79+
static SDDbgOperand fromConst(const Value *Const) {
80+
return SDDbgOperand(Const);
81+
}
82+
83+
bool operator!=(const SDDbgOperand &Other) const { return !(*this == Other); }
84+
bool operator==(const SDDbgOperand &Other) const {
85+
if (kind != Other.kind)
86+
return false;
87+
switch (kind) {
88+
case SDNODE:
89+
return getSDNode() == Other.getSDNode() && getResNo() == Other.getResNo();
90+
case CONST:
91+
return getConst() == Other.getConst();
92+
case VREG:
93+
return getVReg() == Other.getVReg();
94+
case FRAMEIX:
95+
return getFrameIx() == Other.getFrameIx();
96+
default:
97+
llvm_unreachable("unknown kind");
98+
}
99+
}
100+
38101
private:
102+
Kind kind;
39103
union {
40104
struct {
41-
SDNode *Node; ///< Valid for expressions.
42-
unsigned ResNo; ///< Valid for expressions.
105+
SDNode *Node; ///< Valid for expressions.
106+
unsigned ResNo; ///< Valid for expressions.
43107
} s;
44-
const Value *Const; ///< Valid for constants.
45-
unsigned FrameIx; ///< Valid for stack objects.
46-
unsigned VReg; ///< Valid for registers.
108+
const Value *Const; ///< Valid for constants.
109+
unsigned FrameIx; ///< Valid for stack objects.
110+
unsigned VReg; ///< Valid for registers.
47111
} u;
48-
DIVariable *Var;
49-
DIExpression *Expr;
50-
DebugLoc DL;
51-
unsigned Order;
52-
enum DbgValueKind kind;
53-
bool IsIndirect;
54-
bool Invalid = false;
55-
bool Emitted = false;
56112

57-
public:
58113
/// Constructor for non-constants.
59-
SDDbgValue(DIVariable *Var, DIExpression *Expr, SDNode *N, unsigned R,
60-
bool indir, DebugLoc dl, unsigned O)
61-
: Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(indir) {
62-
kind = SDNODE;
114+
SDDbgOperand(SDNode *N, unsigned R) : kind(SDNODE) {
63115
u.s.Node = N;
64116
u.s.ResNo = R;
65117
}
66-
67118
/// Constructor for constants.
68-
SDDbgValue(DIVariable *Var, DIExpression *Expr, const Value *C, DebugLoc dl,
69-
unsigned O)
70-
: Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(false) {
71-
kind = CONST;
72-
u.Const = C;
73-
}
74-
119+
SDDbgOperand(const Value *C) : kind(CONST) { u.Const = C; }
75120
/// Constructor for virtual registers and frame indices.
76-
SDDbgValue(DIVariable *Var, DIExpression *Expr, unsigned VRegOrFrameIdx,
77-
bool IsIndirect, DebugLoc DL, unsigned Order,
78-
enum DbgValueKind Kind)
79-
: Var(Var), Expr(Expr), DL(DL), Order(Order), IsIndirect(IsIndirect) {
121+
SDDbgOperand(unsigned VRegOrFrameIdx, Kind Kind) : kind(Kind) {
80122
assert((Kind == VREG || Kind == FRAMEIX) &&
81123
"Invalid SDDbgValue constructor");
82-
kind = Kind;
83124
if (kind == VREG)
84125
u.VReg = VRegOrFrameIdx;
85126
else
86127
u.FrameIx = VRegOrFrameIdx;
87128
}
129+
};
130+
131+
/// Holds the information from a dbg_value node through SDISel.
132+
/// We do not use SDValue here to avoid including its header.
133+
class SDDbgValue {
134+
public:
135+
// FIXME: These SmallVector sizes were chosen without any kind of performance
136+
// testing.
137+
using LocOpVector = SmallVector<SDDbgOperand, 2>;
138+
using SDNodeVector = SmallVector<SDNode *, 2>;
139+
140+
private:
141+
LocOpVector LocationOps;
142+
SDNodeVector SDNodes;
143+
DIVariable *Var;
144+
DIExpression *Expr;
145+
DebugLoc DL;
146+
unsigned Order;
147+
bool IsIndirect;
148+
bool IsVariadic;
149+
bool Invalid = false;
150+
bool Emitted = false;
88151

89-
/// Returns the kind.
90-
DbgValueKind getKind() const { return kind; }
152+
public:
153+
SDDbgValue(DIVariable *Var, DIExpression *Expr, ArrayRef<SDDbgOperand> L,
154+
ArrayRef<SDNode *> Dependencies, bool IsIndirect, DebugLoc DL,
155+
unsigned O, bool IsVariadic)
156+
: LocationOps(L.begin(), L.end()),
157+
SDNodes(Dependencies.begin(), Dependencies.end()), Var(Var), Expr(Expr),
158+
DL(DL), Order(O), IsIndirect(IsIndirect), IsVariadic(IsVariadic) {
159+
assert(IsVariadic || L.size() == 1);
160+
assert(!(IsVariadic && IsIndirect));
161+
}
91162

92163
/// Returns the DIVariable pointer for the variable.
93164
DIVariable *getVariable() const { return Var; }
94165

95166
/// Returns the DIExpression pointer for the expression.
96167
DIExpression *getExpression() const { return Expr; }
97168

98-
/// Returns the SDNode* for a register ref
99-
SDNode *getSDNode() const { assert (kind==SDNODE); return u.s.Node; }
169+
ArrayRef<SDDbgOperand> getLocationOps() const { return LocationOps; }
100170

101-
/// Returns the ResNo for a register ref
102-
unsigned getResNo() const { assert (kind==SDNODE); return u.s.ResNo; }
171+
LocOpVector copyLocationOps() const { return LocationOps; }
103172

104-
/// Returns the Value* for a constant
105-
const Value *getConst() const { assert (kind==CONST); return u.Const; }
173+
// Returns the SDNodes which this SDDbgValue depends on.
174+
ArrayRef<SDNode *> getSDNodes() const { return SDNodes; }
106175

107-
/// Returns the FrameIx for a stack object
108-
unsigned getFrameIx() const { assert (kind==FRAMEIX); return u.FrameIx; }
109-
110-
/// Returns the Virtual Register for a VReg
111-
unsigned getVReg() const { assert (kind==VREG); return u.VReg; }
176+
SDNodeVector copySDNodes() const { return SDNodes; }
112177

113178
/// Returns whether this is an indirect value.
114179
bool isIndirect() const { return IsIndirect; }
115180

181+
bool isVariadic() const { return IsVariadic; }
182+
116183
/// Returns the DebugLoc.
117184
DebugLoc getDebugLoc() const { return DL; }
118185

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8449,7 +8449,8 @@ SDDbgValue *SelectionDAG::getDbgValue(DIVariable *Var, DIExpression *Expr,
84498449
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
84508450
"Expected inlined-at fields to agree");
84518451
return new (DbgInfo->getAlloc())
8452-
SDDbgValue(Var, Expr, N, R, IsIndirect, DL, O);
8452+
SDDbgValue(Var, Expr, SDDbgOperand::fromNode(N, R), N, IsIndirect, DL, O,
8453+
/*IsVariadic=*/false);
84538454
}
84548455

84558456
/// Constant
@@ -8459,7 +8460,9 @@ SDDbgValue *SelectionDAG::getConstantDbgValue(DIVariable *Var,
84598460
const DebugLoc &DL, unsigned O) {
84608461
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
84618462
"Expected inlined-at fields to agree");
8462-
return new (DbgInfo->getAlloc()) SDDbgValue(Var, Expr, C, DL, O);
8463+
return new (DbgInfo->getAlloc()) SDDbgValue(
8464+
Var, Expr, SDDbgOperand::fromConst(C), {}, /*IsIndirect=*/false, DL, O,
8465+
/*IsVariadic=*/false);
84638466
}
84648467

84658468
/// FrameIndex
@@ -8471,7 +8474,8 @@ SDDbgValue *SelectionDAG::getFrameIndexDbgValue(DIVariable *Var,
84718474
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
84728475
"Expected inlined-at fields to agree");
84738476
return new (DbgInfo->getAlloc())
8474-
SDDbgValue(Var, Expr, FI, IsIndirect, DL, O, SDDbgValue::FRAMEIX);
8477+
SDDbgValue(Var, Expr, SDDbgOperand::fromFrameIdx(FI), {}, IsIndirect, DL,
8478+
O, /*IsVariadic=*/false);
84758479
}
84768480

84778481
/// VReg
@@ -8482,7 +8486,8 @@ SDDbgValue *SelectionDAG::getVRegDbgValue(DIVariable *Var,
84828486
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
84838487
"Expected inlined-at fields to agree");
84848488
return new (DbgInfo->getAlloc())
8485-
SDDbgValue(Var, Expr, VReg, IsIndirect, DL, O, SDDbgValue::VREG);
8489+
SDDbgValue(Var, Expr, SDDbgOperand::fromVReg(VReg), {}, IsIndirect, DL, O,
8490+
/*IsVariadic=*/false);
84868491
}
84878492

84888493
void SelectionDAG::transferDbgValues(SDValue From, SDValue To,
@@ -8503,13 +8508,14 @@ void SelectionDAG::transferDbgValues(SDValue From, SDValue To,
85038508

85048509
SmallVector<SDDbgValue *, 2> ClonedDVs;
85058510
for (SDDbgValue *Dbg : GetDbgValues(FromNode)) {
8506-
if (Dbg->getKind() != SDDbgValue::SDNODE || Dbg->isInvalidated())
8511+
SDDbgOperand DbgOperand = Dbg->getLocationOps()[0];
8512+
if (DbgOperand.getKind() != SDDbgOperand::SDNODE || Dbg->isInvalidated())
85078513
continue;
85088514

85098515
// TODO: assert(!Dbg->isInvalidated() && "Transfer of invalid dbg value");
85108516

85118517
// Just transfer the dbg value attached to From.
8512-
if (Dbg->getResNo() != From.getResNo())
8518+
if (DbgOperand.getResNo() != From.getResNo())
85138519
continue;
85148520

85158521
DIVariable *Var = Dbg->getVariable();
@@ -8583,7 +8589,7 @@ void SelectionDAG::salvageDebugInfo(SDNode &N) {
85838589
}
85848590

85858591
for (SDDbgValue *Dbg : ClonedDVs)
8586-
AddDbgValue(Dbg, Dbg->getSDNode(), false);
8592+
AddDbgValue(Dbg, Dbg->getLocationOps()[0].getSDNode(), false);
85878593
}
85888594

85898595
/// Creates a SDDbgLabel node.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,8 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
11571157
for (auto &DDI : DDIV) {
11581158
const DbgValueInst *DI = DDI.getDI();
11591159
assert(DI && "Ill-formed DanglingDebugInfo");
1160+
assert(!DDI.getDI()->hasArgList() &&
1161+
"Variadic dbg.values should not yet be left dangling.");
11601162
DebugLoc dl = DDI.getdl();
11611163
unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
11621164
unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
@@ -1191,7 +1193,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
11911193
<< "in EmitFuncArgumentDbgValue\n");
11921194
} else {
11931195
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
1194-
auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType());
1196+
auto Undef = UndefValue::get(DDI.getDI()->getValue(0)->getType());
11951197
auto SDV =
11961198
DAG.getConstantDbgValue(Variable, Expr, Undef, dl, DbgSDNodeOrder);
11971199
DAG.AddDbgValue(SDV, nullptr, false);
@@ -1201,7 +1203,9 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
12011203
}
12021204

12031205
void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
1204-
Value *V = DDI.getDI()->getValue();
1206+
assert(!DDI.getDI()->hasArgList() &&
1207+
"Variadic dbg.values should not yet be left dangling.");
1208+
Value *V = DDI.getDI()->getValue(0);
12051209
DILocalVariable *Var = DDI.getDI()->getVariable();
12061210
DIExpression *Expr = DDI.getDI()->getExpression();
12071211
DebugLoc DL = DDI.getdl();
@@ -1245,7 +1249,7 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
12451249
// This was the final opportunity to salvage this debug information, and it
12461250
// couldn't be done. Place an undef DBG_VALUE at this location to terminate
12471251
// any earlier variable location.
1248-
auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType());
1252+
auto Undef = UndefValue::get(DDI.getDI()->getValue(0)->getType());
12491253
auto SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
12501254
DAG.AddDbgValue(SDV, nullptr, false);
12511255

@@ -5977,7 +5981,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
59775981
DILocalVariable *Variable = DI.getVariable();
59785982
DIExpression *Expression = DI.getExpression();
59795983
dropDanglingDebugInfo(Variable, Expression);
5980-
const Value *V = DI.getValue();
5984+
const Value *V = DI.getValue(0);
59815985
if (!V)
59825986
return;
59835987

0 commit comments

Comments
 (0)