Skip to content

Commit 434907e

Browse files
authored
[NFC][AsmPrinter] Refactor FrameIndexExprs as a std::set (#66433)
This avoids the need for a mutable member to implement deferred sorting, and some bespoke code to maintain a SmallVector as a set. The performance impact seems to be negligible in some small tests, and so seems acceptable to greatly simplify the code. An old FIXME and accompanying workaround are dropped. It is ostensibly dead-code within the current codebase.
1 parent 309d1c4 commit 434907e

File tree

2 files changed

+23
-41
lines changed

2 files changed

+23
-41
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,20 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
265265
return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
266266
}
267267

268+
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr) {
269+
std::optional<DIExpression::FragmentInfo> Fragment = Expr.getFragmentInfo();
270+
return Fragment ? Fragment->OffsetInBits : 0;
271+
}
272+
273+
bool llvm::operator<(const FrameIndexExpr &LHS, const FrameIndexExpr &RHS) {
274+
return getFragmentOffsetInBits(*LHS.Expr) <
275+
getFragmentOffsetInBits(*RHS.Expr);
276+
}
277+
278+
bool llvm::operator<(const EntryValueInfo &LHS, const EntryValueInfo &RHS) {
279+
return getFragmentOffsetInBits(LHS.Expr) < getFragmentOffsetInBits(RHS.Expr);
280+
}
281+
268282
Loc::Single::Single(DbgValueLoc ValueLoc)
269283
: ValueLoc(std::make_unique<DbgValueLoc>(ValueLoc)),
270284
Expr(ValueLoc.getExpression()) {
@@ -275,42 +289,15 @@ Loc::Single::Single(DbgValueLoc ValueLoc)
275289
Loc::Single::Single(const MachineInstr *DbgValue)
276290
: Single(getDebugLocValue(DbgValue)) {}
277291

278-
ArrayRef<FrameIndexExpr> Loc::MMI::getFrameIndexExprs() const {
279-
if (FrameIndexExprs.size() == 1)
280-
return FrameIndexExprs;
281-
282-
assert(llvm::all_of(
283-
FrameIndexExprs,
284-
[](const FrameIndexExpr &A) { return A.Expr->isFragment(); }) &&
285-
"multiple FI expressions without DW_OP_LLVM_fragment");
286-
llvm::sort(FrameIndexExprs,
287-
[](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool {
288-
return A.Expr->getFragmentInfo()->OffsetInBits <
289-
B.Expr->getFragmentInfo()->OffsetInBits;
290-
});
291-
292+
const std::set<FrameIndexExpr> &Loc::MMI::getFrameIndexExprs() const {
292293
return FrameIndexExprs;
293294
}
294295

295296
void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) {
296-
// FIXME: This logic should not be necessary anymore, as we now have proper
297-
// deduplication. However, without it, we currently run into the assertion
298-
// below, which means that we are likely dealing with broken input, i.e. two
299-
// non-fragment entries for the same variable at different frame indices.
300-
if (FrameIndexExprs.size()) {
301-
auto *Expr = FrameIndexExprs.back().Expr;
302-
if (!Expr || !Expr->isFragment())
303-
return;
304-
}
305-
306-
if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) {
307-
return FI == Other.FI && Expr == Other.Expr;
308-
}))
309-
FrameIndexExprs.push_back({FI, Expr});
310-
297+
FrameIndexExprs.insert({FI, Expr});
311298
assert((FrameIndexExprs.size() == 1 ||
312299
llvm::all_of(FrameIndexExprs,
313-
[](FrameIndexExpr &FIE) {
300+
[](const FrameIndexExpr &FIE) {
314301
return FIE.Expr && FIE.Expr->isFragment();
315302
})) &&
316303
"conflicting locations for variable");

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ class DbgVariable;
107107
struct FrameIndexExpr {
108108
int FI;
109109
const DIExpression *Expr;
110+
111+
/// Operator enabling sorting based on fragment offset.
112+
friend bool operator<(const FrameIndexExpr &LHS, const FrameIndexExpr &RHS);
110113
};
111114

112115
/// Represents an entry-value location, or a fragment of one.
@@ -115,15 +118,7 @@ struct EntryValueInfo {
115118
const DIExpression &Expr;
116119

117120
/// Operator enabling sorting based on fragment offset.
118-
bool operator<(const EntryValueInfo &Other) const {
119-
return getFragmentOffsetInBits() < Other.getFragmentOffsetInBits();
120-
}
121-
122-
private:
123-
uint64_t getFragmentOffsetInBits() const {
124-
std::optional<DIExpression::FragmentInfo> Fragment = Expr.getFragmentInfo();
125-
return Fragment ? Fragment->OffsetInBits : 0;
126-
}
121+
friend bool operator<(const EntryValueInfo &LHS, const EntryValueInfo &RHS);
127122
};
128123

129124
// Namespace for alternatives of a DbgVariable.
@@ -158,7 +153,7 @@ class Multi {
158153
};
159154
/// Single location defined by (potentially multiple) MMI entries.
160155
struct MMI {
161-
mutable SmallVector<FrameIndexExpr, 1> FrameIndexExprs;
156+
std::set<FrameIndexExpr> FrameIndexExprs;
162157

163158
public:
164159
explicit MMI(const DIExpression *E, int FI) : FrameIndexExprs({{FI, E}}) {
@@ -167,7 +162,7 @@ struct MMI {
167162
}
168163
void addFrameIndexExpr(const DIExpression *Expr, int FI);
169164
/// Get the FI entries, sorted by fragment offset.
170-
ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
165+
const std::set<FrameIndexExpr> &getFrameIndexExprs() const;
171166
};
172167
/// Single location defined by (potentially multiple) EntryValueInfo.
173168
struct EntryValue {

0 commit comments

Comments
 (0)