diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -38,6 +38,7 @@ #include #include #include +#include #include namespace llvm { @@ -407,16 +408,50 @@ void init(); public: - struct VariableDbgInfo { + // Description of the location of a variable whose Address is valid and + // unchanging during function execution. The Address may be: + // * A stack index, which can be negative for fixed stack objects. + // * A MCRegister, whose entry value contains the address of the variable. + class VariableDbgInfo { + std::variant Address; + + public: const DILocalVariable *Var; const DIExpression *Expr; - // The Slot can be negative for fixed stack objects. - int Slot; const DILocation *Loc; VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, int Slot, const DILocation *Loc) - : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {} + : Address(Slot), Var(Var), Expr(Expr), Loc(Loc) {} + + VariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, + MCRegister EntryValReg, const DILocation *Loc) + : Address(EntryValReg), Var(Var), Expr(Expr), Loc(Loc) {} + + // Return true if this variable is in a stack slot. + bool inStackSlot() const { return std::holds_alternative(Address); } + + // Return true if this variable is in the entry value of a register. + bool inEntryValueRegister() const { + return std::holds_alternative(Address); + } + + // Returns the stack slot of this variable, assuming `inStackSlot()` is + // true. + int getStackSlot() const { return std::get(Address); } + + // Returns the MCRegister of this variable, assuming + // `inEntryValueRegister()` is true. + MCRegister getEntryValueRegister() const { + return std::get(Address); + } + + // Updates the stack slot of this variable, assuming `inStackSlot()` is + // true. + void updateStackSlot(int NewSlot) { + assert(inStackSlot()); + Address = NewSlot; + } }; class Delegate { @@ -1227,17 +1262,41 @@ /// \} - /// Collect information used to emit debugging information of a variable. + /// Collect information used to emit debugging information of a variable in a + /// stack slot. void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, int Slot, const DILocation *Loc) { VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc); } + /// Collect information used to emit debugging information of a variable in + /// the entry value of a register. + void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, + MCRegister Reg, const DILocation *Loc) { + VariableDbgInfos.emplace_back(Var, Expr, Reg, Loc); + } + VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; } const VariableDbgInfoMapTy &getVariableDbgInfo() const { return VariableDbgInfos; } + /// Returns the collection of variables for which we have debug info and that + /// have been assigned a stack slot. + auto getInStackSlotVariableDbgInfo() { + return make_filter_range(getVariableDbgInfo(), [](auto &VarInfo) { + return VarInfo.inStackSlot(); + }); + } + + /// Returns the collection of variables for which we have debug info and that + /// have been assigned a stack slot. + auto getInStackSlotVariableDbgInfo() const { + return make_filter_range(getVariableDbgInfo(), [](const auto &VarInfo) { + return VarInfo.inStackSlot(); + }); + } + /// Start tracking the arguments passed to the call \p CallI. void addCallArgsForwardingRegs(const MachineInstr *CallI, CallSiteInfoImpl &&CallInfo) { diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1271,7 +1271,8 @@ const TargetFrameLowering *TFI = TSI.getFrameLowering(); const TargetRegisterInfo *TRI = TSI.getRegisterInfo(); - for (const MachineFunction::VariableDbgInfo &VI : MF.getVariableDbgInfo()) { + for (const MachineFunction::VariableDbgInfo &VI : + MF.getInStackSlotVariableDbgInfo()) { if (!VI.Var) continue; assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) && @@ -1299,7 +1300,8 @@ // Get the frame register used and the offset. Register FrameReg; - StackOffset FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg); + StackOffset FrameOffset = + TFI->getFrameIndexReference(*Asm->MF, VI.getStackSlot(), FrameReg); uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg); assert(!FrameOffset.getScalable() && 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 @@ -1529,7 +1529,7 @@ DwarfCompileUnit &TheCU, DenseSet &Processed) { SmallDenseMap MFVars; LLVM_DEBUG(dbgs() << "DwarfDebug: collecting variables from MF side table\n"); - for (const auto &VI : Asm->MF->getVariableDbgInfo()) { + for (const auto &VI : Asm->MF->getInStackSlotVariableDbgInfo()) { if (!VI.Var) continue; assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) && @@ -1549,7 +1549,7 @@ ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode()); auto RegVar = std::make_unique( cast(Var.first), Var.second); - RegVar->initializeMMI(VI.Expr, VI.Slot); + RegVar->initializeMMI(VI.Expr, VI.getStackSlot()); LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName() << "\n"); diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -491,17 +491,17 @@ // Print the debug variable information. for (const MachineFunction::VariableDbgInfo &DebugVar : - MF.getVariableDbgInfo()) { - assert(DebugVar.Slot >= MFI.getObjectIndexBegin() && - DebugVar.Slot < MFI.getObjectIndexEnd() && + MF.getInStackSlotVariableDbgInfo()) { + int Idx = DebugVar.getStackSlot(); + assert(Idx >= MFI.getObjectIndexBegin() && Idx < MFI.getObjectIndexEnd() && "Invalid stack object index"); - if (DebugVar.Slot < 0) { // Negative index means fixed objects. + if (Idx < 0) { // Negative index means fixed objects. auto &Object = - YMF.FixedStackObjects[FixedStackObjectsIdx[DebugVar.Slot + + YMF.FixedStackObjects[FixedStackObjectsIdx[Idx + MFI.getNumFixedObjects()]]; printStackObjectDbgInfo(DebugVar, Object, MST); } else { - auto &Object = YMF.StackObjects[StackObjectsIdx[DebugVar.Slot]]; + auto &Object = YMF.StackObjects[StackObjectsIdx[Idx]]; printStackObjectDbgInfo(DebugVar, Object, MST); } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10891,12 +10891,12 @@ // If any argument copy elisions occurred and we have debug info, update the // stale frame indices used in the dbg.declare variable info table. - MachineFunction::VariableDbgInfoMapTy &DbgDeclareInfo = MF->getVariableDbgInfo(); - if (!DbgDeclareInfo.empty() && !ArgCopyElisionFrameIndexMap.empty()) { - for (MachineFunction::VariableDbgInfo &VI : DbgDeclareInfo) { - auto I = ArgCopyElisionFrameIndexMap.find(VI.Slot); + if (!ArgCopyElisionFrameIndexMap.empty()) { + for (MachineFunction::VariableDbgInfo &VI : + MF->getInStackSlotVariableDbgInfo()) { + auto I = ArgCopyElisionFrameIndexMap.find(VI.getStackSlot()); if (I != ArgCopyElisionFrameIndexMap.end()) - VI.Slot = I->second; + VI.updateStackSlot(I->second); } } diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp --- a/llvm/lib/CodeGen/StackColoring.cpp +++ b/llvm/lib/CodeGen/StackColoring.cpp @@ -935,12 +935,13 @@ // Remap debug information that refers to stack slots. for (auto &VI : MF->getVariableDbgInfo()) { - if (!VI.Var) + if (!VI.Var || !VI.inStackSlot()) continue; - if (SlotRemap.count(VI.Slot)) { + int Slot = VI.getStackSlot(); + if (SlotRemap.count(Slot)) { LLVM_DEBUG(dbgs() << "Remapping debug info for [" << cast(VI.Var)->getName() << "].\n"); - VI.Slot = SlotRemap[VI.Slot]; + VI.updateStackSlot(SlotRemap[Slot]); FixedDbg++; } } diff --git a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp --- a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp +++ b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp @@ -210,8 +210,9 @@ SlotDbgMap SlotDebugMap; // add variables to the map - for (MachineFunction::VariableDbgInfo &DI : MF.getVariableDbgInfo()) - SlotDebugMap[DI.Slot].insert(DI.Var); + for (MachineFunction::VariableDbgInfo &DI : + MF.getInStackSlotVariableDbgInfo()) + SlotDebugMap[DI.getStackSlot()].insert(DI.Var); // Then add all the spills that have debug data for (MachineBasicBlock &MBB : MF) {