Skip to content

Commit aa3e78a

Browse files
committed
Reapply "[DebugInfo] Correctly track SDNode dependencies for list debug values"
Fixed memory leak error by using BumpAllocator for SDDbgValue arrays. This reverts commit 1b58917.
1 parent dff922f commit aa3e78a

File tree

4 files changed

+253
-35
lines changed

4 files changed

+253
-35
lines changed

llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,17 @@ class SDDbgOperand {
131131
/// We do not use SDValue here to avoid including its header.
132132
class SDDbgValue {
133133
public:
134-
// FIXME: These SmallVector sizes were chosen without any kind of performance
135-
// testing.
136-
using LocOpVector = SmallVector<SDDbgOperand, 2>;
137-
using SDNodeVector = SmallVector<SDNode *, 2>;
138134

139135
private:
140-
LocOpVector LocationOps;
141-
SDNodeVector SDNodes;
136+
// SDDbgValues are allocated by a BumpPtrAllocator, which means the destructor
137+
// may not be called; therefore all member arrays must also be allocated by
138+
// that BumpPtrAllocator, to ensure that they are correctly freed.
139+
size_t NumLocationOps;
140+
SDDbgOperand *LocationOps;
141+
// SDNode dependencies will be calculated as SDNodes that appear in
142+
// LocationOps plus these AdditionalDependencies.
143+
size_t NumAdditionalDependencies;
144+
SDNode **AdditionalDependencies;
142145
DIVariable *Var;
143146
DIExpression *Expr;
144147
DebugLoc DL;
@@ -149,30 +152,58 @@ class SDDbgValue {
149152
bool Emitted = false;
150153

151154
public:
152-
SDDbgValue(DIVariable *Var, DIExpression *Expr, ArrayRef<SDDbgOperand> L,
153-
ArrayRef<SDNode *> Dependencies, bool IsIndirect, DebugLoc DL,
154-
unsigned O, bool IsVariadic)
155-
: LocationOps(L.begin(), L.end()),
156-
SDNodes(Dependencies.begin(), Dependencies.end()), Var(Var), Expr(Expr),
157-
DL(DL), Order(O), IsIndirect(IsIndirect), IsVariadic(IsVariadic) {
155+
SDDbgValue(BumpPtrAllocator &Alloc, DIVariable *Var, DIExpression *Expr,
156+
ArrayRef<SDDbgOperand> L, ArrayRef<SDNode *> Dependencies,
157+
bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic)
158+
: NumLocationOps(L.size()),
159+
LocationOps(Alloc.Allocate<SDDbgOperand>(L.size())),
160+
NumAdditionalDependencies(Dependencies.size()),
161+
AdditionalDependencies(Alloc.Allocate<SDNode *>(Dependencies.size())),
162+
Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect),
163+
IsVariadic(IsVariadic) {
158164
assert(IsVariadic || L.size() == 1);
159165
assert(!(IsVariadic && IsIndirect));
166+
std::copy(L.begin(), L.end(), LocationOps);
167+
std::copy(Dependencies.begin(), Dependencies.end(), AdditionalDependencies);
160168
}
161169

170+
// We allocate arrays with the BumpPtrAllocator and never free or copy them,
171+
// for LocationOps and AdditionalDependencies, as we never expect to copy or
172+
// destroy an SDDbgValue. If we ever start copying or destroying instances, we
173+
// should manage the allocated memory appropriately.
174+
SDDbgValue(const SDDbgValue &Other) = delete;
175+
SDDbgValue &operator=(const SDDbgValue &Other) = delete;
176+
~SDDbgValue() = delete;
177+
162178
/// Returns the DIVariable pointer for the variable.
163179
DIVariable *getVariable() const { return Var; }
164180

165181
/// Returns the DIExpression pointer for the expression.
166182
DIExpression *getExpression() const { return Expr; }
167183

168-
ArrayRef<SDDbgOperand> getLocationOps() const { return LocationOps; }
184+
ArrayRef<SDDbgOperand> getLocationOps() const {
185+
return ArrayRef<SDDbgOperand>(LocationOps, NumLocationOps);
186+
}
169187

170-
LocOpVector copyLocationOps() const { return LocationOps; }
188+
SmallVector<SDDbgOperand> copyLocationOps() const {
189+
return SmallVector<SDDbgOperand>(LocationOps, LocationOps + NumLocationOps);
190+
}
171191

172192
// Returns the SDNodes which this SDDbgValue depends on.
173-
ArrayRef<SDNode *> getSDNodes() const { return SDNodes; }
193+
SmallVector<SDNode *> getSDNodes() const {
194+
SmallVector<SDNode *> Dependencies;
195+
for (SDDbgOperand DbgOp : getLocationOps())
196+
if (DbgOp.getKind() == SDDbgOperand::SDNODE)
197+
Dependencies.push_back(DbgOp.getSDNode());
198+
for (SDNode *Node : getAdditionalDependencies())
199+
Dependencies.push_back(Node);
200+
return Dependencies;
201+
}
174202

175-
SDNodeVector copySDNodes() const { return SDNodes; }
203+
ArrayRef<SDNode *> getAdditionalDependencies() const {
204+
return ArrayRef<SDNode *>(AdditionalDependencies,
205+
NumAdditionalDependencies);
206+
}
176207

177208
/// Returns whether this is an indirect value.
178209
bool isIndirect() const { return IsIndirect; }

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8583,7 +8583,8 @@ SDDbgValue *SelectionDAG::getDbgValue(DIVariable *Var, DIExpression *Expr,
85838583
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
85848584
"Expected inlined-at fields to agree");
85858585
return new (DbgInfo->getAlloc())
8586-
SDDbgValue(Var, Expr, SDDbgOperand::fromNode(N, R), N, IsIndirect, DL, O,
8586+
SDDbgValue(DbgInfo->getAlloc(), Var, Expr, SDDbgOperand::fromNode(N, R),
8587+
{}, IsIndirect, DL, O,
85878588
/*IsVariadic=*/false);
85888589
}
85898590

@@ -8594,9 +8595,10 @@ SDDbgValue *SelectionDAG::getConstantDbgValue(DIVariable *Var,
85948595
const DebugLoc &DL, unsigned O) {
85958596
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
85968597
"Expected inlined-at fields to agree");
8597-
return new (DbgInfo->getAlloc()) SDDbgValue(
8598-
Var, Expr, SDDbgOperand::fromConst(C), {}, /*IsIndirect=*/false, DL, O,
8599-
/*IsVariadic=*/false);
8598+
return new (DbgInfo->getAlloc())
8599+
SDDbgValue(DbgInfo->getAlloc(), Var, Expr, SDDbgOperand::fromConst(C), {},
8600+
/*IsIndirect=*/false, DL, O,
8601+
/*IsVariadic=*/false);
86008602
}
86018603

86028604
/// FrameIndex
@@ -8620,8 +8622,8 @@ SDDbgValue *SelectionDAG::getFrameIndexDbgValue(DIVariable *Var,
86208622
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
86218623
"Expected inlined-at fields to agree");
86228624
return new (DbgInfo->getAlloc())
8623-
SDDbgValue(Var, Expr, SDDbgOperand::fromFrameIdx(FI), Dependencies,
8624-
IsIndirect, DL, O,
8625+
SDDbgValue(DbgInfo->getAlloc(), Var, Expr, SDDbgOperand::fromFrameIdx(FI),
8626+
Dependencies, IsIndirect, DL, O,
86258627
/*IsVariadic=*/false);
86268628
}
86278629

@@ -8632,7 +8634,8 @@ SDDbgValue *SelectionDAG::getVRegDbgValue(DIVariable *Var, DIExpression *Expr,
86328634
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
86338635
"Expected inlined-at fields to agree");
86348636
return new (DbgInfo->getAlloc())
8635-
SDDbgValue(Var, Expr, SDDbgOperand::fromVReg(VReg), {}, IsIndirect, DL, O,
8637+
SDDbgValue(DbgInfo->getAlloc(), Var, Expr, SDDbgOperand::fromVReg(VReg),
8638+
{}, IsIndirect, DL, O,
86368639
/*IsVariadic=*/false);
86378640
}
86388641

@@ -8644,7 +8647,8 @@ SDDbgValue *SelectionDAG::getDbgValueList(DIVariable *Var, DIExpression *Expr,
86448647
assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
86458648
"Expected inlined-at fields to agree");
86468649
return new (DbgInfo->getAlloc())
8647-
SDDbgValue(Var, Expr, Locs, Dependencies, IsIndirect, DL, O, IsVariadic);
8650+
SDDbgValue(DbgInfo->getAlloc(), Var, Expr, Locs, Dependencies, IsIndirect,
8651+
DL, O, IsVariadic);
86488652
}
86498653

86508654
void SelectionDAG::transferDbgValues(SDValue From, SDValue To,
@@ -8707,12 +8711,10 @@ void SelectionDAG::transferDbgValues(SDValue From, SDValue To,
87078711
Expr = *Fragment;
87088712
}
87098713

8710-
auto NewDependencies = Dbg->copySDNodes();
8711-
std::replace(NewDependencies.begin(), NewDependencies.end(), FromNode,
8712-
ToNode);
8714+
auto AdditionalDependencies = Dbg->getAdditionalDependencies();
87138715
// Clone the SDDbgValue and move it to To.
87148716
SDDbgValue *Clone = getDbgValueList(
8715-
Var, Expr, NewLocOps, NewDependencies, Dbg->isIndirect(),
8717+
Var, Expr, NewLocOps, AdditionalDependencies, Dbg->isIndirect(),
87168718
Dbg->getDebugLoc(), std::max(ToNode->getIROrder(), Dbg->getOrder()),
87178719
Dbg->isVariadic());
87188720
ClonedDVs.push_back(Clone);
@@ -8772,11 +8774,9 @@ void SelectionDAG::salvageDebugInfo(SDNode &N) {
87728774
(void)Changed;
87738775
assert(Changed && "Salvage target doesn't use N");
87748776

8775-
auto NewDependencies = DV->copySDNodes();
8776-
std::replace(NewDependencies.begin(), NewDependencies.end(), &N,
8777-
N0.getNode());
8777+
auto AdditionalDependencies = DV->getAdditionalDependencies();
87788778
SDDbgValue *Clone = getDbgValueList(DV->getVariable(), DIExpr,
8779-
NewLocOps, NewDependencies,
8779+
NewLocOps, AdditionalDependencies,
87808780
DV->isIndirect(), DV->getDebugLoc(),
87818781
DV->getOrder(), DV->isVariadic());
87828782
ClonedDVs.push_back(Clone);

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,8 @@ bool SelectionDAGBuilder::handleDebugValue(ArrayRef<const Value *> Values,
13021302
bool IsVariadic) {
13031303
if (Values.empty())
13041304
return true;
1305-
SDDbgValue::LocOpVector LocationOps;
1306-
SDDbgValue::SDNodeVector Dependencies;
1305+
SmallVector<SDDbgOperand> LocationOps;
1306+
SmallVector<SDNode *> Dependencies;
13071307
for (const Value *V : Values) {
13081308
// Constant value.
13091309
if (isa<ConstantInt>(V) || isa<ConstantFP>(V) || isa<UndefValue>(V) ||
@@ -1331,7 +1331,6 @@ bool SelectionDAGBuilder::handleDebugValue(ArrayRef<const Value *> Values,
13311331
// Only emit func arg dbg value for non-variadic dbg.values for now.
13321332
if (!IsVariadic && EmitFuncArgumentDbgValue(V, Var, Expr, dl, false, N))
13331333
return true;
1334-
Dependencies.push_back(N.getNode());
13351334
if (auto *FISDN = dyn_cast<FrameIndexSDNode>(N.getNode())) {
13361335
// Construct a FrameIndexDbgValue for FrameIndexSDNodes so we can
13371336
// describe stack slot locations.
@@ -1343,6 +1342,7 @@ bool SelectionDAGBuilder::handleDebugValue(ArrayRef<const Value *> Values,
13431342
// dbg.value(i32* %px, !"int x", !DIExpression(DW_OP_deref))
13441343
//
13451344
// Both describe the direct values of their associated variables.
1345+
Dependencies.push_back(N.getNode());
13461346
LocationOps.emplace_back(SDDbgOperand::fromFrameIdx(FISDN->getIndex()));
13471347
continue;
13481348
}

0 commit comments

Comments
 (0)