[llvm] 3db7d0d - [MachineFunction][DebugInfo][nfc] Introduce EntryValue variable kind

Felipe de Azevedo Piovezan via llvm-commits llvm-commits at lists.llvm.org
Thu May 11 04:41:51 PDT 2023


Author: Felipe de Azevedo Piovezan
Date: 2023-05-11T07:29:57-04:00
New Revision: 3db7d0dffb9875e8e180567b079f7d8e3fc5843f

URL: https://github.com/llvm/llvm-project/commit/3db7d0dffb9875e8e180567b079f7d8e3fc5843f
DIFF: https://github.com/llvm/llvm-project/commit/3db7d0dffb9875e8e180567b079f7d8e3fc5843f.diff

LOG: [MachineFunction][DebugInfo][nfc] Introduce EntryValue variable kind

MachineFunction keeps a table of variables whose addresses never change
throughout the function. Today, the only kinds of locations it can
handle are stack slots.

However, we could expand this for variables whose address is derived
from the value a register had upon function entry. One case where this
happens is with variables alive across coroutine funclets: these can
be placed in a coroutine frame object whose pointer is placed in a
register that is an argument to coroutine funclets.

```
define @foo(ptr %frame_ptr) {
  dbg.declare(%frame_ptr, !some_var,
              !DIExpression(EntryValue, <ptr_arithmetic>))
```

This is a patch in a series that aims to improve the debug information
generated by the CoroSplit pass in the context of `swiftasync`
arguments. Variables stored in the coroutine frame _must_ be described
the entry_value of the ABI-defined register containing a pointer to the
coroutine frame. Since these variables have a single location throughout
their lifetime, they are candidates for being stored in the
MachineFunction table.

Differential Revision: https://reviews.llvm.org/D149879

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/MachineFunction.h
    llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/lib/CodeGen/MIRPrinter.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/lib/CodeGen/StackColoring.cpp
    llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 3e22c397ae3c3..619f7ccf59331 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -38,6 +38,7 @@
 #include <cstdint>
 #include <memory>
 #include <utility>
+#include <variant>
 #include <vector>
 
 namespace llvm {
@@ -407,16 +408,50 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
   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<int, MCRegister> 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<int>(Address); }
+
+    /// Return true if this variable is in the entry value of a register.
+    bool inEntryValueRegister() const {
+      return std::holds_alternative<MCRegister>(Address);
+    }
+
+    /// Returns the stack slot of this variable, assuming `inStackSlot()` is
+    /// true.
+    int getStackSlot() const { return std::get<int>(Address); }
+
+    /// Returns the MCRegister of this variable, assuming
+    /// `inEntryValueRegister()` is true.
+    MCRegister getEntryValueRegister() const {
+      return std::get<MCRegister>(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 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
 
   /// \}
 
-  /// 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
index 8a1218ae6d200..8161de57b58e0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1271,7 +1271,8 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
   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 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
 
     // 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
index 9b3df2f56f501..fcd20d1e438c1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1529,7 +1529,7 @@ void DwarfDebug::collectVariableInfoFromMFTable(
     DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
   SmallDenseMap<InlinedEntity, DbgVariable *> 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 @@ void DwarfDebug::collectVariableInfoFromMFTable(
     ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
     auto RegVar = std::make_unique<DbgVariable>(
                     cast<DILocalVariable>(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
index 4b2fdfb356cad..8326d83f00573 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -491,17 +491,17 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &YMF,
 
   // 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
index f4ca34ebfd582..b26e00731879c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10891,12 +10891,12 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
 
   // 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
index 3b708a319abf5..66b9086e1d883 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -935,12 +935,13 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
 
   // 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<DILocalVariable>(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
index 3a48dd5b0a034..5d3903ed84ce8 100644
--- a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp
+++ b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp
@@ -210,8 +210,9 @@ struct StackFrameLayoutAnalysisPass : public MachineFunctionPass {
     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) {


        


More information about the llvm-commits mailing list