[RemoveDIs][DebugInfo] Create overloads of debug intrinsic utilities for DPValues (#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 generic code
to handle both DbgVariableIntrinsics and DPValues, reducing code
duplication. This patch doesn't actually add the uses of these functions.
This commit is contained in:
Stephen Tozer
2024-01-17 15:36:52 +00:00
committed by GitHub
parent 59cdf41f07
commit 4f57e2076b
4 changed files with 104 additions and 28 deletions

View File

@@ -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.
///
@@ -191,6 +192,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.

View File

@@ -396,19 +396,6 @@ public:
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,66 @@ public:
/// @}
};
/// This set of functions allow us to write type-generic code that operates on
/// DPValues and DbgVariableIntrinsics, reducing the necessary amount of code
/// duplication for the temporary period in which we support both debug info
/// models.
/// @{
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:

View File

@@ -163,6 +163,18 @@ DebugLoc llvm::getDebugValueLoc(DbgVariableIntrinsic *DII) {
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.
//===----------------------------------------------------------------------===//
@@ -1813,6 +1825,31 @@ 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,
@@ -1910,7 +1947,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.

View File

@@ -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,