@@ -240,14 +240,14 @@ const DIType *DbgVariable::getType() const {
240
240
// / Get .debug_loc entry for the instruction range starting at MI.
241
241
static DbgValueLoc getDebugLocValue (const MachineInstr *MI) {
242
242
const DIExpression *Expr = MI->getDebugExpression ();
243
- const bool IsVariadic = !Expr->isSingleLocationExpression ();
243
+ auto SingleLocExprOpt = DIExpression::convertToNonVariadicExpression (Expr);
244
+ const bool IsVariadic = !SingleLocExprOpt;
244
245
// If we have a variadic debug value instruction that is equivalent to a
245
246
// non-variadic instruction, then convert it to non-variadic form here.
246
247
if (!IsVariadic && !MI->isNonListDebugValue ()) {
247
248
assert (MI->getNumDebugOperands () == 1 &&
248
249
" Mismatched DIExpression and debug operands for debug instruction." );
249
- Expr = DIExpression::get (Expr->getContext (),
250
- Expr->getSingleLocationExpressionElements ());
250
+ Expr = *SingleLocExprOpt;
251
251
}
252
252
assert (MI->getNumOperands () >= 3 );
253
253
SmallVector<DbgValueLocEntry, 4 > DbgValueLocEntries;
@@ -271,31 +271,23 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
271
271
return DbgValueLoc (Expr, DbgValueLocEntries, IsVariadic);
272
272
}
273
273
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 ;
289
279
}
290
280
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 {
292
285
if (FrameIndexExprs.size () == 1 )
293
286
return FrameIndexExprs;
294
287
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 (); }) &&
299
291
" multiple FI expressions without DW_OP_LLVM_fragment" );
300
292
llvm::sort (FrameIndexExprs,
301
293
[](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool {
@@ -306,15 +298,7 @@ ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
306
298
return FrameIndexExprs;
307
299
}
308
300
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) {
318
302
// FIXME: This logic should not be necessary anymore, as we now have proper
319
303
// deduplication. However, without it, we currently run into the assertion
320
304
// below, which means that we are likely dealing with broken input, i.e. two
@@ -325,12 +309,10 @@ void DbgVariable::addMMIEntry(const DbgVariable &V) {
325
309
return ;
326
310
}
327
311
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});
334
316
335
317
assert ((FrameIndexExprs.size () == 1 ||
336
318
llvm::all_of (FrameIndexExprs,
@@ -1579,27 +1561,42 @@ void DwarfDebug::collectVariableInfoFromMFTable(
1579
1561
}
1580
1562
1581
1563
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
+
1582
1589
auto RegVar = std::make_unique<DbgVariable>(
1583
1590
cast<DILocalVariable>(Var.first ), Var.second );
1584
1591
if (VI.inStackSlot ())
1585
- RegVar->initializeMMI (VI.Expr , VI.getStackSlot ());
1592
+ RegVar->emplace <Loc::MMI> (VI.Expr , VI.getStackSlot ());
1586
1593
else
1587
- RegVar->initializeEntryValue (VI.getEntryValueRegister (), *VI.Expr );
1594
+ RegVar->emplace <Loc::EntryValue> (VI.getEntryValueRegister (), *VI.Expr );
1588
1595
LLVM_DEBUG (dbgs () << " Created DbgVariable for " << VI.Var ->getName ()
1589
1596
<< " \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));
1603
1600
}
1604
1601
}
1605
1602
@@ -1947,7 +1944,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
1947
1944
const auto *End =
1948
1945
SingleValueWithClobber ? HistoryMapEntries[1 ].getInstr () : nullptr ;
1949
1946
if (validThroughout (LScopes, MInsn, End, getInstOrdering ())) {
1950
- RegVar->initializeDbgValue (MInsn);
1947
+ RegVar->emplace <Loc::Single> (MInsn);
1951
1948
continue ;
1952
1949
}
1953
1950
}
@@ -1957,7 +1954,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
1957
1954
continue ;
1958
1955
1959
1956
// 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);
1961
1958
1962
1959
// Build the location list for this variable.
1963
1960
SmallVector<DebugLocEntry, 8 > Entries;
@@ -1967,7 +1964,7 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
1967
1964
// that is valid throughout the variable's scope. If so, produce single
1968
1965
// value location.
1969
1966
if (isValidSingleLocation) {
1970
- RegVar->initializeDbgValue (Entries[0 ].getValues ()[0 ]);
1967
+ RegVar->emplace <Loc::Single> (Entries[0 ].getValues ()[0 ]);
1971
1968
continue ;
1972
1969
}
1973
1970
0 commit comments