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

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 08:01:01 PST 2024


Author: Orlando Cazalet-Hyams
Date: 2024-02-20T16:00:55Z
New Revision: ababa964752d5bfa6eb608c97f19d4e68df1d243

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

LOG: [RemoveDIs][NFC] Introduce DbgRecord base class [1/3] (#78252)

Patch 1 of 3 to add llvm.dbg.label support to the RemoveDIs project. The
patch stack adds a new base class

    -> 1. Add DbgRecord base class for DPValue and the not-yet-added
          DPLabel class.
       2. Add the DPLabel class.
       3. Enable dbg.label conversion and add support to passes.

Patches 1 and 2 are NFC.

In the near future we also will rename DPValue to DbgVariableRecord and
DPLabel to DbgLabelRecord, at which point we'll overhaul the function
names too. The name DPLabel keeps things consistent for now.

Added: 
    

Modified: 
    llvm/include/llvm/IR/BasicBlock.h
    llvm/include/llvm/IR/DebugInfo.h
    llvm/include/llvm/IR/DebugProgramInstruction.h
    llvm/include/llvm/IR/Instruction.h
    llvm/include/llvm/Transforms/Utils/ValueMapper.h
    llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
    llvm/lib/CodeGen/CodeGenPrepare.cpp
    llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/lib/IR/AsmWriter.cpp
    llvm/lib/IR/BasicBlock.cpp
    llvm/lib/IR/DebugInfo.cpp
    llvm/lib/IR/DebugProgramInstruction.cpp
    llvm/lib/IR/Instruction.cpp
    llvm/lib/Transforms/Coroutines/CoroFrame.cpp
    llvm/lib/Transforms/Coroutines/CoroSplit.cpp
    llvm/lib/Transforms/IPO/MergeFunctions.cpp
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/lib/Transforms/Scalar/ADCE.cpp
    llvm/lib/Transforms/Scalar/JumpThreading.cpp
    llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
    llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
    llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
    llvm/lib/Transforms/Utils/CodeExtractor.cpp
    llvm/lib/Transforms/Utils/InlineFunction.cpp
    llvm/lib/Transforms/Utils/Local.cpp
    llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
    llvm/lib/Transforms/Utils/LoopUtils.cpp
    llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/lib/Transforms/Utils/ValueMapper.cpp
    llvm/tools/llvm-reduce/DeltaManager.cpp
    llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp
    llvm/tools/llvm-reduce/deltas/ReduceDPValues.h
    llvm/unittests/IR/BasicBlockDbgInfoTest.cpp
    llvm/unittests/IR/DebugInfoTest.cpp
    llvm/unittests/IR/ValueTest.cpp

Removed: 
    


################################################################################
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..1fa6b6f519640e 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -53,6 +53,7 @@
 #include "llvm/IR/DebugLoc.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/SymbolTableListTraits.h"
+#include "llvm/Support/Casting.h"
 
 namespace llvm {
 
@@ -66,43 +67,105 @@ 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
+///   isIdenticalToWhenDefined
+///   isEquivalentTo
+///   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 that dispatch to subclass implementations. These need to be
+  /// manually updated when a new subclass is added.
+  ///@{
+  void deleteRecord();
+  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; }
+
+  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()); }
+  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); }
+
+  void dump() const;
+
+  using self_iterator = simple_ilist<DbgRecord>::iterator;
+  using const_self_iterator = simple_ilist<DbgRecord>::const_iterator;
 
-  using self_iterator = simple_ilist<DPValue>::iterator;
-  using const_self_iterator = simple_ilist<DPValue>::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;
+};
+
+/// 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;
 
-  enum class LocationType {
+public:
+  enum class LocationType : uint8_t {
     Declare,
     Value,
     Assign,
@@ -113,11 +176,18 @@ 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;
+  DIExpression *AddressExpression;
 
+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 +305,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;
 
@@ -270,12 +337,12 @@ class DPValue : public ilist_node<DPValue>, private 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,
@@ -314,43 +381,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 +431,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 +455,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 +464,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, DbgRecord *InsertBefore);
   /// Insert a DPValue after a DPValue contained within this marker.
-  void insertDPValueAfter(DPValue *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.
   /// \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 *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
@@ -438,8 +498,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());
   }
 };
 
@@ -457,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 cd814e21be1ae1..c0e159a342d5b5 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -35,12 +35,13 @@ class MDNode;
 class Module;
 struct AAMDNodes;
 class DPMarker;
+class DbgRecord;
 
 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,
@@ -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/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/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index f8ce8f98864ea3..7b66a851db2527 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,11 @@ class MemLocFragmentFill {
   void process(BasicBlock &BB, VarFragMap &LiveSet) {
     BBInsertBeforeMap[&BB].clear();
     for (auto &I : BB) {
-      for (auto &DPV : 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);
@@ -1492,7 +1496,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 +1511,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 +1919,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 +2176,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 +2466,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 +2568,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 +2633,7 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB,
       }
     };
 
-    for (DPValue &DPV : I.getDbgValueRange())
+    for (DPValue &DPV : DPValue::filter(I.getDbgValueRange()))
       HandleLocsForWedge(&DPV);
     HandleLocsForWedge(&I);
   }
@@ -2715,7 +2719,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/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/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 24ca6a8dca44cb..7c95cef2eeb761 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3275,7 +3275,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/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..251485a403fee6 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 &DR : I.getDbgValueRange())
+        processDbgRecordMetadata(DR);
       processInstructionMetadata(I);
     }
   }
 }
 
-void SlotTracker::processDPValueMetadata(const DPValue &DPV) {
-  CreateMetadataSlot(DPV.getVariable());
-  CreateMetadataSlot(DPV.getDebugLoc());
-  if (DPV.isDbgAssign()) {
-    CreateMetadataSlot(DPV.getAssignID());
+void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
+  if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) {
+    CreateMetadataSlot(DPV->getVariable());
+    CreateMetadataSlot(DPV->getDebugLoc());
+    if (DPV->isDbgAssign())
+      CreateMetadataSlot(DPV->getAssignID());
+  } else {
+    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..0680754444f17f 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 &DR : Marker.getDbgValueRange()) {
+      if (auto *DPV = dyn_cast<DPValue>(&DR))
+        InstList.insert(Inst.getIterator(),
+                        DPV->createDebugIntrinsic(getModule(), nullptr));
+      else
+        llvm_unreachable("unsupported DbgRecord 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..a4fec601908503 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -240,8 +240,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 +256,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;
@@ -1822,7 +1826,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))
@@ -2246,7 +2250,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 a2640d59242ac2..9568b2257e61a0 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -14,9 +14,10 @@
 namespace llvm {
 
 DPValue::DPValue(const DbgVariableIntrinsic *DVI)
-    : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
+    : DbgRecord(ValueKind, DVI->getDebugLoc()),
+      DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
       Variable(DVI->getVariable()), Expression(DVI->getExpression()),
-      DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
+      AddressExpression(nullptr) {
   switch (DVI->getIntrinsicID()) {
   case Intrinsic::dbg_value:
     Type = LocationType::Value;
@@ -40,24 +41,78 @@ 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),
+      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, 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)
-    : DebugValueUser({Value, Address, AssignID}), Variable(Variable),
-      Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
-      Type(LocationType::Assign) {}
+    : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),
+      Type(LocationType::Assign), Variable(Variable), Expression(Expression),
+      AddressExpression(AddressExpression) {}
+
+void DbgRecord::deleteRecord() {
+  switch (RecordKind) {
+  case ValueKind:
+    delete cast<DPValue>(this);
+    break;
+  default:
+    llvm_unreachable("unsupported DbgRecord kind");
+  }
+}
+
+void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
+  switch (RecordKind) {
+  case ValueKind:
+    cast<DPValue>(this)->print(O, IsForDebug);
+    break;
+  default:
+    llvm_unreachable("unsupported DbgRecord 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 DbgRecord kind");
+  };
+}
+
+bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
+  if (RecordKind != R.RecordKind)
+    return false;
+  switch (RecordKind) {
+  case ValueKind:
+    return cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R));
+    break;
+  default:
+    llvm_unreachable("unsupported DbgRecord kind");
+  };
+}
 
-void DPValue::deleteInstr() { delete this; }
+bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
+  if (RecordKind != R.RecordKind)
+    return false;
+  switch (RecordKind) {
+  case ValueKind:
+    return cast<DPValue>(this)->isEquivalentTo(*cast<DPValue>(&R));
+    break;
+  default:
+    llvm_unreachable("unsupported DbgRecord kind");
+  };
+}
 
 DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
                                 DIExpression *Expr, const DILocation *DI) {
@@ -255,6 +310,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 DbgRecord kind");
+  };
+}
+
 DPValue *DPValue::clone() const { return new DPValue(*this); }
 
 DbgVariableIntrinsic *
@@ -338,59 +402,63 @@ bool DPValue::isKillAddress() const {
   return !Addr || isa<UndefValue>(Addr);
 }
 
-const Instruction *DPValue::getInstruction() const {
+const Instruction *DbgRecord::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();
 }
 
-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);
 }
@@ -401,19 +469,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 *DR = &*It;
     StoredDPValues.erase(It);
-    DPV->deleteInstr();
+    DR->deleteRecord();
   }
 }
 
-void DPMarker::dropOneDPValue(DPValue *DPV) {
-  assert(DPV->getMarker() == this);
-  StoredDPValues.erase(DPV->getIterator());
-  DPV->deleteInstr();
+void DPMarker::dropOneDbgValue(DbgRecord *DR) {
+  assert(DR->getMarker() == this);
+  StoredDPValues.erase(DR->getIterator());
+  DR->deleteRecord();
 }
 
 const BasicBlock *DPMarker::getParent() const {
@@ -462,40 +530,40 @@ 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>
+iterator_range<DbgRecord::const_self_iterator>
 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);
 }
-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);
@@ -504,16 +572,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 &DR : Range)
+    DR.setMarker(this);
 
   auto InsertPos =
       (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
@@ -522,10 +590,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 +605,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 &DR : Range) {
+    DbgRecord *New = DR.clone();
     New->setMarker(this);
     StoredDPValues.insert(Pos, *New);
     if (!First)
@@ -558,4 +626,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 994871eb126884..e091ecbf54005a 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 47367d0b84edec..4d0c221b47afa4 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/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 4dbb79f7bef887..4af455c37c788c 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 90b544c8922623..95a9527126c112 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 (DPValue *DPV = dyn_cast<DPValue>(&DR); DPV && DPV->isDbgAssign())
+        if (!at::getAssignmentInsts(DPV).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/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 ec0482ac2cdeb4..7fd6759a61fbae 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,
@@ -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/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..78317df8a9caec 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);
       }
     }
@@ -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/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/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 7424fe31945dc7..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()));
 
@@ -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..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);
     }
   }
 }
@@ -1232,8 +1233,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/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

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.


        


More information about the llvm-commits mailing list