diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -156,14 +156,13 @@ DebugLocStream &Locs; AsmPrinter &Asm; DbgVariable &V; - const MachineInstr &MI; size_t ListIndex; std::optional TagOffset; public: ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm, - DbgVariable &V, const MachineInstr &MI) - : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)), + DbgVariable &V) + : Locs(Locs), Asm(Asm), V(V), ListIndex(Locs.startList(&CU)), TagOffset(std::nullopt) {} void setTagOffset(uint8_t TO) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp @@ -40,8 +40,5 @@ DebugLocStream::ListBuilder::~ListBuilder() { if (!Locs.finalizeList(Asm)) return; - V.initializeDbgValue(&MI); - V.setDebugLocListIndex(ListIndex); - if (TagOffset) - V.setDebugLocListTagOffset(*TagOffset); + V.emplace(ListIndex, TagOffset); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -341,7 +341,7 @@ /// DWARF information necessary to find the actual variable (navigating the /// extra location information encoded in the type) based on the starting /// location. Add the DWARF information to the die. - void addComplexAddress(const DbgVariable &DV, DIE &Die, + void addComplexAddress(const DIExpression *DIExpr, DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -772,10 +772,10 @@ // Add variable address. - unsigned Index = DV.getDebugLocListIndex(); - if (Index != ~0U) { - addLocationList(*VariableDie, dwarf::DW_AT_location, Index); - auto TagOffset = DV.getDebugLocListTagOffset(); + if (auto *Multi = std::get_if(&DV)) { + addLocationList(*VariableDie, dwarf::DW_AT_location, + Multi->getDebugLocListIndex()); + auto TagOffset = Multi->getDebugLocListTagOffset(); if (TagOffset) addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, *TagOffset); @@ -783,13 +783,14 @@ } // Check if variable has a single location description. - if (auto *DVal = DV.getValueLoc()) { + if (const auto *Single = std::get_if(&DV)) { + const DbgValueLoc *DVal = &Single->getValueLoc(); if (!DVal->isVariadic()) { const DbgValueLocEntry *Entry = DVal->getLocEntries().begin(); if (Entry->isLocation()) { addVariableAddress(DV, *VariableDie, Entry->getLoc()); } else if (Entry->isInt()) { - auto *Expr = DV.getSingleExpression(); + auto *Expr = Single->getExpr(); if (Expr && Expr->getNumElements()) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); @@ -823,7 +824,7 @@ return Entry.isLocation() && !Entry.getLoc().getReg(); })) return VariableDie; - const DIExpression *Expr = DV.getSingleExpression(); + const DIExpression *Expr = Single->getExpr(); assert(Expr && "Variadic Debug Value must have an Expression."); DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); @@ -882,11 +883,11 @@ return VariableDie; } - if (const std::set *EntryValues = DV.getEntryValues()) { + if (auto *EntryValue = std::get_if(&DV)) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); // Emit each expression as: EntryValue(Register) . - for (auto [Register, Expr] : *EntryValues) { + for (auto [Register, Expr] : EntryValue->EntryValues) { DwarfExpr.addFragmentOffset(&Expr); DIExpressionCursor Cursor(Expr.getElements()); DwarfExpr.beginEntryValueExpression(Cursor); @@ -899,13 +900,13 @@ } // .. else use frame index. - if (!DV.hasFrameIndexExprs()) + if (!DV.holds()) return VariableDie; std::optional NVPTXAddressSpace; DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - for (const auto &Fragment : DV.getFrameIndexExprs()) { + for (const auto &Fragment : DV.get().getFrameIndexExprs()) { Register FrameReg; const DIExpression *Expr = Fragment.Expr; const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); @@ -1530,8 +1531,9 @@ void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, MachineLocation Location) { - if (DV.hasComplexAddress()) - addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); + auto *Single = std::get_if(&DV); + if (Single && Single->getExpr()) + addComplexAddress(Single->getExpr(), Die, dwarf::DW_AT_location, Location); else addAddress(Die, dwarf::DW_AT_location, Location); } @@ -1562,12 +1564,11 @@ /// DWARF information necessary to find the actual variable given the extra /// address information encoded in the DbgVariable, starting from the starting /// location. Add the DWARF information to the die. -void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, +void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location) { DIELoc *Loc = new (DIEValueAllocator) DIELoc; DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - const DIExpression *DIExpr = DV.getSingleExpression(); DwarfExpr.addFragmentOffset(DIExpr); DwarfExpr.setLocation(Location, DIExpr); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -101,6 +101,8 @@ } }; +class DbgVariable; + /// Proxy for one MMI entry. struct FrameIndexExpr { int FI; @@ -124,34 +126,53 @@ } }; -// Namespace for private alternatives of a DbgVariable. -namespace { +// Namespace for alternatives of a DbgVariable. +namespace Loc { /// Single value location description. -struct SingleLoc { +class Single { std::unique_ptr ValueLoc; const DIExpression *Expr; - SingleLoc(DbgValueLoc ValueLoc) - : ValueLoc(std::make_unique(ValueLoc)), - Expr(ValueLoc.getExpression()) { - if (!Expr->getNumElements()) - Expr = nullptr; - } + +public: + explicit Single(DbgValueLoc ValueLoc); + explicit Single(const MachineInstr *DbgValue); + const DbgValueLoc &getValueLoc() const { return *ValueLoc; } + const DIExpression *getExpr() const { return Expr; } }; /// Multi-value location description. -struct MultiLoc { +class Multi { /// Index of the entry list in DebugLocs. - unsigned DebugLocListIndex = ~0u; + unsigned DebugLocListIndex; /// DW_OP_LLVM_tag_offset value from DebugLocs. std::optional DebugLocListTagOffset; + +public: + explicit Multi(unsigned DebugLocListIndex, + std::optional DebugLocListTagOffset) + : DebugLocListIndex(DebugLocListIndex), + DebugLocListTagOffset(DebugLocListTagOffset) {} + unsigned getDebugLocListIndex() const { return DebugLocListIndex; } + std::optional getDebugLocListTagOffset() const { + return DebugLocListTagOffset; + } }; /// Single location defined by (potentially multiple) MMI entries. -struct MMILoc { +struct MMI { mutable SmallVector FrameIndexExprs; + +public: + explicit MMI(const DIExpression *E, int FI) : FrameIndexExprs({{FI, E}}) { + assert((!E || E->isValid()) && "Expected valid expression"); + assert(FI != std::numeric_limits::max() && "Expected valid index"); + } + void addFrameIndexExpr(const DIExpression *Expr, int FI); + /// Get the FI entries, sorted by fragment offset. + ArrayRef getFrameIndexExprs() const; }; /// Single location defined by (potentially multiple) EntryValueInfo. -struct EntryValueLoc { +struct EntryValue { std::set EntryValues; - EntryValueLoc(MCRegister Reg, const DIExpression &Expr) { + explicit EntryValue(MCRegister Reg, const DIExpression &Expr) { addExpr(Reg, Expr); }; // Add the pair Reg, Expr to the list of entry values describing the variable. @@ -165,7 +186,7 @@ EntryValues.insert({Reg, **NonVariadicExpr}); } }; -} // namespace +} // namespace Loc //===----------------------------------------------------------------------===// /// This class is used to track local variable information. @@ -175,8 +196,8 @@ /// which has not be initialized yet. /// /// Variables can be created from allocas, in which case they're generated from -/// the MMI table. Such variables hold the \c MMILoc alternative which can have -/// multiple expressions and frame indices. +/// the MMI table. Such variables hold the \c Loc::MMI alternative which can +/// have multiple expressions and frame indices. /// /// Variables can be created from the entry value of registers, in which case /// they're generated from the MMI table. Such variables hold the \c @@ -184,14 +205,15 @@ /// multiple *fragment* expressions. /// /// Variables can be created from \c DBG_VALUE instructions. Those whose -/// location changes over time hold a \c MultiLoc alternative which uses \c +/// location changes over time hold a \c Loc::Multi alternative which uses \c /// DebugLocListIndex and (optionally) \c DebugLocListTagOffset, while those -/// with a single location hold a \c SingleLoc alternative which use \c ValueLoc -/// and (optionally) a single \c Expr. +/// with a single location hold a \c Loc::Single alternative which use \c +/// ValueLoc and (optionally) a single \c Expr. class DbgVariable : public DbgEntity, - private std::variant { + public std::variant { +public: /// Member shorthand for std::holds_alternative template bool holds() const { return std::holds_alternative(*this); @@ -207,78 +229,18 @@ return *std::get_if(this); } -public: /// Construct a DbgVariable. /// - /// Creates a variable without any DW_AT_location. Call \a initializeMMI() - /// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions. + /// Creates a variable without any DW_AT_location. DbgVariable(const DILocalVariable *V, const DILocation *IA) : DbgEntity(V, IA, DbgVariableKind) {} - /// Initialize from the MMI table. - void initializeMMI(const DIExpression *E, int FI); - - // Initialize variable's location. - void initializeDbgValue(DbgValueLoc Value); - - void initializeEntryValue(MCRegister Reg, const DIExpression &Expr); - - const std::set *getEntryValues() const { - if (const auto *EV = std::get_if(this)) - return &EV->EntryValues; - return nullptr; - } - std::set *getEntryValues() { - if (auto *EV = std::get_if(this)) - return &EV->EntryValues; - return nullptr; - } - void addEntryValueExpr(MCRegister Reg, const DIExpression &Expr) { - get().addExpr(Reg, Expr); - } - - /// Initialize from a DBG_VALUE instruction. - void initializeDbgValue(const MachineInstr *DbgValue); - // Accessors. const DILocalVariable *getVariable() const { return cast(getEntity()); } - const DIExpression *getSingleExpression() const { - return get().Expr; - } - - void setDebugLocListIndex(uint8_t O) { - if (auto *M = std::get_if(this)) - M->DebugLocListIndex = O; - else - emplace().DebugLocListIndex = O; - } - unsigned getDebugLocListIndex() const { - if (auto *M = std::get_if(this)) - return M->DebugLocListIndex; - return ~0U; - } - void setDebugLocListTagOffset(uint8_t O) { - if (auto *M = std::get_if(this)) - M->DebugLocListTagOffset = O; - else - emplace().DebugLocListTagOffset = O; - } - std::optional getDebugLocListTagOffset() const { - return get().DebugLocListTagOffset; - } StringRef getName() const { return getVariable()->getName(); } - const DbgValueLoc *getValueLoc() const { - if (auto *M = std::get_if(this)) - return M->ValueLoc.get(); - return nullptr; - } - /// Get the FI entries, sorted by fragment offset. - ArrayRef getFrameIndexExprs() const; - bool hasFrameIndexExprs() const { return holds(); } - void addMMIEntry(const DIExpression *Expr, int FI); // Translate tag to proper Dwarf tag. dwarf::Tag getTag() const { @@ -306,8 +268,6 @@ return false; } - bool hasComplexAddress() const { return get().Expr; } - const DIType *getType() const; static bool classof(const DbgEntity *N) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -257,44 +257,23 @@ return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic); } -/// Initialize from the MMI table. -void DbgVariable::initializeMMI(const DIExpression *E, int FI) { - assert(holds() && "Already initialized"); - assert((!E || E->isValid()) && "Expected valid expression"); - assert(FI != std::numeric_limits::max() && "Expected valid index"); - emplace().FrameIndexExprs.push_back({FI, E}); +Loc::Single::Single(DbgValueLoc ValueLoc) + : ValueLoc(std::make_unique(ValueLoc)), + Expr(ValueLoc.getExpression()) { + if (!Expr->getNumElements()) + Expr = nullptr; } -void DbgVariable::initializeDbgValue(DbgValueLoc Value) { - assert(holds() && "Already initialized"); - assert(!Value.getExpression()->isFragment() && "Fragments not supported"); - emplace(Value); -} - -void DbgVariable::initializeDbgValue(const MachineInstr *DbgValue) { - assert(holds() && "Already initialized"); - assert(getVariable() == DbgValue->getDebugVariable() && "Wrong variable"); - assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() && - "Wrong inlined-at"); - emplace(getDebugLocValue(DbgValue)); -} - -void DbgVariable::initializeEntryValue(MCRegister Reg, - const DIExpression &Expr) { - assert(holds() && "Already initialized?"); - emplace(Reg, Expr); -} - -ArrayRef DbgVariable::getFrameIndexExprs() const { - auto &FrameIndexExprs = get().FrameIndexExprs; +Loc::Single::Single(const MachineInstr *DbgValue) + : Single(getDebugLocValue(DbgValue)) {} +ArrayRef Loc::MMI::getFrameIndexExprs() const { if (FrameIndexExprs.size() == 1) return FrameIndexExprs; - assert(llvm::all_of(FrameIndexExprs, - [](const FrameIndexExpr &A) { - return A.Expr->isFragment(); - }) && + assert(llvm::all_of( + FrameIndexExprs, + [](const FrameIndexExpr &A) { return A.Expr->isFragment(); }) && "multiple FI expressions without DW_OP_LLVM_fragment"); llvm::sort(FrameIndexExprs, [](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool { @@ -305,9 +284,7 @@ return FrameIndexExprs; } -void DbgVariable::addMMIEntry(const DIExpression *Expr, int FI) { - auto &FrameIndexExprs = get().FrameIndexExprs; - +void Loc::MMI::addFrameIndexExpr(const DIExpression *Expr, int FI) { // FIXME: This logic should not be necessary anymore, as we now have proper // deduplication. However, without it, we currently run into the assertion // below, which means that we are likely dealing with broken input, i.e. two @@ -1570,19 +1547,20 @@ ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode()); if (DbgVariable *DbgVar = MFVars.lookup(Var)) { - if (DbgVar->hasFrameIndexExprs()) - DbgVar->addMMIEntry(VI.Expr, VI.getStackSlot()); + if (auto *MMI = std::get_if(DbgVar)) + MMI->addFrameIndexExpr(VI.Expr, VI.getStackSlot()); else - DbgVar->addEntryValueExpr(VI.getEntryValueRegister(), *VI.Expr); + DbgVar->get().addExpr(VI.getEntryValueRegister(), + *VI.Expr); continue; } auto RegVar = std::make_unique( cast(Var.first), Var.second); if (VI.inStackSlot()) - RegVar->initializeMMI(VI.Expr, VI.getStackSlot()); + RegVar->emplace(VI.Expr, VI.getStackSlot()); else - RegVar->initializeEntryValue(VI.getEntryValueRegister(), *VI.Expr); + RegVar->emplace(VI.getEntryValueRegister(), *VI.Expr); LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName() << "\n"); InfoHolder.addScopeVariable(Scope, RegVar.get()); @@ -1921,7 +1899,7 @@ const auto *End = SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr; if (validThroughout(LScopes, MInsn, End, getInstOrdering())) { - RegVar->initializeDbgValue(MInsn); + RegVar->emplace(MInsn); continue; } } @@ -1931,7 +1909,7 @@ continue; // Handle multiple DBG_VALUE instructions describing one variable. - DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar, *MInsn); + DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar); // Build the location list for this variable. SmallVector Entries; @@ -1941,7 +1919,7 @@ // that is valid throughout the variable's scope. If so, produce single // value location. if (isValidSingleLocation) { - RegVar->initializeDbgValue(Entries[0].getValues()[0]); + RegVar->emplace(Entries[0].getValues()[0]); continue; }