[llvm] [RemoveDIs] Add DPLabels support (PR #82633)

Orlando Cazalet-Hyams via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 22 07:34:20 PST 2024


https://github.com/OCHyams created https://github.com/llvm/llvm-project/pull/82633

Patch 2 of 3 to add llvm.dbg.label support to the RemoveDIs project. The
patch stack adds the DPLabel class, which is the RemoveDIs llvm.dbg.label
equivalent.

       1. Add DbgRecord base class for DPValue and the not-yet-added
           DPLabel class.
       2. Add the DPLabel class.
    -> 3. Add support to passes.
  
AssignemntTrackingAnalysis support could have gone two ways:
1. Have the analysis store a DPLabel representation in its results - SelectionDAGBuilder reads the analysis results and ignores all DbgRecord kinds.
2. Ignore DPLabels in the analysis - SelectionDAGBuilder reads the analysis results but still needs to iterate over DPLabels from the IR.

I went with option 2 because it's less work and IMO 1 is no more correct conceptually. One thing to note is that this does sink the labels to the bottom of packs of debug records. e.g., [value, label, value] becomes [value, value, label]. This shouldn't be a problem because labels and variable locations don't have an ordering requirement. The ordering between variable locations is maintained and the label movement is deterministic. A self-hosted opt comes out identical with and without these labels enabled (next patch), fwiw.

---

("Enable dbg.label conversion" was originally part of 3, but that'll come separately in order to minimise the size of the capstone patch in case we need to revert it)

I've added --try-experimental-debuginfo-iterators to affected tests - I figure this is still useful in case we need to un-enable RemoveDIs temporarily.

>From 679db62e71ff8cda9dbcb6f7759e02d3d5c173e0 Mon Sep 17 00:00:00 2001
From: OCHyams <orlando.hyams at sony.com>
Date: Mon, 15 Jan 2024 16:30:41 +0000
Subject: [PATCH 1/8] CodeExtractor

---
 llvm/lib/Transforms/Utils/CodeExtractor.cpp | 30 +++++++++++++++++----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 8ebcf0c04fd5a9..abcf3c30d2983b 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -1585,8 +1585,27 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
     return cast<DILocalVariable>(NewVar);
   };
 
-  auto UpdateDPValuesOnInst = [&](Instruction &I) -> void {
-    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
+  auto UpdateDbgRecordsOnInst = [&](Instruction &I) -> void {
+    for (DbgRecord &DR : I.getDbgValueRange()) {
+      if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
+        // Point the intrinsic to a fresh label within the new function if the
+        // intrinsic was not inlined from some other function. Matches
+        // llvm.dbg.label intrinsic version in loop below.
+        if (DPL->getDebugLoc().getInlinedAt())
+          continue;
+        DILabel *OldLabel = DPL->getLabel();
+        DINode *&NewLabel = RemappedMetadata[OldLabel];
+        if (!NewLabel) {
+          DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram(
+              *OldLabel->getScope(), *NewSP, Ctx, Cache);
+          NewLabel = DILabel::get(Ctx, NewScope, OldLabel->getName(),
+                                  OldLabel->getFile(), OldLabel->getLine());
+        }
+        DPL->setLabel(cast<DILabel>(NewLabel));
+        continue;
+      }
+
+      DPValue &DPV = cast<DPValue>(DR);
       // Apply the two updates that dbg.values get: invalid operands, and
       // variable metadata fixup.
       if (any_of(DPV.location_ops(), IsInvalidLocation)) {
@@ -1599,13 +1618,11 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
       }
       if (!DPV.getDebugLoc().getInlinedAt())
         DPV.setVariable(GetUpdatedDIVariable(DPV.getVariable()));
-      DPV.setDebugLoc(DebugLoc::replaceInlinedAtSubprogram(DPV.getDebugLoc(),
-                                                           *NewSP, Ctx, Cache));
     }
   };
 
   for (Instruction &I : instructions(NewFunc)) {
-    UpdateDPValuesOnInst(I);
+    UpdateDbgRecordsOnInst(I);
 
     auto *DII = dyn_cast<DbgInfoIntrinsic>(&I);
     if (!DII)
@@ -1658,6 +1675,9 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
     if (const DebugLoc &DL = I.getDebugLoc())
       I.setDebugLoc(
           DebugLoc::replaceInlinedAtSubprogram(DL, *NewSP, Ctx, Cache));
+    for (DbgRecord &DR : I.getDbgValueRange())
+      DR.setDebugLoc(DebugLoc::replaceInlinedAtSubprogram(DR.getDebugLoc(),
+                                                          *NewSP, Ctx, Cache));
 
     // Loop info metadata may contain line locations. Fix them up.
     auto updateLoopInfoLoc = [&Ctx, &Cache, NewSP](Metadata *MD) -> Metadata * {

>From 83c973c6e45c0f29746f617ada54f65a74d1089d Mon Sep 17 00:00:00 2001
From: OCHyams <orlando.hyams at sony.com>
Date: Mon, 15 Jan 2024 16:49:08 +0000
Subject: [PATCH 2/8] SelectionDAG

---
 .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp   | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index e893a5b616d33e..33b689925b5573 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1249,9 +1249,17 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) {
   }
 
   // Is there is any debug-info attached to this instruction, in the form of
-  // DPValue non-instruction debug-info records.
-  for (DbgRecord &DPR : I.getDbgValueRange()) {
-    DPValue &DPV = cast<DPValue>(DPR);
+  // DbgRecord non-instruction debug-info records.
+  for (DbgRecord &DR : I.getDbgValueRange()) {
+    if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
+      assert(DPL->getLabel() && "Missing label");
+      SDDbgLabel *SDV =
+          DAG.getDbgLabel(DPL->getLabel(), DPL->getDebugLoc(), SDNodeOrder);
+      DAG.AddDbgLabel(SDV);
+      continue;
+    }
+
+    DPValue &DPV = cast<DPValue>(DR);
     DILocalVariable *Variable = DPV.getVariable();
     DIExpression *Expression = DPV.getExpression();
     dropDanglingDebugInfo(Variable, Expression);

>From ddad58416f6258d7c34de0573c53c462f8bee1ad Mon Sep 17 00:00:00 2001
From: OCHyams <orlando.hyams at sony.com>
Date: Mon, 15 Jan 2024 16:58:43 +0000
Subject: [PATCH 3/8] FasttISel

---
 llvm/include/llvm/IR/DebugProgramInstruction.h |  5 +++++
 llvm/lib/CodeGen/SelectionDAG/FastISel.cpp     | 17 +++++++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index 1c8619741eb69f..9b30b8330c4090 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -157,6 +157,11 @@ class DbgRecord : public ilist_node<DbgRecord> {
   ~DbgRecord() = default;
 };
 
+inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) {
+  R.print(OS);
+  return OS;
+}
+
 /// Records a position in IR for a source label (DILabel). Corresponds to the
 /// llvm.dbg.label intrinsic.
 /// FIXME: Rename DbgLabelRecord when DPValue is renamed to DbgVariableRecord.
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 5651498dd3f5aa..246762dd7ab628 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1188,11 +1188,24 @@ void FastISel::handleDbgInfo(const Instruction *II) {
   MIMD = MIMetadata();
 
   // Reverse order of debug records, because fast-isel walks through backwards.
-  for (DbgRecord &DPR : llvm::reverse(II->getDbgValueRange())) {
+  for (DbgRecord &DR : llvm::reverse(II->getDbgValueRange())) {
     flushLocalValueMap();
     recomputeInsertPt();
 
-    DPValue &DPV = cast<DPValue>(DPR);
+    if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
+      assert(DPL->getLabel() && "Missing label");
+      if (!FuncInfo.MF->getMMI().hasDebugInfo()) {
+        LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DPL << "\n");
+        continue;
+      }
+
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DPL->getDebugLoc(),
+              TII.get(TargetOpcode::DBG_LABEL))
+          .addMetadata(DPL->getLabel());
+      continue;
+    }
+
+    DPValue &DPV = cast<DPValue>(DR);
 
     Value *V = nullptr;
     if (!DPV.hasArgList())

>From eca5848d1244dc0ce0cf43a02567608110561b3f Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 21 Feb 2024 10:25:33 +0000
Subject: [PATCH 4/8] AsmWriter: processDbgRecordMetadata

---
 llvm/lib/IR/AsmWriter.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index c2a470c5fc7162..fba404c9b027cb 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1141,12 +1141,14 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
 void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
   if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) {
     CreateMetadataSlot(DPV->getVariable());
-    CreateMetadataSlot(DPV->getDebugLoc());
     if (DPV->isDbgAssign())
       CreateMetadataSlot(DPV->getAssignID());
+  } else if (const DPLabel *DPL = dyn_cast<const DPLabel>(&DR)) {
+    CreateMetadataSlot(DPL->getLabel());
   } else {
     llvm_unreachable("unsupported DbgRecord kind");
   }
+  CreateMetadataSlot(DR.getDebugLoc());
 }
 
 void SlotTracker::processInstructionMetadata(const Instruction &I) {

>From 72821d5bf1bc5e4c833d7cc61f2ca3353f92d098 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 21 Feb 2024 10:44:25 +0000
Subject: [PATCH 5/8] SpeculativeExecutionPass

---
 llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp  | 2 ++
 llvm/test/Transforms/SpeculativeExecution/PR46267.ll | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
index f4f3070d11c7bb..4bf4b906299bd0 100644
--- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
+++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
@@ -293,6 +293,8 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
   for (const auto &I : FromBlock) {
     // Make note of any DPValues that need hoisting.
     for (DbgRecord &DR : I.getDbgValueRange()) {
+      if (isa<DPLabel>(DR))
+        continue;
       DPValue &DPV = cast<DPValue>(DR);
       if (HasNoUnhoistedInstr(DPV.location_ops()))
         DPValuesToHoist[DPV.getInstruction()].push_back(&DPV);
diff --git a/llvm/test/Transforms/SpeculativeExecution/PR46267.ll b/llvm/test/Transforms/SpeculativeExecution/PR46267.ll
index c27b492b4b8765..06d0e66c6986ec 100644
--- a/llvm/test/Transforms/SpeculativeExecution/PR46267.ll
+++ b/llvm/test/Transforms/SpeculativeExecution/PR46267.ll
@@ -41,12 +41,16 @@ land.rhs:                                         ; preds = %entry
 ; CHECK-NEXT: call void @llvm.dbg.declare(metadata ptr %y
 ; CHECK-NEXT: %a0 = load i32, ptr undef, align 1
 ; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %a0
+; CHECK-NEXT: call void @llvm.dbg.label
   call void @llvm.dbg.label(metadata !11), !dbg !10
   %y = alloca i32, align 4
   call void @llvm.dbg.declare(metadata ptr %y, metadata !14, metadata !DIExpression()), !dbg !10
 
   %a0 = load i32, ptr undef, align 1
   call void @llvm.dbg.value(metadata i32 %a0, metadata !9, metadata !DIExpression()), !dbg !10
+  ;; RemoveDIs: Check a label that is attached to a hoisted instruction
+  ;; gets left behind (match intrinsic-style debug info behaviour).
+  call void @llvm.dbg.label(metadata !15), !dbg !10
 
   %a2 = add i32 %i, 0
   call void @llvm.dbg.value(metadata i32 %a2, metadata !13, metadata !DIExpression()), !dbg !10
@@ -82,3 +86,4 @@ attributes #1 = { nounwind readnone speculatable willreturn }
 !12 = !DILocalVariable(name: "x", scope: !6, file: !1, line: 3, type: !4)
 !13 = !DILocalVariable(name: "a2", scope: !6, file: !1, line: 3, type: !4)
 !14 = !DILocalVariable(name: "y", scope: !6, file: !1, line: 3, type: !4)
+!15 = !DILabel(scope: !6, name: "label2", file: !1, line: 2)
\ No newline at end of file

>From 37be2f32960677af5291205470b96628f33f08a9 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 21 Feb 2024 11:28:14 +0000
Subject: [PATCH 6/8] GlobalISel

---
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 7c95cef2eeb761..38bb808dd5bd53 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3275,7 +3275,17 @@ void IRTranslator::translateDbgDeclareRecord(Value *Address, bool HasArgList,
 
 void IRTranslator::translateDbgInfo(const Instruction &Inst,
                                       MachineIRBuilder &MIRBuilder) {
-  for (DPValue &DPV : DPValue::filter(Inst.getDbgValueRange())) {
+  for (DbgRecord &DR : Inst.getDbgValueRange()) {
+    if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
+      MIRBuilder.setDebugLoc(DPL->getDebugLoc());
+      assert(DPL->getLabel() && "Missing label");
+      assert(DPL->getLabel()->isValidLocationForIntrinsic(
+                 MIRBuilder.getDebugLoc()) &&
+             "Expected inlined-at fields to agree");
+      MIRBuilder.buildDbgLabel(DPL->getLabel());
+      continue;
+    }
+    DPValue &DPV = cast<DPValue>(DR);
     const DILocalVariable *Variable = DPV.getVariable();
     const DIExpression *Expression = DPV.getExpression();
     Value *V = DPV.getVariableLocationOp(0);

>From 010d4be72d2e18de8ae4ef1644871ad28e29d1c7 Mon Sep 17 00:00:00 2001
From: OCHyams <orlando.hyams at sony.com>
Date: Mon, 15 Jan 2024 19:22:08 +0000
Subject: [PATCH 7/8] tests

---
 llvm/test/CodeGen/Generic/live-debug-label.ll             | 3 ++-
 llvm/test/CodeGen/MIR/X86/branch-folder-with-label.mir    | 1 +
 llvm/test/CodeGen/PowerPC/debug-label-fast-isel.ll        | 2 +-
 llvm/test/DebugInfo/Generic/PR37395.ll                    | 1 +
 llvm/test/DebugInfo/Generic/debug-label-inline.ll         | 1 +
 llvm/test/DebugInfo/Generic/debug-label-mi.ll             | 5 ++++-
 llvm/test/DebugInfo/Generic/debug-label-opt.ll            | 6 ++++++
 llvm/test/DebugInfo/Generic/debug-label.ll                | 4 +++-
 llvm/test/DebugInfo/X86/debug-label-unreached.ll          | 1 +
 llvm/test/DebugInfo/X86/live-debug-vars-nodebug.ll        | 8 ++++++++
 llvm/test/Transforms/HotColdSplit/split-out-dbg-label.ll  | 1 +
 llvm/test/Transforms/SimplifyCFG/bbi-23595.ll             | 1 +
 .../Util/strip-nonlinetable-debuginfo-labels.ll           | 1 +
 13 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/llvm/test/CodeGen/Generic/live-debug-label.ll b/llvm/test/CodeGen/Generic/live-debug-label.ll
index 3121b8700ed119..095ec9931ceeb4 100644
--- a/llvm/test/CodeGen/Generic/live-debug-label.ll
+++ b/llvm/test/CodeGen/Generic/live-debug-label.ll
@@ -1,5 +1,6 @@
 ; RUN: llc < %s -stop-after=virtregrewriter -o - | FileCheck %s
-;
+; RUN: llc --try-experimental-debuginfo-iterators < %s -stop-after=virtregrewriter -o - | FileCheck %s
+
 ; NVPTX produces a different order of the BBs
 ; XFAIL: target=nvptx{{.*}}
 ; Both RISC-V and AMDGPU(GCN) deploy two VirtRegRewriter in their codegen
diff --git a/llvm/test/CodeGen/MIR/X86/branch-folder-with-label.mir b/llvm/test/CodeGen/MIR/X86/branch-folder-with-label.mir
index ce225d4567e91e..f7666fdcb26128 100644
--- a/llvm/test/CodeGen/MIR/X86/branch-folder-with-label.mir
+++ b/llvm/test/CodeGen/MIR/X86/branch-folder-with-label.mir
@@ -39,6 +39,7 @@
 # }
 #
 # RUN: llc -o - %s -mtriple=x86_64-- -run-pass=branch-folder | FileCheck %s
+# RUN: llc --try-experimental-debuginfo-iterators -o - %s -mtriple=x86_64-- -run-pass=branch-folder | FileCheck %s
 --- |
   ; ModuleID = 'test.ll'
   source_filename = "test.ll"
diff --git a/llvm/test/CodeGen/PowerPC/debug-label-fast-isel.ll b/llvm/test/CodeGen/PowerPC/debug-label-fast-isel.ll
index 73848d829c5b2e..61f806cd309bbe 100644
--- a/llvm/test/CodeGen/PowerPC/debug-label-fast-isel.ll
+++ b/llvm/test/CodeGen/PowerPC/debug-label-fast-isel.ll
@@ -1,5 +1,5 @@
 ; RUN: llc < %s -mtriple powerpc64-ibm-aix-xcoff | FileCheck %s --check-prefix=CHECKASM
-
+; RUN: llc --try-experimental-debuginfo-iterators < %s -mtriple powerpc64-ibm-aix-xcoff | FileCheck %s --check-prefix=CHECKASM
 ; This is a case copied from test/DebugInfo/Generic/debug-label-mi.ll. This test
 ; is to explicitly check that fast isel for XCOFF works as expected for debug
 ; related intrinsics.
diff --git a/llvm/test/DebugInfo/Generic/PR37395.ll b/llvm/test/DebugInfo/Generic/PR37395.ll
index c2649392ff9c33..788500154279d3 100644
--- a/llvm/test/DebugInfo/Generic/PR37395.ll
+++ b/llvm/test/DebugInfo/Generic/PR37395.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -passes=lcssa -S %s | FileCheck %s
+; RUN: opt --try-experimental-debuginfo-iterators -passes=lcssa -S %s | FileCheck %s
 source_filename = "small.c"
 
 @a = common dso_local global i32 0, align 4, !dbg !0
diff --git a/llvm/test/DebugInfo/Generic/debug-label-inline.ll b/llvm/test/DebugInfo/Generic/debug-label-inline.ll
index 26407cc8f702a8..0342b0af748c5a 100644
--- a/llvm/test/DebugInfo/Generic/debug-label-inline.ll
+++ b/llvm/test/DebugInfo/Generic/debug-label-inline.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -O0 -filetype=obj -o - %s | llvm-dwarfdump -v - | FileCheck %s
+; RUN: llc --try-experimental-debuginfo-iterators -O0 -filetype=obj -o - %s | llvm-dwarfdump -v - | FileCheck %s
 ;
 ; Bug 47129
 ; XFAIL: target=sparc{{.*}}
diff --git a/llvm/test/DebugInfo/Generic/debug-label-mi.ll b/llvm/test/DebugInfo/Generic/debug-label-mi.ll
index ad92dd2f5a7c29..b7086bcc7c3e91 100644
--- a/llvm/test/DebugInfo/Generic/debug-label-mi.ll
+++ b/llvm/test/DebugInfo/Generic/debug-label-mi.ll
@@ -2,11 +2,14 @@
 ; REQUIRES: asserts
 ; RUN: llc -debug-only=isel %s -o /dev/null 2> %t.debug
 ; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
-;
+; RUN: llc --try-experimental-debuginfo-iterators -debug-only=isel %s -o /dev/null 2> %t.debug
+; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
+
 ; CHECKMI: DBG_LABEL "top", debug-location !9
 ; CHECKMI: DBG_LABEL "done", debug-location !11
 ;
 ; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECKASM
+; RUN: llc --try-experimental-debuginfo-iterators %s -o - | FileCheck %s --check-prefix=CHECKASM
 ;
 ; CHECKASM: DEBUG_LABEL: foo:top
 ; CHECKASM: DEBUG_LABEL: foo:done
diff --git a/llvm/test/DebugInfo/Generic/debug-label-opt.ll b/llvm/test/DebugInfo/Generic/debug-label-opt.ll
index e875216164305a..8426f696c5c60f 100644
--- a/llvm/test/DebugInfo/Generic/debug-label-opt.ll
+++ b/llvm/test/DebugInfo/Generic/debug-label-opt.ll
@@ -3,6 +3,12 @@
 ; REQUIRES: asserts
 ; RUN: llc -debug-only=isel %s -o /dev/null 2> %t.debug
 ; RUN: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
+;; FIXME: RemoveDIs debug output is slightly different, e.g.:
+;; -  DBG_LABEL "top", debug-location !9; debug-label-mi.c:4:1
+;; +  DBG_LABEL "top", debug-location !DILocation(line: 4, column: 1, scope: !4); debug-label-mi.c:4:1
+;; Disable these run lines until that is understood/fixed.
+; run: llc --try-experimental-debuginfo-iterators -debug-only=isel %s -o /dev/null 2> %t.debug
+; run: cat %t.debug | FileCheck %s --check-prefix=CHECKMI
 ;
 ; CHECKMI: DBG_LABEL "end_sum", debug-location !17
 ; CHECKMI: DBG_LABEL "end", debug-location !19
diff --git a/llvm/test/DebugInfo/Generic/debug-label.ll b/llvm/test/DebugInfo/Generic/debug-label.ll
index eff482a25ee0fe..fbe0f975bf33ad 100644
--- a/llvm/test/DebugInfo/Generic/debug-label.ll
+++ b/llvm/test/DebugInfo/Generic/debug-label.ll
@@ -1,5 +1,6 @@
 ; RUN: llc -O0 -filetype=obj -o - %s | llvm-dwarfdump -v - | FileCheck %s
-;
+; RUN: llc --try-experimental-debuginfo-iterators -O0 -filetype=obj -o - %s | llvm-dwarfdump -v - | FileCheck %s
+
 ; CHECK: .debug_info contents:
 ; CHECK: DW_TAG_label
 ; CHECK-NEXT: DW_AT_name {{.*}}"top"
@@ -14,6 +15,7 @@
 ; CHECK-NOT: DW_AT_name {{.*}}"top"
 ;
 ; RUN: llc -O0 -o - %s | FileCheck %s -check-prefix=ASM
+; RUN: llc --try-experimental-debuginfo-iterators  -O0 -o - %s | FileCheck %s -check-prefix=ASM
 ;
 ; ASM: [[TOP_LOW_PC:[.0-9a-zA-Z]+]]:{{[[:space:]].*}}DEBUG_LABEL: foo:top
 ; ASM: [[DONE_LOW_PC:[.0-9a-zA-Z]+]]:{{[[:space:]].*}}DEBUG_LABEL: foo:done
diff --git a/llvm/test/DebugInfo/X86/debug-label-unreached.ll b/llvm/test/DebugInfo/X86/debug-label-unreached.ll
index b84fb07d93ea61..f4d4acaa71153f 100644
--- a/llvm/test/DebugInfo/X86/debug-label-unreached.ll
+++ b/llvm/test/DebugInfo/X86/debug-label-unreached.ll
@@ -1,6 +1,7 @@
 ; Test unreachable llvm.dbg.label
 ;
 ; RUN: llc -filetype=obj -split-dwarf-file debug.dwo -mtriple=x86_64-unknown-linux-gnu -o - %s | llvm-dwarfdump -v - | FileCheck %s
+; RUN: llc --try-experimental-debuginfo-iterators -filetype=obj -split-dwarf-file debug.dwo -mtriple=x86_64-unknown-linux-gnu -o - %s | llvm-dwarfdump -v - | FileCheck %s
 ;
 ; CHECK: .debug_info.dwo contents:
 ; CHECK: DW_TAG_label
diff --git a/llvm/test/DebugInfo/X86/live-debug-vars-nodebug.ll b/llvm/test/DebugInfo/X86/live-debug-vars-nodebug.ll
index 35d05392209dbf..334a6e5f4c5e88 100644
--- a/llvm/test/DebugInfo/X86/live-debug-vars-nodebug.ll
+++ b/llvm/test/DebugInfo/X86/live-debug-vars-nodebug.ll
@@ -5,6 +5,10 @@
 ; RUN:   -experimental-debug-variable-locations \
 ; RUN:   | FileCheck %s --check-prefix=EXPER-INPUT
 
+; RUN: llc %s -mtriple=x86_64-unknown-unknown -o - -stop-before=finalize-isel \
+; RUN:   --try-experimental-debuginfo-iterators \
+; RUN:   | FileCheck %s --check-prefix=EXPER-INPUT
+
 ; RUN: llc %s -mtriple=x86_64-unknown-unknown -o - -stop-after=livedebugvars \
 ; RUN:   | FileCheck %s --check-prefix=OUTPUT
 
@@ -12,6 +16,10 @@
 ; RUN:   -experimental-debug-variable-locations \
 ; RUN:   | FileCheck %s --check-prefix=OUTPUT
 
+; RUN: llc %s -mtriple=x86_64-unknown-unknown -o - -stop-after=livedebugvars \
+; RUN:   --try-experimental-debuginfo-iterators \
+; RUN:   | FileCheck %s --check-prefix=OUTPUT
+
 ; This test checks that LiveDebugVariables strips all debug instructions
 ; from nodebug functions. Such instructions occur when a function with debug
 ; info is inlined into a nodebug function.
diff --git a/llvm/test/Transforms/HotColdSplit/split-out-dbg-label.ll b/llvm/test/Transforms/HotColdSplit/split-out-dbg-label.ll
index 97bb13d4bdcfb9..3c0ec0d212f55d 100644
--- a/llvm/test/Transforms/HotColdSplit/split-out-dbg-label.ll
+++ b/llvm/test/Transforms/HotColdSplit/split-out-dbg-label.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -passes=hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
+; RUN: opt --try-experimental-debuginfo-iterators  -passes=hotcoldsplit -hotcoldsplit-threshold=0 -S < %s | FileCheck %s
 
 ; When an llvm.dbg.label intrinsic is extracted into a new function, make sure
 ; that its metadata argument is a DILabel that points to a scope within the new
diff --git a/llvm/test/Transforms/SimplifyCFG/bbi-23595.ll b/llvm/test/Transforms/SimplifyCFG/bbi-23595.ll
index 4b1147cd79b8a0..4e536f522034e7 100644
--- a/llvm/test/Transforms/SimplifyCFG/bbi-23595.ll
+++ b/llvm/test/Transforms/SimplifyCFG/bbi-23595.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 | FileCheck %s
+; RUN: opt --try-experimental-debuginfo-iterators  < %s -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 | FileCheck %s
 
 ; In 'simplifycfg', during the flattening of a 'br', the instructions for the
 ; 'true' and 'false' parts, are moved out from their respective basic blocks.
diff --git a/llvm/test/Transforms/Util/strip-nonlinetable-debuginfo-labels.ll b/llvm/test/Transforms/Util/strip-nonlinetable-debuginfo-labels.ll
index bd20e8ce8a4ff3..148b12f515acb2 100644
--- a/llvm/test/Transforms/Util/strip-nonlinetable-debuginfo-labels.ll
+++ b/llvm/test/Transforms/Util/strip-nonlinetable-debuginfo-labels.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -S -passes=strip-nonlinetable-debuginfo %s -o - | FileCheck %s
+; RUN: opt --try-experimental-debuginfo-iterators -S -passes=strip-nonlinetable-debuginfo %s -o - | FileCheck %s
 ; CHECK: define void @f()
 define void @f() !dbg !4 {
 entry:

>From e24159c303945357470495798b1e970f3007b342 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 21 Feb 2024 16:38:47 +0000
Subject: [PATCH 8/8] assortment of fixes etc

---
 llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp   |  9 ++++-----
 .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp  | 15 ++++++++++-----
 llvm/lib/Transforms/Utils/BasicBlockUtils.cpp     | 10 +++++++++-
 .../lib/Transforms/Utils/MemoryTaggingSupport.cpp |  3 +--
 llvm/lib/Transforms/Utils/ValueMapper.cpp         |  5 +++++
 5 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index 7b66a851db2527..3b84624c3d4dca 100644
--- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
+++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
@@ -829,11 +829,7 @@ class MemLocFragmentFill {
   void process(BasicBlock &BB, VarFragMap &LiveSet) {
     BBInsertBeforeMap[&BB].clear();
     for (auto &I : BB) {
-      for (DbgRecord &DR : I.getDbgValueRange()) {
-        // FIXME: DPValue::filter usage needs attention in this file; we need
-        // to make sure dbg.labels are handled correctly in RemoveDIs mode.
-        // Cast below to ensure this gets fixed when DPLabels are introduced.
-        DPValue &DPV = cast<DPValue>(DR);
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
         if (const auto *Locs = FnVarLocs->getWedge(&DPV)) {
           for (const VarLocInfo &Loc : *Locs) {
             addDef(Loc, &DPV, *I.getParent(), LiveSet);
@@ -1919,6 +1915,9 @@ void AssignmentTrackingLowering::process(BasicBlock &BB, BlockInfo *LiveSet) {
     // attached DPValues, or a non-debug instruction with attached unprocessed
     // DPValues.
     if (II != EI && II->hasDbgValues()) {
+      // Skip over non-variable debug records (i.e., labels). They're going to
+      // be read from IR (possibly re-ordering them within the debug record
+      // range) rather than from the analysis results.
       for (DPValue &DPV : DPValue::filter(II->getDbgValueRange())) {
         resetInsertionPoint(DPV);
         processDPValue(DPV, LiveSet);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 33b689925b5573..ee600d389c2cc3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1241,13 +1241,16 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) {
                              It->Expr, Vals.size() > 1, It->DL, SDNodeOrder);
       }
     }
-    // We must early-exit here to prevent any DPValues from being emitted below,
-    // as we have just emitted the debug values resulting from assignment
-    // tracking analysis, making any existing DPValues redundant (and probably
-    // less correct).
-    return;
   }
 
+  // We must skip DPValues if they've already been processed above as we
+  // have just emitted the debug values resulting from assignment tracking
+  // analysis, making any existing DPValues redundant (and probably less
+  // correct). We still need to process DPLabels. This does sink DPLabels
+  // to the bottom of the group of debug records. That sholdn't be important
+  // as it does so deterministcally and ordering between DPLabels and DPValues
+  // is immaterial (other than for MIR/IR printing).
+  bool SkipDPValues = DAG.getFunctionVarLocs();
   // Is there is any debug-info attached to this instruction, in the form of
   // DbgRecord non-instruction debug-info records.
   for (DbgRecord &DR : I.getDbgValueRange()) {
@@ -1259,6 +1262,8 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) {
       continue;
     }
 
+    if (SkipDPValues)
+      continue;
     DPValue &DPV = cast<DPValue>(DR);
     DILocalVariable *Variable = DPV.getVariable();
     DIExpression *Expression = DPV.getExpression();
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 7fd6759a61fbae..5bb109a04ff178 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -386,7 +386,15 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) {
   SmallVector<DPValue *, 8> ToBeRemoved;
   SmallDenseSet<DebugVariable> VariableSet;
   for (auto &I : reverse(*BB)) {
-    for (DPValue &DPV : reverse(DPValue::filter(I.getDbgValueRange()))) {
+    for (DbgRecord &DR : reverse(I.getDbgValueRange())) {
+      if (isa<DPLabel>(DR)) {
+        // Emulate existing behaviour (see comment below for dbg.declares).
+        // FIXME: Don't do this.
+        VariableSet.clear();
+        continue;
+      }
+
+      DPValue &DPV = cast<DPValue>(DR);
       // Skip declare-type records, as the debug intrinsic method only works
       // on dbg.value intrinsics.
       if (DPV.getType() == DPValue::LocationType::Declare) {
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index 08fdd3b75ffcbd..2ff7c015107677 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -111,8 +111,7 @@ Instruction *getUntagLocationIfFunctionExit(Instruction &Inst) {
 
 void StackInfoBuilder::visit(Instruction &Inst) {
   // Visit non-intrinsic debug-info records attached to Inst.
-  for (DbgRecord &DR : Inst.getDbgValueRange()) {
-    DPValue &DPV = cast<DPValue>(DR);
+  for (DPValue &DPV : DPValue::filter(Inst.getDbgValueRange())) {
     auto AddIfInteresting = [&](Value *V) {
       if (auto *AI = dyn_cast_or_null<AllocaInst>(V)) {
         if (!isInterestingAlloca(*AI))
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 6e46469f5a601e..91ab2795a4b9d3 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -538,6 +538,11 @@ Value *Mapper::mapValue(const Value *V) {
 }
 
 void Mapper::remapDPValue(DbgRecord &DR) {
+  if (DPLabel *DPL = dyn_cast<DPLabel>(&DR)) {
+    DPL->setLabel(cast<DILabel>(mapMetadata(DPL->getLabel())));
+    return;
+  }
+
   DPValue &V = cast<DPValue>(DR);
   // Remap variables and DILocations.
   auto *MappedVar = mapMetadata(V.getVariable());



More information about the llvm-commits mailing list