Skip to content

Commit 2037e2a

Browse files
Merge pull request #7486 from felipepiovezan/felipe/cherry-pick-stable
Cherry pick debug info fixes for single-location debug values
2 parents a149ae2 + e086990 commit 2037e2a

File tree

11 files changed

+411
-421
lines changed

11 files changed

+411
-421
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2905,7 +2905,7 @@ class DIExpression : public MDNode {
29052905
/// Similar to `convertToNonVariadicExpression`, but faster and cheaper - it
29062906
/// does not check whether the expression is a single-location expression, and
29072907
/// it returns elements rather than creating a new DIExpression.
2908-
ArrayRef<uint64_t> getSingleLocationExpressionElements() const;
2908+
std::optional<ArrayRef<uint64_t>> getSingleLocationExpressionElements() const;
29092909

29102910
/// Removes all elements from \p Expr that do not apply to an undef debug
29112911
/// value, which includes every operator that computes the value/location on

llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,5 @@ void DebugLocStream::finalizeEntry() {
4040
DebugLocStream::ListBuilder::~ListBuilder() {
4141
if (!Locs.finalizeList(Asm))
4242
return;
43-
V.initializeDbgValue(&MI);
44-
V.setDebugLocListIndex(ListIndex);
45-
if (TagOffset)
46-
V.setDebugLocListTagOffset(*TagOffset);
43+
V.emplace<Loc::Multi>(ListIndex, TagOffset);
4744
}

llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,13 @@ class DebugLocStream::ListBuilder {
156156
DebugLocStream &Locs;
157157
AsmPrinter &Asm;
158158
DbgVariable &V;
159-
const MachineInstr &MI;
160159
size_t ListIndex;
161160
std::optional<uint8_t> TagOffset;
162161

163162
public:
164163
ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm,
165-
DbgVariable &V, const MachineInstr &MI)
166-
: Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)),
164+
DbgVariable &V)
165+
: Locs(Locs), Asm(Asm), V(V), ListIndex(Locs.startList(&CU)),
167166
TagOffset(std::nullopt) {}
168167

169168
void setTagOffset(uint8_t TO) {

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 195 additions & 190 deletions
Large diffs are not rendered by default.

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ class DwarfCompileUnit final : public DwarfUnit {
342342
/// DWARF information necessary to find the actual variable (navigating the
343343
/// extra location information encoded in the type) based on the starting
344344
/// location. Add the DWARF information to the die.
345-
void addComplexAddress(const DbgVariable &DV, DIE &Die,
345+
void addComplexAddress(const DIExpression *DIExpr, DIE &Die,
346346
dwarf::Attribute Attribute,
347347
const MachineLocation &Location);
348348

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 53 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,14 @@ const DIType *DbgVariable::getType() const {
240240
/// Get .debug_loc entry for the instruction range starting at MI.
241241
static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
242242
const DIExpression *Expr = MI->getDebugExpression();
243-
const bool IsVariadic = !Expr->isSingleLocationExpression();
243+
auto SingleLocExprOpt = DIExpression::convertToNonVariadicExpression(Expr);
244+
const bool IsVariadic = !SingleLocExprOpt;
244245
// If we have a variadic debug value instruction that is equivalent to a
245246
// non-variadic instruction, then convert it to non-variadic form here.
246247
if (!IsVariadic && !MI->isNonListDebugValue()) {
247248
assert(MI->getNumDebugOperands() == 1 &&
248249
"Mismatched DIExpression and debug operands for debug instruction.");
249-
Expr = DIExpression::get(Expr->getContext(),
250-
Expr->getSingleLocationExpressionElements());
250+
Expr = *SingleLocExprOpt;
251251
}
252252
assert(MI->getNumOperands() >= 3);
253253
SmallVector<DbgValueLocEntry, 4> DbgValueLocEntries;
@@ -271,31 +271,23 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
271271
return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
272272
}
273273

274-
void DbgVariable::initializeDbgValue(const MachineInstr *DbgValue) {
275-
assert(FrameIndexExprs.empty() && "Already initialized?");
276-
assert(!ValueLoc.get() && "Already initialized?");
277-
278-
assert(getVariable() == DbgValue->getDebugVariable() && "Wrong variable");
279-
assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() &&
280-
"Wrong inlined-at");
281-
282-
ValueLoc = std::make_unique<DbgValueLoc>(getDebugLocValue(DbgValue));
283-
// Use the debug value's expression as a FrameIndexExpr iff it is suitable,
284-
// which requires it to be non-variadic.
285-
if (auto E = DIExpression::convertToNonVariadicExpression(
286-
DbgValue->getDebugExpression()))
287-
if ((*E)->getNumElements())
288-
FrameIndexExprs.push_back({0, *E});
274+
Loc::Single::Single(DbgValueLoc ValueLoc)
275+
: ValueLoc(std::make_unique<DbgValueLoc>(ValueLoc)),
276+
Expr(ValueLoc.getExpression()) {
277+
if (!Expr->getNumElements())
278+
Expr = nullptr;
289279
}
290280

291-
ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
281+
Loc::Single::Single(const MachineInstr *DbgValue)
282+
: Single(getDebugLocValue(DbgValue)) {}
283+
284+
ArrayRef<FrameIndexExpr> Loc::MMI::getFrameIndexExprs() const {
292285
if (FrameIndexExprs.size() == 1)
293286
return FrameIndexExprs;
294287

295-
assert(llvm::all_of(FrameIndexExprs,
296-
[](const FrameIndexExpr &A) {
297-
return A.Expr->isFragment();
298-
}) &&
288+
assert(llvm::all_of(
289+
FrameIndexExprs,
290+
[](const FrameIndexExpr &A) { return A.Expr->isFragment(); }) &&
299291
"multiple FI expressions without DW_OP_LLVM_fragment");
300292
llvm::sort(FrameIndexExprs,
301293
[](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool {
@@ -306,15 +298,7 @@ ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
306298
return FrameIndexExprs;
307299
}
308300

309-
void DbgVariable::addMMIEntry(const DbgVariable &V) {
310-
assert(DebugLocListIndex == ~0U && !ValueLoc.get() && "not an MMI entry");
311-
assert(V.DebugLocListIndex == ~0U && !V.ValueLoc.get() && "not an MMI entry");
312-
assert(V.getVariable() == getVariable() && "conflicting variable");
313-
assert(V.getInlinedAt() == getInlinedAt() && "conflicting inlined-at location");
314-
315-
assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
316-
assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
317-
301+
void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) {
318302
// FIXME: This logic should not be necessary anymore, as we now have proper
319303
// deduplication. However, without it, we currently run into the assertion
320304
// below, which means that we are likely dealing with broken input, i.e. two
@@ -325,12 +309,10 @@ void DbgVariable::addMMIEntry(const DbgVariable &V) {
325309
return;
326310
}
327311

328-
for (const auto &FIE : V.FrameIndexExprs)
329-
// Ignore duplicate entries.
330-
if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) {
331-
return FIE.FI == Other.FI && FIE.Expr == Other.Expr;
332-
}))
333-
FrameIndexExprs.push_back(FIE);
312+
if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) {
313+
return FI == Other.FI && Expr == Other.Expr;
314+
}))
315+
FrameIndexExprs.push_back({FI, Expr});
334316

335317
assert((FrameIndexExprs.size() == 1 ||
336318
llvm::all_of(FrameIndexExprs,
@@ -1579,27 +1561,42 @@ void DwarfDebug::collectVariableInfoFromMFTable(
15791561
}
15801562

15811563
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
1564+
1565+
// If we have already seen information for this variable, add to what we
1566+
// already know.
1567+
if (DbgVariable *PreviousLoc = MFVars.lookup(Var)) {
1568+
auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1569+
auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1570+
// Previous and new locations are both stack slots (MMI).
1571+
if (PreviousMMI && VI.inStackSlot())
1572+
PreviousMMI->addFrameIndexExpr(VI.Expr, VI.getStackSlot());
1573+
// Previous and new locations are both entry values.
1574+
else if (PreviousEntryValue && VI.inEntryValueRegister())
1575+
PreviousEntryValue->addExpr(VI.getEntryValueRegister(), *VI.Expr);
1576+
else {
1577+
// Locations differ, this should (rarely) happen in optimized async
1578+
// coroutines.
1579+
// Prefer whichever location has an EntryValue.
1580+
if (PreviousLoc->holds<Loc::MMI>())
1581+
PreviousLoc->emplace<Loc::EntryValue>(VI.getEntryValueRegister(),
1582+
*VI.Expr);
1583+
LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()
1584+
<< ", conflicting fragment location types\n");
1585+
}
1586+
continue;
1587+
}
1588+
15821589
auto RegVar = std::make_unique<DbgVariable>(
15831590
cast<DILocalVariable>(Var.first), Var.second);
15841591
if (VI.inStackSlot())
1585-
RegVar->initializeMMI(VI.Expr, VI.getStackSlot());
1592+
RegVar->emplace<Loc::MMI>(VI.Expr, VI.getStackSlot());
15861593
else
1587-
RegVar->initializeEntryValue(VI.getEntryValueRegister(), *VI.Expr);
1594+
RegVar->emplace<Loc::EntryValue>(VI.getEntryValueRegister(), *VI.Expr);
15881595
LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName()
15891596
<< "\n");
1590-
1591-
if (DbgVariable *DbgVar = MFVars.lookup(Var)) {
1592-
if (DbgVar->hasFrameIndexExprs() && RegVar->hasFrameIndexExprs())
1593-
DbgVar->addMMIEntry(*RegVar);
1594-
else if (VI.inEntryValueRegister())
1595-
DbgVar->getEntryValue()->addExpr(VI.getEntryValueRegister(), *VI.Expr);
1596-
else
1597-
LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()
1598-
<< ", conflicting fragment types\n");
1599-
} else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
1600-
MFVars.insert({Var, RegVar.get()});
1601-
ConcreteEntities.push_back(std::move(RegVar));
1602-
}
1597+
InfoHolder.addScopeVariable(Scope, RegVar.get());
1598+
MFVars.insert({Var, RegVar.get()});
1599+
ConcreteEntities.push_back(std::move(RegVar));
16031600
}
16041601
}
16051602

@@ -1947,7 +1944,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
19471944
const auto *End =
19481945
SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr;
19491946
if (validThroughout(LScopes, MInsn, End, getInstOrdering())) {
1950-
RegVar->initializeDbgValue(MInsn);
1947+
RegVar->emplace<Loc::Single>(MInsn);
19511948
continue;
19521949
}
19531950
}
@@ -1957,7 +1954,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
19571954
continue;
19581955

19591956
// Handle multiple DBG_VALUE instructions describing one variable.
1960-
DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar, *MInsn);
1957+
DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar);
19611958

19621959
// Build the location list for this variable.
19631960
SmallVector<DebugLocEntry, 8> Entries;
@@ -1967,7 +1964,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
19671964
// that is valid throughout the variable's scope. If so, produce single
19681965
// value location.
19691966
if (isValidSingleLocation) {
1970-
RegVar->initializeDbgValue(Entries[0].getValues()[0]);
1967+
RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
19711968
continue;
19721969
}
19731970

0 commit comments

Comments
 (0)