[llvm] Add code to handle llvm.dbg.values in SROA. (PR #94068)

Shubham Sandeep Rastogi via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 4 13:11:15 PDT 2024


https://github.com/rastogishubham updated https://github.com/llvm/llvm-project/pull/94068

>From 3345d6e116b4fd1887bd0c75b869fc22bbb17d64 Mon Sep 17 00:00:00 2001
From: Shubham Sandeep Rastogi <srastogi22 at apple.com>
Date: Fri, 31 May 2024 14:00:46 -0700
Subject: [PATCH] Add code to handle #dbg_values in SROA.

This patch adds a bunch of functions that will be used to properly
handle debug information for #dbg_values in the SROA pass.
---
 llvm/include/llvm/IR/DebugInfo.h              |  2 ++
 .../include/llvm/IR/DebugProgramInstruction.h |  5 ++++
 llvm/include/llvm/IR/IntrinsicInst.h          |  7 +++++
 llvm/include/llvm/Transforms/Utils/Local.h    |  7 +++++
 llvm/lib/IR/DebugInfo.cpp                     | 17 +++++++++++
 llvm/lib/Transforms/Utils/Local.cpp           | 28 +++++++++++++++++++
 6 files changed, 66 insertions(+)

diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index 5b80218d6c5cc..73f45c3769be4 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -43,6 +43,8 @@ class Module;
 TinyPtrVector<DbgDeclareInst *> findDbgDeclares(Value *V);
 /// As above, for DVRDeclares.
 TinyPtrVector<DbgVariableRecord *> findDVRDeclares(Value *V);
+/// As above, for DVRValues.
+TinyPtrVector<DbgVariableRecord *> findDVRValues(Value *V);
 
 /// Finds the llvm.dbg.value intrinsics describing a value.
 void findDbgValues(
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index ed8081a3cad19..0eb30dfef54a9 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -426,6 +426,11 @@ class DbgVariableRecord : public DbgRecord, protected DebugValueUser {
   /// Does this describe the address of a local variable. True for dbg.addr
   /// and dbg.declare, but not dbg.value, which describes its value.
   bool isAddressOfVariable() const { return Type == LocationType::Declare; }
+
+  /// Does this describe the value of a local variable. False for dbg.declare,
+  /// but True for dbg.value, which describes its value.
+  bool isValueOfVariable() const { return Type == LocationType::Value; }
+
   LocationType getType() const { return Type; }
 
   void setKillLocation();
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index fcd3a1025ac13..7168a17212313 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -341,6 +341,13 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
     return getIntrinsicID() == Intrinsic::dbg_declare;
   }
 
+  /// Does this describe the value of a local variable. True for dbg.value,
+  /// but not dbg.declare, which describes its address, or dbg.assign, which
+  /// describes a combination of the variable's value and address.
+  bool isValueOfVariable() const {
+    return getIntrinsicID() == Intrinsic::dbg_value;
+  }
+
   void setKillLocation() {
     // TODO: When/if we remove duplicate values from DIArgLists, we don't need
     // this set anymore.
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 6937ec8dfd21c..d9ec9913eeb58 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -259,6 +259,13 @@ CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
 ///  Dbg Intrinsic utilities
 ///
 
+/// Moves an llvm.dbg.value intrinsic before a store to an alloca'd value
+/// that has an associated llvm.dbg.value intrinsic.
+void MoveDebugValueToStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
+                              DIBuilder &Builder);
+void MoveDebugValueToStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI,
+                              DIBuilder &Builder);
+
 /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 4c3f37ceaaa46..dc3dad91db8f4 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -80,6 +80,23 @@ TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) {
   return Declares;
 }
 
+TinyPtrVector<DbgVariableRecord *> llvm::findDVRValues(Value *V) {
+  // This function is hot. Check whether the value has any metadata to avoid a
+  // DenseMap lookup.
+  if (!V->isUsedByMetadata())
+    return {};
+  auto *L = LocalAsMetadata::getIfExists(V);
+  if (!L)
+    return {};
+
+  TinyPtrVector<DbgVariableRecord *> Values;
+  for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())
+    if (DVR->getType() == DbgVariableRecord::LocationType::Value)
+      Values.push_back(DVR);
+
+  return Values;
+}
+
 template <typename IntrinsicT, bool DbgAssignAndValuesOnly>
 static void
 findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V,
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index ce0f4c7668a40..f90ee060ba3e3 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1731,6 +1731,21 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                     SI->getIterator());
 }
 
+/// Moves an llvm.dbg.value intrinsic before a store to an alloca'd value
+/// that has an associated llvm.dbg.value intrinsic.
+void llvm::MoveDebugValueToStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI,
+                                    DIBuilder &Builder) {
+  auto *DIVar = DII->getVariable();
+  assert(DIVar && "Missing variable");
+  auto *DIExpr = DII->getExpression();
+  Value *DV = SI->getValueOperand();
+
+  DebugLoc NewLoc = getDebugValueLoc(DII);
+
+  insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
+                                    SI->getIterator());
+}
+
 /// 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,
@@ -1805,6 +1820,19 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
   SI->getParent()->insertDbgRecordBefore(NewDVR, SI->getIterator());
 }
 
+void llvm::MoveDebugValueToStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
+                                    DIBuilder &Builder) {
+  auto *DIVar = DVR->getVariable();
+  assert(DIVar && "Missing variable");
+  auto *DIExpr = DVR->getExpression();
+  Value *DV = SI->getValueOperand();
+
+  DebugLoc NewLoc = getDebugValueLoc(DVR);
+
+  insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
+                                    SI->getIterator());
+}
+
 /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
 /// llvm.dbg.declare intrinsic.
 void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,



More information about the llvm-commits mailing list