[llvm] [DebugInfo][RemoveDIs] Add local-utility plumbing for DPValues (PR #72276)

Jeremy Morse via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 16 05:16:34 PST 2023


https://github.com/jmorse updated https://github.com/llvm/llvm-project/pull/72276

>From 9b81ac3c5e8bc72c3d5d908cee6ccf0c3c4ef09a Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Wed, 7 Jun 2023 12:35:04 +0100
Subject: [PATCH 1/4] [DebugInfo][RemoveDIs] Add local-utility plumbing for
 DPValues

This patch re-implements a variety of debug-info maintenence functions to
use DPValues instead of DbgValueInst's: supporting the "new" non-intrinsic
representation of debug-info. As per [0], we need to have parallel
implementations of various utilities for a time, and these are the most
fundamental utilities used throughout the compiler.

I've added --try-experimental-debuginfo-iterators to a variety of RUN
lines: this is a flag that turns on "new debug-info" if it's built into
LLVM, and not otherwise. This should ensure that we have the same behaviour
for the same IR inputs, but using a different internal representation. For
the most part these changes affect SROA/Mem2Reg promotion of dbg.declares
into dbg.value intrinsics (now DPValues), we're leaving dbg.declares as
instructions until later in the day. There's also some salvaging changes
made.

I believe the tests that I've added cover almost all the code being updated
here. The only thing I'm not confident about is SimplifyCFG, which calls
rewriteDebugUsers down a variety of code paths. Those changes can't
immediately get full coverage as an additional patch is needed that updates
handling of Unreachable instructions, will upload that shortly.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939/9
---
 llvm/include/llvm/Transforms/Utils/Local.h    |   9 +-
 .../InstCombine/InstructionCombining.cpp      |   6 +-
 llvm/lib/Transforms/Utils/Local.cpp           | 392 ++++++++++++++++--
 .../test/DebugInfo/salvage-cast-debug-info.ll |   1 +
 llvm/test/DebugInfo/salvage-gep.ll            |   1 +
 .../Transforms/InstCombine/debuginfo-dce.ll   |   1 +
 .../InstCombine/salvage-dbg-declare.ll        |   1 +
 .../Transforms/Mem2Reg/ConvertDebugInfo.ll    |   1 +
 .../Transforms/Mem2Reg/ConvertDebugInfo2.ll   |   1 +
 .../Mem2Reg/dbg-inline-scope-for-phi.ll       |   1 +
 .../dbg_declare_to_value_conversions.ll       |   1 +
 .../Transforms/Mem2Reg/debug-alloca-phi-2.ll  |   1 +
 .../Transforms/Mem2Reg/debug-alloca-phi.ll    |   1 +
 .../Transforms/Mem2Reg/debug-alloca-vla-1.ll  |   1 +
 .../Transforms/Mem2Reg/debug-alloca-vla-2.ll  |   1 +
 ...f_intrinsics_when_deleting_instructions.ll |   1 +
 llvm/test/Transforms/SROA/dbg-inline.ll       |   5 +
 llvm/test/Transforms/SROA/dbg-single-piece.ll |   5 +
 .../SafeStack/X86/debug-loc-dynamic.ll        |   1 +
 .../Transforms/SafeStack/X86/debug-loc.ll     |   1 +
 .../Transforms/SafeStack/X86/debug-loc2.ll    |   1 +
 .../SimplifyCFG/tail-merge-noreturn.ll        |   1 +
 .../test/Transforms/Util/salvage-debuginfo.ll |   2 +
 23 files changed, 396 insertions(+), 40 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index fa8405a6191eba8..9547677397f8021 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -262,16 +262,22 @@ CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
 /// that has an associated llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                      StoreInst *SI, DIBuilder &Builder);
+void ConvertDebugDeclareToDebugValue(DPValue *DPV,
+                                     StoreInst *SI, DIBuilder &Builder);
 
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                      LoadInst *LI, DIBuilder &Builder);
+void ConvertDebugDeclareToDebugValue(DPValue *DPV,
+                                     LoadInst *LI, DIBuilder &Builder);
 
 /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
 /// llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                      PHINode *LI, DIBuilder &Builder);
+void ConvertDebugDeclareToDebugValue(DPValue *DPV,
+                                     PHINode *LI, DIBuilder &Builder);
 
 /// Lowers llvm.dbg.declare intrinsics into appropriate set of
 /// llvm.dbg.value intrinsics.
@@ -307,7 +313,8 @@ void salvageDebugInfo(Instruction &I);
 /// \p Insns, rather than all debug users from findDbgUsers( \p I).
 /// Mark undef if salvaging cannot be completed.
 void salvageDebugInfoForDbgValues(Instruction &I,
-                                  ArrayRef<DbgVariableIntrinsic *> Insns);
+                                  ArrayRef<DbgVariableIntrinsic *> Insns,
+                                  ArrayRef<DPValue *> DPInsns);
 
 /// Given an instruction \p I and DIExpression \p DIExpr operating on
 /// it, append the effects of \p I to the DIExpression operand list
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 2e0b185769041cc..5940ab735e74756 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3921,6 +3921,7 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I,
   // For all debug values in the destination block, the sunk instruction
   // will still be available, so they do not need to be dropped.
   SmallVector<DbgVariableIntrinsic *, 2> DbgUsersToSalvage;
+  SmallVector<DPValue *, 2> DPValuesToSalvage;
   for (auto &DbgUser : DbgUsers)
     if (DbgUser->getParent() != DestBlock)
       DbgUsersToSalvage.push_back(DbgUser);
@@ -3964,7 +3965,10 @@ bool InstCombinerImpl::tryToSinkInstruction(Instruction *I,
 
   // Perform salvaging without the clones, then sink the clones.
   if (!DIIClones.empty()) {
-    salvageDebugInfoForDbgValues(*I, DbgUsersToSalvage);
+    // RemoveDIs: pass in empty vector of DPValues until we get to instrumenting
+    // this pass.
+    SmallVector<DPValue *, 1> DummyDPValues;
+    salvageDebugInfoForDbgValues(*I, DbgUsersToSalvage, DummyDPValues);
     // The clones are in reverse order of original appearance, reverse again to
     // maintain the original order.
     for (auto &DIIClone : llvm::reverse(DIIClones)) {
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index aacf66bfe38eb91..ba97cdf8f3c4b4c 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -69,6 +69,7 @@
 #include "llvm/IR/Value.h"
 #include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
@@ -86,6 +87,8 @@
 using namespace llvm;
 using namespace llvm::PatternMatch;
 
+extern cl::opt<bool> UseNewDbgInfoFormat;
+
 #define DEBUG_TYPE "local"
 
 STATISTIC(NumRemoved, "Number of unreachable basic blocks removed");
@@ -608,10 +611,13 @@ void llvm::RecursivelyDeleteTriviallyDeadInstructions(
 
 bool llvm::replaceDbgUsesWithUndef(Instruction *I) {
   SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
-  findDbgUsers(DbgUsers, I);
+  SmallVector<DPValue *, 1> DPUsers;
+  findDbgUsers(DbgUsers, I, &DPUsers);
   for (auto *DII : DbgUsers)
     DII->setKillLocation();
-  return !DbgUsers.empty();
+  for (auto *DPV : DPUsers)
+    DPV->setKillLocation();
+  return !DbgUsers.empty() || !DPUsers.empty();
 }
 
 /// areAllUsesEqual - Check whether the uses of a value are all the same.
@@ -1566,12 +1572,18 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
   // is removed by LowerDbgDeclare(), we need to make sure that we are
   // not inserting the same dbg.value intrinsic over and over.
   SmallVector<DbgValueInst *, 1> DbgValues;
-  findDbgValues(DbgValues, APN);
+  SmallVector<DPValue *, 1> DPValues;
+  findDbgValues(DbgValues, APN, &DPValues);
   for (auto *DVI : DbgValues) {
     assert(is_contained(DVI->getValues(), APN));
     if ((DVI->getVariable() == DIVar) && (DVI->getExpression() == DIExpr))
       return true;
   }
+  for (auto *DPV : DPValues) {
+    assert(is_contained(DPV->location_ops(), APN));
+    if ((DPV->getVariable() == DIVar) && (DPV->getExpression() == DIExpr))
+      return true;
+  }
   return false;
 }
 
@@ -1607,6 +1619,57 @@ static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) {
   // Could not determine size of variable. Conservatively return false.
   return false;
 }
+// RemoveDIs: duplicate implementation of the above, using DPValues, the
+// replacement for dbg.values.
+static bool valueCoversEntireFragment(Type *ValTy, DPValue *DPV) {
+  const DataLayout &DL = DPV->getModule()->getDataLayout();
+  TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy);
+  if (std::optional<uint64_t> FragmentSize = DPV->getFragmentSizeInBits())
+    return TypeSize::isKnownGE(ValueSize, TypeSize::Fixed(*FragmentSize));
+
+  // We can't always calculate the size of the DI variable (e.g. if it is a
+  // VLA). Try to use the size of the alloca that the dbg intrinsic describes
+  // intead.
+  if (DPV->isAddressOfVariable()) {
+    // DPV should have exactly 1 location when it is an address.
+    assert(DPV->getNumVariableLocationOps() == 1 &&
+           "address of variable must have exactly 1 location operand.");
+    if (auto *AI =
+            dyn_cast_or_null<AllocaInst>(DPV->getVariableLocationOp(0))) {
+      if (std::optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) {
+        return TypeSize::isKnownGE(ValueSize, *FragmentSize);
+      }
+    }
+  }
+  // Could not determine size of variable. Conservatively return false.
+  return false;
+}
+
+static void insertDbgValueOrDPValue(DIBuilder &Builder, Value *DV, DILocalVariable *DIVar, DIExpression *DIExpr, const DebugLoc &NewLoc, BasicBlock::iterator Instr) {
+  if (!UseNewDbgInfoFormat) {
+    auto *DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, (Instruction*)nullptr);
+    DbgVal->insertBefore(Instr);
+  } else {
+    // RemoveDIs: if we're using the new debug-info format, allocate a
+    // DPValue directly instead of a dbg.value intrinsic.
+    ValueAsMetadata *DVAM = ValueAsMetadata::get(DV);
+    DPValue *DV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get());
+    Instr->getParent()->insertDPValueBefore(DV, Instr);
+  }
+}
+
+static void insertDbgValueOrDPValueAfter(DIBuilder &Builder, Value *DV, DILocalVariable *DIVar, DIExpression *DIExpr, const DebugLoc &NewLoc, BasicBlock::iterator Instr) {
+  if (!UseNewDbgInfoFormat) {
+    auto *DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, (Instruction*)nullptr);
+    DbgVal->insertAfter(&*Instr);
+  } else {
+    // RemoveDIs: if we're using the new debug-info format, allocate a
+    // DPValue directly instead of a dbg.value intrinsic.
+    ValueAsMetadata *DVAM = ValueAsMetadata::get(DV);
+    DPValue *DV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get());
+    Instr->getParent()->insertDPValueAfter(DV, &*Instr);
+  }
+}
 
 /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
@@ -1636,7 +1699,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
       DIExpr->isDeref() || (!DIExpr->startsWithDeref() &&
                             valueCoversEntireFragment(DV->getType(), DII));
   if (CanConvert) {
-    Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, SI);
+    insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, SI->getIterator());
     return;
   }
 
@@ -1648,7 +1711,18 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
   // know which part) we insert an dbg.value intrinsic to indicate that we
   // know nothing about the variable's content.
   DV = UndefValue::get(DV->getType());
-  Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, SI);
+  insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, SI->getIterator());
+}
+
+// RemoveDIs: duplicate the getDebugValueLoc method using DPValues instead of
+// dbg.value intrinsics.
+static DebugLoc getDebugValueLocDPV(DPValue *DPV, Instruction *Src) {
+  // Original dbg.declare must have a location.
+  const DebugLoc &DeclareLoc = DPV->getDebugLoc();
+  MDNode *Scope = DeclareLoc.getScope();
+  DILocation *InlinedAt = DeclareLoc.getInlinedAt();
+  // Produce an unknown location with the correct scope / inlinedAt fields.
+  return DILocation::get(DPV->getContext(), 0, 0, Scope, InlinedAt);
 }
 
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
@@ -1674,9 +1748,39 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
   // future if multi-location support is added to the IR, it might be
   // preferable to keep tracking both the loaded value and the original
   // address in case the alloca can not be elided.
-  Instruction *DbgValue = Builder.insertDbgValueIntrinsic(
-      LI, DIVar, DIExpr, NewLoc, (Instruction *)nullptr);
-  DbgValue->insertAfter(LI);
+  insertDbgValueOrDPValueAfter(Builder, LI, DIVar, DIExpr, NewLoc, LI->getIterator());
+}
+
+void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
+                                           StoreInst *SI, DIBuilder &Builder) {
+  assert(DPV->isAddressOfVariable());
+  auto *DIVar = DPV->getVariable();
+  assert(DIVar && "Missing variable");
+  auto *DIExpr = DPV->getExpression();
+  Value *DV = SI->getValueOperand();
+
+  DebugLoc NewLoc = getDebugValueLocDPV(DPV, SI);
+
+  if (!valueCoversEntireFragment(DV->getType(), DPV)) {
+    // FIXME: If storing to a part of the variable described by the dbg.declare,
+    // then we want to insert a DPValue.value for the corresponding fragment.
+    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: "
+                      << *DPV << '\n');
+    // For now, when there is a store to parts of the variable (but we do not
+    // know which part) we insert an DPValue record to indicate that we know
+    // nothing about the variable's content.
+    DV = UndefValue::get(DV->getType());
+    ValueAsMetadata *DVAM = ValueAsMetadata::get(DV);
+    DPValue *NewDPV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get());
+    SI->getParent()->insertDPValueBefore(NewDPV, SI->getIterator());
+    return;
+  }
+
+  assert(UseNewDbgInfoFormat);
+  // Create a DPValue directly and insert.
+  ValueAsMetadata *DVAM = ValueAsMetadata::get(DV);
+  DPValue *NewDPV = new DPValue(DVAM, DIVar, DIExpr, NewLoc.get());
+  SI->getParent()->insertDPValueBefore(NewDPV, SI->getIterator());
 }
 
 /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
@@ -1707,8 +1811,38 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
   // The block may be a catchswitch block, which does not have a valid
   // insertion point.
   // FIXME: Insert dbg.value markers in the successors when appropriate.
-  if (InsertionPt != BB->end())
-    Builder.insertDbgValueIntrinsic(APN, DIVar, DIExpr, NewLoc, &*InsertionPt);
+  if (InsertionPt != BB->end()) {
+    insertDbgValueOrDPValue(Builder, APN, DIVar, DIExpr, NewLoc, InsertionPt);
+  }
+}
+
+void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
+                                           LoadInst *LI, DIBuilder &Builder) {
+  auto *DIVar = DPV->getVariable();
+  auto *DIExpr = DPV->getExpression();
+  assert(DIVar && "Missing variable");
+
+  if (!valueCoversEntireFragment(LI->getType(), DPV)) {
+    // FIXME: If only referring to a part of the variable described by the
+    // dbg.declare, then we want to insert a DPValue for the corresponding
+    // fragment.
+    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: "
+                      << *DPV << '\n');
+    return;
+  }
+
+  DebugLoc NewLoc = getDebugValueLocDPV(DPV, nullptr);
+
+  // We are now tracking the loaded value instead of the address. In the
+  // future if multi-location support is added to the IR, it might be
+  // preferable to keep tracking both the loaded value and the original
+  // address in case the alloca can not be elided.
+  assert(UseNewDbgInfoFormat);
+
+  // Create a DPValue directly and insert.
+  ValueAsMetadata *LIVAM = ValueAsMetadata::get(LI);
+  DPValue *DV = new DPValue(LIVAM, DIVar, DIExpr, NewLoc.get());
+  LI->getParent()->insertDPValueAfter(DV, LI);
 }
 
 /// Determine whether this alloca is either a VLA or an array.
@@ -1721,6 +1855,36 @@ static bool isArray(AllocaInst *AI) {
 static bool isStructure(AllocaInst *AI) {
   return AI->getAllocatedType() && AI->getAllocatedType()->isStructTy();
 }
+void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
+                                           PHINode *APN, DIBuilder &Builder) {
+  auto *DIVar = DPV->getVariable();
+  auto *DIExpr = DPV->getExpression();
+  assert(DIVar && "Missing variable");
+
+  if (PhiHasDebugValue(DIVar, DIExpr, APN))
+    return;
+
+  if (!valueCoversEntireFragment(APN->getType(), DPV)) {
+    // FIXME: If only referring to a part of the variable described by the
+    // dbg.declare, then we want to insert a DPValue for the corresponding
+    // fragment.
+    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: "
+                      << *DPV << '\n');
+    return;
+  }
+
+  BasicBlock *BB = APN->getParent();
+  auto InsertionPt = BB->getFirstInsertionPt();
+
+  DebugLoc NewLoc = getDebugValueLocDPV(DPV, nullptr);
+
+  // The block may be a catchswitch block, which does not have a valid
+  // insertion point.
+  // FIXME: Insert DPValue markers in the successors when appropriate.
+  if (InsertionPt != BB->end()) {
+    insertDbgValueOrDPValue(Builder, APN, DIVar, DIExpr, NewLoc, InsertionPt);
+  }
+}
 
 /// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set
 /// of llvm.dbg.value intrinsics.
@@ -1777,8 +1941,7 @@ bool llvm::LowerDbgDeclare(Function &F) {
             DebugLoc NewLoc = getDebugValueLoc(DDI);
             auto *DerefExpr =
                 DIExpression::append(DDI->getExpression(), dwarf::DW_OP_deref);
-            DIB.insertDbgValueIntrinsic(AI, DDI->getVariable(), DerefExpr,
-                                        NewLoc, CI);
+            insertDbgValueOrDPValue(DIB, AI, DDI->getVariable(), DerefExpr, NewLoc, CI->getIterator());
           }
         } else if (BitCastInst *BI = dyn_cast<BitCastInst>(U)) {
           if (BI->getType()->isPointerTy())
@@ -1878,14 +2041,12 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
   return !DbgDeclares.empty();
 }
 
-static void replaceOneDbgValueForAlloca(DbgValueInst *DVI, Value *NewAddress,
+static void updateOneDbgValueForAlloca(const DebugLoc &Loc, DILocalVariable *DIVar, DIExpression *DIExpr,
+                                        Value *NewAddress, DbgValueInst *DVI, DPValue *DPV,
                                         DIBuilder &Builder, int Offset) {
-  const DebugLoc &Loc = DVI->getDebugLoc();
-  auto *DIVar = DVI->getVariable();
-  auto *DIExpr = DVI->getExpression();
   assert(DIVar && "Missing variable");
 
-  // This is an alloca-based llvm.dbg.value. The first thing it should do with
+  // This is an alloca-based dbg.value/DPValue. The first thing it should do with
   // the alloca pointer is dereference it. Otherwise we don't know how to handle
   // it and give up.
   if (!DIExpr || DIExpr->getNumElements() < 1 ||
@@ -1893,29 +2054,46 @@ static void replaceOneDbgValueForAlloca(DbgValueInst *DVI, Value *NewAddress,
     return;
 
   // Insert the offset before the first deref.
-  // We could just change the offset argument of dbg.value, but it's unsigned...
   if (Offset)
     DIExpr = DIExpression::prepend(DIExpr, 0, Offset);
 
-  Builder.insertDbgValueIntrinsic(NewAddress, DIVar, DIExpr, Loc, DVI);
-  DVI->eraseFromParent();
+  if (DVI) {
+    DVI->setExpression(DIExpr);
+    DVI->replaceVariableLocationOp(0u, NewAddress);
+  } else {
+    assert(DPV);
+    DPV->setExpression(DIExpr);
+    DPV->replaceVariableLocationOp(0u, NewAddress);
+  }
 }
 
 void llvm::replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
                                     DIBuilder &Builder, int Offset) {
-  if (auto *L = LocalAsMetadata::getIfExists(AI))
-    if (auto *MDV = MetadataAsValue::getIfExists(AI->getContext(), L))
-      for (Use &U : llvm::make_early_inc_range(MDV->uses()))
-        if (auto *DVI = dyn_cast<DbgValueInst>(U.getUser()))
-          replaceOneDbgValueForAlloca(DVI, NewAllocaAddress, Builder, Offset);
+  SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
+  SmallVector<DPValue *, 1> DPUsers;
+  findDbgUsers(DbgUsers, AI, &DPUsers);
+
+  // Attempt to replace dbg.values that use this alloca.
+  for (auto *DV : DbgUsers) {
+    auto *DVI = dyn_cast<DbgValueInst>(DV);
+    if (!DVI)
+      continue;
+    updateOneDbgValueForAlloca(DVI->getDebugLoc(), DVI->getVariable(), DVI->getExpression(), NewAllocaAddress, DVI, nullptr, Builder, Offset);
+  }
+
+  // Replace any DPValues that use this alloca.
+  for (DPValue *DPV : DPUsers) {
+    updateOneDbgValueForAlloca(DPV->getDebugLoc(), DPV->getVariable(), DPV->getExpression(), NewAllocaAddress, nullptr, DPV, Builder, Offset);
+  }
 }
 
 /// Where possible to salvage debug information for \p I do so.
 /// If not possible mark undef.
 void llvm::salvageDebugInfo(Instruction &I) {
   SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
-  findDbgUsers(DbgUsers, &I);
-  salvageDebugInfoForDbgValues(I, DbgUsers);
+  SmallVector<DPValue *, 1> DPUsers;
+  findDbgUsers(DbgUsers, &I, &DPUsers);
+  salvageDebugInfoForDbgValues(I, DbgUsers, DPUsers);
 }
 
 /// Salvage the address component of \p DAI.
@@ -1953,7 +2131,7 @@ static void salvageDbgAssignAddress(DbgAssignIntrinsic *DAI) {
 }
 
 void llvm::salvageDebugInfoForDbgValues(
-    Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
+    Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers, ArrayRef<DPValue *> DPUsers) {
   // These are arbitrary chosen limits on the maximum number of values and the
   // maximum size of a debug expression we can salvage up to, used for
   // performance reasons.
@@ -2019,12 +2197,68 @@ void llvm::salvageDebugInfoForDbgValues(
     LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
     Salvaged = true;
   }
+  // Duplicate of above block for DPValues.
+  for (auto *DPV : DPUsers) {
+    // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they
+    // are implicitly pointing out the value as a DWARF memory location
+    // description.
+    bool StackValue = DPV->getType() == DPValue::LocationType::Value;
+    auto DPVLocation = DPV->location_ops();
+    assert(
+        is_contained(DPVLocation, &I) &&
+        "DbgVariableIntrinsic must use salvaged instruction as its location");
+    SmallVector<Value *, 4> AdditionalValues;
+    // 'I' may appear more than once in DPV's location ops, and each use of 'I'
+    // must be updated in the DIExpression and potentially have additional
+    // values added; thus we call salvageDebugInfoImpl for each 'I' instance in
+    // DPVLocation.
+    Value *Op0 = nullptr;
+    DIExpression *SalvagedExpr = DPV->getExpression();
+    auto LocItr = find(DPVLocation, &I);
+    while (SalvagedExpr && LocItr != DPVLocation.end()) {
+      SmallVector<uint64_t, 16> Ops;
+      unsigned LocNo = std::distance(DPVLocation.begin(), LocItr);
+      uint64_t CurrentLocOps = SalvagedExpr->getNumLocationOperands();
+      Op0 = salvageDebugInfoImpl(I, CurrentLocOps, Ops, AdditionalValues);
+      if (!Op0)
+        break;
+      SalvagedExpr =
+          DIExpression::appendOpsToArg(SalvagedExpr, Ops, LocNo, StackValue);
+      LocItr = std::find(++LocItr, DPVLocation.end(), &I);
+    }
+    // salvageDebugInfoImpl should fail on examining the first element of
+    // DbgUsers, or none of them.
+    if (!Op0)
+      break;
+
+    DPV->replaceVariableLocationOp(&I, Op0);
+    bool IsValidSalvageExpr = SalvagedExpr->getNumElements() <= MaxExpressionSize;
+    if (AdditionalValues.empty() && IsValidSalvageExpr) {
+      DPV->setExpression(SalvagedExpr);
+    } else if (DPV->getType() == DPValue::LocationType::Value && IsValidSalvageExpr &&
+               DPV->getNumVariableLocationOps() + AdditionalValues.size() <=
+                   MaxDebugArgs) {
+      DPV->addVariableLocationOps(AdditionalValues, SalvagedExpr);
+    } else {
+      // Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is
+      // currently only valid for stack value expressions.
+      // Also do not salvage if the resulting DIArgList would contain an
+      // unreasonably large number of values.
+      Value *Undef = UndefValue::get(I.getOperand(0)->getType());
+      DPV->replaceVariableLocationOp(I.getOperand(0), Undef);
+    }
+    LLVM_DEBUG(dbgs() << "SALVAGE: " << DPV << '\n');
+    Salvaged = true;
+  }
 
   if (Salvaged)
     return;
 
   for (auto *DII : DbgUsers)
     DII->setKillLocation();
+
+  for (auto *DPV : DPUsers)
+    DPV->setKillLocation();
 }
 
 Value *getSalvageOpsForGEP(GetElementPtrInst *GEP, const DataLayout &DL,
@@ -2239,16 +2473,20 @@ using DbgValReplacement = std::optional<DIExpression *>;
 /// changes are made.
 static bool rewriteDebugUsers(
     Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT,
-    function_ref<DbgValReplacement(DbgVariableIntrinsic &DII)> RewriteExpr) {
+    function_ref<DbgValReplacement(DbgVariableIntrinsic &DII)> RewriteExpr,
+    function_ref<DbgValReplacement(DPValue &DPV)> RewriteDPVExpr) {
   // Find debug users of From.
   SmallVector<DbgVariableIntrinsic *, 1> Users;
-  findDbgUsers(Users, &From);
-  if (Users.empty())
+  SmallVector<DPValue *, 1> DPUsers;
+  findDbgUsers(Users, &From, &DPUsers);
+  if (Users.empty() && DPUsers.empty())
     return false;
 
   // Prevent use-before-def of To.
   bool Changed = false;
+
   SmallPtrSet<DbgVariableIntrinsic *, 1> UndefOrSalvage;
+  SmallPtrSet<DPValue *, 1> UndefOrSalvageDPV;
   if (isa<Instruction>(&To)) {
     bool DomPointAfterFrom = From.getNextNonDebugInstruction() == &DomPoint;
 
@@ -2266,6 +2504,33 @@ static bool rewriteDebugUsers(
         UndefOrSalvage.insert(DII);
       }
     }
+
+    // DPValue implementation of the above.
+    // RemoveDIs misery: The above loop of intrinsic-users are ordered by the
+    // use-list of the corresponding metadata-as-value: in reverse order of when
+    // they were added. Wheras DPUsers are ordered by when they were added to
+    // the replaceable-metadata map, i.e., in the order they were added. Thus to
+    // have matching orders between the two, we have to reverse here. For
+    // RemoveDIs we might in the long run need to consider whether this implicit
+    // ordering is relied upon by any other part of LLVM.
+    for (auto *DPV : llvm::reverse(DPUsers)) {
+      Instruction *MarkedInstr = DPV->getMarker()->MarkedInstr;
+      Instruction *NextNonDebug = MarkedInstr;
+      // The next instruction might still be a dbg.declare, skip over it.
+      if (isa<DbgVariableIntrinsic>(NextNonDebug))
+        NextNonDebug = NextNonDebug->getNextNonDebugInstruction();
+
+      if (DomPointAfterFrom && NextNonDebug == &DomPoint) {
+        LLVM_DEBUG(dbgs() << "MOVE:  " << *DPV << '\n');
+        DPV->removeFromParent();
+        // Ensure there's a marker.
+        DomPoint.getParent()->createMarker(std::next(DomPoint.getIterator()));
+        DomPoint.getParent()->insertDPValueAfter(DPV, &DomPoint);
+        Changed = true;
+      } else if (!DT.dominates(&DomPoint, MarkedInstr)) {
+        UndefOrSalvageDPV.insert(DPV);
+      }
+    }
   }
 
   // Update debug users without use-before-def risk.
@@ -2282,8 +2547,21 @@ static bool rewriteDebugUsers(
     LLVM_DEBUG(dbgs() << "REWRITE:  " << *DII << '\n');
     Changed = true;
   }
+  for (auto *DPV : DPUsers) {
+    if (UndefOrSalvageDPV.count(DPV))
+      continue;
 
-  if (!UndefOrSalvage.empty()) {
+    DbgValReplacement DVR = RewriteDPVExpr(*DPV);
+    if (!DVR)
+      continue;
+
+    DPV->replaceVariableLocationOp(&From, &To);
+    DPV->setExpression(*DVR);
+    LLVM_DEBUG(dbgs() << "REWRITE:  " << DPV << '\n');
+    Changed = true;
+  }
+
+  if (!UndefOrSalvage.empty() || !UndefOrSalvageDPV.empty()) {
     // Try to salvage the remaining debug users.
     salvageDebugInfo(From);
     Changed = true;
@@ -2331,12 +2609,15 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
   auto Identity = [&](DbgVariableIntrinsic &DII) -> DbgValReplacement {
     return DII.getExpression();
   };
+  auto IdentityDPV = [&](DPValue &DPV) -> DbgValReplacement {
+    return DPV.getExpression();
+  };
 
   // Handle no-op conversions.
   Module &M = *From.getModule();
   const DataLayout &DL = M.getDataLayout();
   if (isBitCastSemanticsPreserving(DL, FromTy, ToTy))
-    return rewriteDebugUsers(From, To, DomPoint, DT, Identity);
+    return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDPV);
 
   // Handle integer-to-integer widening and narrowing.
   // FIXME: Use DW_OP_convert when it's available everywhere.
@@ -2348,7 +2629,7 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
     // When the width of the result grows, assume that a debugger will only
     // access the low `FromBits` bits when inspecting the source variable.
     if (FromBits < ToBits)
-      return rewriteDebugUsers(From, To, DomPoint, DT, Identity);
+      return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDPV);
 
     // The width of the result has shrunk. Use sign/zero extension to describe
     // the source variable's high bits.
@@ -2364,7 +2645,21 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
       return DIExpression::appendExt(DII.getExpression(), ToBits, FromBits,
                                      Signed);
     };
-    return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt);
+    // RemoveDIs: duplicate implementation working on DPValues rather than on
+    // dbg.value intrinsics.
+    auto SignOrZeroExtDPV = [&](DPValue &DPV) -> DbgValReplacement {
+      DILocalVariable *Var = DPV.getVariable();
+
+      // Without knowing signedness, sign/zero extension isn't possible.
+      auto Signedness = Var->getSignedness();
+      if (!Signedness)
+        return std::nullopt;
+
+      bool Signed = *Signedness == DIBasicType::Signedness::Signed;
+      return DIExpression::appendExt(DPV.getExpression(), ToBits, FromBits,
+                                     Signed);
+    };
+    return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt, SignOrZeroExtDPV);
   }
 
   // TODO: Floating-point conversions, vectors.
@@ -2378,6 +2673,8 @@ llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
   // Delete the instructions backwards, as it has a reduced likelihood of
   // having to update as many def-use and use-def chains.
   Instruction *EndInst = BB->getTerminator(); // Last not to be deleted.
+  // RemoveDIs: erasing debug-info must be done manually.
+  EndInst->dropDbgValues();
   while (EndInst != &BB->front()) {
     // Delete the next to last instruction.
     Instruction *Inst = &*--EndInst->getIterator();
@@ -2391,6 +2688,8 @@ llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
       ++NumDeadDbgInst;
     else
       ++NumDeadInst;
+    // RemoveDIs: erasing debug-info must be done manually.
+    Inst->dropDbgValues();
     Inst->eraseFromParent();
   }
   return {NumDeadInst, NumDeadDbgInst};
@@ -3121,9 +3420,24 @@ void llvm::copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI,
 
 void llvm::dropDebugUsers(Instruction &I) {
   SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
-  findDbgUsers(DbgUsers, &I);
-  for (auto *DII : DbgUsers)
-    DII->eraseFromParent();
+  SmallVector<DPValue *, 1> DPUsers;
+  findDbgUsers(DbgUsers, &I, &DPUsers);
+  for (auto *DII : DbgUsers) {
+    if (auto *DbgValue = dyn_cast<DbgValueInst>(DII)) {
+      // Don't delete dbg.values, that's bad.
+      DbgValue->setKillLocation();
+    } else {
+      DII->eraseFromParent();
+    }
+  }
+  for (auto *DPV : DPUsers) {
+    if (DPV->getType() == DPValue::LocationType::Value) {
+      // Don't delete DPValues, that's bad.
+      DPV->setKillLocation();
+    } else {
+      DPV->eraseFromParent();
+    }
+  }
 }
 
 void llvm::hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,
@@ -3155,6 +3469,8 @@ void llvm::hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,
     I->dropUBImplyingAttrsAndMetadata();
     if (I->isUsedByMetadata())
       dropDebugUsers(*I);
+    // RemoveDIs: drop debug-info too as the following code does.
+    I->dropDbgValues();
     if (I->isDebugOrPseudoInst()) {
       // Remove DbgInfo and pseudo probe Intrinsics.
       II = I->eraseFromParent();
diff --git a/llvm/test/DebugInfo/salvage-cast-debug-info.ll b/llvm/test/DebugInfo/salvage-cast-debug-info.ll
index c196bcd052673eb..4676aee3d4e4800 100644
--- a/llvm/test/DebugInfo/salvage-cast-debug-info.ll
+++ b/llvm/test/DebugInfo/salvage-cast-debug-info.ll
@@ -1,4 +1,5 @@
 ; RUN: opt %s -passes=debugify,early-cse -earlycse-debug-hash -S | FileCheck %s
+; RUN: opt %s -passes=debugify,early-cse -earlycse-debug-hash -S --try-experimental-debuginfo-iterators | FileCheck %s
 define i32 @foo(i64 %nose, i32 %more) {
 ; CHECK-LABEL: @foo(
 ; CHECK: call void @llvm.dbg.value(metadata i64 %nose, metadata [[V1:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned
diff --git a/llvm/test/DebugInfo/salvage-gep.ll b/llvm/test/DebugInfo/salvage-gep.ll
index 4d7448ff3f4b64d..01191da1ed8fa70 100644
--- a/llvm/test/DebugInfo/salvage-gep.ll
+++ b/llvm/test/DebugInfo/salvage-gep.ll
@@ -1,4 +1,5 @@
 ; RUN: opt %s -passes=dce -S | FileCheck %s
+; RUN: opt %s -passes=dce -S --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Tests the salvaging of GEP instructions, specifically struct indexing,
 ; non-constant array indexing, and non-constant array indexing into an array of
diff --git a/llvm/test/Transforms/InstCombine/debuginfo-dce.ll b/llvm/test/Transforms/InstCombine/debuginfo-dce.ll
index 1049d8380aad986..257222cb70c2382 100644
--- a/llvm/test/Transforms/InstCombine/debuginfo-dce.ll
+++ b/llvm/test/Transforms/InstCombine/debuginfo-dce.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -passes=instcombine %s -S -o - | FileCheck %s
+; RUN: opt -passes=instcombine %s -S -o - --try-experimental-debuginfo-iterators | FileCheck %s
 ; Verify that the eliminated instructions (bitcast, gep, load) are salvaged into
 ; a DIExpression.
 ;
diff --git a/llvm/test/Transforms/InstCombine/salvage-dbg-declare.ll b/llvm/test/Transforms/InstCombine/salvage-dbg-declare.ll
index e7805618edf6f16..8554296a406d8c0 100644
--- a/llvm/test/Transforms/InstCombine/salvage-dbg-declare.ll
+++ b/llvm/test/Transforms/InstCombine/salvage-dbg-declare.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s
+; RUN: opt -passes=instcombine -S -o - %s --try-experimental-debuginfo-iterators | FileCheck %s
 
 declare dso_local i32 @bar(ptr)
 
diff --git a/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll b/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
index 02d048dc4821ef0..ac3bf8f8d78e4a1 100644
--- a/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
+++ b/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
+; RUN: opt < %s -passes=mem2reg -S --try-experimental-debuginfo-iterators | FileCheck %s
 
 define double @testfunc(i32 %i, double %j) nounwind ssp !dbg !1 {
 entry:
diff --git a/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll b/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll
index 588b14f22c39bd7..97ff751bb73af3e 100644
--- a/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll
+++ b/llvm/test/Transforms/Mem2Reg/ConvertDebugInfo2.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -S -passes=mem2reg <%s | FileCheck %s
+; RUN: opt -S -passes=mem2reg <%s --try-experimental-debuginfo-iterators | FileCheck %s
 
 declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
 
diff --git a/llvm/test/Transforms/Mem2Reg/dbg-inline-scope-for-phi.ll b/llvm/test/Transforms/Mem2Reg/dbg-inline-scope-for-phi.ll
index 2b3905b9a7bd844..53a33c8ad8d4e74 100644
--- a/llvm/test/Transforms/Mem2Reg/dbg-inline-scope-for-phi.ll
+++ b/llvm/test/Transforms/Mem2Reg/dbg-inline-scope-for-phi.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -S < %s -passes='function(mem2reg),require<verify>' | FileCheck %s
+; RUN: opt -S < %s -passes='function(mem2reg),require<verify>' --try-experimental-debuginfo-iterators | FileCheck %s
 
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.13.0"
diff --git a/llvm/test/Transforms/Mem2Reg/dbg_declare_to_value_conversions.ll b/llvm/test/Transforms/Mem2Reg/dbg_declare_to_value_conversions.ll
index 04d963841acf778..8012c2b97a6b67f 100644
--- a/llvm/test/Transforms/Mem2Reg/dbg_declare_to_value_conversions.ll
+++ b/llvm/test/Transforms/Mem2Reg/dbg_declare_to_value_conversions.ll
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -passes='mem2reg' -S | FileCheck %s
+; RUN: opt < %s -passes='mem2reg' -S --try-experimental-debuginfo-iterators | FileCheck %s
 target datalayout = "e-p:64:64"
 
 ; An intrinsic without any expressions should always be converted.
diff --git a/llvm/test/Transforms/Mem2Reg/debug-alloca-phi-2.ll b/llvm/test/Transforms/Mem2Reg/debug-alloca-phi-2.ll
index 871543bb44c2c8b..e4c638d39ccffdb 100644
--- a/llvm/test/Transforms/Mem2Reg/debug-alloca-phi-2.ll
+++ b/llvm/test/Transforms/Mem2Reg/debug-alloca-phi-2.ll
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
+; RUN: opt < %s -passes=mem2reg -S --try-experimental-debuginfo-iterators | FileCheck %s
 source_filename = "bugpoint-output.bc"
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.12.0"
diff --git a/llvm/test/Transforms/Mem2Reg/debug-alloca-phi.ll b/llvm/test/Transforms/Mem2Reg/debug-alloca-phi.ll
index 3202c18869eb95b..01f45e9c081d396 100644
--- a/llvm/test/Transforms/Mem2Reg/debug-alloca-phi.ll
+++ b/llvm/test/Transforms/Mem2Reg/debug-alloca-phi.ll
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
+; RUN: opt < %s -passes=mem2reg -S --try-experimental-debuginfo-iterators | FileCheck %s
 source_filename = "bugpoint-output.bc"
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.12.0"
diff --git a/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-1.ll b/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-1.ll
index 8aa9df286427ea4..9b29f981b26c1fc 100644
--- a/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-1.ll
+++ b/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-1.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
+; RUN: opt < %s -passes=mem2reg -S --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Testing conversion from dbg.declare to dbg.value when the variable is a VLA.
 ;
diff --git a/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-2.ll b/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-2.ll
index 972ec66b906b839..894e9555ee6ebb1 100644
--- a/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-2.ll
+++ b/llvm/test/Transforms/Mem2Reg/debug-alloca-vla-2.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -passes=mem2reg -S | FileCheck %s
+; RUN: opt < %s -passes=mem2reg -S --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Testing conversion from dbg.declare to dbg.value when the variable is a VLA.
 ;
diff --git a/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll b/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll
index 7d05212708d13ec..ef9b86db52f2b41 100644
--- a/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll
+++ b/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -passes=reassociate -S | FileCheck %s
+; RUN: opt < %s -passes=reassociate -S --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Check that reassociate pass now undefs debug intrinsics that reference a value
 ; that gets dropped and cannot be salvaged.
diff --git a/llvm/test/Transforms/SROA/dbg-inline.ll b/llvm/test/Transforms/SROA/dbg-inline.ll
index 336ebb4efc8da77..454ca13230bfa61 100644
--- a/llvm/test/Transforms/SROA/dbg-inline.ll
+++ b/llvm/test/Transforms/SROA/dbg-inline.ll
@@ -4,6 +4,11 @@
 
 ; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
 ; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+
+;; Duplicate copies for RemoveDIs, eliminating debug intrinsics.
+; RUN: opt < %s -passes='sroa<preserve-cfg>' -S --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt < %s -passes='sroa<modify-cfg>' -S --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+
 source_filename = "/tmp/inlinesplit.cpp"
 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.15.0"
diff --git a/llvm/test/Transforms/SROA/dbg-single-piece.ll b/llvm/test/Transforms/SROA/dbg-single-piece.ll
index c60be8d74054eb6..9df1a835b42e55c 100644
--- a/llvm/test/Transforms/SROA/dbg-single-piece.ll
+++ b/llvm/test/Transforms/SROA/dbg-single-piece.ll
@@ -1,6 +1,11 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -passes='sroa<preserve-cfg>' %s -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
 ; RUN: opt -passes='sroa<modify-cfg>' %s -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+
+;; Duplicate copies for RemoveDIs project, eliminating debug intrinsics
+; RUN: opt -passes='sroa<preserve-cfg>' %s -S --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt -passes='sroa<modify-cfg>' %s -S --try-experimental-debuginfo-iterators | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
 %foo = type { [8 x i8], [8 x i8] }
diff --git a/llvm/test/Transforms/SafeStack/X86/debug-loc-dynamic.ll b/llvm/test/Transforms/SafeStack/X86/debug-loc-dynamic.ll
index c118c486e5aa90e..b5d862b03b623f5 100644
--- a/llvm/test/Transforms/SafeStack/X86/debug-loc-dynamic.ll
+++ b/llvm/test/Transforms/SafeStack/X86/debug-loc-dynamic.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s
+; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Test llvm.dbg.value for dynamic allocas moved onto the unsafe stack.
 ; In the dynamic alloca case, the dbg.value does not change with the exception
diff --git a/llvm/test/Transforms/SafeStack/X86/debug-loc.ll b/llvm/test/Transforms/SafeStack/X86/debug-loc.ll
index 8501f7446f99fd1..41240f7d7a916f3 100644
--- a/llvm/test/Transforms/SafeStack/X86/debug-loc.ll
+++ b/llvm/test/Transforms/SafeStack/X86/debug-loc.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s
+; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Test debug location for the local variables moved onto the unsafe stack.
 
diff --git a/llvm/test/Transforms/SafeStack/X86/debug-loc2.ll b/llvm/test/Transforms/SafeStack/X86/debug-loc2.ll
index 05b66a5175cc719..a7164ef0f45c309 100644
--- a/llvm/test/Transforms/SafeStack/X86/debug-loc2.ll
+++ b/llvm/test/Transforms/SafeStack/X86/debug-loc2.ll
@@ -1,4 +1,5 @@
 ; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s
+; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Test llvm.dbg.value for the local variables moved onto the unsafe stack.
 ; SafeStack rewrites them relative to the unsafe stack pointer (base address of
diff --git a/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll b/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll
index d44efce15ada270..5af708a2d0d8d61 100644
--- a/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll
+++ b/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts  -S < %s | FileCheck %s
+; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts  -S < %s --try-experimental-debuginfo-iterators | FileCheck %s
 
 ; Test that we tail merge noreturn call blocks and phi constants properly.
 
diff --git a/llvm/test/Transforms/Util/salvage-debuginfo.ll b/llvm/test/Transforms/Util/salvage-debuginfo.ll
index 566104e9e358b0e..5058095491bbbe9 100644
--- a/llvm/test/Transforms/Util/salvage-debuginfo.ll
+++ b/llvm/test/Transforms/Util/salvage-debuginfo.ll
@@ -1,5 +1,7 @@
 ; RUN: opt -passes=adce %s -S -o - | FileCheck %s
 ; RUN: opt -passes=bdce %s -S -o - | FileCheck %s
+; RUN: opt -passes=adce %s -S -o - --try-experimental-debuginfo-iterators | FileCheck %s
+; RUN: opt -passes=bdce %s -S -o - --try-experimental-debuginfo-iterators | FileCheck %s
 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx"
 define void @f(i32) !dbg !8 {

>From c20a7728427fbd295a5bf0740fa51c3f7ce73652 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Thu, 16 Nov 2023 11:02:54 +0000
Subject: [PATCH 2/4] Follow review feedback:

 * get insertDPValueAfter to create markers
 * remove redundant param from getDebugValueLocDPV
 * Have replaceDbgValueForAlloca search for DbgValue only
 * Switch dropDebugUsers back to the original behaviour
---
 llvm/lib/IR/BasicBlock.cpp          |  5 ++--
 llvm/lib/Transforms/Utils/Local.cpp | 42 +++++++++--------------------
 2 files changed, 15 insertions(+), 32 deletions(-)

diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index a41bcff58e529af..7037f5f524ee069 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -985,8 +985,9 @@ void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) {
   assert(I->getParent() == this);
 
   iterator NextIt = std::next(I->getIterator());
-  DPMarker *NextMarker =
-      (NextIt == end()) ? getTrailingDPValues() : NextIt->DbgMarker;
+  DPMarker *NextMarker = getMarker(NextIt);
+  if (!NextMarker)
+    NextMarker = createMarker(NextIt);
   NextMarker->insertDPValue(DPV, true);
 }
 
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index ba97cdf8f3c4b4c..dfe64c3d695896c 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1716,7 +1716,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
 
 // RemoveDIs: duplicate the getDebugValueLoc method using DPValues instead of
 // dbg.value intrinsics.
-static DebugLoc getDebugValueLocDPV(DPValue *DPV, Instruction *Src) {
+static DebugLoc getDebugValueLocDPV(DPValue *DPV) {
   // Original dbg.declare must have a location.
   const DebugLoc &DeclareLoc = DPV->getDebugLoc();
   MDNode *Scope = DeclareLoc.getScope();
@@ -1759,7 +1759,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
   auto *DIExpr = DPV->getExpression();
   Value *DV = SI->getValueOperand();
 
-  DebugLoc NewLoc = getDebugValueLocDPV(DPV, SI);
+  DebugLoc NewLoc = getDebugValueLocDPV(DPV);
 
   if (!valueCoversEntireFragment(DV->getType(), DPV)) {
     // FIXME: If storing to a part of the variable described by the dbg.declare,
@@ -1831,7 +1831,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
     return;
   }
 
-  DebugLoc NewLoc = getDebugValueLocDPV(DPV, nullptr);
+  DebugLoc NewLoc = getDebugValueLocDPV(DPV);
 
   // We are now tracking the loaded value instead of the address. In the
   // future if multi-location support is added to the IR, it might be
@@ -1876,7 +1876,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
   BasicBlock *BB = APN->getParent();
   auto InsertionPt = BB->getFirstInsertionPt();
 
-  DebugLoc NewLoc = getDebugValueLocDPV(DPV, nullptr);
+  DebugLoc NewLoc = getDebugValueLocDPV(DPV);
 
   // The block may be a catchswitch block, which does not have a valid
   // insertion point.
@@ -2069,22 +2069,17 @@ static void updateOneDbgValueForAlloca(const DebugLoc &Loc, DILocalVariable *DIV
 
 void llvm::replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
                                     DIBuilder &Builder, int Offset) {
-  SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
+  SmallVector<DbgValueInst *, 1> DbgUsers;
   SmallVector<DPValue *, 1> DPUsers;
-  findDbgUsers(DbgUsers, AI, &DPUsers);
+  findDbgValues(DbgUsers, AI, &DPUsers);
 
   // Attempt to replace dbg.values that use this alloca.
-  for (auto *DV : DbgUsers) {
-    auto *DVI = dyn_cast<DbgValueInst>(DV);
-    if (!DVI)
-      continue;
+  for (auto *DVI : DbgUsers)
     updateOneDbgValueForAlloca(DVI->getDebugLoc(), DVI->getVariable(), DVI->getExpression(), NewAllocaAddress, DVI, nullptr, Builder, Offset);
-  }
 
   // Replace any DPValues that use this alloca.
-  for (DPValue *DPV : DPUsers) {
+  for (DPValue *DPV : DPUsers)
     updateOneDbgValueForAlloca(DPV->getDebugLoc(), DPV->getVariable(), DPV->getExpression(), NewAllocaAddress, nullptr, DPV, Builder, Offset);
-  }
 }
 
 /// Where possible to salvage debug information for \p I do so.
@@ -2524,7 +2519,6 @@ static bool rewriteDebugUsers(
         LLVM_DEBUG(dbgs() << "MOVE:  " << *DPV << '\n');
         DPV->removeFromParent();
         // Ensure there's a marker.
-        DomPoint.getParent()->createMarker(std::next(DomPoint.getIterator()));
         DomPoint.getParent()->insertDPValueAfter(DPV, &DomPoint);
         Changed = true;
       } else if (!DT.dominates(&DomPoint, MarkedInstr)) {
@@ -3422,22 +3416,10 @@ void llvm::dropDebugUsers(Instruction &I) {
   SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
   SmallVector<DPValue *, 1> DPUsers;
   findDbgUsers(DbgUsers, &I, &DPUsers);
-  for (auto *DII : DbgUsers) {
-    if (auto *DbgValue = dyn_cast<DbgValueInst>(DII)) {
-      // Don't delete dbg.values, that's bad.
-      DbgValue->setKillLocation();
-    } else {
-      DII->eraseFromParent();
-    }
-  }
-  for (auto *DPV : DPUsers) {
-    if (DPV->getType() == DPValue::LocationType::Value) {
-      // Don't delete DPValues, that's bad.
-      DPV->setKillLocation();
-    } else {
-      DPV->eraseFromParent();
-    }
-  }
+  for (auto *DII : DbgUsers)
+    DII->eraseFromParent();
+  for (auto *DPV : DPUsers)
+    DPV->eraseFromParent();
 }
 
 void llvm::hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,

>From 716b3a026c898af1019146779d7aa7052edc63f4 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Thu, 16 Nov 2023 11:19:42 +0000
Subject: [PATCH 3/4] Drop DPValues for token typed instrs

---
 llvm/lib/Transforms/Utils/Local.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index dfe64c3d695896c..849ccd1dee7c7ac 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -2675,6 +2675,9 @@ llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
     if (!Inst->use_empty() && !Inst->getType()->isTokenTy())
       Inst->replaceAllUsesWith(PoisonValue::get(Inst->getType()));
     if (Inst->isEHPad() || Inst->getType()->isTokenTy()) {
+      // EHPads can't have DPValues attached to them, but it might be possible
+      // for things with token type.
+      Inst->dropDbgValues();
       EndInst = Inst;
       continue;
     }

>From 784dfc3e895874845d8e8e21507d1c5e960006dd Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Thu, 16 Nov 2023 13:16:02 +0000
Subject: [PATCH 4/4] clang-format

---
 llvm/include/llvm/Transforms/Utils/Local.h | 13 ++--
 llvm/lib/Transforms/Utils/Local.cpp        | 88 ++++++++++++++--------
 2 files changed, 62 insertions(+), 39 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 9547677397f8021..2df3c9049c7d62e 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -262,22 +262,22 @@ CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
 /// that has an associated llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                      StoreInst *SI, DIBuilder &Builder);
-void ConvertDebugDeclareToDebugValue(DPValue *DPV,
-                                     StoreInst *SI, DIBuilder &Builder);
+void ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI,
+                                     DIBuilder &Builder);
 
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                      LoadInst *LI, DIBuilder &Builder);
-void ConvertDebugDeclareToDebugValue(DPValue *DPV,
-                                     LoadInst *LI, DIBuilder &Builder);
+void ConvertDebugDeclareToDebugValue(DPValue *DPV, LoadInst *LI,
+                                     DIBuilder &Builder);
 
 /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
 /// llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                      PHINode *LI, DIBuilder &Builder);
-void ConvertDebugDeclareToDebugValue(DPValue *DPV,
-                                     PHINode *LI, DIBuilder &Builder);
+void ConvertDebugDeclareToDebugValue(DPValue *DPV, PHINode *LI,
+                                     DIBuilder &Builder);
 
 /// Lowers llvm.dbg.declare intrinsics into appropriate set of
 /// llvm.dbg.value intrinsics.
@@ -308,7 +308,6 @@ void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
 /// cannot be salvaged changes its debug uses to undef.
 void salvageDebugInfo(Instruction &I);
 
-
 /// Implementation of salvageDebugInfo, applying only to instructions in
 /// \p Insns, rather than all debug users from findDbgUsers( \p I).
 /// Mark undef if salvaging cannot be completed.
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 849ccd1dee7c7ac..db63b74f7849341 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1645,9 +1645,14 @@ static bool valueCoversEntireFragment(Type *ValTy, DPValue *DPV) {
   return false;
 }
 
-static void insertDbgValueOrDPValue(DIBuilder &Builder, Value *DV, DILocalVariable *DIVar, DIExpression *DIExpr, const DebugLoc &NewLoc, BasicBlock::iterator Instr) {
+static void insertDbgValueOrDPValue(DIBuilder &Builder, Value *DV,
+                                    DILocalVariable *DIVar,
+                                    DIExpression *DIExpr,
+                                    const DebugLoc &NewLoc,
+                                    BasicBlock::iterator Instr) {
   if (!UseNewDbgInfoFormat) {
-    auto *DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, (Instruction*)nullptr);
+    auto *DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc,
+                                                   (Instruction *)nullptr);
     DbgVal->insertBefore(Instr);
   } else {
     // RemoveDIs: if we're using the new debug-info format, allocate a
@@ -1658,9 +1663,14 @@ static void insertDbgValueOrDPValue(DIBuilder &Builder, Value *DV, DILocalVariab
   }
 }
 
-static void insertDbgValueOrDPValueAfter(DIBuilder &Builder, Value *DV, DILocalVariable *DIVar, DIExpression *DIExpr, const DebugLoc &NewLoc, BasicBlock::iterator Instr) {
+static void insertDbgValueOrDPValueAfter(DIBuilder &Builder, Value *DV,
+                                         DILocalVariable *DIVar,
+                                         DIExpression *DIExpr,
+                                         const DebugLoc &NewLoc,
+                                         BasicBlock::iterator Instr) {
   if (!UseNewDbgInfoFormat) {
-    auto *DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc, (Instruction*)nullptr);
+    auto *DbgVal = Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, NewLoc,
+                                                   (Instruction *)nullptr);
     DbgVal->insertAfter(&*Instr);
   } else {
     // RemoveDIs: if we're using the new debug-info format, allocate a
@@ -1699,7 +1709,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
       DIExpr->isDeref() || (!DIExpr->startsWithDeref() &&
                             valueCoversEntireFragment(DV->getType(), DII));
   if (CanConvert) {
-    insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, SI->getIterator());
+    insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc,
+                            SI->getIterator());
     return;
   }
 
@@ -1711,7 +1722,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
   // know which part) we insert an dbg.value intrinsic to indicate that we
   // know nothing about the variable's content.
   DV = UndefValue::get(DV->getType());
-  insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc, SI->getIterator());
+  insertDbgValueOrDPValue(Builder, DV, DIVar, DIExpr, NewLoc,
+                          SI->getIterator());
 }
 
 // RemoveDIs: duplicate the getDebugValueLoc method using DPValues instead of
@@ -1748,11 +1760,12 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
   // future if multi-location support is added to the IR, it might be
   // preferable to keep tracking both the loaded value and the original
   // address in case the alloca can not be elided.
-  insertDbgValueOrDPValueAfter(Builder, LI, DIVar, DIExpr, NewLoc, LI->getIterator());
+  insertDbgValueOrDPValueAfter(Builder, LI, DIVar, DIExpr, NewLoc,
+                               LI->getIterator());
 }
 
-void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
-                                           StoreInst *SI, DIBuilder &Builder) {
+void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, StoreInst *SI,
+                                           DIBuilder &Builder) {
   assert(DPV->isAddressOfVariable());
   auto *DIVar = DPV->getVariable();
   assert(DIVar && "Missing variable");
@@ -1764,8 +1777,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
   if (!valueCoversEntireFragment(DV->getType(), DPV)) {
     // FIXME: If storing to a part of the variable described by the dbg.declare,
     // then we want to insert a DPValue.value for the corresponding fragment.
-    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: "
-                      << *DPV << '\n');
+    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: " << *DPV
+                      << '\n');
     // For now, when there is a store to parts of the variable (but we do not
     // know which part) we insert an DPValue record to indicate that we know
     // nothing about the variable's content.
@@ -1816,8 +1829,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
   }
 }
 
-void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
-                                           LoadInst *LI, DIBuilder &Builder) {
+void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, LoadInst *LI,
+                                           DIBuilder &Builder) {
   auto *DIVar = DPV->getVariable();
   auto *DIExpr = DPV->getExpression();
   assert(DIVar && "Missing variable");
@@ -1826,8 +1839,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
     // FIXME: If only referring to a part of the variable described by the
     // dbg.declare, then we want to insert a DPValue for the corresponding
     // fragment.
-    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: "
-                      << *DPV << '\n');
+    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: " << *DPV
+                      << '\n');
     return;
   }
 
@@ -1855,8 +1868,8 @@ static bool isArray(AllocaInst *AI) {
 static bool isStructure(AllocaInst *AI) {
   return AI->getAllocatedType() && AI->getAllocatedType()->isStructTy();
 }
-void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
-                                           PHINode *APN, DIBuilder &Builder) {
+void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV, PHINode *APN,
+                                           DIBuilder &Builder) {
   auto *DIVar = DPV->getVariable();
   auto *DIExpr = DPV->getExpression();
   assert(DIVar && "Missing variable");
@@ -1868,8 +1881,8 @@ void llvm::ConvertDebugDeclareToDebugValue(DPValue *DPV,
     // FIXME: If only referring to a part of the variable described by the
     // dbg.declare, then we want to insert a DPValue for the corresponding
     // fragment.
-    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: "
-                      << *DPV << '\n');
+    LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to DPValue: " << *DPV
+                      << '\n');
     return;
   }
 
@@ -1941,7 +1954,8 @@ bool llvm::LowerDbgDeclare(Function &F) {
             DebugLoc NewLoc = getDebugValueLoc(DDI);
             auto *DerefExpr =
                 DIExpression::append(DDI->getExpression(), dwarf::DW_OP_deref);
-            insertDbgValueOrDPValue(DIB, AI, DDI->getVariable(), DerefExpr, NewLoc, CI->getIterator());
+            insertDbgValueOrDPValue(DIB, AI, DDI->getVariable(), DerefExpr,
+                                    NewLoc, CI->getIterator());
           }
         } else if (BitCastInst *BI = dyn_cast<BitCastInst>(U)) {
           if (BI->getType()->isPointerTy())
@@ -2041,14 +2055,16 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
   return !DbgDeclares.empty();
 }
 
-static void updateOneDbgValueForAlloca(const DebugLoc &Loc, DILocalVariable *DIVar, DIExpression *DIExpr,
-                                        Value *NewAddress, DbgValueInst *DVI, DPValue *DPV,
-                                        DIBuilder &Builder, int Offset) {
+static void updateOneDbgValueForAlloca(const DebugLoc &Loc,
+                                       DILocalVariable *DIVar,
+                                       DIExpression *DIExpr, Value *NewAddress,
+                                       DbgValueInst *DVI, DPValue *DPV,
+                                       DIBuilder &Builder, int Offset) {
   assert(DIVar && "Missing variable");
 
-  // This is an alloca-based dbg.value/DPValue. The first thing it should do with
-  // the alloca pointer is dereference it. Otherwise we don't know how to handle
-  // it and give up.
+  // This is an alloca-based dbg.value/DPValue. The first thing it should do
+  // with the alloca pointer is dereference it. Otherwise we don't know how to
+  // handle it and give up.
   if (!DIExpr || DIExpr->getNumElements() < 1 ||
       DIExpr->getElement(0) != dwarf::DW_OP_deref)
     return;
@@ -2075,11 +2091,15 @@ void llvm::replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
 
   // Attempt to replace dbg.values that use this alloca.
   for (auto *DVI : DbgUsers)
-    updateOneDbgValueForAlloca(DVI->getDebugLoc(), DVI->getVariable(), DVI->getExpression(), NewAllocaAddress, DVI, nullptr, Builder, Offset);
+    updateOneDbgValueForAlloca(DVI->getDebugLoc(), DVI->getVariable(),
+                               DVI->getExpression(), NewAllocaAddress, DVI,
+                               nullptr, Builder, Offset);
 
   // Replace any DPValues that use this alloca.
   for (DPValue *DPV : DPUsers)
-    updateOneDbgValueForAlloca(DPV->getDebugLoc(), DPV->getVariable(), DPV->getExpression(), NewAllocaAddress, nullptr, DPV, Builder, Offset);
+    updateOneDbgValueForAlloca(DPV->getDebugLoc(), DPV->getVariable(),
+                               DPV->getExpression(), NewAllocaAddress, nullptr,
+                               DPV, Builder, Offset);
 }
 
 /// Where possible to salvage debug information for \p I do so.
@@ -2126,7 +2146,8 @@ static void salvageDbgAssignAddress(DbgAssignIntrinsic *DAI) {
 }
 
 void llvm::salvageDebugInfoForDbgValues(
-    Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers, ArrayRef<DPValue *> DPUsers) {
+    Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers,
+    ArrayRef<DPValue *> DPUsers) {
   // These are arbitrary chosen limits on the maximum number of values and the
   // maximum size of a debug expression we can salvage up to, used for
   // performance reasons.
@@ -2227,10 +2248,12 @@ void llvm::salvageDebugInfoForDbgValues(
       break;
 
     DPV->replaceVariableLocationOp(&I, Op0);
-    bool IsValidSalvageExpr = SalvagedExpr->getNumElements() <= MaxExpressionSize;
+    bool IsValidSalvageExpr =
+        SalvagedExpr->getNumElements() <= MaxExpressionSize;
     if (AdditionalValues.empty() && IsValidSalvageExpr) {
       DPV->setExpression(SalvagedExpr);
-    } else if (DPV->getType() == DPValue::LocationType::Value && IsValidSalvageExpr &&
+    } else if (DPV->getType() == DPValue::LocationType::Value &&
+               IsValidSalvageExpr &&
                DPV->getNumVariableLocationOps() + AdditionalValues.size() <=
                    MaxDebugArgs) {
       DPV->addVariableLocationOps(AdditionalValues, SalvagedExpr);
@@ -2653,7 +2676,8 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
       return DIExpression::appendExt(DPV.getExpression(), ToBits, FromBits,
                                      Signed);
     };
-    return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt, SignOrZeroExtDPV);
+    return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt,
+                             SignOrZeroExtDPV);
   }
 
   // TODO: Floating-point conversions, vectors.



More information about the llvm-commits mailing list