[llvm] [RemoveDIs][NFC] Introduce DbgRecord base class [1/3] (PR #78252)

Orlando Cazalet-Hyams via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 07:05:58 PST 2024


https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/78252

>From 356f5b472d423e23b2d2588594b9846001932a1d Mon Sep 17 00:00:00 2001
From: OCHyams <orlando.hyams at sony.com>
Date: Fri, 12 Jan 2024 16:16:26 +0000
Subject: [PATCH 1/7] [RemoveDIs][NFC] Introduce DbgRecord base class [1/3]

---
 llvm/include/llvm/IR/BasicBlock.h             |  11 +-
 llvm/include/llvm/IR/DebugInfo.h              |   2 +
 .../include/llvm/IR/DebugProgramInstruction.h | 202 +++++++++++-------
 llvm/include/llvm/IR/Instruction.h            |  11 +-
 llvm/include/llvm/IR/Metadata.h               |   1 +
 .../llvm/Transforms/Utils/ValueMapper.h       |  10 +-
 llvm/lib/CodeGen/CodeGenPrepare.cpp           |   5 +-
 llvm/lib/CodeGen/SelectionDAG/FastISel.cpp    |   4 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |   3 +-
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |   5 +-
 llvm/lib/IR/AsmWriter.cpp                     |  31 ++-
 llvm/lib/IR/BasicBlock.cpp                    |  22 +-
 llvm/lib/IR/DebugInfo.cpp                     |  11 +-
 llvm/lib/IR/DebugProgramInstruction.cpp       | 135 +++++++-----
 llvm/lib/IR/Instruction.cpp                   |  16 +-
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp  |   2 +-
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp  |   2 +-
 llvm/lib/Transforms/Scalar/ADCE.cpp           |  10 +-
 llvm/lib/Transforms/Scalar/JumpThreading.cpp  |   6 +-
 llvm/lib/Transforms/Utils/BasicBlockUtils.cpp |   4 +-
 llvm/lib/Transforms/Utils/CodeExtractor.cpp   |   2 +-
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |   4 +-
 llvm/lib/Transforms/Utils/Local.cpp           |   4 +-
 .../Transforms/Utils/LoopRotationUtils.cpp    |   9 +-
 llvm/lib/Transforms/Utils/LoopUtils.cpp       |   4 +-
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp     |   3 +-
 llvm/lib/Transforms/Utils/ValueMapper.cpp     |   4 +-
 llvm/unittests/IR/BasicBlockDbgInfoTest.cpp   |  38 ++--
 llvm/unittests/IR/DebugInfoTest.cpp           |  25 ++-
 llvm/unittests/IR/ValueTest.cpp               |   4 +-
 30 files changed, 360 insertions(+), 230 deletions(-)

diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index a72b68d867f36e..ed25cb96ae9645 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -130,10 +130,10 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
   DPMarker *getNextMarker(Instruction *I);
 
   /// Insert a DPValue into a block at the position given by \p I.
-  void insertDPValueAfter(DPValue *DPV, Instruction *I);
+  void insertDPValueAfter(DbgRecord *DPV, Instruction *I);
 
   /// Insert a DPValue into a block at the position given by \p Here.
-  void insertDPValueBefore(DPValue *DPV, InstListType::iterator Here);
+  void insertDPValueBefore(DbgRecord *DPV, InstListType::iterator Here);
 
   /// Eject any debug-info trailing at the end of a block. DPValues can
   /// transiently be located "off the end" of a block if the blocks terminator
@@ -147,7 +147,7 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
   /// occur: inserting into the middle of a sequence of dbg.value intrinsics
   /// does not have an equivalent with DPValues.
   void reinsertInstInDPValues(Instruction *I,
-                              std::optional<DPValue::self_iterator> Pos);
+                              std::optional<DbgRecord::self_iterator> Pos);
 
 private:
   void setParent(Function *parent);
@@ -194,8 +194,9 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
   friend void Instruction::moveBeforeImpl(BasicBlock &BB,
                                           InstListType::iterator I,
                                           bool Preserve);
-  friend iterator_range<DPValue::self_iterator> Instruction::cloneDebugInfoFrom(
-      const Instruction *From, std::optional<DPValue::self_iterator> FromHere,
+  friend iterator_range<DbgRecord::self_iterator>
+  Instruction::cloneDebugInfoFrom(
+      const Instruction *From, std::optional<DbgRecord::self_iterator> FromHere,
       bool InsertAtHead);
 
   /// Creates a new BasicBlock.
diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index b2f079393400b7..022df64880aebd 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -111,6 +111,8 @@ class DebugInfoFinder {
   void processLocation(const Module &M, const DILocation *Loc);
   // Process a DPValue, much like a DbgVariableIntrinsic.
   void processDPValue(const Module &M, const DPValue &DPV);
+  /// Dispatch to DbgRecord subclasses handlers.
+  void processDbgRecord(const Module &M, const DbgRecord &DPE);
 
   /// Process subprogram.
   void processSubprogram(DISubprogram *SP);
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index 594f613aa8ed8b..1c1dd31d9c3c80 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -50,9 +50,11 @@
 #include "llvm/ADT/ilist.h"
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/ADT/iterator.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DebugLoc.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/SymbolTableListTraits.h"
+#include "llvm/Support/Casting.h"
 
 namespace llvm {
 
@@ -66,43 +68,99 @@ class DPMarker;
 class DPValue;
 class raw_ostream;
 
-/// Record of a variable value-assignment, aka a non instruction representation
-/// of the dbg.value intrinsic. Features various methods copied across from the
-/// Instruction class to aid ease-of-use. DPValue objects should always be
-/// linked into a DPMarker's StoredDPValues list. The marker connects a DPValue
-/// back to it's position in the BasicBlock.
+/// Base class for non-instruction debug metadata records that have positions
+/// within IR. Features various methods copied across from the Instruction
+/// class to aid ease-of-use. DbgRecords should always be linked into a
+/// DPMarker's StoredDPValues list. The marker connects a DbgRecord back to
+/// it's position in the BasicBlock.
 ///
-/// This class inherits from DebugValueUser to allow LLVM's metadata facilities
-/// to update our references to metadata beneath our feet.
-class DPValue : public ilist_node<DPValue>, private DebugValueUser {
-  friend class DebugValueUser;
-
-  // NB: there is no explicit "Value" field in this class, it's effectively the
-  // DebugValueUser superclass instead. The referred to Value can either be a
-  // ValueAsMetadata or a DIArgList.
+/// We need a discriminator for dyn/isa casts. In order to avoid paying for a
+/// vtable for "virtual" functions too, subclasses must add a new discriminator
+/// value (RecordKind) and cases to a few functions in the base class:
+///   deleteRecord()
+///   clone()
+///   both print methods
+class DbgRecord : public ilist_node<DbgRecord> {
+public:
+  /// Marker that this DbgRecord is linked into.
+  DPMarker *Marker = nullptr;
+  /// Subclass discriminator.
+  enum Kind : uint8_t { ValueKind };
 
-  DILocalVariable *Variable;
-  DIExpression *Expression;
+protected:
   DebugLoc DbgLoc;
-  DIExpression *AddressExpression;
+  Kind RecordKind; ///< Subclass discriminator.
 
 public:
-  void deleteInstr();
+  DbgRecord(Kind RecordKind, DebugLoc DL)
+      : DbgLoc(DL), RecordKind(RecordKind) {}
+
+  /// Methods requiring subclass implementations.
+  ///@{
+  void deleteRecord();
+  DbgRecord *clone() const;
+  void print(raw_ostream &O, bool IsForDebug = false) const;
+  void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const;
+  ///@}
+
+  Kind getRecordKind() const { return RecordKind; }
+
+  void setMarker(DPMarker *M) { Marker = M; }
+
+  DPMarker *getMarker() { return Marker; }
+  const DPMarker *getMarker() const { return Marker; }
+
+  BasicBlock *getBlock();
+  const BasicBlock *getBlock() const;
+
+  Function *getFunction();
+  const Function *getFunction() const;
+
+  Module *getModule();
+  const Module *getModule() const;
+
+  LLVMContext &getContext();
+  const LLVMContext &getContext() const;
 
   const Instruction *getInstruction() const;
   const BasicBlock *getParent() const;
   BasicBlock *getParent();
-  void dump() const;
+
   void removeFromParent();
   void eraseFromParent();
 
   DPValue *getNextNode() { return &*std::next(getIterator()); }
   DPValue *getPrevNode() { return &*std::prev(getIterator()); }
 
-  using self_iterator = simple_ilist<DPValue>::iterator;
-  using const_self_iterator = simple_ilist<DPValue>::const_iterator;
+  DPValue *getNextNode() { return &*std::next(getIterator()); }
+  DPValue *getPrevNode() { return &*std::prev(getIterator()); }
+
+  DebugLoc getDebugLoc() const { return DbgLoc; }
+  void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
+
+  void dump() const;
+
+  using self_iterator = simple_ilist<DbgRecord>::iterator;
+  using const_self_iterator = simple_ilist<DbgRecord>::const_iterator;
+
+protected:
+  /// Similarly to Value, we avoid paying the cost of a vtable
+  /// by protecting the dtor and having deleteRecord dispatch
+  /// cleanup.
+  /// Use deleteRecord to delete a generic record.
+  ~DbgRecord() = default;
+};
 
-  enum class LocationType {
+/// Record of a variable value-assignment, aka a non instruction representation
+/// of the dbg.value intrinsic.
+///
+/// This class inherits from DebugValueUser to allow LLVM's metadata facilities
+/// to update our references to metadata beneath our feet.
+class DPValue : public DbgRecord, protected DebugValueUser {
+  friend class DebugValueUser;
+
+public:
+  enum class LocationType : uint8_t {
     Declare,
     Value,
     Assign,
@@ -113,11 +171,17 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
   /// Classification of the debug-info record that this DPValue represents.
   /// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
   /// currently supported, but it would be trivial to do so.
+  /// FIXME: We could use spare padding bits from DbgRecord for this.
   LocationType Type;
 
-  /// Marker that this DPValue is linked into.
-  DPMarker *Marker = nullptr;
+  // NB: there is no explicit "Value" field in this class, it's effectively the
+  // DebugValueUser superclass instead. The referred to Value can either be a
+  // ValueAsMetadata or a DIArgList.
+
+  DILocalVariable *Variable;
+  DIExpression *Expression;
 
+public:
   /// Create a new DPValue representing the intrinsic \p DVI, for example the
   /// assignment represented by a dbg.value.
   DPValue(const DbgVariableIntrinsic *DVI);
@@ -235,9 +299,6 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
   bool isAddressOfVariable() const { return Type == LocationType::Declare; }
   LocationType getType() const { return Type; }
 
-  DebugLoc getDebugLoc() const { return DbgLoc; }
-  void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
-
   void setKillLocation();
   bool isKillLocation() const;
 
@@ -314,43 +375,37 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
   /// \returns A new dbg.value intrinsic representiung this DPValue.
   DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
                                              Instruction *InsertBefore) const;
-  void setMarker(DPMarker *M) { Marker = M; }
-
-  DPMarker *getMarker() { return Marker; }
-  const DPMarker *getMarker() const { return Marker; }
-
-  BasicBlock *getBlock();
-  const BasicBlock *getBlock() const;
-
-  Function *getFunction();
-  const Function *getFunction() const;
 
-  Module *getModule();
-  const Module *getModule() const;
-
-  LLVMContext &getContext();
-  const LLVMContext &getContext() const;
-
-  /// Insert this DPValue prior to \p InsertBefore. Must not be called if this
-  /// is already contained in a DPMarker.
-  void insertBefore(DPValue *InsertBefore);
-  void insertAfter(DPValue *InsertAfter);
-  void moveBefore(DPValue *MoveBefore);
-  void moveAfter(DPValue *MoveAfter);
+  /// Handle changes to the location of the Value(s) that we refer to happening
+  /// "under our feet".
+  void handleChangedLocation(Metadata *NewLocation);
 
   void print(raw_ostream &O, bool IsForDebug = false) const;
   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
+
+  /// Filter the DbgRecord range to DPValue types only and downcast.
+  static inline auto
+  filter(iterator_range<simple_ilist<DbgRecord>::iterator> R) {
+    return map_range(
+        make_filter_range(R, [](DbgRecord &E) { return isa<DPValue>(E); }),
+        [](DbgRecord &E) { return std::ref(cast<DPValue>(E)); });
+  }
+
+  /// Support type inquiry through isa, cast, and dyn_cast.
+  static bool classof(const DbgRecord *E) {
+    return E->getRecordKind() == ValueKind;
+  }
 };
 
 /// Per-instruction record of debug-info. If an Instruction is the position of
 /// some debugging information, it points at a DPMarker storing that info. Each
 /// marker points back at the instruction that owns it. Various utilities are
-/// provided for manipulating the DPValues contained within this marker.
+/// provided for manipulating the DbgRecords contained within this marker.
 ///
-/// This class has a rough surface area, because it's needed to preserve the one
-/// arefact that we can't yet eliminate from the intrinsic / dbg.value
-/// debug-info design: the order of DPValues/records is significant, and
-/// duplicates can exist. Thus, if one has a run of debug-info records such as:
+/// This class has a rough surface area, because it's needed to preserve the
+/// one arefact that we can't yet eliminate from the intrinsic / dbg.value
+/// debug-info design: the order of records is significant, and duplicates can
+/// exist. Thus, if one has a run of debug-info records such as:
 ///    dbg.value(...
 ///    %foo = barinst
 ///    dbg.value(...
@@ -370,12 +425,11 @@ class DPMarker {
   /// operations that move a marker from one instruction to another.
   Instruction *MarkedInstr = nullptr;
 
-  /// List of DPValues, each recording a single variable assignment, the
-  /// equivalent of a dbg.value intrinsic. There is a one-to-one relationship
-  /// between each dbg.value in a block and each DPValue once the
-  /// representation has been converted, and the ordering of DPValues is
-  /// meaningful in the same was a dbg.values.
-  simple_ilist<DPValue> StoredDPValues;
+  /// List of DbgRecords, the non-instruction equivalent of llvm.dbg.*
+  /// intrinsics. There is a one-to-one relationship between each debug
+  /// intrinsic in a block and each DbgRecord once the representation has been
+  /// converted, and the ordering is meaningful in the same way.
+  simple_ilist<DbgRecord> StoredDPValues;
   bool empty() const { return StoredDPValues.empty(); }
 
   const BasicBlock *getParent() const;
@@ -395,8 +449,8 @@ class DPMarker {
   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
 
   /// Produce a range over all the DPValues in this Marker.
-  iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange();
-  iterator_range<simple_ilist<DPValue>::const_iterator>
+  iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange();
+  iterator_range<simple_ilist<DbgRecord>::const_iterator>
   getDbgValueRange() const;
   /// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead
   /// is true, place them before existing DPValues, otherwise afterwards.
@@ -404,31 +458,31 @@ class DPMarker {
   /// Transfer the DPValues in \p Range from \p Src into this DPMarker. If
   /// \p InsertAtHead is true, place them before existing DPValues, otherwise
   // afterwards.
-  void absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
+  void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
                          DPMarker &Src, bool InsertAtHead);
   /// Insert a DPValue into this DPMarker, at the end of the list. If
   /// \p InsertAtHead is true, at the start.
-  void insertDPValue(DPValue *New, bool InsertAtHead);
+  void insertDPValue(DbgRecord *New, bool InsertAtHead);
   /// Insert a DPValue prior to a DPValue contained within this marker.
-  void insertDPValue(DPValue *New, DPValue *InsertBefore);
+  void insertDPValue(DbgRecord *New, DPValue *InsertBefore);
   /// Insert a DPValue after a DPValue contained within this marker.
-  void insertDPValueAfter(DPValue *New, DPValue *InsertAfter);
+  void insertDPValueAfter(DbgRecord *New, DPValue *InsertAfter);
   /// Clone all DPMarkers from \p From into this marker. There are numerous
   /// options to customise the source/destination, due to gnarliness, see class
   /// comment.
   /// \p FromHere If non-null, copy from FromHere to the end of From's DPValues
   /// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues
   /// \returns Range over all the newly cloned DPValues
-  iterator_range<simple_ilist<DPValue>::iterator>
+  iterator_range<simple_ilist<DbgRecord>::iterator>
   cloneDebugInfoFrom(DPMarker *From,
-                     std::optional<simple_ilist<DPValue>::iterator> FromHere,
+                     std::optional<simple_ilist<DbgRecord>::iterator> FromHere,
                      bool InsertAtHead = false);
   /// Erase all DPValues in this DPMarker.
-  void dropDPValues();
-  /// Erase a single DPValue from this marker. In an ideal future, we would
+  void dropDbgValues();
+  /// Erase a single DbgRecord from this marker. In an ideal future, we would
   /// never erase an assignment in this way, but it's the equivalent to
-  /// erasing a dbg.value from a block.
-  void dropOneDPValue(DPValue *DPV);
+  /// erasing a debug intrinsic from a block.
+  void dropOneDbgValue(DbgRecord *DPE);
 
   /// We generally act like all llvm Instructions have a range of DPValues
   /// attached to them, but in reality sometimes we don't allocate the DPMarker
@@ -438,8 +492,10 @@ class DPMarker {
   /// DPValue in that range, but they should be using the Official (TM) API for
   /// that.
   static DPMarker EmptyDPMarker;
-  static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange(){
-    return make_range(EmptyDPMarker.StoredDPValues.end(), EmptyDPMarker.StoredDPValues.end());
+  static iterator_range<simple_ilist<DbgRecord>::iterator>
+  getEmptyDPValueRange() {
+    return make_range(EmptyDPMarker.StoredDPValues.end(),
+                      EmptyDPMarker.StoredDPValues.end());
   }
 };
 
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index cd814e21be1ae1..c1a5a3d6c60941 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -35,6 +35,7 @@ class MDNode;
 class Module;
 struct AAMDNodes;
 class DPMarker;
+class DbgRecord;
 
 template <> struct ilist_alloc_traits<Instruction> {
   static inline void deleteNode(Instruction *V);
@@ -72,20 +73,20 @@ class Instruction : public User,
   /// \p InsertAtHead Whether the cloned DPValues should be placed at the end
   ///    or the beginning of existing DPValues attached to this.
   /// \returns A range over the newly cloned DPValues.
-  iterator_range<simple_ilist<DPValue>::iterator> cloneDebugInfoFrom(
+  iterator_range<simple_ilist<DbgRecord>::iterator> cloneDebugInfoFrom(
       const Instruction *From,
-      std::optional<simple_ilist<DPValue>::iterator> FromHere = std::nullopt,
+      std::optional<simple_ilist<DbgRecord>::iterator> FromHere = std::nullopt,
       bool InsertAtHead = false);
 
   /// Return a range over the DPValues attached to this instruction.
-  iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange() const {
+  iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange() const {
     return llvm::getDbgValueRange(DbgMarker);
   }
 
   /// Return an iterator to the position of the "Next" DPValue after this
   /// instruction, or std::nullopt. This is the position to pass to
   /// BasicBlock::reinsertInstInDPValues when re-inserting an instruction.
-  std::optional<simple_ilist<DPValue>::iterator> getDbgReinsertionPosition();
+  std::optional<simple_ilist<DbgRecord>::iterator> getDbgReinsertionPosition();
 
   /// Returns true if any DPValues are attached to this instruction.
   bool hasDbgValues() const;
@@ -100,7 +101,7 @@ class Instruction : public User,
   void dropDbgValues();
 
   /// Erase a single DPValue \p I that is attached to this instruction.
-  void dropOneDbgValue(DPValue *I);
+  void dropOneDbgValue(DbgRecord *I);
 
   /// Handle the debug-info implications of this instruction being removed. Any
   /// attached DPValues need to "fall" down onto the next instruction.
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index da6744fdd09166..715d0fa6e028d2 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -44,6 +44,7 @@ class Module;
 class ModuleSlotTracker;
 class raw_ostream;
 class DPValue;
+class DbgRecord;
 template <typename T> class StringMapEntry;
 template <typename ValueTy> class StringMapEntryStorage;
 class Type;
diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
index e1f2796d97ceb1..dd183bc04f0c24 100644
--- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
@@ -22,7 +22,8 @@
 namespace llvm {
 
 class Constant;
-class DPValue;
+class DIBuilder;
+class DbgRecord;
 class Function;
 class GlobalVariable;
 class Instruction;
@@ -33,7 +34,7 @@ class Type;
 class Value;
 
 using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
-using DPValueIterator = simple_ilist<DPValue>::iterator;
+using DbgRecordIterator = simple_ilist<DbgRecord>::iterator;
 
 /// This is a class that can be implemented by clients to remap types when
 /// cloning constants and instructions.
@@ -180,7 +181,7 @@ class ValueMapper {
 
   void remapInstruction(Instruction &I);
   void remapDPValue(Module *M, DPValue &V);
-  void remapDPValueRange(Module *M, iterator_range<DPValueIterator> Range);
+  void remapDPValueRange(Module *M, iterator_range<DbgRecordIterator> Range);
   void remapFunction(Function &F);
   void remapGlobalObjectMetadata(GlobalObject &GO);
 
@@ -275,7 +276,8 @@ inline void RemapDPValue(Module *M, DPValue *V, ValueToValueMapTy &VM,
 }
 
 /// Remap the Values used in the DPValue \a V using the value map \a VM.
-inline void RemapDPValueRange(Module *M, iterator_range<DPValueIterator> Range,
+inline void RemapDPValueRange(Module *M,
+                              iterator_range<DbgRecordIterator> Range,
                               ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
                               ValueMapTypeRemapper *TypeMapper = nullptr,
                               ValueMaterializer *Materializer = nullptr) {
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 32a25b49b4e4b0..4036f18dbc6794 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -8505,7 +8505,7 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
 
 bool CodeGenPrepare::fixupDPValuesOnInst(Instruction &I) {
   bool AnyChange = false;
-  for (DPValue &DPV : I.getDbgValueRange())
+  for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
     AnyChange |= fixupDPValue(DPV);
   return AnyChange;
 }
@@ -8618,7 +8618,8 @@ bool CodeGenPrepare::placeDbgValues(Function &F) {
 
       // If this isn't a dbg.value, process any attached DPValue records
       // attached to this instruction.
-      for (DPValue &DPV : llvm::make_early_inc_range(Insn.getDbgValueRange())) {
+      for (DPValue &DPV : llvm::make_early_inc_range(
+               DPValue::filter(Insn.getDbgValueRange()))) {
         if (DPV.Type != DPValue::LocationType::Value)
           continue;
         DbgProcessor(&DPV, &Insn);
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index f8756527da87f6..5651498dd3f5aa 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1188,10 +1188,12 @@ void FastISel::handleDbgInfo(const Instruction *II) {
   MIMD = MIMetadata();
 
   // Reverse order of debug records, because fast-isel walks through backwards.
-  for (DPValue &DPV : llvm::reverse(II->getDbgValueRange())) {
+  for (DbgRecord &DPR : llvm::reverse(II->getDbgValueRange())) {
     flushLocalValueMap();
     recomputeInsertPt();
 
+    DPValue &DPV = cast<DPValue>(DPR);
+
     Value *V = nullptr;
     if (!DPV.hasArgList())
       V = DPV.getVariableLocationOp(0);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index b2782cbdc73e86..2bdf48643edc3b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1250,7 +1250,8 @@ 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 (DPValue &DPV : I.getDbgValueRange()) {
+  for (DbgRecord &DPR : I.getDbgValueRange()) {
+    DPValue &DPV = cast<DPValue>(DPR);
     DILocalVariable *Variable = DPV.getVariable();
     DIExpression *Expression = DPV.getExpression();
     dropDanglingDebugInfo(Variable, Expression);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index ad5a3302230c86..9b5ab4267b80e9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1461,9 +1461,8 @@ static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) {
     if (DI && processDbgDeclare(FuncInfo, DI->getAddress(), DI->getExpression(),
                                 DI->getVariable(), DI->getDebugLoc()))
       FuncInfo.PreprocessedDbgDeclares.insert(DI);
-
-    for (const DPValue &DPV : I.getDbgValueRange()) {
-      if (DPV.getType() == DPValue::LocationType::Declare &&
+    for (const DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
+      if (DPV.Type == DPValue::LocationType::Declare &&
           processDbgDeclare(FuncInfo, DPV.getVariableLocationOp(0),
                             DPV.getExpression(), DPV.getVariable(),
                             DPV.getDebugLoc()))
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index d3c64a57f7fdfd..d96f0469fbbcd8 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -862,7 +862,7 @@ class SlotTracker : public AbstractSlotTrackerStorage {
   void processInstructionMetadata(const Instruction &I);
 
   /// Add all of the metadata from an instruction.
-  void processDPValueMetadata(const DPValue &DPV);
+  void processDbgRecordMetadata(const DbgRecord &DPV);
 };
 
 } // end namespace llvm
@@ -1131,18 +1131,21 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
   processGlobalObjectMetadata(F);
   for (auto &BB : F) {
     for (auto &I : BB) {
-      for (const DPValue &DPV : I.getDbgValueRange())
-        processDPValueMetadata(DPV);
+      for (const DbgRecord &DPV : I.getDbgValueRange())
+        processDbgRecordMetadata(DPV);
       processInstructionMetadata(I);
     }
   }
 }
 
 void SlotTracker::processDPValueMetadata(const DPValue &DPV) {
-  CreateMetadataSlot(DPV.getVariable());
-  CreateMetadataSlot(DPV.getDebugLoc());
-  if (DPV.isDbgAssign()) {
-    CreateMetadataSlot(DPV.getAssignID());
+  if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) {
+    CreateMetadataSlot(DPV->getVariable());
+    CreateMetadataSlot(DPV->getDebugLoc());
+    if (DPV.isDbgAssign()) {
+      CreateMetadataSlot(DPV.getAssignID());
+  } else {
+    llvm_unreachable("unsupported DbgRecord kind");
   }
 }
 
@@ -2673,6 +2676,7 @@ class AssemblyWriter {
   void printInstruction(const Instruction &I);
   void printDPMarker(const DPMarker &DPI);
   void printDPValue(const DPValue &DPI);
+  void printDbgRecord(const DbgRecord &DPI);
 
   void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
   void printUseLists(const Function *F);
@@ -4561,8 +4565,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
 void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
   // There's no formal representation of a DPMarker -- print purely as a
   // debugging aid.
-  for (const DPValue &DPI2 : Marker.StoredDPValues) {
-    printDPValue(DPI2);
+  for (const DbgRecord &DPR : Marker.StoredDPValues) {
+    printDbgRecord(DPR);
     Out << "\n";
   }
 
@@ -4572,6 +4576,13 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
   return;
 }
 
+void AssemblyWriter::printDbgRecord(const DbgRecord &DR) {
+  if (auto *DPV = dyn_cast<DPValue>(&DR))
+    printDPValue(*DPV);
+  else
+    llvm_unreachable("unsupported dbg record");
+}
+
 void AssemblyWriter::printDPValue(const DPValue &Value) {
   // There's no formal representation of a DPValue -- print purely as a
   // debugging aid.
@@ -5144,7 +5155,7 @@ void DPMarker::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'
 
 // Value::dump - allow easy printing of Values from the debugger.
 LLVM_DUMP_METHOD
-void DPValue::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
+void DbgRecord::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }
 
 // Type::dump - allow easy printing of Types from the debugger.
 LLVM_DUMP_METHOD
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index bf02eba9fb448d..4e36c258d5e947 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -70,7 +70,7 @@ void BasicBlock::convertToNewDbgValues() {
   // Iterate over all instructions in the instruction list, collecting dbg.value
   // instructions and converting them to DPValues. Once we find a "real"
   // instruction, attach all those DPValues to a DPMarker in that instruction.
-  SmallVector<DPValue *, 4> DPVals;
+  SmallVector<DbgRecord *, 4> DPVals;
   for (Instruction &I : make_early_inc_range(InstList)) {
     assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?");
     if (DbgVariableIntrinsic *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
@@ -88,7 +88,7 @@ void BasicBlock::convertToNewDbgValues() {
     createMarker(&I);
     DPMarker *Marker = I.DbgMarker;
 
-    for (DPValue *DPV : DPVals)
+    for (DbgRecord *DPV : DPVals)
       Marker->insertDPValue(DPV, false);
 
     DPVals.clear();
@@ -107,9 +107,13 @@ void BasicBlock::convertFromNewDbgValues() {
       continue;
 
     DPMarker &Marker = *Inst.DbgMarker;
-    for (DPValue &DPV : Marker.getDbgValueRange())
-      InstList.insert(Inst.getIterator(),
-                      DPV.createDebugIntrinsic(getModule(), nullptr));
+    for (DbgRecord &DPR : Marker.getDbgValueRange()) {
+      if (auto *DPV = dyn_cast<DPValue>(&DPR))
+        InstList.insert(Inst.getIterator(),
+                        DPV->createDebugIntrinsic(getModule(), nullptr));
+      else
+        llvm_unreachable("unsupported entity kind");
+    }
 
     Marker.eraseFromParent();
   };
@@ -163,9 +167,9 @@ bool BasicBlock::validateDbgValues(bool Assert, bool Msg, raw_ostream *OS) {
                 "Debug Marker points to incorrect instruction?");
 
     // Now validate any DPValues in the marker.
-    for (DPValue &DPV : CurrentDebugMarker->getDbgValueRange()) {
+    for (DbgRecord &DPR : CurrentDebugMarker->getDbgValueRange()) {
       // Validate DebugProgramValues.
-      TestFailure(DPV.getMarker() == CurrentDebugMarker,
+      TestFailure(DPR.getMarker() == CurrentDebugMarker,
                   "Not pointing at correct next marker!");
 
       // Verify that no DbgValues appear prior to PHIs.
@@ -1086,7 +1090,7 @@ void BasicBlock::splice(iterator Dest, BasicBlock *Src, iterator First,
   flushTerminatorDbgValues();
 }
 
-void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) {
+void BasicBlock::insertDPValueAfter(DbgRecord *DPV, Instruction *I) {
   assert(IsNewDbgInfoFormat);
   assert(I->getParent() == this);
 
@@ -1095,7 +1099,7 @@ void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) {
   NextMarker->insertDPValue(DPV, true);
 }
 
-void BasicBlock::insertDPValueBefore(DPValue *DPV,
+void BasicBlock::insertDPValueBefore(DbgRecord *DPV,
                                      InstListType::iterator Where) {
   // We should never directly insert at the end of the block, new DPValues
   // shouldn't be generated at times when there's no terminator.
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index eaa5cb36a49c14..17c7e8e787350e 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -125,10 +125,11 @@ static void findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V,
       if (!DPValues)
         continue;
       DIArgList *DI = cast<DIArgList>(AL);
-      for (DPValue *DPV : DI->getAllDPValueUsers())
+      for (DPValue *DPV : DI->getAllDPValueUsers()) {
         if (Type == DPValue::LocationType::Any || DPV->getType() == Type)
           if (EncounteredDPValues.insert(DPV).second)
             DPValues->push_back(DPV);
+      }
     }
   }
 }
@@ -240,8 +241,8 @@ void DebugInfoFinder::processInstruction(const Module &M,
   if (auto DbgLoc = I.getDebugLoc())
     processLocation(M, DbgLoc.get());
 
-  for (const DPValue &DPV : I.getDbgValueRange())
-    processDPValue(M, DPV);
+  for (const DbgRecord &DPR : I.getDbgValueRange())
+    processDbgRecord(M, DPR);
 }
 
 void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
@@ -256,6 +257,10 @@ void DebugInfoFinder::processDPValue(const Module &M, const DPValue &DPV) {
   processLocation(M, DPV.getDebugLoc().get());
 }
 
+void DebugInfoFinder::processDbgRecord(const Module &M, const DbgRecord &DPR) {
+  processDPValue(M, cast<DPValue>(DPR));
+}
+
 void DebugInfoFinder::processType(DIType *DT) {
   if (!addType(DT))
     return;
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index a2640d59242ac2..a72c6408766045 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -14,9 +14,9 @@
 namespace llvm {
 
 DPValue::DPValue(const DbgVariableIntrinsic *DVI)
-    : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
-      Variable(DVI->getVariable()), Expression(DVI->getExpression()),
-      DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
+    : DbgRecord(ValueKind, DVI->getDebugLoc()),
+      DebugValueUser(DVI->getRawLocation(), nullptr, nullptr), Variable(DVI->getVariable()),
+      Expression(DVI->getExpression()) {
   switch (DVI->getIntrinsicID()) {
   case Intrinsic::dbg_value:
     Type = LocationType::Value;
@@ -40,24 +40,45 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI)
 }
 
 DPValue::DPValue(const DPValue &DPV)
-    : DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()),
-      Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()),
-      AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {}
+    : DbgRecord(ValueKind, DPV.getDebugLoc()),
+      DebugValueUser({DPV.DebugValues, nullptr, nullptr}), Type(DPV.getType()),
+      Variable(DPV.getVariable()), Expression(DPV.getExpression()), AddressExpression(DPV.AddressExpression) {}
 
 DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
                  const DILocation *DI, LocationType Type)
-    : DebugValueUser({Location, nullptr, nullptr}), Variable(DV),
-      Expression(Expr), DbgLoc(DI), Type(Type) {}
+    : DbgRecord(ValueKind, DI), DebugValueUser(Location), Type(Type),
+      Variable(DV), Expression(Expr) {}
 
-DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
-                 DIExpression *Expression, DIAssignID *AssignID,
-                 Metadata *Address, DIExpression *AddressExpression,
-                 const DILocation *DI)
-    : DebugValueUser({Value, Address, AssignID}), Variable(Variable),
-      Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
-      Type(LocationType::Assign) {}
+void DbgRecord::deleteRecord() {
+  switch (RecordKind) {
+  case ValueKind:
+    delete cast<DPValue>(this);
+    break;
+  default:
+    llvm_unreachable("unsupported record kind");
+  }
+}
 
-void DPValue::deleteInstr() { delete this; }
+void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
+  switch (RecordKind) {
+  case ValueKind:
+    cast<DPValue>(this)->print(O, IsForDebug);
+    break;
+  default:
+    llvm_unreachable("unsupported record kind");
+  };
+}
+
+void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,
+                      bool IsForDebug) const {
+  switch (RecordKind) {
+  case ValueKind:
+    cast<DPValue>(this)->print(O, MST, IsForDebug);
+    break;
+  default:
+    llvm_unreachable("unsupported record kind");
+  };
+}
 
 DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
                                 DIExpression *Expr, const DILocation *DI) {
@@ -255,6 +276,15 @@ std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
   return getVariable()->getSizeInBits();
 }
 
+DbgRecord *DbgRecord::clone() const {
+  switch (RecordKind) {
+  case ValueKind:
+    return cast<DPValue>(this)->clone();
+  default:
+    llvm_unreachable("unsupported record kind");
+  };
+}
+
 DPValue *DPValue::clone() const { return new DPValue(*this); }
 
 DbgVariableIntrinsic *
@@ -342,27 +372,31 @@ const Instruction *DPValue::getInstruction() const {
   return Marker->MarkedInstr;
 }
 
-const BasicBlock *DPValue::getParent() const {
+const BasicBlock *DbgRecord::getParent() const {
   return Marker->MarkedInstr->getParent();
 }
 
-BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); }
+BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); }
 
-BasicBlock *DPValue::getBlock() { return Marker->getParent(); }
+BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); }
 
-const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); }
+const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); }
 
-Function *DPValue::getFunction() { return getBlock()->getParent(); }
+Function *DbgRecord::getFunction() { return getBlock()->getParent(); }
 
-const Function *DPValue::getFunction() const { return getBlock()->getParent(); }
+const Function *DbgRecord::getFunction() const {
+  return getBlock()->getParent();
+}
 
-Module *DPValue::getModule() { return getFunction()->getParent(); }
+Module *DbgRecord::getModule() { return getFunction()->getParent(); }
 
-const Module *DPValue::getModule() const { return getFunction()->getParent(); }
+const Module *DbgRecord::getModule() const {
+  return getFunction()->getParent();
+}
 
-LLVMContext &DPValue::getContext() { return getBlock()->getContext(); }
+LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); }
 
-const LLVMContext &DPValue::getContext() const {
+const LLVMContext &DbgRecord::getContext() const {
   return getBlock()->getContext();
 }
 
@@ -401,19 +435,19 @@ void DPValue::moveAfter(DPValue *MoveAfter) {
 // DPValues.
 DPMarker DPMarker::EmptyDPMarker;
 
-void DPMarker::dropDPValues() {
+void DPMarker::dropDbgValues() {
   while (!StoredDPValues.empty()) {
     auto It = StoredDPValues.begin();
-    DPValue *DPV = &*It;
+    DbgRecord *DPE = &*It;
     StoredDPValues.erase(It);
-    DPV->deleteInstr();
+    DPE->deleteRecord();
   }
 }
 
-void DPMarker::dropOneDPValue(DPValue *DPV) {
-  assert(DPV->getMarker() == this);
-  StoredDPValues.erase(DPV->getIterator());
-  DPV->deleteInstr();
+void DPMarker::dropOneDbgValue(DbgRecord *DPE) {
+  assert(DPE->getMarker() == this);
+  StoredDPValues.erase(DPE->getIterator());
+  DPE->deleteRecord();
 }
 
 const BasicBlock *DPMarker::getParent() const {
@@ -462,11 +496,15 @@ void DPMarker::removeFromParent() {
 void DPMarker::eraseFromParent() {
   if (MarkedInstr)
     removeFromParent();
-  dropDPValues();
+  dropDbgValues();
   delete this;
 }
 
-iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() {
+iterator_range<DbgRecord::self_iterator> DPMarker::getDbgValueRange() {
+  return make_range(StoredDPValues.begin(), StoredDPValues.end());
+}
+iterator_range<DPValue::const_self_iterator>
+DPMarker::getDbgValueRange() const {
   return make_range(StoredDPValues.begin(), StoredDPValues.end());
 }
 iterator_range<DPValue::const_self_iterator>
@@ -474,17 +512,17 @@ DPMarker::getDbgValueRange() const {
   return make_range(StoredDPValues.begin(), StoredDPValues.end());
 }
 
-void DPValue::removeFromParent() {
+void DbgRecord::removeFromParent() {
   getMarker()->StoredDPValues.erase(getIterator());
   Marker = nullptr;
 }
 
-void DPValue::eraseFromParent() {
+void DbgRecord::eraseFromParent() {
   removeFromParent();
-  deleteInstr();
+  deleteRecord();
 }
 
-void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) {
+void DPMarker::insertDPValue(DbgRecord *New, bool InsertAtHead) {
   auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
   StoredDPValues.insert(It, *New);
   New->setMarker(this);
@@ -504,16 +542,16 @@ void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) {
 
 void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
   auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
-  for (DPValue &DPV : Src.StoredDPValues)
+  for (DbgRecord &DPV : Src.StoredDPValues)
     DPV.setMarker(this);
 
   StoredDPValues.splice(It, Src.StoredDPValues);
 }
 
-void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
+void DPMarker::absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
                                  DPMarker &Src, bool InsertAtHead) {
-  for (DPValue &DPV : Range)
-    DPV.setMarker(this);
+  for (DbgRecord &DPE : Range)
+    DPE.setMarker(this);
 
   auto InsertPos =
       (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
@@ -522,10 +560,10 @@ void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
                         Range.end());
 }
 
-iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
-    DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here,
+iterator_range<simple_ilist<DbgRecord>::iterator> DPMarker::cloneDebugInfoFrom(
+    DPMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here,
     bool InsertAtHead) {
-  DPValue *First = nullptr;
+  DbgRecord *First = nullptr;
   // Work out what range of DPValues to clone: normally all the contents of the
   // "From" marker, optionally we can start from the from_here position down to
   // end().
@@ -537,8 +575,8 @@ iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
   // Clone each DPValue and insert into StoreDPValues; optionally place them at
   // the start or the end of the list.
   auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
-  for (DPValue &DPV : Range) {
-    DPValue *New = DPV.clone();
+  for (DbgRecord &DPE : Range) {
+    DbgRecord *New = DPE.clone();
     New->setMarker(this);
     StoredDPValues.insert(Pos, *New);
     if (!First)
@@ -558,4 +596,3 @@ iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
 }
 
 } // end namespace llvm
-
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 23a3e72da51d44..345b050b7077a9 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -218,10 +218,9 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I,
     getParent()->flushTerminatorDbgValues();
 }
 
-iterator_range<DPValue::self_iterator>
-Instruction::cloneDebugInfoFrom(const Instruction *From,
-                                std::optional<DPValue::self_iterator> FromHere,
-                                bool InsertAtHead) {
+iterator_range<DbgRecord::self_iterator> Instruction::cloneDebugInfoFrom(
+    const Instruction *From, std::optional<DbgRecord::self_iterator> FromHere,
+    bool InsertAtHead) {
   if (!From->DbgMarker)
     return DPMarker::getEmptyDPValueRange();
 
@@ -235,7 +234,8 @@ Instruction::cloneDebugInfoFrom(const Instruction *From,
   return DbgMarker->cloneDebugInfoFrom(From->DbgMarker, FromHere, InsertAtHead);
 }
 
-std::optional<DPValue::self_iterator> Instruction::getDbgReinsertionPosition() {
+std::optional<DbgRecord::self_iterator>
+Instruction::getDbgReinsertionPosition() {
   // Is there a marker on the next instruction?
   DPMarker *NextMarker = getParent()->getNextMarker(this);
   if (!NextMarker)
@@ -294,11 +294,11 @@ void Instruction::adoptDbgValues(BasicBlock *BB, BasicBlock::iterator It,
 
 void Instruction::dropDbgValues() {
   if (DbgMarker)
-    DbgMarker->dropDPValues();
+    DbgMarker->dropDbgValues();
 }
 
-void Instruction::dropOneDbgValue(DPValue *DPV) {
-  DbgMarker->dropOneDPValue(DPV);
+void Instruction::dropOneDbgValue(DbgRecord *DPV) {
+  DbgMarker->dropOneDbgValue(DPV);
 }
 
 bool Instruction::comesBefore(const Instruction *Other) const {
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index e69c718f0ae3ac..c3c4de4278b9cc 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -1925,7 +1925,7 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
       U->replaceUsesOfWith(Def, CurrentReload);
       // Instructions are added to Def's user list if the attached
       // debug records use Def. Update those now.
-      for (auto &DPV : U->getDbgValueRange())
+      for (DPValue &DPV : DPValue::filter(U->getDbgValueRange()))
         DPV.replaceVariableLocationOp(Def, CurrentReload, true);
     }
   }
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index aed4cd027d0338..e802b5789b4dcb 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -627,7 +627,7 @@ collectDbgVariableIntrinsics(Function &F) {
   SmallVector<DbgVariableIntrinsic *, 8> Intrinsics;
   SmallVector<DPValue *> DPValues;
   for (auto &I : instructions(F)) {
-    for (DPValue &DPV : I.getDbgValueRange())
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
       DPValues.push_back(&DPV);
     if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
       Intrinsics.push_back(DVI);
diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp
index 90b544c8922623..ab6513884d646e 100644
--- a/llvm/lib/Transforms/Scalar/ADCE.cpp
+++ b/llvm/lib/Transforms/Scalar/ADCE.cpp
@@ -548,15 +548,15 @@ ADCEChanged AggressiveDeadCodeElimination::removeDeadInstructions() {
     // attached to this instruction, and drop any for scopes that aren't alive,
     // like the rest of this loop does. Extending support to assignment tracking
     // is future work.
-    for (DPValue &DPV : make_early_inc_range(I.getDbgValueRange())) {
+    for (DbgRecord &DR : make_early_inc_range(I.getDbgValueRange())) {
       // Avoid removing a DPV that is linked to instructions because it holds
       // information about an existing store.
-      if (DPV.isDbgAssign())
-        if (!at::getAssignmentInsts(&DPV).empty())
+      if (DR.isDbgAssign())
+        if (!at::getAssignmentInsts(&DR).empty())
           continue;
-      if (AliveScopes.count(DPV.getDebugLoc()->getScope()))
+      if (AliveScopes.count(DR.getDebugLoc()->getScope()))
         continue;
-      I.dropOneDbgValue(&DPV);
+      I.dropOneDbgValue(&DR);
     }
 
     // Check if the instruction is alive.
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index bb33a5da288ce9..5816bf2a22598d 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -401,7 +401,7 @@ static bool replaceFoldableUses(Instruction *Cond, Value *ToVal,
     Changed |= replaceNonLocalUsesWith(Cond, ToVal);
   for (Instruction &I : reverse(*KnownAtEndOfBB)) {
     // Replace any debug-info record users of Cond with ToVal.
-    for (DPValue &DPV : I.getDbgValueRange())
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
       DPV.replaceVariableLocationOp(Cond, ToVal, true);
 
     // Reached the Cond whose uses we are trying to replace, so there are no
@@ -2082,7 +2082,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
 
   auto CloneAndRemapDbgInfo = [&](Instruction *NewInst, Instruction *From) {
     auto DPVRange = NewInst->cloneDebugInfoFrom(From);
-    for (DPValue &DPV : DPVRange)
+    for (DPValue &DPV : DPValue::filter(DPVRange))
       RetargetDPValueIfPossible(&DPV);
   };
 
@@ -2117,7 +2117,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI,
     DPMarker *Marker = RangeBB->getMarker(BE);
     DPMarker *EndMarker = NewBB->createMarker(NewBB->end());
     auto DPVRange = EndMarker->cloneDebugInfoFrom(Marker, std::nullopt);
-    for (DPValue &DPV : DPVRange)
+    for (DPValue &DPV : DPValue::filter(DPVRange))
       RetargetDPValueIfPossible(&DPV);
   }
 
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index ec0482ac2cdeb4..4eee3387647be2 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -386,7 +386,7 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) {
   SmallVector<DPValue *, 8> ToBeRemoved;
   SmallDenseSet<DebugVariable> VariableSet;
   for (auto &I : reverse(*BB)) {
-    for (DPValue &DPV : reverse(I.getDbgValueRange())) {
+    for (DPValue &DPV : reverse(DPValue::filter(I.getDbgValueRange()))) {
       // Skip declare-type records, as the debug intrinsic method only works
       // on dbg.value intrinsics.
       if (DPV.getType() == DPValue::LocationType::Declare) {
@@ -496,7 +496,7 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) {
   DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>>
       VariableMap;
   for (auto &I : *BB) {
-    for (DPValue &DPV : I.getDbgValueRange()) {
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
       if (DPV.getType() == DPValue::LocationType::Declare)
         continue;
       DebugVariable Key(DPV.getVariable(), std::nullopt,
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 57d3926515993f..8ebcf0c04fd5a9 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -1586,7 +1586,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
   };
 
   auto UpdateDPValuesOnInst = [&](Instruction &I) -> void {
-    for (auto &DPV : I.getDbgValueRange()) {
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
       // Apply the two updates that dbg.values get: invalid operands, and
       // variable metadata fixup.
       if (any_of(DPV.location_ops(), IsInvalidLocation)) {
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index d4d4bf5ebdf36e..f888cc336d937d 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1710,7 +1710,7 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
   };
 
   // Helper-util for updating debug-info records attached to instructions.
-  auto UpdateDPV = [&](DPValue *DPV) {
+  auto UpdateDPV = [&](DbgRecord *DPV) {
     assert(DPV->getDebugLoc() && "Debug Value must have debug loc");
     if (NoInlineLineTables) {
       DPV->setDebugLoc(TheCallDL);
@@ -1728,7 +1728,7 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
          ++BI) {
       UpdateInst(*BI);
-      for (DPValue &DPV : BI->getDbgValueRange()) {
+      for (DbgRecord &DPV : BI->getDbgValueRange()) {
         UpdateDPV(&DPV);
       }
     }
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index e4aa25f7ac6ad3..1373f5f7f4490c 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1911,7 +1911,7 @@ bool llvm::LowerDbgDeclare(Function &F) {
     for (Instruction &BI : FI) {
       if (auto *DDI = dyn_cast<DbgDeclareInst>(&BI))
         Dbgs.push_back(DDI);
-      for (DPValue &DPV : BI.getDbgValueRange()) {
+      for (DPValue &DPV : DPValue::filter(BI.getDbgValueRange())) {
         if (DPV.getType() == DPValue::LocationType::Declare)
           DPVs.push_back(&DPV);
       }
@@ -1996,7 +1996,7 @@ static void insertDPValuesForPHIs(BasicBlock *BB,
   // Map existing PHI nodes to their DPValues.
   DenseMap<Value *, DPValue *> DbgValueMap;
   for (auto &I : *BB) {
-    for (auto &DPV : I.getDbgValueRange()) {
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
       for (Value *V : DPV.location_ops())
         if (auto *Loc = dyn_cast_or_null<PHINode>(V))
           DbgValueMap.insert({Loc, &DPV});
diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
index ec59a077302037..b12c1b9bb9d5e4 100644
--- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
@@ -554,7 +554,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
         DbgIntrinsics.insert(makeHash(DII));
         // Until RemoveDIs supports dbg.declares in DPValue format, we'll need
         // to collect DPValues attached to any other debug intrinsics.
-        for (const DPValue &DPV : DII->getDbgValueRange())
+        for (const DPValue &DPV : DPValue::filter(DII->getDbgValueRange()))
           DbgIntrinsics.insert(makeHash(&DPV));
       } else {
         break;
@@ -564,7 +564,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
     // Build DPValue hashes for DPValues attached to the terminator, which isn't
     // considered in the loop above.
     for (const DPValue &DPV :
-         OrigPreheader->getTerminator()->getDbgValueRange())
+         DPValue::filter(OrigPreheader->getTerminator()->getDbgValueRange()))
       DbgIntrinsics.insert(makeHash(&DPV));
 
     // Remember the local noalias scope declarations in the header. After the
@@ -621,7 +621,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
           RemapDPValueRange(M, DbgValueRange, ValueMap,
                             RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
           // Erase anything we've seen before.
-          for (DPValue &DPV : make_early_inc_range(DbgValueRange))
+          for (DPValue &DPV :
+               make_early_inc_range(DPValue::filter(DbgValueRange)))
             if (DbgIntrinsics.count(makeHash(&DPV)))
               DPV.eraseFromParent();
         }
@@ -647,7 +648,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
                           RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
         NextDbgInsts = DPMarker::getEmptyDPValueRange();
         // Erase anything we've seen before.
-        for (DPValue &DPV : make_early_inc_range(Range))
+        for (DPValue &DPV : make_early_inc_range(DPValue::filter(Range)))
           if (DbgIntrinsics.count(makeHash(&DPV)))
             DPV.eraseFromParent();
       }
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 002bc90c9b5677..a4fdc1f8c12e50 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -632,8 +632,8 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
 
         // RemoveDIs: do the same as below for DPValues.
         if (Block->IsNewDbgInfoFormat) {
-          for (DPValue &DPV :
-               llvm::make_early_inc_range(I.getDbgValueRange())) {
+          for (DPValue &DPV : llvm::make_early_inc_range(
+                   DPValue::filter(I.getDbgValueRange()))) {
             DebugVariable Key(DPV.getVariable(), DPV.getExpression(),
                               DPV.getDebugLoc().get());
             if (!DeadDebugSet.insert(Key).second)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 7424fe31945dc7..b7099d8947a909 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3847,7 +3847,8 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI,
 
   if (PredBlock->IsNewDbgInfoFormat) {
     PredBlock->getTerminator()->cloneDebugInfoFrom(BB->getTerminator());
-    for (DPValue &DPV : PredBlock->getTerminator()->getDbgValueRange()) {
+    for (DPValue &DPV :
+         DPValue::filter(PredBlock->getTerminator()->getDbgValueRange())) {
       RemapDPValue(M, &DPV, VMap,
                    RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
     }
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 93a4c829df06cb..37585446bfd37c 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -1232,8 +1232,8 @@ void ValueMapper::remapDPValue(Module *M, DPValue &V) {
 }
 
 void ValueMapper::remapDPValueRange(
-    Module *M, iterator_range<DPValue::self_iterator> Range) {
-  for (DPValue &DPV : Range) {
+    Module *M, iterator_range<DbgRecord::self_iterator> Range) {
+  for (DPValue &DPV : DPValue::filter(Range)) {
     remapDPValue(M, DPV);
   }
 }
diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
index 53b191c6883841..b773bffd7a03fc 100644
--- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
+++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
@@ -163,8 +163,8 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) {
   EXPECT_EQ(Marker2->StoredDPValues.size(), 1u);
 
   // Unlink them and try to re-insert them through the basic block.
-  DPValue *DPV1 = &*Marker1->StoredDPValues.begin();
-  DPValue *DPV2 = &*Marker2->StoredDPValues.begin();
+  DbgRecord *DPV1 = &*Marker1->StoredDPValues.begin();
+  DbgRecord *DPV2 = &*Marker2->StoredDPValues.begin();
   DPV1->removeFromParent();
   DPV2->removeFromParent();
   EXPECT_TRUE(Marker1->StoredDPValues.empty());
@@ -188,8 +188,8 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) {
   EXPECT_EQ(BB.size(), 1u);
   EXPECT_EQ(Marker2->StoredDPValues.size(), 2u);
   // They should also be in the correct order.
-  SmallVector<DPValue *, 2> DPVs;
-  for (DPValue &DPV : Marker2->getDbgValueRange())
+  SmallVector<DbgRecord *, 2> DPVs;
+  for (DbgRecord &DPV : Marker2->getDbgValueRange())
     DPVs.push_back(&DPV);
   EXPECT_EQ(DPVs[0], DPV1);
   EXPECT_EQ(DPVs[1], DPV2);
@@ -199,13 +199,13 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) {
   EXPECT_EQ(BB.getTrailingDPValues(), nullptr);
   Instr2->removeFromParent();
   EXPECT_TRUE(BB.empty());
-  EndMarker = BB.getTrailingDPValues();;
+  EndMarker = BB.getTrailingDPValues();
   ASSERT_NE(EndMarker, nullptr);
   EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u);
   // Again, these should arrive in the correct order.
 
   DPVs.clear();
-  for (DPValue &DPV : EndMarker->getDbgValueRange())
+  for (DbgRecord &DPV : EndMarker->getDbgValueRange())
     DPVs.push_back(&DPV);
   EXPECT_EQ(DPVs[0], DPV1);
   EXPECT_EQ(DPVs[1], DPV2);
@@ -226,7 +226,7 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) {
 
   // Remove Instr1: now the DPValues will fall down again,
   Instr1->removeFromParent();
-  EndMarker = BB.getTrailingDPValues();;
+  EndMarker = BB.getTrailingDPValues();
   EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u);
 
   // Inserting a terminator, however it's intended, should dislodge the
@@ -391,7 +391,7 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) {
   ASSERT_FALSE(BInst->DbgMarker);
   ASSERT_TRUE(CInst->DbgMarker);
   ASSERT_EQ(CInst->DbgMarker->StoredDPValues.size(), 1u);
-  DPValue *DPV1 = &*CInst->DbgMarker->StoredDPValues.begin();
+  DbgRecord *DPV1 = &*CInst->DbgMarker->StoredDPValues.begin();
   ASSERT_TRUE(DPV1);
   EXPECT_FALSE(BInst->hasDbgValues());
 
@@ -399,7 +399,7 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) {
   // tested in DPMarker test.
   auto Range1 = BInst->cloneDebugInfoFrom(CInst);
   EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 1u);
-  DPValue *DPV2 = &*BInst->DbgMarker->StoredDPValues.begin();
+  DbgRecord *DPV2 = &*BInst->DbgMarker->StoredDPValues.begin();
   EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u);
   EXPECT_EQ(&*Range1.begin(), DPV2);
   EXPECT_NE(DPV1, DPV2);
@@ -531,15 +531,15 @@ class DbgSpliceTest : public ::testing::Test {
     Branch = &*Last;
     CInst = &*Dest;
 
-    DPVA = &*BInst->DbgMarker->StoredDPValues.begin();
-    DPVB = &*Branch->DbgMarker->StoredDPValues.begin();
-    DPVConst = &*CInst->DbgMarker->StoredDPValues.begin();
+    DPVA = cast<DPValue>(&*BInst->DbgMarker->StoredDPValues.begin());
+    DPVB = cast<DPValue>(&*Branch->DbgMarker->StoredDPValues.begin());
+    DPVConst = cast<DPValue>(&*CInst->DbgMarker->StoredDPValues.begin());
   }
 
   void TearDown() override { UseNewDbgInfoFormat = false; }
 
   bool InstContainsDPValue(Instruction *I, DPValue *DPV) {
-    for (DPValue &D : I->getDbgValueRange()) {
+    for (DbgRecord &D : I->getDbgValueRange()) {
       if (&D == DPV) {
         // Confirm too that the links between the records are correct.
         EXPECT_EQ(DPV->Marker, I->DbgMarker);
@@ -551,8 +551,8 @@ class DbgSpliceTest : public ::testing::Test {
   }
 
   bool CheckDPVOrder(Instruction *I, SmallVector<DPValue *> CheckVals) {
-    SmallVector<DPValue *> Vals;
-    for (DPValue &D : I->getDbgValueRange())
+    SmallVector<DbgRecord *> Vals;
+    for (DbgRecord &D : I->getDbgValueRange())
       Vals.push_back(&D);
 
     EXPECT_EQ(Vals.size(), CheckVals.size());
@@ -1389,8 +1389,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) {
   ASSERT_TRUE(BInst->hasDbgValues());
   EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 2u);
   SmallVector<DPValue *, 2> DPValues;
-  for (DPValue &DPV : BInst->getDbgValueRange())
-    DPValues.push_back(&DPV);
+  for (DbgRecord &DPV : BInst->getDbgValueRange())
+    DPValues.push_back(cast<DPValue>(&DPV));
 
   EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0));
   Value *SecondDPVValue = DPValues[1]->getVariableLocationOp(0);
@@ -1459,8 +1459,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) {
   ASSERT_TRUE(BInst->hasDbgValues());
   EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 1u);
   SmallVector<DPValue *, 2> DPValues;
-  for (DPValue &DPV : BInst->getDbgValueRange())
-    DPValues.push_back(&DPV);
+  for (DbgRecord &DPV : BInst->getDbgValueRange())
+    DPValues.push_back(cast<DPValue>(&DPV));
 
   EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0));
   // No trailing DPValues in the entry block now.
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp
index be8f590a27eb4d..65db93e537f7df 100644
--- a/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/llvm/unittests/IR/DebugInfoTest.cpp
@@ -955,7 +955,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) {
   FirstInst->DbgMarker->insertDPValue(DPV1, false);
   FirstInst->DbgMarker->insertDPValue(DPV2, true);
   unsigned int ItCount = 0;
-  for (DPValue &Item : FirstInst->DbgMarker->getDbgValueRange()) {
+  for (DbgRecord &Item : FirstInst->DbgMarker->getDbgValueRange()) {
     EXPECT_TRUE((&Item == DPV2 && ItCount == 0) ||
               (&Item == DPV1 && ItCount == 1));
     EXPECT_EQ(Item.getMarker(), FirstInst->DbgMarker);
@@ -968,17 +968,18 @@ TEST(MetadataTest, ConvertDbgToDPValue) {
   ItCount = 0;
   // Check these things store the same information; but that they're not the same
   // objects.
-  for (DPValue &Item : RetInst->DbgMarker->getDbgValueRange()) {
+  for (DPValue &Item :
+       DPValue::filter(RetInst->DbgMarker->getDbgValueRange())) {
     EXPECT_TRUE((Item.getRawLocation() == DPV2->getRawLocation() && ItCount == 0) ||
                 (Item.getRawLocation() == DPV1->getRawLocation() && ItCount == 1));
-    
+
     EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker);
     EXPECT_NE(&Item, DPV1);
     EXPECT_NE(&Item, DPV2);
     ++ItCount;
   }
 
-  RetInst->DbgMarker->dropDPValues();
+  RetInst->DbgMarker->dropDbgValues();
   EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 0u);
 
   // Try cloning one single DPValue.
@@ -987,10 +988,12 @@ TEST(MetadataTest, ConvertDbgToDPValue) {
   EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 1u);
   // The second DPValue should have been cloned; it should have the same values
   // as DPV1.
-  EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.begin()->getRawLocation(),
+  EXPECT_EQ(cast<DPValue>(RetInst->DbgMarker->StoredDPValues.begin())
+                ->getRawLocation(),
             DPV1->getRawLocation());
   // We should be able to drop individual DPValues.
-  RetInst->DbgMarker->dropOneDPValue(&*RetInst->DbgMarker->StoredDPValues.begin());
+  RetInst->DbgMarker->dropOneDbgValue(
+      &*RetInst->DbgMarker->StoredDPValues.begin());
 
   // "Aborb" a DPMarker: this means pretend that the instruction it's attached
   // to is disappearing so it needs to be transferred into "this" marker.
@@ -998,7 +1001,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) {
   EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 2u);
   // Should be the DPV1 and DPV2 objects.
   ItCount = 0;
-  for (DPValue &Item : RetInst->DbgMarker->getDbgValueRange()) {
+  for (DbgRecord &Item : RetInst->DbgMarker->getDbgValueRange()) {
     EXPECT_TRUE((&Item == DPV2 && ItCount == 0) ||
               (&Item == DPV1 && ItCount == 1));
     EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker);
@@ -1019,7 +1022,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) {
   EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u);
   // Test again that it's those two DPValues, DPV1 and DPV2.
   ItCount = 0;
-  for (DPValue &Item : EndMarker->getDbgValueRange()) {
+  for (DbgRecord &Item : EndMarker->getDbgValueRange()) {
     EXPECT_TRUE((&Item == DPV2 && ItCount == 0) ||
               (&Item == DPV1 && ItCount == 1));
     EXPECT_EQ(Item.getMarker(), EndMarker);
@@ -1110,13 +1113,15 @@ TEST(MetadataTest, DPValueConversionRoutines) {
   EXPECT_EQ(SecondInst, SecondInst->DbgMarker->MarkedInstr);
 
   EXPECT_EQ(FirstInst->DbgMarker->StoredDPValues.size(), 1u);
-  DPValue *DPV1 = &*FirstInst->DbgMarker->getDbgValueRange().begin();
+  DPValue *DPV1 =
+      cast<DPValue>(&*FirstInst->DbgMarker->getDbgValueRange().begin());
   EXPECT_EQ(DPV1->getMarker(), FirstInst->DbgMarker);
   // Should point at %a, an argument.
   EXPECT_TRUE(isa<Argument>(DPV1->getVariableLocationOp(0)));
 
   EXPECT_EQ(SecondInst->DbgMarker->StoredDPValues.size(), 1u);
-  DPValue *DPV2 = &*SecondInst->DbgMarker->getDbgValueRange().begin();
+  DPValue *DPV2 =
+      cast<DPValue>(&*SecondInst->DbgMarker->getDbgValueRange().begin());
   EXPECT_EQ(DPV2->getMarker(), SecondInst->DbgMarker);
   // Should point at FirstInst.
   EXPECT_EQ(DPV2->getVariableLocationOp(0), FirstInst);
diff --git a/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp
index 760b6b603c6a53..6146719bb29627 100644
--- a/llvm/unittests/IR/ValueTest.cpp
+++ b/llvm/unittests/IR/ValueTest.cpp
@@ -379,8 +379,8 @@ TEST(ValueTest, replaceUsesOutsideBlockDPValue) {
   EXPECT_TRUE(Branch->hasDbgValues());
   EXPECT_TRUE(Ret->hasDbgValues());
 
-  DPValue *DPV1 = &*Branch->getDbgValueRange().begin();
-  DPValue *DPV2 = &*Ret->getDbgValueRange().begin();
+  DPValue *DPV1 = cast<DPValue>(&*Branch->getDbgValueRange().begin());
+  DPValue *DPV2 = cast<DPValue>(&*Ret->getDbgValueRange().begin());
 
   A->replaceUsesOutsideBlock(B, Entry);
   // These users are in Entry so shouldn't be changed.

>From d92252bef5008301e58391f462578365ec629a89 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 19 Feb 2024 17:13:23 +0000
Subject: [PATCH 2/7] rebase fallout

---
 .../include/llvm/IR/DebugProgramInstruction.h | 30 +++++---
 llvm/include/llvm/IR/Instruction.h            |  2 +-
 .../CodeGen/AssignmentTrackingAnalysis.cpp    | 24 +++---
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp  |  2 +-
 llvm/lib/IR/AsmWriter.cpp                     | 10 +--
 llvm/lib/IR/DebugInfo.cpp                     |  4 +-
 llvm/lib/IR/DebugProgramInstruction.cpp       | 76 ++++++++++++-------
 llvm/lib/Transforms/IPO/MergeFunctions.cpp    |  4 +-
 .../InstCombine/InstructionCombining.cpp      |  3 +-
 llvm/lib/Transforms/Scalar/ADCE.cpp           |  4 +-
 .../Transforms/Scalar/LoopStrengthReduce.cpp  |  2 +-
 .../Scalar/SpeculativeExecution.cpp           |  5 +-
 llvm/lib/Transforms/Utils/BasicBlockUtils.cpp |  2 +-
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |  2 +-
 .../Transforms/Utils/MemoryTaggingSupport.cpp |  3 +-
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp     | 20 ++---
 llvm/lib/Transforms/Utils/ValueMapper.cpp     |  9 ++-
 17 files changed, 117 insertions(+), 85 deletions(-)

diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index 1c1dd31d9c3c80..a66efdf0dc0fca 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -77,8 +77,10 @@ class raw_ostream;
 /// We need a discriminator for dyn/isa casts. In order to avoid paying for a
 /// vtable for "virtual" functions too, subclasses must add a new discriminator
 /// value (RecordKind) and cases to a few functions in the base class:
-///   deleteRecord()
-///   clone()
+///   deleteRecord
+///   clone
+///   isIdenticalToWhenDefined
+///   isEquivalentTo
 ///   both print methods
 class DbgRecord : public ilist_node<DbgRecord> {
 public:
@@ -101,6 +103,8 @@ class DbgRecord : public ilist_node<DbgRecord> {
   DbgRecord *clone() const;
   void print(raw_ostream &O, bool IsForDebug = false) const;
   void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const;
+  bool isIdenticalToWhenDefined(const DbgRecord &R) const;
+  bool isEquivalentTo(const DbgRecord &R) const;
   ///@}
 
   Kind getRecordKind() const { return RecordKind; }
@@ -129,11 +133,12 @@ class DbgRecord : public ilist_node<DbgRecord> {
   void removeFromParent();
   void eraseFromParent();
 
-  DPValue *getNextNode() { return &*std::next(getIterator()); }
-  DPValue *getPrevNode() { return &*std::prev(getIterator()); }
-
-  DPValue *getNextNode() { return &*std::next(getIterator()); }
-  DPValue *getPrevNode() { return &*std::prev(getIterator()); }
+  DbgRecord *getNextNode() { return &*std::next(getIterator()); }
+  DbgRecord *getPrevNode() { return &*std::prev(getIterator()); }
+  void insertBefore(DbgRecord *InsertBefore);
+  void insertAfter(DbgRecord *InsertAfter);
+  void moveBefore(DbgRecord *MoveBefore);
+  void moveAfter(DbgRecord *MoveAfter);
 
   DebugLoc getDebugLoc() const { return DbgLoc; }
   void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
@@ -180,6 +185,7 @@ class DPValue : public DbgRecord, protected DebugValueUser {
 
   DILocalVariable *Variable;
   DIExpression *Expression;
+  DIExpression *AddressExpression;
 
 public:
   /// Create a new DPValue representing the intrinsic \p DVI, for example the
@@ -331,12 +337,12 @@ class DPValue : public DbgRecord, protected DebugValueUser {
   /// is described.
   std::optional<uint64_t> getFragmentSizeInBits() const;
 
-  bool isEquivalentTo(const DPValue &Other) {
+  bool isEquivalentTo(const DPValue &Other) const {
     return DbgLoc == Other.DbgLoc && isIdenticalToWhenDefined(Other);
   }
   // Matches the definition of the Instruction version, equivalent to above but
   // without checking DbgLoc.
-  bool isIdenticalToWhenDefined(const DPValue &Other) {
+  bool isIdenticalToWhenDefined(const DPValue &Other) const {
     return std::tie(Type, DebugValues, Variable, Expression,
                     AddressExpression) ==
            std::tie(Other.Type, Other.DebugValues, Other.Variable,
@@ -464,9 +470,9 @@ class DPMarker {
   /// \p InsertAtHead is true, at the start.
   void insertDPValue(DbgRecord *New, bool InsertAtHead);
   /// Insert a DPValue prior to a DPValue contained within this marker.
-  void insertDPValue(DbgRecord *New, DPValue *InsertBefore);
+  void insertDPValue(DbgRecord *New, DbgRecord *InsertBefore);
   /// Insert a DPValue after a DPValue contained within this marker.
-  void insertDPValueAfter(DbgRecord *New, DPValue *InsertAfter);
+  void insertDPValueAfter(DbgRecord *New, DbgRecord *InsertAfter);
   /// Clone all DPMarkers from \p From into this marker. There are numerous
   /// options to customise the source/destination, due to gnarliness, see class
   /// comment.
@@ -513,7 +519,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DPValue &Value) {
 /// to be inlined as it's frequently called, but also come after the declaration
 /// of DPMarker. Thus: it's pre-declared by users like Instruction, then an
 /// inlineable body defined here.
-inline iterator_range<simple_ilist<DPValue>::iterator>
+inline iterator_range<simple_ilist<DbgRecord>::iterator>
 getDbgValueRange(DPMarker *DbgMarker) {
   if (!DbgMarker)
     return DPMarker::getEmptyDPValueRange();
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index c1a5a3d6c60941..c0e159a342d5b5 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -41,7 +41,7 @@ template <> struct ilist_alloc_traits<Instruction> {
   static inline void deleteNode(Instruction *V);
 };
 
-iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange(DPMarker *);
+iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange(DPMarker *);
 
 class Instruction : public User,
                     public ilist_node_with_parent<Instruction, BasicBlock,
diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index f8ce8f98864ea3..2f51540d4d9312 100644
--- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
+++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
@@ -82,7 +82,7 @@ template <> struct llvm::DenseMapInfo<VariableID> {
   }
 };
 
-using VarLocInsertPt = PointerUnion<const Instruction *, const DPValue *>;
+using VarLocInsertPt = PointerUnion<const Instruction *, const DbgRecord *>;
 
 namespace std {
 template <> struct hash<VarLocInsertPt> {
@@ -218,14 +218,14 @@ void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) {
   // block includes VarLocs for any DPValues attached to that instruction.
   for (auto &P : Builder.VarLocsBeforeInst) {
     // Process VarLocs attached to a DPValue alongside their marker Instruction.
-    if (isa<const DPValue *>(P.first))
+    if (isa<const DbgRecord *>(P.first))
       continue;
     const Instruction *I = cast<const Instruction *>(P.first);
     unsigned BlockStart = VarLocRecords.size();
     // Any VarLocInfos attached to a DPValue should now be remapped to their
     // marker Instruction, in order of DPValue appearance and prior to any
     // VarLocInfos attached directly to that instruction.
-    for (const DPValue &DPV : I->getDbgValueRange()) {
+    for (const DPValue &DPV : DPValue::filter(I->getDbgValueRange())) {
       // Even though DPV defines a variable location, VarLocsBeforeInst can
       // still be empty if that VarLoc was redundant.
       if (!Builder.VarLocsBeforeInst.count(&DPV))
@@ -829,7 +829,7 @@ class MemLocFragmentFill {
   void process(BasicBlock &BB, VarFragMap &LiveSet) {
     BBInsertBeforeMap[&BB].clear();
     for (auto &I : BB) {
-      for (auto &DPV : I.getDbgValueRange()) {
+      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);
@@ -1492,7 +1492,7 @@ const char *locStr(AssignmentTrackingLowering::LocKind Loc) {
 }
 #endif
 
-VarLocInsertPt getNextNode(const DPValue *DPV) {
+VarLocInsertPt getNextNode(const DbgRecord *DPV) {
   auto NextIt = ++(DPV->getIterator());
   if (NextIt == DPV->getMarker()->getDbgValueRange().end())
     return DPV->getMarker()->MarkedInstr;
@@ -1507,7 +1507,7 @@ VarLocInsertPt getNextNode(const Instruction *Inst) {
 VarLocInsertPt getNextNode(VarLocInsertPt InsertPt) {
   if (isa<const Instruction *>(InsertPt))
     return getNextNode(cast<const Instruction *>(InsertPt));
-  return getNextNode(cast<const DPValue *>(InsertPt));
+  return getNextNode(cast<const DbgRecord *>(InsertPt));
 }
 
 DbgAssignIntrinsic *CastToDbgAssign(DbgVariableIntrinsic *DVI) {
@@ -1915,7 +1915,7 @@ void AssignmentTrackingLowering::process(BasicBlock &BB, BlockInfo *LiveSet) {
     // attached DPValues, or a non-debug instruction with attached unprocessed
     // DPValues.
     if (II != EI && II->hasDbgValues()) {
-      for (DPValue &DPV : II->getDbgValueRange()) {
+      for (DPValue &DPV : DPValue::filter(II->getDbgValueRange())) {
         resetInsertionPoint(DPV);
         processDPValue(DPV, LiveSet);
         assert(LiveSet->isValid());
@@ -2172,7 +2172,7 @@ static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares(
   };
   for (auto &BB : Fn) {
     for (auto &I : BB) {
-      for (auto &DPV : I.getDbgValueRange())
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
         ProcessDbgRecord(&DPV, DPDeclares);
       if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) {
         ProcessDbgRecord(DII, InstDeclares);
@@ -2462,7 +2462,7 @@ bool AssignmentTrackingLowering::emitPromotedVarLocs(
   for (auto &BB : Fn) {
     for (auto &I : BB) {
       // Skip instructions other than dbg.values and dbg.assigns.
-      for (DPValue &DPV : I.getDbgValueRange())
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
         if (DPV.isDbgValue() || DPV.isDbgAssign())
           TranslateDbgRecord(&DPV);
       auto *DVI = dyn_cast<DbgValueInst>(&I);
@@ -2564,7 +2564,7 @@ removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
       }
     };
     HandleLocsForWedge(&I);
-    for (DPValue &DPV : reverse(I.getDbgValueRange()))
+    for (DPValue &DPV : reverse(DPValue::filter(I.getDbgValueRange())))
       HandleLocsForWedge(&DPV);
   }
 
@@ -2629,7 +2629,7 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB,
       }
     };
 
-    for (DPValue &DPV : I.getDbgValueRange())
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
       HandleLocsForWedge(&DPV);
     HandleLocsForWedge(&I);
   }
@@ -2715,7 +2715,7 @@ removeUndefDbgLocsFromEntryBlock(const BasicBlock *BB,
         Changed = true;
       }
     };
-    for (DPValue &DPV : I.getDbgValueRange())
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
       HandleLocsForWedge(&DPV);
     HandleLocsForWedge(&I);
   }
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 311dd9d9739a6d..cd012068993100 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3274,7 +3274,7 @@ void IRTranslator::translateDbgDeclareRecord(Value *Address, bool HasArgList,
 
 void IRTranslator::translateDbgInfo(const Instruction &Inst,
                                       MachineIRBuilder &MIRBuilder) {
-  for (DPValue &DPV : Inst.getDbgValueRange()) {
+  for (DPValue &DPV : DPValue::filter(Inst.getDbgValueRange())) {
     const DILocalVariable *Variable = DPV.getVariable();
     const DIExpression *Expression = DPV.getExpression();
     Value *V = DPV.getVariableLocationOp(0);
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index d96f0469fbbcd8..251485a403fee6 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1131,19 +1131,19 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
   processGlobalObjectMetadata(F);
   for (auto &BB : F) {
     for (auto &I : BB) {
-      for (const DbgRecord &DPV : I.getDbgValueRange())
-        processDbgRecordMetadata(DPV);
+      for (const DbgRecord &DR : I.getDbgValueRange())
+        processDbgRecordMetadata(DR);
       processInstructionMetadata(I);
     }
   }
 }
 
-void SlotTracker::processDPValueMetadata(const DPValue &DPV) {
+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());
+    if (DPV->isDbgAssign())
+      CreateMetadataSlot(DPV->getAssignID());
   } else {
     llvm_unreachable("unsupported DbgRecord kind");
   }
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 17c7e8e787350e..8b82d19b4aa894 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -1827,7 +1827,7 @@ void at::deleteAll(Function *F) {
   SmallVector<DPValue *, 12> DPToDelete;
   for (BasicBlock &BB : *F) {
     for (Instruction &I : BB) {
-      for (auto &DPV : I.getDbgValueRange())
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
         if (DPV.isDbgAssign())
           DPToDelete.push_back(&DPV);
       if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I))
@@ -2251,7 +2251,7 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) {
   };
   for (auto &BB : F) {
     for (auto &I : BB) {
-      for (auto &DPV : I.getDbgValueRange()) {
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
         if (DPV.isDbgDeclare())
           ProcessDeclare(&DPV, DPVDeclares);
       }
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index a72c6408766045..f09a2a9f7ce00c 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -15,8 +15,9 @@ namespace llvm {
 
 DPValue::DPValue(const DbgVariableIntrinsic *DVI)
     : DbgRecord(ValueKind, DVI->getDebugLoc()),
-      DebugValueUser(DVI->getRawLocation(), nullptr, nullptr), Variable(DVI->getVariable()),
-      Expression(DVI->getExpression()) {
+      DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
+      Variable(DVI->getVariable()), Expression(DVI->getExpression()),
+      AddressExpression(nullptr) {
   switch (DVI->getIntrinsicID()) {
   case Intrinsic::dbg_value:
     Type = LocationType::Value;
@@ -40,14 +41,15 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI)
 }
 
 DPValue::DPValue(const DPValue &DPV)
-    : DbgRecord(ValueKind, DPV.getDebugLoc()),
-      DebugValueUser({DPV.DebugValues, nullptr, nullptr}), Type(DPV.getType()),
-      Variable(DPV.getVariable()), Expression(DPV.getExpression()), AddressExpression(DPV.AddressExpression) {}
+    : DbgRecord(ValueKind, DPV.getDebugLoc()), DebugValueUser(DPV.DebugValues),
+      Type(DPV.getType()), Variable(DPV.getVariable()),
+      Expression(DPV.getExpression()),
+      AddressExpression(DPV.AddressExpression) {}
 
 DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
                  const DILocation *DI, LocationType Type)
-    : DbgRecord(ValueKind, DI), DebugValueUser(Location), Type(Type),
-      Variable(DV), Expression(Expr) {}
+    : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}),
+      Type(Type), Variable(DV), Expression(Expr) {}
 
 void DbgRecord::deleteRecord() {
   switch (RecordKind) {
@@ -65,7 +67,7 @@ void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
     cast<DPValue>(this)->print(O, IsForDebug);
     break;
   default:
-    llvm_unreachable("unsupported record kind");
+    llvm_unreachable("unsupported DbgRecord kind");
   };
 }
 
@@ -76,7 +78,31 @@ void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,
     cast<DPValue>(this)->print(O, MST, IsForDebug);
     break;
   default:
-    llvm_unreachable("unsupported record kind");
+    llvm_unreachable("unsupported DbgRecord kind");
+  };
+}
+
+bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
+  if (RecordKind != R.RecordKind)
+    return false;
+  switch (RecordKind) {
+  case ValueKind:
+    cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R));
+    break;
+  default:
+    llvm_unreachable("unsupported DbgRecord kind");
+  };
+}
+
+bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
+  if (RecordKind != R.RecordKind)
+    return false;
+  switch (RecordKind) {
+  case ValueKind:
+    cast<DPValue>(this)->isEquivalentTo(*cast<DPValue>(&R));
+    break;
+  default:
+    llvm_unreachable("unsupported DbgRecord kind");
   };
 }
 
@@ -368,7 +394,7 @@ bool DPValue::isKillAddress() const {
   return !Addr || isa<UndefValue>(Addr);
 }
 
-const Instruction *DPValue::getInstruction() const {
+const Instruction *DbgRecord::getInstruction() const {
   return Marker->MarkedInstr;
 }
 
@@ -400,31 +426,31 @@ const LLVMContext &DbgRecord::getContext() const {
   return getBlock()->getContext();
 }
 
-void DPValue::insertBefore(DPValue *InsertBefore) {
+void DbgRecord::insertBefore(DbgRecord *InsertBefore) {
   assert(!getMarker() &&
-         "Cannot insert a DPValue that is already has a DPMarker!");
+         "Cannot insert a DbgRecord that is already has a DPMarker!");
   assert(InsertBefore->getMarker() &&
-         "Cannot insert a DPValue before a DPValue that does not have a "
+         "Cannot insert a DbgRecord before a DbgRecord that does not have a "
          "DPMarker!");
   InsertBefore->getMarker()->insertDPValue(this, InsertBefore);
 }
-void DPValue::insertAfter(DPValue *InsertAfter) {
+void DbgRecord::insertAfter(DbgRecord *InsertAfter) {
   assert(!getMarker() &&
-         "Cannot insert a DPValue that is already has a DPMarker!");
+         "Cannot insert a DbgRecord that is already has a DPMarker!");
   assert(InsertAfter->getMarker() &&
-         "Cannot insert a DPValue after a DPValue that does not have a "
+         "Cannot insert a DbgRecord after a DbgRecord that does not have a "
          "DPMarker!");
   InsertAfter->getMarker()->insertDPValueAfter(this, InsertAfter);
 }
-void DPValue::moveBefore(DPValue *MoveBefore) {
+void DbgRecord::moveBefore(DbgRecord *MoveBefore) {
   assert(getMarker() &&
-         "Canot move a DPValue that does not currently have a DPMarker!");
+         "Canot move a DbgRecord that does not currently have a DPMarker!");
   removeFromParent();
   insertBefore(MoveBefore);
 }
-void DPValue::moveAfter(DPValue *MoveAfter) {
+void DbgRecord::moveAfter(DbgRecord *MoveAfter) {
   assert(getMarker() &&
-         "Canot move a DPValue that does not currently have a DPMarker!");
+         "Canot move a DbgRecord that does not currently have a DPMarker!");
   removeFromParent();
   insertAfter(MoveAfter);
 }
@@ -503,11 +529,7 @@ void DPMarker::eraseFromParent() {
 iterator_range<DbgRecord::self_iterator> DPMarker::getDbgValueRange() {
   return make_range(StoredDPValues.begin(), StoredDPValues.end());
 }
-iterator_range<DPValue::const_self_iterator>
-DPMarker::getDbgValueRange() const {
-  return make_range(StoredDPValues.begin(), StoredDPValues.end());
-}
-iterator_range<DPValue::const_self_iterator>
+iterator_range<DbgRecord::const_self_iterator>
 DPMarker::getDbgValueRange() const {
   return make_range(StoredDPValues.begin(), StoredDPValues.end());
 }
@@ -527,13 +549,13 @@ void DPMarker::insertDPValue(DbgRecord *New, bool InsertAtHead) {
   StoredDPValues.insert(It, *New);
   New->setMarker(this);
 }
-void DPMarker::insertDPValue(DPValue *New, DPValue *InsertBefore) {
+void DPMarker::insertDPValue(DbgRecord *New, DbgRecord *InsertBefore) {
   assert(InsertBefore->getMarker() == this &&
          "DPValue 'InsertBefore' must be contained in this DPMarker!");
   StoredDPValues.insert(InsertBefore->getIterator(), *New);
   New->setMarker(this);
 }
-void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) {
+void DPMarker::insertDPValueAfter(DbgRecord *New, DbgRecord *InsertAfter) {
   assert(InsertAfter->getMarker() == this &&
          "DPValue 'InsertAfter' must be contained in this DPMarker!");
   StoredDPValues.insert(++(InsertAfter->getIterator()), *New);
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index 4af9b2206745e2..1428a09040a34b 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -643,7 +643,7 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
        BI != BIE; ++BI) {
     // Examine DPValues as they happen "before" the instruction. Are they
     // connected to parameters?
-    for (DPValue &DPV : BI->getDbgValueRange()) {
+    for (DPValue &DPV : DPValue::filter(BI->getDbgValueRange())) {
       if (DPV.isDbgValue() || DPV.isDbgAssign()) {
         ExamineDbgValue(&DPV, PDPVRelated);
       } else {
@@ -686,7 +686,7 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
 
   // Collect the set of unrelated instructions and debug records.
   for (Instruction &I : *GEntryBlock) {
-    for (auto &DPV : I.getDbgValueRange())
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
       IsPDIRelated(&DPV, PDPVRelated, PDPVUnrelatedWL);
     IsPDIRelated(&I, PDIRelated, PDIUnrelatedWL);
   }
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 7450f39c1e7641..87b52e420f4825 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4484,7 +4484,8 @@ void InstCombinerImpl::tryToSinkInstructionDPValues(
     // For all instruction/variable pairs needing extra filtering, find the
     // latest assignment.
     for (const Instruction *Inst : DupSet) {
-      for (DPValue &DPV : llvm::reverse(Inst->getDbgValueRange())) {
+      for (DPValue &DPV :
+           llvm::reverse(DPValue::filter(Inst->getDbgValueRange()))) {
         DebugVariable DbgUserVariable =
             DebugVariable(DPV.getVariable(), DPV.getExpression(),
                           DPV.getDebugLoc()->getInlinedAt());
diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp
index ab6513884d646e..95a9527126c112 100644
--- a/llvm/lib/Transforms/Scalar/ADCE.cpp
+++ b/llvm/lib/Transforms/Scalar/ADCE.cpp
@@ -551,8 +551,8 @@ ADCEChanged AggressiveDeadCodeElimination::removeDeadInstructions() {
     for (DbgRecord &DR : make_early_inc_range(I.getDbgValueRange())) {
       // Avoid removing a DPV that is linked to instructions because it holds
       // information about an existing store.
-      if (DR.isDbgAssign())
-        if (!at::getAssignmentInsts(&DR).empty())
+      if (DPValue *DPV = dyn_cast<DPValue>(&DR); DPV && DPV->isDbgAssign())
+        if (!at::getAssignmentInsts(DPV).empty())
           continue;
       if (AliveScopes.count(DR.getDebugLoc()->getScope()))
         continue;
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 6f6d1f9c760689..627c863f7091fc 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -6712,7 +6712,7 @@ static void DbgGatherSalvagableDVI(
         SalvageableDVISCEVs.push_back(std::move(NewRec));
         return true;
       };
-      for (auto &DPV : I.getDbgValueRange()) {
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
         if (DPV.isDbgValue() || DPV.isDbgAssign())
           ProcessDbgValue(&DPV);
       }
diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
index 87b0f50860e1b5..f4f3070d11c7bb 100644
--- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
+++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
@@ -292,10 +292,11 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
   unsigned NotHoistedInstCount = 0;
   for (const auto &I : FromBlock) {
     // Make note of any DPValues that need hoisting.
-    for (DPValue &DPV : I.getDbgValueRange())
+    for (DbgRecord &DR : I.getDbgValueRange()) {
+      DPValue &DPV = cast<DPValue>(DR);
       if (HasNoUnhoistedInstr(DPV.location_ops()))
         DPValuesToHoist[DPV.getInstruction()].push_back(&DPV);
-
+    }
     const InstructionCost Cost = ComputeSpeculationCost(&I, *TTI);
     if (Cost.isValid() && isSafeToSpeculativelyExecute(&I) &&
         AllPrecedingUsesFromBlockHoisted(&I)) {
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 4eee3387647be2..7fd6759a61fbae 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -545,7 +545,7 @@ static bool DPValuesRemoveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) {
   // Remove undef dbg.assign intrinsics that are encountered before
   // any non-undef intrinsics from the entry block.
   for (auto &I : *BB) {
-    for (DPValue &DPV : I.getDbgValueRange()) {
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
       if (!DPV.isDbgValue() && !DPV.isDbgAssign())
         continue;
       bool IsDbgValueKind =
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index f888cc336d937d..78317df8a9caec 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1829,7 +1829,7 @@ static void fixupAssignments(Function::iterator Start, Function::iterator End) {
   // attachment or use, replace it with a new version.
   for (auto BBI = Start; BBI != End; ++BBI) {
     for (Instruction &I : *BBI) {
-      for (DPValue &DPV : I.getDbgValueRange()) {
+      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
         if (DPV.isDbgAssign())
           DPV.setAssignId(GetNewID(DPV.getAssignID()));
       }
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index 1ffa003db7d569..08fdd3b75ffcbd 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -111,7 +111,8 @@ Instruction *getUntagLocationIfFunctionExit(Instruction &Inst) {
 
 void StackInfoBuilder::visit(Instruction &Inst) {
   // Visit non-intrinsic debug-info records attached to Inst.
-  for (auto &DPV : Inst.getDbgValueRange()) {
+  for (DbgRecord &DR : Inst.getDbgValueRange()) {
+    DPValue &DPV = cast<DPValue>(DR);
     auto AddIfInteresting = [&](Value *V) {
       if (auto *AI = dyn_cast_or_null<AllocaInst>(V)) {
         if (!isInterestingAlloca(*AI))
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index b7099d8947a909..9562d44400448b 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1538,7 +1538,7 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1,
   if (!I1->hasDbgValues())
     return;
   using CurrentAndEndIt =
-      std::pair<DPValue::self_iterator, DPValue::self_iterator>;
+      std::pair<DbgRecord::self_iterator, DbgRecord::self_iterator>;
   // Vector of {Current, End} iterators.
   SmallVector<CurrentAndEndIt> Itrs;
   Itrs.reserve(OtherInsts.size() + 1);
@@ -1550,7 +1550,7 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1,
   // Return true if all Current are identical.
   auto allIdentical = [](const SmallVector<CurrentAndEndIt> &Itrs) {
     return all_of(make_first_range(ArrayRef(Itrs).drop_front()),
-                  [&](DPValue::self_iterator I) {
+                  [&](DbgRecord::self_iterator I) {
                     return Itrs[0].first->isIdenticalToWhenDefined(*I);
                   });
   };
@@ -1565,18 +1565,18 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1,
         {Other->getDbgValueRange().begin(), Other->getDbgValueRange().end()});
   }
 
-  // Iterate in lock-step until any of the DPValue lists are exausted. If
-  // the lock-step DPValues are identical, hoist all of them to TI.
+  // Iterate in lock-step until any of the DbgRecord lists are exausted. If
+  // the lock-step DbgRecord are identical, hoist all of them to TI.
   // This replicates the dbg.* intrinsic behaviour in
   // hoistCommonCodeFromSuccessors.
   while (none_of(Itrs, atEnd)) {
     bool HoistDPVs = allIdentical(Itrs);
     for (CurrentAndEndIt &Pair : Itrs) {
       // Increment Current iterator now as we may be about to move the DPValue.
-      DPValue &DPV = *Pair.first++;
+      DbgRecord &DR = *Pair.first++;
       if (HoistDPVs) {
-        DPV.removeFromParent();
-        TI->getParent()->insertDPValueBefore(&DPV, TI->getIterator());
+        DR.removeFromParent();
+        TI->getParent()->insertDPValueBefore(&DR, TI->getIterator());
       }
     }
   }
@@ -3207,9 +3207,9 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI,
   // instructions, in the same way that dbg.value intrinsics are dropped at the
   // end of this block.
   for (auto &It : make_range(ThenBB->begin(), ThenBB->end()))
-    for (DPValue &DPV : make_early_inc_range(It.getDbgValueRange()))
-      if (!DPV.isDbgAssign())
-        It.dropOneDbgValue(&DPV);
+    for (DbgRecord &DR : make_early_inc_range(It.getDbgValueRange()))
+      if (DPValue *DPV = dyn_cast<DPValue>(&DR); DPV && !DPV->isDbgAssign())
+        It.dropOneDbgValue(DPV);
   BB->splice(BI->getIterator(), ThenBB, ThenBB->begin(),
              std::prev(ThenBB->end()));
 
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 37585446bfd37c..6e46469f5a601e 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -146,7 +146,7 @@ class Mapper {
   Value *mapValue(const Value *V);
   void remapInstruction(Instruction *I);
   void remapFunction(Function &F);
-  void remapDPValue(DPValue &DPV);
+  void remapDPValue(DbgRecord &DPV);
 
   Constant *mapConstant(const Constant *C) {
     return cast_or_null<Constant>(mapValue(C));
@@ -537,7 +537,8 @@ Value *Mapper::mapValue(const Value *V) {
   return getVM()[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
 }
 
-void Mapper::remapDPValue(DPValue &V) {
+void Mapper::remapDPValue(DbgRecord &DR) {
+  DPValue &V = cast<DPValue>(DR);
   // Remap variables and DILocations.
   auto *MappedVar = mapMetadata(V.getVariable());
   auto *MappedDILoc = mapMetadata(V.getDebugLoc());
@@ -1060,8 +1061,8 @@ void Mapper::remapFunction(Function &F) {
   for (BasicBlock &BB : F) {
     for (Instruction &I : BB) {
       remapInstruction(&I);
-      for (DPValue &DPV : I.getDbgValueRange())
-        remapDPValue(DPV);
+      for (DbgRecord &DR : I.getDbgValueRange())
+        remapDPValue(DR);
     }
   }
 }

>From e3334474cb01a24b569f5ae8dceb5803359fc538 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Tue, 20 Feb 2024 11:01:15 +0000
Subject: [PATCH 3/7] rebase fallout: add missing ctor

---
 llvm/lib/IR/DebugProgramInstruction.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index f09a2a9f7ce00c..9438bd211cdf79 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -51,6 +51,14 @@ DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
     : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}),
       Type(Type), Variable(DV), Expression(Expr) {}
 
+DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
+                 DIExpression *Expression, DIAssignID *AssignID,
+                 Metadata *Address, DIExpression *AddressExpression,
+                 const DILocation *DI)
+    : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),
+      Variable(Variable), Expression(Expression),
+      AddressExpression(AddressExpression), Type(LocationType::Assign) {}
+
 void DbgRecord::deleteRecord() {
   switch (RecordKind) {
   case ValueKind:

>From f3ade8ba3516aeb718aeacdba52ad22045fa8709 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Tue, 20 Feb 2024 11:06:34 +0000
Subject: [PATCH 4/7] Add FIXME

---
 llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index 2f51540d4d9312..7b66a851db2527 100644
--- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
+++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
@@ -829,7 +829,11 @@ class MemLocFragmentFill {
   void process(BasicBlock &BB, VarFragMap &LiveSet) {
     BBInsertBeforeMap[&BB].clear();
     for (auto &I : BB) {
-      for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) {
+      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);
         if (const auto *Locs = FnVarLocs->getWedge(&DPV)) {
           for (const VarLocInfo &Loc : *Locs) {
             addDef(Loc, &DPV, *I.getParent(), LiveSet);

>From c410dcd8f6fde59b8419a634a8e216671e506f6f Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Tue, 20 Feb 2024 11:11:48 +0000
Subject: [PATCH 5/7] fix warnings

---
 llvm/lib/IR/DebugProgramInstruction.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index 9438bd211cdf79..58a0da284c2cee 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -56,8 +56,8 @@ DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
                  Metadata *Address, DIExpression *AddressExpression,
                  const DILocation *DI)
     : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),
-      Variable(Variable), Expression(Expression),
-      AddressExpression(AddressExpression), Type(LocationType::Assign) {}
+      Type(LocationType::Assign), Variable(Variable), Expression(Expression),
+      AddressExpression(AddressExpression) {}
 
 void DbgRecord::deleteRecord() {
   switch (RecordKind) {
@@ -95,7 +95,7 @@ bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
     return false;
   switch (RecordKind) {
   case ValueKind:
-    cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R));
+    return cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R));
     break;
   default:
     llvm_unreachable("unsupported DbgRecord kind");
@@ -107,7 +107,7 @@ bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
     return false;
   switch (RecordKind) {
   case ValueKind:
-    cast<DPValue>(this)->isEquivalentTo(*cast<DPValue>(&R));
+    return cast<DPValue>(this)->isEquivalentTo(*cast<DPValue>(&R));
     break;
   default:
     llvm_unreachable("unsupported DbgRecord kind");

>From 4931e65666c0778d70a9297f975ab30e8fc0b68e Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Tue, 20 Feb 2024 11:34:40 +0000
Subject: [PATCH 6/7] address feedback

---
 .../include/llvm/IR/DebugProgramInstruction.h |  5 ++--
 llvm/lib/IR/BasicBlock.cpp                    |  6 ++---
 llvm/lib/IR/DebugInfo.cpp                     |  3 +--
 llvm/lib/IR/DebugProgramInstruction.cpp       | 24 +++++++++----------
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index a66efdf0dc0fca..0976dd87881f5f 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -97,7 +97,8 @@ class DbgRecord : public ilist_node<DbgRecord> {
   DbgRecord(Kind RecordKind, DebugLoc DL)
       : DbgLoc(DL), RecordKind(RecordKind) {}
 
-  /// Methods requiring subclass implementations.
+  /// Methods that dispatch to subclass implementations. These need to be
+  /// manually updated when a new subclass is added.
   ///@{
   void deleteRecord();
   DbgRecord *clone() const;
@@ -488,7 +489,7 @@ class DPMarker {
   /// Erase a single DbgRecord from this marker. In an ideal future, we would
   /// never erase an assignment in this way, but it's the equivalent to
   /// erasing a debug intrinsic from a block.
-  void dropOneDbgValue(DbgRecord *DPE);
+  void dropOneDbgValue(DbgRecord *DR);
 
   /// We generally act like all llvm Instructions have a range of DPValues
   /// attached to them, but in reality sometimes we don't allocate the DPMarker
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index 4e36c258d5e947..0680754444f17f 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -107,12 +107,12 @@ void BasicBlock::convertFromNewDbgValues() {
       continue;
 
     DPMarker &Marker = *Inst.DbgMarker;
-    for (DbgRecord &DPR : Marker.getDbgValueRange()) {
-      if (auto *DPV = dyn_cast<DPValue>(&DPR))
+    for (DbgRecord &DR : Marker.getDbgValueRange()) {
+      if (auto *DPV = dyn_cast<DPValue>(&DR))
         InstList.insert(Inst.getIterator(),
                         DPV->createDebugIntrinsic(getModule(), nullptr));
       else
-        llvm_unreachable("unsupported entity kind");
+        llvm_unreachable("unsupported DbgRecord kind");
     }
 
     Marker.eraseFromParent();
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 8b82d19b4aa894..a4fec601908503 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -125,11 +125,10 @@ static void findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V,
       if (!DPValues)
         continue;
       DIArgList *DI = cast<DIArgList>(AL);
-      for (DPValue *DPV : DI->getAllDPValueUsers()) {
+      for (DPValue *DPV : DI->getAllDPValueUsers())
         if (Type == DPValue::LocationType::Any || DPV->getType() == Type)
           if (EncounteredDPValues.insert(DPV).second)
             DPValues->push_back(DPV);
-      }
     }
   }
 }
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index 58a0da284c2cee..9568b2257e61a0 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -65,7 +65,7 @@ void DbgRecord::deleteRecord() {
     delete cast<DPValue>(this);
     break;
   default:
-    llvm_unreachable("unsupported record kind");
+    llvm_unreachable("unsupported DbgRecord kind");
   }
 }
 
@@ -315,7 +315,7 @@ DbgRecord *DbgRecord::clone() const {
   case ValueKind:
     return cast<DPValue>(this)->clone();
   default:
-    llvm_unreachable("unsupported record kind");
+    llvm_unreachable("unsupported DbgRecord kind");
   };
 }
 
@@ -472,16 +472,16 @@ DPMarker DPMarker::EmptyDPMarker;
 void DPMarker::dropDbgValues() {
   while (!StoredDPValues.empty()) {
     auto It = StoredDPValues.begin();
-    DbgRecord *DPE = &*It;
+    DbgRecord *DR = &*It;
     StoredDPValues.erase(It);
-    DPE->deleteRecord();
+    DR->deleteRecord();
   }
 }
 
-void DPMarker::dropOneDbgValue(DbgRecord *DPE) {
-  assert(DPE->getMarker() == this);
-  StoredDPValues.erase(DPE->getIterator());
-  DPE->deleteRecord();
+void DPMarker::dropOneDbgValue(DbgRecord *DR) {
+  assert(DR->getMarker() == this);
+  StoredDPValues.erase(DR->getIterator());
+  DR->deleteRecord();
 }
 
 const BasicBlock *DPMarker::getParent() const {
@@ -580,8 +580,8 @@ void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
 
 void DPMarker::absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
                                  DPMarker &Src, bool InsertAtHead) {
-  for (DbgRecord &DPE : Range)
-    DPE.setMarker(this);
+  for (DbgRecord &DR : Range)
+    DR.setMarker(this);
 
   auto InsertPos =
       (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
@@ -605,8 +605,8 @@ iterator_range<simple_ilist<DbgRecord>::iterator> DPMarker::cloneDebugInfoFrom(
   // Clone each DPValue and insert into StoreDPValues; optionally place them at
   // the start or the end of the list.
   auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
-  for (DbgRecord &DPE : Range) {
-    DbgRecord *New = DPE.clone();
+  for (DbgRecord &DR : Range) {
+    DbgRecord *New = DR.clone();
     New->setMarker(this);
     StoredDPValues.insert(Pos, *New);
     if (!First)

>From c22d33894ce280e995989280ae880844e25f8e9b Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Tue, 20 Feb 2024 15:05:22 +0000
Subject: [PATCH 7/7] llvm-reduce changes

---
 llvm/tools/llvm-reduce/DeltaManager.cpp          | 2 +-
 llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp | 8 ++++----
 llvm/tools/llvm-reduce/deltas/ReduceDPValues.h   | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 56e39b8f9316fa..fa42920ee91296 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -92,7 +92,7 @@ static cl::list<std::string>
     DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass)      \
     DELTA_PASS("global-variables", reduceGlobalsDeltaPass)                     \
     DELTA_PASS("di-metadata", reduceDIMetadataDeltaPass)                       \
-    DELTA_PASS("dpvalues", reduceDPValuesDeltaPass)                            \
+    DELTA_PASS("dbg-records", reduceDbgRecordDeltaPass)                        \
     DELTA_PASS("metadata", reduceMetadataDeltaPass)                            \
     DELTA_PASS("named-metadata", reduceNamedMetadataDeltaPass)                 \
     DELTA_PASS("arguments", reduceArgumentsDeltaPass)                          \
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp
index 8f5bafd950e34b..f0d02a78ac6acf 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp
@@ -29,11 +29,11 @@ static void extractDPValuesFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
   for (auto &F : M)
     for (auto &BB : F)
       for (auto &I : BB)
-        for (DPValue &DPV : llvm::make_early_inc_range(I.getDbgValueRange()))
+        for (DbgRecord &DR : llvm::make_early_inc_range(I.getDbgValueRange()))
           if (!O.shouldKeep())
-            DPV.eraseFromParent();
+            DR.eraseFromParent();
 }
 
-void llvm::reduceDPValuesDeltaPass(TestRunner &Test) {
-  runDeltaPass(Test, extractDPValuesFromModule, "Reducing DPValues");
+void llvm::reduceDbgRecordDeltaPass(TestRunner &Test) {
+  runDeltaPass(Test, extractDPValuesFromModule, "Reducing DbgRecords");
 }
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h
index 34ebd271b4f24e..1d3b8a35daa34b 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h
+++ b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h
@@ -19,7 +19,7 @@
 #include "llvm/IR/DebugProgramInstruction.h"
 
 namespace llvm {
-void reduceDPValuesDeltaPass(TestRunner &Test);
+void reduceDbgRecordDeltaPass(TestRunner &Test);
 } // namespace llvm
 
 #endif



More information about the llvm-commits mailing list