[llvm] d499df0 - [RemoveDIs][DebugInfo] Add DPVAssign variant of DPValue (#77912)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 16 05:42:55 PST 2024
Author: Stephen Tozer
Date: 2024-01-16T13:42:50Z
New Revision: d499df02a2508641d67918d7dc41b2e01a4a4114
URL: https://github.com/llvm/llvm-project/commit/d499df02a2508641d67918d7dc41b2e01a4a4114
DIFF: https://github.com/llvm/llvm-project/commit/d499df02a2508641d67918d7dc41b2e01a4a4114.diff
LOG: [RemoveDIs][DebugInfo] Add DPVAssign variant of DPValue (#77912)
This implements the DbgAssignIntrinsic class as a variant of DPValues -
unfortunately this involves increasing the size of the `DebugValueUser`
storage by 3x, but this is necessary to enable assigns to be
represented, and can be offset in a future patch by splitting DPValue
into subclasses such that each variant can store only the fields it
needs. This patch does not actually create DPVAssigns in any case;
future patches will handle this variant in all cases where generic
DPValue handling does not. This patch also does not implement tracking
support for DIAssignIDs, which is necessary to find DPVAssigns that
reference a given DIAssignID; that is added in a subsequent patch.
Added:
Modified:
llvm/include/llvm/IR/DebugProgramInstruction.h
llvm/include/llvm/IR/Metadata.h
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/DebugProgramInstruction.cpp
llvm/lib/IR/Metadata.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index e089475cb0e7f3..737417fb9b9a54 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -61,6 +61,7 @@ class BasicBlock;
class MDNode;
class Module;
class DbgVariableIntrinsic;
+class DIAssignID;
class DPMarker;
class DPValue;
class raw_ostream;
@@ -83,6 +84,7 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
DILocalVariable *Variable;
DIExpression *Expression;
DebugLoc DbgLoc;
+ DIExpression *AddressExpression;
public:
void deleteInstr();
@@ -102,6 +104,7 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
enum class LocationType {
Declare,
Value,
+ Assign,
End, ///< Marks the end of the concrete types.
Any, ///< To indicate all LocationTypes in searches.
@@ -122,6 +125,21 @@ 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, LocationType Type = LocationType::Value);
+ DPValue(Metadata *Value, DILocalVariable *Variable, DIExpression *Expression,
+ DIAssignID *AssignID, Metadata *Address,
+ DIExpression *AddressExpression, const DILocation *DI);
+
+ static DPValue *createDPVAssign(Value *Val, DILocalVariable *Variable,
+ DIExpression *Expression,
+ DIAssignID *AssignID, Value *Address,
+ DIExpression *AddressExpression,
+ const DILocation *DI);
+ static DPValue *createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
+ DILocalVariable *Variable,
+ DIExpression *Expression,
+ Value *Address,
+ DIExpression *AddressExpression,
+ const DILocation *DI);
static DPValue *createDPValue(Value *Location, DILocalVariable *DV,
DIExpression *Expr, const DILocation *DI);
@@ -213,7 +231,7 @@ class DPValue : public ilist_node<DPValue>, private 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::Value; }
+ bool isAddressOfVariable() const { return Type == LocationType::Declare; }
LocationType getType() const { return Type; }
DebugLoc getDebugLoc() const { return DbgLoc; }
@@ -226,7 +244,11 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
DIExpression *getExpression() const { return Expression; }
- Metadata *getRawLocation() const { return DebugValue; }
+ /// Returns the metadata operand for the first location description. i.e.,
+ /// dbg intrinsic dbg.value,declare operand and dbg.assign 1st location
+ /// operand (the "value componenet"). Note the operand (singular) may be
+ /// a DIArgList which is a list of values.
+ Metadata *getRawLocation() const { return DebugValues[0]; }
Value *getValue(unsigned OpIdx = 0) const {
return getVariableLocationOp(OpIdx);
@@ -240,7 +262,7 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
(isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) ||
isa<MDNode>(NewLocation)) &&
"Location for a DPValue must be either ValueAsMetadata or DIArgList");
- resetDebugValue(NewLocation);
+ resetDebugValue(0, NewLocation);
}
/// Get the size (in bits) of the variable, or fragment of the variable that
@@ -248,28 +270,50 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
std::optional<uint64_t> getFragmentSizeInBits() const;
bool isEquivalentTo(const DPValue &Other) {
- return std::tie(Type, DebugValue, Variable, Expression, DbgLoc) ==
- std::tie(Other.Type, Other.DebugValue, Other.Variable,
+ return std::tie(Type, DebugValues, Variable, Expression, DbgLoc) ==
+ std::tie(Other.Type, Other.DebugValues, Other.Variable,
Other.Expression, Other.DbgLoc);
}
// Matches the definition of the Instruction version, equivalent to above but
// without checking DbgLoc.
bool isIdenticalToWhenDefined(const DPValue &Other) {
- return std::tie(Type, DebugValue, Variable, Expression) ==
- std::tie(Other.Type, Other.DebugValue, Other.Variable,
+ return std::tie(Type, DebugValues, Variable, Expression) ==
+ std::tie(Other.Type, Other.DebugValues, Other.Variable,
Other.Expression);
}
+ /// @name DbgAssign Methods
+ /// @{
+ bool isDbgAssign() const { return getType() == LocationType::Assign; }
+
+ Value *getAddress() const;
+ Metadata *getRawAddress() const {
+ return isDbgAssign() ? DebugValues[1] : DebugValues[0];
+ }
+ Metadata *getRawAssignID() const { return DebugValues[2]; }
+ DIAssignID *getAssignID() const;
+ DIExpression *getAddressExpression() const { return AddressExpression; }
+ void setAddressExpression(DIExpression *NewExpr) {
+ AddressExpression = NewExpr;
+ }
+ void setAssignId(DIAssignID *New);
+ void setAddress(Value *V) { resetDebugValue(1, ValueAsMetadata::get(V)); }
+ /// Kill the address component.
+ void setKillAddress();
+ /// 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;
+
+ /// @}
+
DPValue *clone() const;
/// Convert this DPValue back into a dbg.value intrinsic.
/// \p InsertBefore Optional position to insert this intrinsic.
/// \returns A new dbg.value intrinsic representiung this DPValue.
DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
Instruction *InsertBefore) const;
- /// Handle changes to the location of the Value(s) that we refer to happening
- /// "under our feet".
- void handleChangedLocation(Metadata *NewLocation);
-
void setMarker(DPMarker *M) { Marker = M; }
DPMarker *getMarker() { return Marker; }
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 4498423c4c460d..b512451d385f63 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -211,31 +211,45 @@ class MetadataAsValue : public Value {
/// lookup and callback handling.
class DebugValueUser {
protected:
- Metadata *DebugValue;
+ // Capacity to store 3 debug values.
+ // TODO: Not all DebugValueUser instances need all 3 elements, if we
+ // restructure the DPValue class then we can template parameterize this array
+ // size.
+ std::array<Metadata *, 3> DebugValues;
+
+ ArrayRef<Metadata *> getDebugValues() const { return DebugValues; }
public:
DPValue *getUser();
const DPValue *getUser() const;
- void handleChangedValue(Metadata *NewDebugValue);
+ /// To be called by ReplaceableMetadataImpl::replaceAllUsesWith, where `Old`
+ /// is a pointer to one of the pointers in `DebugValues` (so should be type
+ /// Metadata**), and `NewDebugValue` is the new Metadata* that is replacing
+ /// *Old.
+ /// For manually replacing elements of DebugValues,
+ /// `resetDebugValue(Idx, NewDebugValue)` should be used instead.
+ void handleChangedValue(void *Old, Metadata *NewDebugValue);
DebugValueUser() = default;
- explicit DebugValueUser(Metadata *DebugValue) : DebugValue(DebugValue) {
- trackDebugValue();
+ explicit DebugValueUser(std::array<Metadata *, 3> DebugValues)
+ : DebugValues(DebugValues) {
+ trackDebugValues();
}
-
- DebugValueUser(DebugValueUser &&X) : DebugValue(X.DebugValue) {
- retrackDebugValue(X);
+ DebugValueUser(DebugValueUser &&X) {
+ DebugValues = X.DebugValues;
+ retrackDebugValues(X);
}
- DebugValueUser(const DebugValueUser &X) : DebugValue(X.DebugValue) {
- trackDebugValue();
+ DebugValueUser(const DebugValueUser &X) {
+ DebugValues = X.DebugValues;
+ trackDebugValues();
}
DebugValueUser &operator=(DebugValueUser &&X) {
if (&X == this)
return *this;
- untrackDebugValue();
- DebugValue = X.DebugValue;
- retrackDebugValue(X);
+ untrackDebugValues();
+ DebugValues = X.DebugValues;
+ retrackDebugValues(X);
return *this;
}
@@ -243,35 +257,41 @@ class DebugValueUser {
if (&X == this)
return *this;
- untrackDebugValue();
- DebugValue = X.DebugValue;
- trackDebugValue();
+ untrackDebugValues();
+ DebugValues = X.DebugValues;
+ trackDebugValues();
return *this;
}
- ~DebugValueUser() { untrackDebugValue(); }
+ ~DebugValueUser() { untrackDebugValues(); }
- void resetDebugValue() {
- untrackDebugValue();
- DebugValue = nullptr;
+ void resetDebugValues() {
+ untrackDebugValues();
+ DebugValues.fill(nullptr);
}
- void resetDebugValue(Metadata *DebugValue) {
- untrackDebugValue();
- this->DebugValue = DebugValue;
- trackDebugValue();
+
+ void resetDebugValue(size_t Idx, Metadata *DebugValue) {
+ assert(Idx < 3 && "Invalid debug value index.");
+ untrackDebugValue(Idx);
+ DebugValues[Idx] = DebugValue;
+ trackDebugValue(Idx);
}
bool operator==(const DebugValueUser &X) const {
- return DebugValue == X.DebugValue;
+ return DebugValues == X.DebugValues;
}
bool operator!=(const DebugValueUser &X) const {
- return DebugValue != X.DebugValue;
+ return DebugValues != X.DebugValues;
}
private:
- void trackDebugValue();
- void untrackDebugValue();
- void retrackDebugValue(DebugValueUser &X);
+ void trackDebugValue(size_t Idx);
+ void trackDebugValues();
+
+ void untrackDebugValue(size_t Idx);
+ void untrackDebugValues();
+
+ void retrackDebugValues(DebugValueUser &X);
};
/// API for tracking metadata references through RAUW and deletion.
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 278cdfce411050..3c15784a0ed5eb 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1140,6 +1140,9 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
void SlotTracker::processDPValueMetadata(const DPValue &DPV) {
CreateMetadataSlot(DPV.getVariable());
CreateMetadataSlot(DPV.getDebugLoc());
+ if (DPV.isDbgAssign()) {
+ CreateMetadataSlot(DPV.getAssignID());
+ }
}
void SlotTracker::processInstructionMetadata(const Instruction &I) {
@@ -4571,7 +4574,22 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
void AssemblyWriter::printDPValue(const DPValue &Value) {
// There's no formal representation of a DPValue -- print purely as a
// debugging aid.
- Out << " DPValue { ";
+ Out << " DPValue ";
+
+ switch (Value.getType()) {
+ case DPValue::LocationType::Value:
+ Out << "value";
+ break;
+ case DPValue::LocationType::Declare:
+ Out << "declare";
+ break;
+ case DPValue::LocationType::Assign:
+ Out << "assign";
+ break;
+ default:
+ llvm_unreachable("Tried to print a DPValue with an invalid LocationType!");
+ }
+ Out << " { ";
auto WriterCtx = getContext();
WriteAsOperandInternal(Out, Value.getRawLocation(), WriterCtx, true);
Out << ", ";
@@ -4579,6 +4597,14 @@ void AssemblyWriter::printDPValue(const DPValue &Value) {
Out << ", ";
WriteAsOperandInternal(Out, Value.getExpression(), WriterCtx, true);
Out << ", ";
+ if (Value.isDbgAssign()) {
+ WriteAsOperandInternal(Out, Value.getAssignID(), WriterCtx, true);
+ Out << ", ";
+ WriteAsOperandInternal(Out, Value.getRawAddress(), WriterCtx, true);
+ Out << ", ";
+ WriteAsOperandInternal(Out, Value.getAddressExpression(), WriterCtx, true);
+ Out << ", ";
+ }
WriteAsOperandInternal(Out, Value.getDebugLoc().get(), WriterCtx, true);
Out << " marker @" << Value.getMarker();
Out << " }";
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
index 11ac118de389de..fd234685d5fd4b 100644
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ b/llvm/lib/IR/DebugProgramInstruction.cpp
@@ -14,8 +14,9 @@
namespace llvm {
DPValue::DPValue(const DbgVariableIntrinsic *DVI)
- : DebugValueUser(DVI->getRawLocation()), Variable(DVI->getVariable()),
- Expression(DVI->getExpression()), DbgLoc(DVI->getDebugLoc()) {
+ : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
+ Variable(DVI->getVariable()), Expression(DVI->getExpression()),
+ DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
switch (DVI->getIntrinsicID()) {
case Intrinsic::dbg_value:
Type = LocationType::Value;
@@ -23,6 +24,15 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI)
case Intrinsic::dbg_declare:
Type = LocationType::Declare;
break;
+ case Intrinsic::dbg_assign: {
+ Type = LocationType::Assign;
+ const DbgAssignIntrinsic *Assign =
+ static_cast<const DbgAssignIntrinsic *>(DVI);
+ resetDebugValue(1, Assign->getRawAddress());
+ AddressExpression = Assign->getAddressExpression();
+ setAssignId(Assign->getAssignID());
+ break;
+ }
default:
llvm_unreachable(
"Trying to create a DPValue with an invalid intrinsic type!");
@@ -30,14 +40,22 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI)
}
DPValue::DPValue(const DPValue &DPV)
- : DebugValueUser(DPV.getRawLocation()),
- Variable(DPV.getVariable()), Expression(DPV.getExpression()),
- DbgLoc(DPV.getDebugLoc()), Type(DPV.getType()) {}
+ : DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()),
+ Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()),
+ AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {}
DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
const DILocation *DI, LocationType Type)
- : DebugValueUser(Location), Variable(DV), Expression(Expr), DbgLoc(DI),
- Type(Type) {}
+ : DebugValueUser({Location, nullptr, nullptr}), Variable(DV),
+ Expression(Expr), DbgLoc(DI), Type(Type) {}
+
+DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
+ DIExpression *Expression, DIAssignID *AssignID,
+ Metadata *Address, DIExpression *AddressExpression,
+ const DILocation *DI)
+ : DebugValueUser({Value, Address, AssignID}), Variable(Variable),
+ Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
+ Type(LocationType::Assign) {}
void DPValue::deleteInstr() { delete this; }
@@ -69,6 +87,30 @@ DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
return NewDPVDeclare;
}
+DPValue *DPValue::createDPVAssign(Value *Val, DILocalVariable *Variable,
+ DIExpression *Expression,
+ DIAssignID *AssignID, Value *Address,
+ DIExpression *AddressExpression,
+ const DILocation *DI) {
+ return new DPValue(ValueAsMetadata::get(Val), Variable, Expression, AssignID,
+ ValueAsMetadata::get(Address), AddressExpression, DI);
+}
+
+DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
+ DILocalVariable *Variable,
+ DIExpression *Expression,
+ Value *Address,
+ DIExpression *AddressExpression,
+ const DILocation *DI) {
+ auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
+ assert(Link && "Linked instruction must have DIAssign metadata attached");
+ auto *NewDPVAssign = DPValue::createDPVAssign(Val, Variable, Expression,
+ cast<DIAssignID>(Link), Address,
+ AddressExpression, DI);
+ LinkedInstr->getParent()->insertDPValueAfter(NewDPVAssign, LinkedInstr);
+ return NewDPVAssign;
+}
+
iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
auto *MD = getRawLocation();
// If a Value has been deleted, the "location" for this DPValue will be
@@ -124,10 +166,15 @@ static ValueAsMetadata *getAsMetadata(Value *V) {
void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue,
bool AllowEmpty) {
assert(NewValue && "Values must be non-null");
+
+ bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
+ if (DbgAssignAddrReplaced)
+ setAddress(NewValue);
+
auto Locations = location_ops();
auto OldIt = find(Locations, OldValue);
if (OldIt == Locations.end()) {
- if (AllowEmpty)
+ if (AllowEmpty || DbgAssignAddrReplaced)
return;
llvm_unreachable("OldValue must be a current location");
}
@@ -218,9 +265,6 @@ DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
"Cannot clone from BasicBlock that is not part of a Module or "
"DICompileUnit!");
LLVMContext &Context = getDebugLoc()->getContext();
- Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
- MetadataAsValue::get(Context, getVariable()),
- MetadataAsValue::get(Context, getExpression())};
Function *IntrinsicFn;
// Work out what sort of intrinsic we're going to produce.
@@ -231,16 +275,34 @@ DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
case DPValue::LocationType::Value:
IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
break;
+ case DPValue::LocationType::Assign:
+ IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);
+ break;
case DPValue::LocationType::End:
case DPValue::LocationType::Any:
llvm_unreachable("Invalid LocationType");
- break;
}
// Create the intrinsic from this DPValue's information, optionally insert
// into the target location.
- DbgVariableIntrinsic *DVI = cast<DbgVariableIntrinsic>(
- CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
+ DbgVariableIntrinsic *DVI;
+ if (isDbgAssign()) {
+ Value *AssignArgs[] = {
+ MetadataAsValue::get(Context, getRawLocation()),
+ MetadataAsValue::get(Context, getVariable()),
+ MetadataAsValue::get(Context, getExpression()),
+ MetadataAsValue::get(Context, getAssignID()),
+ MetadataAsValue::get(Context, getRawAddress()),
+ MetadataAsValue::get(Context, getAddressExpression())};
+ DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
+ IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
+ } else {
+ Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
+ MetadataAsValue::get(Context, getVariable()),
+ MetadataAsValue::get(Context, getExpression())};
+ DVI = cast<DbgVariableIntrinsic>(
+ CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
+ }
DVI->setTailCall();
DVI->setDebugLoc(getDebugLoc());
if (InsertBefore)
@@ -249,8 +311,30 @@ DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
return DVI;
}
-void DPValue::handleChangedLocation(Metadata *NewLocation) {
- resetDebugValue(NewLocation);
+Value *DPValue::getAddress() const {
+ auto *MD = getRawAddress();
+ if (auto *V = dyn_cast<ValueAsMetadata>(MD))
+ return V->getValue();
+
+ // When the value goes to null, it gets replaced by an empty MDNode.
+ assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
+ return nullptr;
+}
+
+DIAssignID *DPValue::getAssignID() const {
+ return cast<DIAssignID>(DebugValues[2]);
+}
+
+void DPValue::setAssignId(DIAssignID *New) { resetDebugValue(2, New); }
+
+void DPValue::setKillAddress() {
+ resetDebugValue(
+ 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
+}
+
+bool DPValue::isKillAddress() const {
+ Value *Addr = getAddress();
+ return !Addr || isa<UndefValue>(Addr);
}
const BasicBlock *DPValue::getParent() const {
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 515893d079b8cb..da5d4940a6ab9b 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -152,26 +152,47 @@ DPValue *DebugValueUser::getUser() { return static_cast<DPValue *>(this); }
const DPValue *DebugValueUser::getUser() const {
return static_cast<const DPValue *>(this);
}
-void DebugValueUser::handleChangedValue(Metadata *NewMD) {
- getUser()->handleChangedLocation(NewMD);
+
+void DebugValueUser::handleChangedValue(void *Old, Metadata *New) {
+ // NOTE: We could inform the "owner" that a value has changed through
+ // getOwner, if needed.
+ auto OldMD = static_cast<Metadata **>(Old);
+ ptr
diff _t Idx = std::distance(DebugValues.begin(), OldMD);
+ resetDebugValue(Idx, New);
}
-void DebugValueUser::trackDebugValue() {
- if (DebugValue)
- MetadataTracking::track(&DebugValue, *DebugValue, *this);
+void DebugValueUser::trackDebugValue(size_t Idx) {
+ assert(Idx < 3 && "Invalid debug value index.");
+ Metadata *&MD = DebugValues[Idx];
+ if (MD)
+ MetadataTracking::track(&MD, *MD, *this);
}
-void DebugValueUser::untrackDebugValue() {
- if (DebugValue)
- MetadataTracking::untrack(DebugValue);
+void DebugValueUser::trackDebugValues() {
+ for (Metadata *&MD : DebugValues)
+ if (MD)
+ MetadataTracking::track(&MD, *MD, *this);
}
-void DebugValueUser::retrackDebugValue(DebugValueUser &X) {
- assert(DebugValue == X.DebugValue && "Expected values to match");
- if (X.DebugValue) {
- MetadataTracking::retrack(X.DebugValue, DebugValue);
- X.DebugValue = nullptr;
- }
+void DebugValueUser::untrackDebugValue(size_t Idx) {
+ assert(Idx < 3 && "Invalid debug value index.");
+ Metadata *&MD = DebugValues[Idx];
+ if (MD)
+ MetadataTracking::untrack(MD);
+}
+
+void DebugValueUser::untrackDebugValues() {
+ for (Metadata *&MD : DebugValues)
+ if (MD)
+ MetadataTracking::untrack(MD);
+}
+
+void DebugValueUser::retrackDebugValues(DebugValueUser &X) {
+ assert(DebugValueUser::operator==(X) && "Expected values to match");
+ for (const auto &[MD, XMD] : zip(DebugValues, X.DebugValues))
+ if (XMD)
+ MetadataTracking::retrack(XMD, MD);
+ X.DebugValues.fill(nullptr);
}
bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
@@ -362,7 +383,7 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
}
if (Owner.is<DebugValueUser *>()) {
- Owner.get<DebugValueUser *>()->getUser()->handleChangedLocation(MD);
+ Owner.get<DebugValueUser *>()->handleChangedValue(Pair.first, MD);
continue;
}
More information about the llvm-commits
mailing list