Skip to content

Commit a08bf30

Browse files
committed
[NFC][AsmPrinter] Refactor FrameIndexExprs as a std::set
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 ae84b16 commit a08bf30

File tree

2 files changed

+22
-41
lines changed

2 files changed

+22
-41
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,19 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
257257
return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
258258
}
259259

260+
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr) {
261+
std::optional<DIExpression::FragmentInfo> Fragment = Expr.getFragmentInfo();
262+
return Fragment ? Fragment->OffsetInBits : 0;
263+
}
264+
265+
bool FrameIndexExpr::operator<(const FrameIndexExpr &Other) const {
266+
return getFragmentOffsetInBits(*Expr) < getFragmentOffsetInBits(*Other.Expr);
267+
}
268+
269+
bool EntryValueInfo::operator<(const EntryValueInfo &Other) const {
270+
return getFragmentOffsetInBits(Expr) < getFragmentOffsetInBits(Other.Expr);
271+
}
272+
260273
Loc::Single::Single(DbgValueLoc ValueLoc)
261274
: ValueLoc(std::make_unique<DbgValueLoc>(ValueLoc)),
262275
Expr(ValueLoc.getExpression()) {
@@ -267,42 +280,15 @@ Loc::Single::Single(DbgValueLoc ValueLoc)
267280
Loc::Single::Single(const MachineInstr *DbgValue)
268281
: Single(getDebugLocValue(DbgValue)) {}
269282

270-
ArrayRef<FrameIndexExpr> Loc::MMI::getFrameIndexExprs() const {
271-
if (FrameIndexExprs.size() == 1)
272-
return FrameIndexExprs;
273-
274-
assert(llvm::all_of(
275-
FrameIndexExprs,
276-
[](const FrameIndexExpr &A) { return A.Expr->isFragment(); }) &&
277-
"multiple FI expressions without DW_OP_LLVM_fragment");
278-
llvm::sort(FrameIndexExprs,
279-
[](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool {
280-
return A.Expr->getFragmentInfo()->OffsetInBits <
281-
B.Expr->getFragmentInfo()->OffsetInBits;
282-
});
283-
283+
const std::set<FrameIndexExpr> &Loc::MMI::getFrameIndexExprs() const {
284284
return FrameIndexExprs;
285285
}
286286

287287
void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) {
288-
// FIXME: This logic should not be necessary anymore, as we now have proper
289-
// deduplication. However, without it, we currently run into the assertion
290-
// below, which means that we are likely dealing with broken input, i.e. two
291-
// non-fragment entries for the same variable at different frame indices.
292-
if (FrameIndexExprs.size()) {
293-
auto *Expr = FrameIndexExprs.back().Expr;
294-
if (!Expr || !Expr->isFragment())
295-
return;
296-
}
297-
298-
if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) {
299-
return FI == Other.FI && Expr == Other.Expr;
300-
}))
301-
FrameIndexExprs.push_back({FI, Expr});
302-
288+
FrameIndexExprs.insert({FI, Expr});
303289
assert((FrameIndexExprs.size() == 1 ||
304290
llvm::all_of(FrameIndexExprs,
305-
[](FrameIndexExpr &FIE) {
291+
[](const FrameIndexExpr &FIE) {
306292
return FIE.Expr && FIE.Expr->isFragment();
307293
})) &&
308294
"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+
bool operator<(const FrameIndexExpr &Other) const;
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+
bool operator<(const EntryValueInfo &Other) const;
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)