[llvm] [RemoveDIs][DebugInfo] Create overloads of debug intrinsic utilities for DPValues (PR #78313)

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 16 08:53:24 PST 2024


https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/78313

In preparation for the major chunk of the assignment tracking implementation, this patch adds a new set of overloaded versions of existing functions that take DbgVariableIntrinsics, with the overloads taking DPValues. This is used specifically to allow us to use auto* parameter lambdas to handle both DbgVariableIntrinsics and DPValues, reducing code duplication. This patch doesn't actually add the uses of these functions, so they will initially be unused, but it's easier from a review perspective to verify these functions do what they should be doing here, rather than alongside substantial changes scattered about elsewhere in LLVM.

>From afbe0694e23f8c2efa04ed3fd9cb7392b0f7d510 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Wed, 3 Jan 2024 13:46:23 +0000
Subject: [PATCH] Create overloads of debug intrinsic utilities for DPValues

---
 llvm/include/llvm/IR/DebugInfo.h     |  6 +++
 llvm/include/llvm/IR/IntrinsicInst.h | 71 +++++++++++++++++++++++-----
 llvm/lib/IR/DebugInfo.cpp            | 37 ++++++++++++++-
 llvm/lib/Transforms/Utils/Local.cpp  | 14 ------
 4 files changed, 100 insertions(+), 28 deletions(-)

diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index eb5728647a81d8..b79936952d30c9 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -58,6 +58,7 @@ DISubprogram *getDISubprogram(const MDNode *Scope);
 /// Produce a DebugLoc to use for each dbg.declare that is promoted to a
 /// dbg.value.
 DebugLoc getDebugValueLoc(DbgVariableIntrinsic *DII);
+DebugLoc getDebugValueLoc(DPValue *DPV);
 
 /// Strip debug info in the module if it exists.
 ///
@@ -200,6 +201,11 @@ AssignmentInstRange getAssignmentInsts(DIAssignID *ID);
 inline AssignmentInstRange getAssignmentInsts(const DbgAssignIntrinsic *DAI) {
   return getAssignmentInsts(DAI->getAssignID());
 }
+inline AssignmentInstRange getAssignmentInsts(const DPValue *DPV) {
+  assert(DPV->isDbgAssign() &&
+         "Can't get assignment instructions for non-assign DPV!");
+  return getAssignmentInsts(DPV->getAssignID());
+}
 
 //
 // Utilities for enumerating llvm.dbg.assign intrinsic from an assignment ID.
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index b8d578d0fee082..be65108aa6db89 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -396,19 +396,6 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
     return getExpression()->getFragmentInfo();
   }
 
-  /// Get the FragmentInfo for the variable if it exists, otherwise return a
-  /// FragmentInfo that covers the entire variable if the variable size is
-  /// known, otherwise return a zero-sized fragment.
-  DIExpression::FragmentInfo getFragmentOrEntireVariable() const {
-    DIExpression::FragmentInfo VariableSlice(0, 0);
-    // Get the fragment or variable size, or zero.
-    if (auto Sz = getFragmentSizeInBits())
-      VariableSlice.SizeInBits = *Sz;
-    if (auto Frag = getExpression()->getFragmentInfo())
-      VariableSlice.OffsetInBits = Frag->OffsetInBits;
-    return VariableSlice;
-  }
-
   /// \name Casting methods
   /// @{
   static bool classof(const IntrinsicInst *I) {
@@ -547,6 +534,64 @@ class DbgLabelInst : public DbgInfoIntrinsic {
   /// @}
 };
 
+/// Wrapper functions for opaque interfacing between DbgVariableIntrinsics and
+/// DPValues.
+/// @{
+inline bool IsaDbgValue(DPValue *DPV) { return DPV->isDbgValue(); }
+inline bool IsaDbgDeclare(DPValue *DPV) { return DPV->isDbgDeclare(); }
+inline bool IsaDbgAssign(DPValue *DPV) { return DPV->isDbgAssign(); }
+
+inline bool IsaDbgValue(DbgVariableIntrinsic *DVI) {
+  return isa<DbgValueInst>(DVI);
+}
+inline bool IsaDbgDeclare(DbgVariableIntrinsic *DVI) {
+  return isa<DbgDeclareInst>(DVI);
+}
+inline bool IsaDbgAssign(DbgVariableIntrinsic *DVI) {
+  return isa<DbgAssignIntrinsic>(DVI);
+}
+
+inline DPValue *CastToDbgValue(DPValue *DPV) { return DPV; }
+inline DPValue *CastToDbgDeclare(DPValue *DPV) { return DPV; }
+inline DPValue *CastToDbgAssign(DPValue *DPV) { return DPV; }
+
+inline DbgValueInst *CastToDbgValue(DbgVariableIntrinsic *DVI) {
+  return cast<DbgValueInst>(DVI);
+}
+inline DbgDeclareInst *CastToDbgDeclare(DbgVariableIntrinsic *DVI) {
+  return cast<DbgDeclareInst>(DVI);
+}
+inline DbgAssignIntrinsic *CastToDbgAssign(DbgVariableIntrinsic *DVI) {
+  return cast<DbgAssignIntrinsic>(DVI);
+}
+
+inline DPValue *DynCastToDbgValue(DPValue *DPV) {
+  if (!DPV->isDbgValue())
+    return nullptr;
+  return DPV;
+}
+inline DPValue *DynCastToDbgDeclare(DPValue *DPV) {
+  if (!DPV->isDbgDeclare())
+    return nullptr;
+  return DPV;
+}
+inline DPValue *DynCastToDbgAssign(DPValue *DPV) {
+  if (!DPV->isDbgAssign())
+    return nullptr;
+  return DPV;
+}
+
+inline DbgValueInst *DynCastToDbgValue(DbgVariableIntrinsic *DVI) {
+  return dyn_cast<DbgValueInst>(DVI);
+}
+inline DbgDeclareInst *DynCastToDbgDeclare(DbgVariableIntrinsic *DVI) {
+  return dyn_cast<DbgDeclareInst>(DVI);
+}
+inline DbgAssignIntrinsic *DynCastToDbgAssign(DbgVariableIntrinsic *DVI) {
+  return dyn_cast<DbgAssignIntrinsic>(DVI);
+}
+/// @}
+
 /// This is the common base class for vector predication intrinsics.
 class VPIntrinsic : public IntrinsicInst {
 public:
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 6b7dd74916517d..bbfda61023675c 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -162,6 +162,17 @@ DebugLoc llvm::getDebugValueLoc(DbgVariableIntrinsic *DII) {
   // with the correct scope / inlinedAt fields.
   return DILocation::get(DII->getContext(), 0, 0, Scope, InlinedAt);
 }
+DebugLoc llvm::getDebugValueLoc(DPValue *DPV) {
+  // Original dbg.declare must have a location.
+  const DebugLoc &DeclareLoc = DPV->getDebugLoc();
+  MDNode *Scope = DeclareLoc.getScope();
+  DILocation *InlinedAt = DeclareLoc.getInlinedAt();
+  // Because no machine insts can come from debug intrinsics, only the scope
+  // and inlinedAt is significant. Zero line numbers are used in case this
+  // DebugLoc leaks into any adjacent instructions. Produce an unknown location
+  // with the correct scope / inlinedAt fields.
+  return DILocation::get(DPV->getContext(), 0, 0, Scope, InlinedAt);
+}
 
 //===----------------------------------------------------------------------===//
 // DebugInfoFinder implementations.
@@ -1824,6 +1835,30 @@ void at::deleteAll(Function *F) {
     DAI->eraseFromParent();
 }
 
+/// Get the FragmentInfo for the variable if it exists, otherwise return a
+/// FragmentInfo that covers the entire variable if the variable size is
+/// known, otherwise return a zero-sized fragment.
+static DIExpression::FragmentInfo
+getFragmentOrEntireVariable(const DPValue *DPV) {
+  DIExpression::FragmentInfo VariableSlice(0, 0);
+  // Get the fragment or variable size, or zero.
+  if (auto Sz = DPV->getFragmentSizeInBits())
+    VariableSlice.SizeInBits = *Sz;
+  if (auto Frag = DPV->getExpression()->getFragmentInfo())
+    VariableSlice.OffsetInBits = Frag->OffsetInBits;
+  return VariableSlice;
+}
+static DIExpression::FragmentInfo
+getFragmentOrEntireVariable(const DbgVariableIntrinsic *DVI) {
+  DIExpression::FragmentInfo VariableSlice(0, 0);
+  // Get the fragment or variable size, or zero.
+  if (auto Sz = DVI->getFragmentSizeInBits())
+    VariableSlice.SizeInBits = *Sz;
+  if (auto Frag = DVI->getExpression()->getFragmentInfo())
+    VariableSlice.OffsetInBits = Frag->OffsetInBits;
+  return VariableSlice;
+}
+
 bool at::calculateFragmentIntersect(
     const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
     uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DAI,
@@ -1921,7 +1956,7 @@ bool at::calculateFragmentIntersect(
   if (DAI->isKillAddress())
     return false;
 
-  DIExpression::FragmentInfo VarFrag = DAI->getFragmentOrEntireVariable();
+  DIExpression::FragmentInfo VarFrag = getFragmentOrEntireVariable(DAI);
   if (VarFrag.SizeInBits == 0)
     return false; // Variable size is unknown.
 
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d1b42f28923f5e..2a1ac85ee55bf5 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1724,20 +1724,6 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                           SI->getIterator());
 }
 
-namespace llvm {
-// RemoveDIs: duplicate the getDebugValueLoc method using DPValues instead of
-// dbg.value intrinsics. In llvm namespace so that it overloads the
-// DbgVariableIntrinsic version.
-static DebugLoc getDebugValueLoc(DPValue *DPV) {
-  // 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);
-}
-} // namespace llvm
-
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
 void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,



More information about the llvm-commits mailing list