Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for dbg.assign in DPValues #2

Draft
wants to merge 4 commits into
base: gbhyamso/really-the-final-version-honest
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion llvm/include/llvm/IR/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Module;
/// Finds dbg.declare intrinsics declaring local variables as living in the
/// memory that 'V' points to.
TinyPtrVector<DbgDeclareInst *> FindDbgDeclareUses(Value *V);
TinyPtrVector<DPValue *> FindDPDeclareUses(Value *V);

/// Finds the llvm.dbg.value intrinsics describing a value.
void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues,
Expand All @@ -54,6 +55,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.
///
Expand Down Expand Up @@ -187,6 +189,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.
Expand All @@ -210,6 +217,7 @@ using AssignmentMarkerRange = iterator_range<DbgAssignIt>;
/// Return a range of dbg.assign intrinsics which use \ID as an operand.
/// Iterators invalidated by deleting an intrinsic contained in this range.
AssignmentMarkerRange getAssignmentMarkers(DIAssignID *ID);
void getDPAssignmentMarkers(DIAssignID *ID, SmallVectorImpl<DPValue *> DPAssigns);
/// Return a range of dbg.assign intrinsics for which \p Inst performs the
/// assignment they encode.
/// Iterators invalidated by deleting an intrinsic contained in this range.
Expand All @@ -219,6 +227,15 @@ inline AssignmentMarkerRange getAssignmentMarkers(const Instruction *Inst) {
else
return make_range(Value::user_iterator(), Value::user_iterator());
}
inline void getDPAssignmentMarkers(const Instruction *Inst, SmallVectorImpl<DPValue *> &DPAssigns) {
if (auto *ID = Inst->getMetadata(LLVMContext::MD_DIAssignID))
DPAssigns = cast<DIAssignID>(ID)->getAllDPValueUsers();
}
inline SmallVector<DPValue *> getDPAssignmentMarkers(const Instruction *Inst) {
if (auto *ID = Inst->getMetadata(LLVMContext::MD_DIAssignID))
return cast<DIAssignID>(ID)->getAllDPValueUsers();
return SmallVector<DPValue *>();
}

/// Delete the llvm.dbg.assign intrinsics linked to \p Inst.
void deleteAssignmentMarkers(const Instruction *Inst);
Expand All @@ -240,7 +257,8 @@ void deleteAll(Function *F);
/// Result contains a zero-sized fragment if there's no intersect.
bool calculateFragmentIntersect(
const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DAI,
uint64_t SliceSizeInBits,
PointerUnion<const DbgAssignIntrinsic *, const DPValue *> Assign,
std::optional<DIExpression::FragmentInfo> &Result);

/// Helper struct for trackAssignments, below. We don't use the similar
Expand All @@ -255,6 +273,8 @@ struct VarRecord {

VarRecord(DbgVariableIntrinsic *DVI)
: Var(DVI->getVariable()), DL(getDebugValueLoc(DVI)) {}
VarRecord(DPValue *DPV)
: Var(DPV->getVariable()), DL(getDebugValueLoc(DPV)) {}
VarRecord(DILocalVariable *Var, DILocation *DL) : Var(Var), DL(DL) {}
friend bool operator<(const VarRecord &LHS, const VarRecord &RHS) {
return std::tie(LHS.Var, LHS.DL) < std::tie(RHS.Var, RHS.DL);
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,10 @@ class DIAssignID : public MDNode {
// This node has no operands to replace.
void replaceOperandWith(unsigned I, Metadata *New) = delete;

SmallVector<DPValue *> getAllDPValueUsers() {
return Context.getReplaceableUses()->getAllDPValueUsers();
}

static DIAssignID *getDistinct(LLVMContext &Context) {
return getImpl(Context, Distinct);
}
Expand Down Expand Up @@ -3790,6 +3794,7 @@ class DebugVariable {

public:
DebugVariable(const DbgVariableIntrinsic *DII);
DebugVariable(const DPValue *DPV);

DebugVariable(const DILocalVariable *Var,
std::optional<FragmentInfo> FragmentInfo,
Expand Down
120 changes: 120 additions & 0 deletions llvm/include/llvm/IR/DebugProgramInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
DILocalVariable *Variable;
DIExpression *Expression;
DebugLoc DbgLoc;
DIExpression *AddressExpression;
DIAssignID *AssignID;

public:
void deleteInstr();
Expand All @@ -100,12 +102,21 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
void removeFromParent();
void eraseFromParent();


DPValue *getNextNode() {
return &*(++getIterator());
}
DPValue *getPrevNode() {
return &*(--getIterator());
}

using self_iterator = simple_ilist<DPValue>::iterator;
using const_self_iterator = simple_ilist<DPValue>::const_iterator;

enum class LocationType {
Declare,
Value,
Assign,
};
/// Classification of the debug-info record that this DPValue represents.
/// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
Expand All @@ -123,6 +134,27 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
/// assigning \p Location to the DV / Expr / DI variable.
DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
const DILocation *DI);
DPValue(Metadata *Value, DILocalVariable *Variable,
DIExpression *Expression, DIAssignID *AssignID, Metadata *Address,
DIExpression *AddressExpression, const DILocation *DI);
~DPValue() {
untrackAssignID();
}

static DPValue *createDPValue(
Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
const DILocation *DI, Instruction *InsertBefore = nullptr);
static DPValue *createDPDeclare(
Value *Address, DILocalVariable *DV, DIExpression *Expr,
const DILocation *DI, Instruction *InsertBefore = nullptr);
static DPValue *createDPAssign(
Metadata *Value, DILocalVariable *Variable, DIExpression *Expression,
DIAssignID *AssignID, Metadata *Address, DIExpression *AddressExpression,
const DILocation *DI, Instruction *InsertBefore = nullptr);
static DPValue *createLinkedDPAssign(
Instruction *LinkedInstr, Metadata *ValueMD, DILocalVariable *Variable,
DIExpression *Expression, Value *Address,
DIExpression *AddressExpression, const DILocation *DI);

/// Iterator for ValueAsMetadata that internally uses direct pointer iteration
/// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
Expand Down Expand Up @@ -172,6 +204,9 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
}
};

bool isDbgDeclare() { return Type == LocationType::Declare; }
bool isDbgValue() { return Type == LocationType::Value; }

/// Get the locations corresponding to the variable referenced by the debug
/// info intrinsic. Depending on the intrinsic, this could be the
/// variable's value or its address.
Expand Down Expand Up @@ -238,6 +273,10 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
/// a DIArgList which is a list of values.
Metadata *getRawLocation() const { return DebugValues[0]; }

Value *getValue(unsigned OpIdx = 0) const {
return getVariableLocationOp(OpIdx);
}

/// Use of this should generally be avoided; instead,
/// replaceVariableLocationOp and addVariableLocationOps should be used where
/// possible to avoid creating invalid state.
Expand All @@ -253,6 +292,78 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
/// is described.
std::optional<uint64_t> getFragmentSizeInBits() const;

/// 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;
}

/////////////////////////////////////////////
/// DbgAssign Methods

bool isDbgAssign() const { return getType() == LocationType::Assign; }

Value *getAddress() const;
Metadata *getRawAddress() const {
return DebugValues[1];
}
Metadata *getRawAssignID() const {
return AssignID;
}
DIAssignID *getAssignID() const { return AssignID; }
Metadata *getRawAddressExpression() const {
return AddressExpression;
}
DIExpression *getAddressExpression() const {
return AddressExpression;
}
void setAddressExpression(DIExpression *NewExpr) {
AddressExpression = NewExpr;
}
void setAssignId(DIAssignID *New) {
untrackAssignID();
AssignID = New;
trackAssignID();
}
void setAddress(Value *V) {
resetDebugValue(1, ValueAsMetadata::get(V));
}
/// Kill the address component.
void setKillAddress() {
resetDebugValue(1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
}
/// Check whether this kills the address component. This doesn't take into
/// account the position of the intrinsic, therefore a returned value of false
/// does not guarentee the address is a valid location for the variable at the
/// intrinsic's position in IR.
bool isKillAddress() const {
Value *Addr = getAddress();
return !Addr || isa<UndefValue>(Addr);
}

private:
void trackAssignID() {
if (AssignID)
MetadataTracking::track(&AssignID, *AssignID, *this);
}
void untrackAssignID() {
if (AssignID)
MetadataTracking::untrack(&AssignID, *AssignID);
}
public:
/////////////////////////////////////////////

bool isEquivalentTo(const DPValue &Other) {
return std::tie(Type, DebugValues, Variable, Expression, DbgLoc, AddressExpression, AssignID) == std::tie(Other.Type, Other.DebugValues, Other.Variable, Other.Expression, Other.DbgLoc, Other.AddressExpression, Other.AssignID);
}

DPValue *clone() const;
/// Convert this DPValue back into a dbg.value intrinsic.
/// \p InsertBefore Optional position to insert this intrinsic.
Expand All @@ -276,6 +387,11 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
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 print(raw_ostream &O, bool IsForDebug = false) const;
void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
};
Expand Down Expand Up @@ -339,6 +455,10 @@ class DPMarker {
/// 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);
/// Insert a DPValue prior to a DPValue contained within this marker.
void insertDPValue(DPValue *New, DPValue *InsertBefore);
/// Insert a DPValue after a DPValue contained within this marker.
void insertDPValueAfter(DPValue *New, DPValue *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.
Expand Down
62 changes: 62 additions & 0 deletions llvm/include/llvm/IR/IntrinsicInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,68 @@ 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:
Expand Down
Loading