Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DebugInfo][RemoveDIs] Interpret DPValue objects in SelectionDAG #72253

Merged
merged 3 commits into from
Nov 21, 2023

Conversation

jmorse
Copy link
Member

@jmorse jmorse commented Nov 14, 2023

DPValues are the non-intrinsic replacements for dbg.values, and when an IR function is converted by SelectionDAG we need to convert the variable location information in the same way. Happily all the information is in the same format, it's just stored in a slightly different object, therefore this patch refactors a few things to store the set of {Variable,Expr,DILocation,Location} instead of just a pointer to a DbgValueInst.

This also adds a hook in llc that's much like the one I've added to opt in PR #71937, allowing tests to optionally ask for the use RemoveDIs mode if support for it is built into the compiler.

I've added that flag to a variety of SelectionDAG debug-info tests to ensure that we get some coverage on the RemoveDIs / debug-info-iterator buildbot.

DPValues are the non-intrinsic replacements for dbg.values, and when an IR
function is converted by SelectionDAG we need to convert the variable
location information in the same way. Happily all the information is in the
same format, it's just stored in a slightly different object, therefore
this patch refactors a few things to store the set of
{Variable,Expr,DILocation,Location} instead of just a pointer to a
DbgValueInst.

This also adds a hook in llc that's much like the one I've added to opt in
PR llvm#71937, allowing tests to optionally ask for the use RemoveDIs mode if
support for it is built into the compiler.

I've added that flag to a variety of SelectionDAG debug-info tests to
ensure that we get some coverage on the RemoveDIs / debug-info-iterator
buildbot.
@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label Nov 14, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 14, 2023

@llvm/pr-subscribers-llvm-selectiondag

@llvm/pr-subscribers-debuginfo

Author: Jeremy Morse (jmorse)

Changes

DPValues are the non-intrinsic replacements for dbg.values, and when an IR function is converted by SelectionDAG we need to convert the variable location information in the same way. Happily all the information is in the same format, it's just stored in a slightly different object, therefore this patch refactors a few things to store the set of {Variable,Expr,DILocation,Location} instead of just a pointer to a DbgValueInst.

This also adds a hook in llc that's much like the one I've added to opt in PR #71937, allowing tests to optionally ask for the use RemoveDIs mode if support for it is built into the compiler.

I've added that flag to a variety of SelectionDAG debug-info tests to ensure that we get some coverage on the RemoveDIs / debug-info-iterator buildbot.


Patch is 28.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72253.diff

15 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+76-55)
  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (+27-35)
  • (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+4-1)
  • (modified) llvm/test/DebugInfo/X86/arg-dbg-value-list.ll (+3)
  • (modified) llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll (+2)
  • (modified) llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll (+1)
  • (modified) llvm/test/DebugInfo/X86/dbg-val-list-undef.ll (+3)
  • (modified) llvm/test/DebugInfo/X86/dbg-value-arg-movement.ll (+3)
  • (modified) llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll (+4)
  • (modified) llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll (+4)
  • (modified) llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll (+4)
  • (modified) llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll (+4)
  • (modified) llvm/test/DebugInfo/X86/sdag-dbgvalue-ssareg.ll (+4)
  • (modified) llvm/test/DebugInfo/X86/sdag-ir-salvage.ll (+5)
  • (modified) llvm/tools/llc/llc.cpp (+17)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index aab0d5c5a348bfe..408c084ee4a7d9d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1148,12 +1148,7 @@ SDValue SelectionDAGBuilder::getControlRoot() {
   return updateRoot(PendingExports);
 }
 
-void SelectionDAGBuilder::visit(const Instruction &I) {
-  // Set up outgoing PHI node register values before emitting the terminator.
-  if (I.isTerminator()) {
-    HandlePHINodesInSuccessorBlocks(I.getParent());
-  }
-
+void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) {
   // Add SDDbgValue nodes for any var locs here. Do so before updating
   // SDNodeOrder, as this mapping is {Inst -> Locs BEFORE Inst}.
   if (FunctionVarLocs const *FnVarLocs = DAG.getFunctionVarLocs()) {
@@ -1169,10 +1164,50 @@ void SelectionDAGBuilder::visit(const Instruction &I) {
       }
       SmallVector<Value *> Values(It->Values.location_ops());
       if (!handleDebugValue(Values, Var, It->Expr, It->DL, SDNodeOrder,
-                            It->Values.hasArgList()))
-        addDanglingDebugInfo(It, SDNodeOrder);
+                            It->Values.hasArgList())) {
+        SmallVector<Value *, 4> Vals;
+        for (Value *V : It->Values.location_ops())
+          Vals.push_back(V);
+        addDanglingDebugInfo(Vals, FnVarLocs->getDILocalVariable(It->VariableID), It->Expr, Vals.size() > 1, It->DL, SDNodeOrder);
+      }
+    }
+  }
+
+  // Is there is any debug-info attached to this instruction, in the form of
+  // DPValue non-instruction debug-info records.
+  for (DPValue &DPV : I.getDbgValueRange()) {
+    DILocalVariable *Variable = DPV.getVariable();
+    DIExpression *Expression = DPV.getExpression();
+    dropDanglingDebugInfo(Variable, Expression);
+
+    // A DPValue with no locations is a kill location.
+    SmallVector<Value *, 4> Values(DPV.location_ops());
+    if (Values.empty()) {
+      handleKillDebugValue(Variable, Expression, DPV.getDebugLoc(), SDNodeOrder);
+      continue;
+    }
+
+    // A DPValue with an undef or absent location is also a kill location.
+    if (llvm::any_of(Values, [](Value *V) { return !V || isa<UndefValue>(V);})) {
+      handleKillDebugValue(Variable, Expression, DPV.getDebugLoc(), SDNodeOrder);
+      continue;
+    }
+
+    bool IsVariadic = DPV.hasArgList();
+    if (!handleDebugValue(Values, Variable, Expression, DPV.getDebugLoc(),
+                          SDNodeOrder, IsVariadic)) {
+      addDanglingDebugInfo(Values, Variable, Expression, IsVariadic, DPV.getDebugLoc(), SDNodeOrder);
     }
   }
+}
+
+void SelectionDAGBuilder::visit(const Instruction &I) {
+  visitDbgInfo(I);
+
+  // Set up outgoing PHI node register values before emitting the terminator.
+  if (I.isTerminator()) {
+    HandlePHINodesInSuccessorBlocks(I.getParent());
+  }
 
   // Increase the SDNodeOrder if dealing with a non-debug instruction.
   if (!isa<DbgInfoIntrinsic>(I))
@@ -1232,14 +1267,12 @@ void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) {
 static bool handleDanglingVariadicDebugInfo(SelectionDAG &DAG,
                                             DILocalVariable *Variable,
                                             DebugLoc DL, unsigned Order,
-                                            RawLocationWrapper Values,
+                                            SmallVectorImpl<Value*> &Values,
                                             DIExpression *Expression) {
-  if (!Values.hasArgList())
-    return false;
   // For variadic dbg_values we will now insert an undef.
   // FIXME: We can potentially recover these!
   SmallVector<SDDbgOperand, 2> Locs;
-  for (const Value *V : Values.location_ops()) {
+  for (const Value *V : Values) {
     auto *Undef = UndefValue::get(V->getType());
     Locs.push_back(SDDbgOperand::fromConst(Undef));
   }
@@ -1250,43 +1283,31 @@ static bool handleDanglingVariadicDebugInfo(SelectionDAG &DAG,
   return true;
 }
 
-void SelectionDAGBuilder::addDanglingDebugInfo(const VarLocInfo *VarLoc,
-                                               unsigned Order) {
-  if (!handleDanglingVariadicDebugInfo(
-          DAG,
-          const_cast<DILocalVariable *>(DAG.getFunctionVarLocs()
-                                            ->getVariable(VarLoc->VariableID)
-                                            .getVariable()),
-          VarLoc->DL, Order, VarLoc->Values, VarLoc->Expr)) {
-    DanglingDebugInfoMap[VarLoc->Values.getVariableLocationOp(0)].emplace_back(
-        VarLoc, Order);
-  }
-}
-
-void SelectionDAGBuilder::addDanglingDebugInfo(const DbgValueInst *DI,
-                                               unsigned Order) {
-  // We treat variadic dbg_values differently at this stage.
-  if (!handleDanglingVariadicDebugInfo(
-          DAG, DI->getVariable(), DI->getDebugLoc(), Order,
-          DI->getWrappedLocation(), DI->getExpression())) {
-    // TODO: Dangling debug info will eventually either be resolved or produce
-    // an Undef DBG_VALUE. However in the resolution case, a gap may appear
-    // between the original dbg.value location and its resolved DBG_VALUE,
-    // which we should ideally fill with an extra Undef DBG_VALUE.
-    assert(DI->getNumVariableLocationOps() == 1 &&
-           "DbgValueInst without an ArgList should have a single location "
-           "operand.");
-    DanglingDebugInfoMap[DI->getValue(0)].emplace_back(DI, Order);
+void SelectionDAGBuilder::addDanglingDebugInfo(SmallVectorImpl<Value *> &Values,
+                                               DILocalVariable *Var, DIExpression *Expr, bool IsVariadic,
+                                               DebugLoc DL, unsigned Order) {
+  if (IsVariadic) {
+    handleDanglingVariadicDebugInfo(
+          DAG, Var, DL, Order, Values, Expr);
+    return;
   }
+  // TODO: Dangling debug info will eventually either be resolved or produce
+  // an Undef DBG_VALUE. However in the resolution case, a gap may appear
+  // between the original dbg.value location and its resolved DBG_VALUE,
+  // which we should ideally fill with an extra Undef DBG_VALUE.
+  assert(Values.size() == 1);
+  DanglingDebugInfoMap[Values[0]].emplace_back(Var, Expr, DL, Order);
+  // FIXME: In the variadic case, the variable location information is
+  // dropped.
 }
 
 void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,
                                                 const DIExpression *Expr) {
   auto isMatchingDbgValue = [&](DanglingDebugInfo &DDI) {
-    DIVariable *DanglingVariable = DDI.getVariable(DAG.getFunctionVarLocs());
+    DIVariable *DanglingVariable = DDI.getVariable();
     DIExpression *DanglingExpr = DDI.getExpression();
     if (DanglingVariable == Variable && Expr->fragmentsOverlap(DanglingExpr)) {
-      LLVM_DEBUG(dbgs() << "Dropping dangling debug info for " << printDDI(DDI)
+      LLVM_DEBUG(dbgs() << "Dropping dangling debug info for " << printDDI(nullptr, DDI)
                         << "\n");
       return true;
     }
@@ -1300,7 +1321,7 @@ void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,
     // whether it can be salvaged.
     for (auto &DDI : DDIV)
       if (isMatchingDbgValue(DDI))
-        salvageUnresolvedDbgValue(DDI);
+        salvageUnresolvedDbgValue(DDIMI.first, DDI);
 
     erase_if(DDIV, isMatchingDbgValue);
   }
@@ -1319,7 +1340,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
     DebugLoc DL = DDI.getDebugLoc();
     unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
     unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
-    DILocalVariable *Variable = DDI.getVariable(DAG.getFunctionVarLocs());
+    DILocalVariable *Variable = DDI.getVariable();
     DIExpression *Expr = DDI.getExpression();
     assert(Variable->isValidLocationForIntrinsic(DL) &&
            "Expected inlined-at fields to agree");
@@ -1333,7 +1354,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
       // calling EmitFuncArgumentDbgValue here.
       if (!EmitFuncArgumentDbgValue(V, Variable, Expr, DL,
                                     FuncArgumentDbgValueKind::Value, Val)) {
-        LLVM_DEBUG(dbgs() << "Resolve dangling debug info for " << printDDI(DDI)
+        LLVM_DEBUG(dbgs() << "Resolve dangling debug info for " << printDDI(V, DDI)
                           << "\n");
         LLVM_DEBUG(dbgs() << "  By mapping to:\n    "; Val.dump());
         // Increase the SDNodeOrder for the DbgValue here to make sure it is
@@ -1348,9 +1369,9 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
         DAG.AddDbgValue(SDV, false);
       } else
         LLVM_DEBUG(dbgs() << "Resolved dangling debug info for "
-                          << printDDI(DDI) << " in EmitFuncArgumentDbgValue\n");
+                          << printDDI(V, DDI) << " in EmitFuncArgumentDbgValue\n");
     } else {
-      LLVM_DEBUG(dbgs() << "Dropping debug info for " << printDDI(DDI) << "\n");
+      LLVM_DEBUG(dbgs() << "Dropping debug info for " << printDDI(V, DDI) << "\n");
       auto Undef = UndefValue::get(V->getType());
       auto SDV =
           DAG.getConstantDbgValue(Variable, Expr, Undef, DL, DbgSDNodeOrder);
@@ -1360,14 +1381,13 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
   DDIV.clear();
 }
 
-void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
+void SelectionDAGBuilder::salvageUnresolvedDbgValue(const Value *V, DanglingDebugInfo &DDI) {
   // TODO: For the variadic implementation, instead of only checking the fail
   // state of `handleDebugValue`, we need know specifically which values were
   // invalid, so that we attempt to salvage only those values when processing
   // a DIArgList.
-  Value *V = DDI.getVariableLocationOp(0);
-  Value *OrigV = V;
-  DILocalVariable *Var = DDI.getVariable(DAG.getFunctionVarLocs());
+  const Value *OrigV = V;
+  DILocalVariable *Var = DDI.getVariable();
   DIExpression *Expr = DDI.getExpression();
   DebugLoc DL = DDI.getDebugLoc();
   unsigned SDOrder = DDI.getSDNodeOrder();
@@ -1384,11 +1404,12 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
   // a non-instruction is seen, such as a constant expression or global
   // variable. FIXME: Further work could recover those too.
   while (isa<Instruction>(V)) {
-    Instruction &VAsInst = *cast<Instruction>(V);
+    const Instruction &VAsInst = *cast<const Instruction>(V);
     // Temporary "0", awaiting real implementation.
     SmallVector<uint64_t, 16> Ops;
     SmallVector<Value *, 4> AdditionalValues;
-    V = salvageDebugInfoImpl(VAsInst, Expr->getNumLocationOperands(), Ops,
+    V = salvageDebugInfoImpl(const_cast<Instruction&>(VAsInst),
+                             Expr->getNumLocationOperands(), Ops,
                              AdditionalValues);
     // If we cannot salvage any further, and haven't yet found a suitable debug
     // expression, bail out.
@@ -1421,7 +1442,7 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
   auto *Undef = UndefValue::get(OrigV->getType());
   auto *SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
   DAG.AddDbgValue(SDV, false);
-  LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n  " << printDDI(DDI)
+  LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n  " << printDDI(OrigV, DDI)
                     << "\n");
 }
 
@@ -1572,7 +1593,7 @@ void SelectionDAGBuilder::resolveOrClearDbgInfo() {
   // Try to fixup any remaining dangling debug info -- and drop it if we can't.
   for (auto &Pair : DanglingDebugInfoMap)
     for (auto &DDI : Pair.second)
-      salvageUnresolvedDbgValue(DDI);
+      salvageUnresolvedDbgValue(const_cast<Value*>(Pair.first), DDI);
   clearDanglingDebugInfo();
 }
 
@@ -6313,7 +6334,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
     bool IsVariadic = DI.hasArgList();
     if (!handleDebugValue(Values, Variable, Expression, DI.getDebugLoc(),
                           SDNodeOrder, IsVariadic))
-      addDanglingDebugInfo(&DI, SDNodeOrder);
+      addDanglingDebugInfo(Values, Variable, Expression, IsVariadic, DI.getDebugLoc(), SDNodeOrder);
     return;
   }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index a97884f0efb9a9b..f49aab2c30430dc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -106,38 +106,24 @@ class SelectionDAGBuilder {
 
   /// Helper type for DanglingDebugInfoMap.
   class DanglingDebugInfo {
-    using DbgValTy = const DbgValueInst *;
-    using VarLocTy = const VarLocInfo *;
-    PointerUnion<DbgValTy, VarLocTy> Info;
     unsigned SDNodeOrder = 0;
 
   public:
+    DILocalVariable *Variable;
+    DIExpression *Expression;
+    DebugLoc dl;
     DanglingDebugInfo() = default;
-    DanglingDebugInfo(const DbgValueInst *DI, unsigned SDNO)
-        : Info(DI), SDNodeOrder(SDNO) {}
-    DanglingDebugInfo(const VarLocInfo *VarLoc, unsigned SDNO)
-        : Info(VarLoc), SDNodeOrder(SDNO) {}
-
-    DILocalVariable *getVariable(const FunctionVarLocs *Locs) const {
-      if (isa<VarLocTy>(Info))
-        return Locs->getDILocalVariable(cast<VarLocTy>(Info)->VariableID);
-      return cast<DbgValTy>(Info)->getVariable();
+    DanglingDebugInfo(DILocalVariable *Var, DIExpression *Expr, DebugLoc DL, unsigned SDNO)
+        : SDNodeOrder(SDNO), Variable(Var), Expression(Expr), dl(std::move(DL)) {}
+
+    DILocalVariable *getVariable() const {
+      return Variable;
     }
     DIExpression *getExpression() const {
-      if (isa<VarLocTy>(Info))
-        return cast<VarLocTy>(Info)->Expr;
-      return cast<DbgValTy>(Info)->getExpression();
-    }
-    Value *getVariableLocationOp(unsigned Idx) const {
-      assert(Idx == 0 && "Dangling variadic debug values not supported yet");
-      if (isa<VarLocTy>(Info))
-        return cast<VarLocTy>(Info)->Values.getVariableLocationOp(Idx);
-      return cast<DbgValTy>(Info)->getVariableLocationOp(Idx);
+      return Expression;
     }
     DebugLoc getDebugLoc() const {
-      if (isa<VarLocTy>(Info))
-        return cast<VarLocTy>(Info)->DL;
-      return cast<DbgValTy>(Info)->getDebugLoc();
+      return dl;
     }
     unsigned getSDNodeOrder() const { return SDNodeOrder; }
 
@@ -145,15 +131,19 @@ class SelectionDAGBuilder {
     /// accommodate the fact that an argument is required for getVariable.
     /// Call SelectionDAGBuilder::printDDI instead of using directly.
     struct Print {
-      Print(const DanglingDebugInfo &DDI, const FunctionVarLocs *VarLocs)
-          : DDI(DDI), VarLocs(VarLocs) {}
+      Print(const Value *V, const DanglingDebugInfo &DDI)
+          : V(V), DDI(DDI) {}
+      const Value *V;
       const DanglingDebugInfo &DDI;
-      const FunctionVarLocs *VarLocs;
       friend raw_ostream &operator<<(raw_ostream &OS,
                                      const DanglingDebugInfo::Print &P) {
-        OS << "DDI(var=" << *P.DDI.getVariable(P.VarLocs)
-           << ", val= " << *P.DDI.getVariableLocationOp(0)
-           << ", expr=" << *P.DDI.getExpression()
+        OS << "DDI(var=" << *P.DDI.getVariable();
+        if (P.V)
+          OS << ", val=" << *P.V;
+        else
+          OS << ", val=nullptr";
+
+        OS << ", expr=" << *P.DDI.getExpression()
            << ", order=" << P.DDI.getSDNodeOrder()
            << ", loc=" << P.DDI.getDebugLoc() << ")";
         return OS;
@@ -164,8 +154,8 @@ class SelectionDAGBuilder {
   /// Returns an object that defines `raw_ostream &operator<<` for printing.
   /// Usage example:
   ////    errs() << printDDI(MyDanglingInfo) << " is dangling\n";
-  DanglingDebugInfo::Print printDDI(const DanglingDebugInfo &DDI) {
-    return DanglingDebugInfo::Print(DDI, DAG.getFunctionVarLocs());
+  DanglingDebugInfo::Print printDDI(const Value *V, const DanglingDebugInfo &DDI) {
+    return DanglingDebugInfo::Print(V, DDI);
   }
 
   /// Helper type for DanglingDebugInfoMap.
@@ -344,6 +334,7 @@ class SelectionDAGBuilder {
                                   ISD::NodeType ExtendType = ISD::ANY_EXTEND);
 
   void visit(const Instruction &I);
+  void visitDbgInfo(const Instruction &I);
 
   void visit(unsigned Opcode, const User &I);
 
@@ -352,8 +343,9 @@ class SelectionDAGBuilder {
   SDValue getCopyFromRegs(const Value *V, Type *Ty);
 
   /// Register a dbg_value which relies on a Value which we have not yet seen.
-  void addDanglingDebugInfo(const DbgValueInst *DI, unsigned Order);
-  void addDanglingDebugInfo(const VarLocInfo *VarLoc, unsigned Order);
+  void addDanglingDebugInfo(SmallVectorImpl<Value *> &Values,
+    DILocalVariable *Var, DIExpression *Expr, bool IsVariadic,
+                                                 DebugLoc DL, unsigned Order);
 
   /// If we have dangling debug info that describes \p Variable, or an
   /// overlapping part of variable considering the \p Expr, then this method
@@ -368,7 +360,7 @@ class SelectionDAGBuilder {
   /// For the given dangling debuginfo record, perform last-ditch efforts to
   /// resolve the debuginfo to something that is represented in this DAG. If
   /// this cannot be done, produce an Undef debug value record.
-  void salvageUnresolvedDbgValue(DanglingDebugInfo &DDI);
+  void salvageUnresolvedDbgValue(const Value *V, DanglingDebugInfo &DDI);
 
   /// For a given list of Values, attempt to create and record a SDDbgValue in
   /// the SelectionDAG.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 0cc426254806ddf..bf6298c7520a754 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -685,10 +685,13 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
   CurDAG->NewNodesMustHaveLegalTypes = false;
 
   // Lower the instructions. If a call is emitted as a tail call, cease emitting
-  // nodes for this block.
+  // nodes for this block. If an instruction is elided, don't emit it, but do
+  // handle any debug-info attached to it.
   for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
     if (!ElidedArgCopyInstrs.count(&*I))
       SDB->visit(*I);
+    else
+      SDB->visitDbgInfo(*I);
   }
 
   // Make sure the root of the DAG is up-to-date.
diff --git a/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll b/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll
index 828cebfd0728d82..798bbb6d3790892 100644
--- a/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll
+++ b/llvm/test/DebugInfo/X86/arg-dbg-value-list.ll
@@ -5,6 +5,9 @@
 ; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations=false -stop-before=finalize-isel -o - | FileCheck %s
 ; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations -stop-before=finalize-isel -o - | FileCheck %s
 
+; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations=false -stop-before=finalize-isel -o - --try-experimental-debuginfo-iterators | FileCheck %s
+; RUN: llc %s -start-after=codegenprepare --experimental-debug-variable-locations -stop-before=finalize-isel -o - --try-experimental-debuginfo-iterators | FileCheck %s
+
 ;; Check that unused argument values are handled the same way for variadic
 ;; dbg_values as non-variadics.
 
diff --git a/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll b/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll
index adeaa0fd318a4c6..b98e99c53dfe613 100644
--- a/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll
+++ b/llvm/test/DebugInfo/X86/dbg-empty-metadata-lowering.ll
@@ -1,5 +1,7 @@
 ; RUN: llc %s -stop-after=finalize-isel -o - \
 ; RUN: | FileCheck %s --implicit-check-not=DBG --check-prefixes=AT-DISABLED,BOTH
+; RUN: llc %s -stop-after=finalize-isel -o - --try-experimental-debuginfo-iterators \
+; RUN: | FileCheck %s --implicit-check-not=DBG --check-prefixes=AT-DISABLED,BOTH
 ;; Check that dbg.values with empty metadata are treated as kills (i.e. become
 ;; DBG_VALUE $noreg, ...). dbg.declares with empty metadata location operands
 ;; should be ignored.
diff --git a/llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll b/llvm/test/DebugInfo/X86/dbg-val-list-dangling.ll
index 5292...
[truncated]

Copy link

github-actions bot commented Nov 14, 2023

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff da843aa09f4cb5caab1cf0c802f2d203ada84c54 2157a0599556c9d5438a26351f64cda1d064afac -- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/tools/llc/llc.cpp
View the diff from clang-format here.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index bf6298c752..e42032e121 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -225,8 +225,9 @@ namespace llvm {
       IS.TM.setOptLevel(NewOptLevel);
       LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
                         << IS.MF->getFunction().getName() << "\n");
-      LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel) << " ; After: -O"
-                        << static_cast<int>(NewOptLevel) << "\n");
+      LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel)
+                        << " ; After: -O" << static_cast<int>(NewOptLevel)
+                        << "\n");
       if (NewOptLevel == CodeGenOptLevel::None) {
         IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
         LLVM_DEBUG(

Copy link
Contributor

@OCHyams OCHyams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (with nits and formatting)

Comment on lines 189 to 191
static cl::opt<bool> TryUseNewDbgInfoFormat("try-experimental-debuginfo-iterators",
cl::desc("Enable debuginfo iterator positions, if they're built in"),
cl::init(false));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't this land in another patch? (or maybe I'm confused).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the previous one was for opt, while this is llc.

@@ -7,6 +7,11 @@
; RUN: -experimental-debug-variable-locations=true \
; RUN: | FileCheck %s --check-prefixes=CHECK,INSTRREF

; RUN: llc -mtriple=x86_64-unknown-unknown -start-after=codegenprepare \
; RUN: -stop-before finalize-isel %s -o - \
; RUN: -experimental-debug-variable-locations=false --try-experimental-debuginfo-iterators \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to check -experimental-debug-variable-locations=*true* --try-experimental-debuginfo-iterators too? Same question for other similar tests.

OS << "DDI(var=" << *P.DDI.getVariable(P.VarLocs)
<< ", val= " << *P.DDI.getVariableLocationOp(0)
<< ", expr=" << *P.DDI.getExpression()
OS << "DDI(var=" << *P.DDI.getVariable();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the parameter isn't needed anymore getVariable(P.VarLocs)

    /// Helper for printing DanglingDebugInfo. This hoop-jumping is to
    /// accommodate the fact that an argument is required for getVariable.
    /// Call SelectionDAGBuilder::printDDI instead of using directly.

Can we delete this blob of code?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave this a shot, however we still need to store a pointer to the Value. Looking at the call-sites to printDDI, it's generating an object that operator<<'s to an output stream. We could re-factor those sites to serialise the Value, then the DDI, but that's then getting into a cleanup commit. (Ultimately this is because the expectation of a few call sites is that it can dump all the relevant data of a DDI in one operation, hence all this technical jiggery pokery).

Comment on lines 1300 to 1301
// FIXME: In the variadic case, the variable location information is
// dropped.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is an old comment - it looks true to some definition of "dropped" but possibly should be placed/merged into handleDanglingVariadicDebugInfo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm. I think I wrote this in during an earlier prototype and it's bounced around here and there in the meantime. All the variadic stuff goes through handleDanglingVariadicDebugInfo, and that has a comment about how we just replace it with an undef, so I think the limitations of the code are adequately commented upon.

@jmorse jmorse merged commit 4495485 into llvm:main Nov 21, 2023
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debuginfo llvm:SelectionDAG SelectionDAGISel as well
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants