diff options
author | Orlando Cazalet-Hyams <orlando.hyams@sony.com> | 2024-02-20 16:00:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-20 16:00:55 +0000 |
commit | ababa964752d5bfa6eb608c97f19d4e68df1d243 (patch) | |
tree | 26b6cb86bafab688a348e950479323949092e568 /llvm | |
parent | 8f7ae64ea108de54d9aad963c55e1aef7dc62b86 (diff) | |
download | llvm-ababa964752d5bfa6eb608c97f19d4e68df1d243.zip llvm-ababa964752d5bfa6eb608c97f19d4e68df1d243.tar.gz llvm-ababa964752d5bfa6eb608c97f19d4e68df1d243.tar.bz2 |
[RemoveDIs][NFC] Introduce DbgRecord base class [1/3] (#78252)
Patch 1 of 3 to add llvm.dbg.label support to the RemoveDIs project. The
patch stack adds a new base class
-> 1. Add DbgRecord base class for DPValue and the not-yet-added
DPLabel class.
2. Add the DPLabel class.
3. Enable dbg.label conversion and add support to passes.
Patches 1 and 2 are NFC.
In the near future we also will rename DPValue to DbgVariableRecord and
DPLabel to DbgLabelRecord, at which point we'll overhaul the function
names too. The name DPLabel keeps things consistent for now.
Diffstat (limited to 'llvm')
39 files changed, 461 insertions, 289 deletions
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index a72b68d..ed25cb9 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -130,10 +130,10 @@ public: DPMarker *getNextMarker(Instruction *I); /// Insert a DPValue into a block at the position given by \p I. - void insertDPValueAfter(DPValue *DPV, Instruction *I); + void insertDPValueAfter(DbgRecord *DPV, Instruction *I); /// Insert a DPValue into a block at the position given by \p Here. - void insertDPValueBefore(DPValue *DPV, InstListType::iterator Here); + void insertDPValueBefore(DbgRecord *DPV, InstListType::iterator Here); /// Eject any debug-info trailing at the end of a block. DPValues can /// transiently be located "off the end" of a block if the blocks terminator @@ -147,7 +147,7 @@ public: /// occur: inserting into the middle of a sequence of dbg.value intrinsics /// does not have an equivalent with DPValues. void reinsertInstInDPValues(Instruction *I, - std::optional<DPValue::self_iterator> Pos); + std::optional<DbgRecord::self_iterator> Pos); private: void setParent(Function *parent); @@ -194,8 +194,9 @@ public: friend void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, bool Preserve); - friend iterator_range<DPValue::self_iterator> Instruction::cloneDebugInfoFrom( - const Instruction *From, std::optional<DPValue::self_iterator> FromHere, + friend iterator_range<DbgRecord::self_iterator> + Instruction::cloneDebugInfoFrom( + const Instruction *From, std::optional<DbgRecord::self_iterator> FromHere, bool InsertAtHead); /// Creates a new BasicBlock. diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h index b2f0793..022df64 100644 --- a/llvm/include/llvm/IR/DebugInfo.h +++ b/llvm/include/llvm/IR/DebugInfo.h @@ -111,6 +111,8 @@ public: void processLocation(const Module &M, const DILocation *Loc); // Process a DPValue, much like a DbgVariableIntrinsic. void processDPValue(const Module &M, const DPValue &DPV); + /// Dispatch to DbgRecord subclasses handlers. + void processDbgRecord(const Module &M, const DbgRecord &DPE); /// Process subprogram. void processSubprogram(DISubprogram *SP); diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index 594f613..1fa6b6f 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -53,6 +53,7 @@ #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/SymbolTableListTraits.h" +#include "llvm/Support/Casting.h" namespace llvm { @@ -66,43 +67,105 @@ class DPMarker; class DPValue; class raw_ostream; -/// Record of a variable value-assignment, aka a non instruction representation -/// of the dbg.value intrinsic. Features various methods copied across from the -/// Instruction class to aid ease-of-use. DPValue objects should always be -/// linked into a DPMarker's StoredDPValues list. The marker connects a DPValue -/// back to it's position in the BasicBlock. +/// Base class for non-instruction debug metadata records that have positions +/// within IR. Features various methods copied across from the Instruction +/// class to aid ease-of-use. DbgRecords should always be linked into a +/// DPMarker's StoredDPValues list. The marker connects a DbgRecord back to +/// it's position in the BasicBlock. /// -/// This class inherits from DebugValueUser to allow LLVM's metadata facilities -/// to update our references to metadata beneath our feet. -class DPValue : public ilist_node<DPValue>, private DebugValueUser { - friend class DebugValueUser; - - // NB: there is no explicit "Value" field in this class, it's effectively the - // DebugValueUser superclass instead. The referred to Value can either be a - // ValueAsMetadata or a DIArgList. +/// We need a discriminator for dyn/isa casts. In order to avoid paying for a +/// vtable for "virtual" functions too, subclasses must add a new discriminator +/// value (RecordKind) and cases to a few functions in the base class: +/// deleteRecord +/// clone +/// isIdenticalToWhenDefined +/// isEquivalentTo +/// both print methods +class DbgRecord : public ilist_node<DbgRecord> { +public: + /// Marker that this DbgRecord is linked into. + DPMarker *Marker = nullptr; + /// Subclass discriminator. + enum Kind : uint8_t { ValueKind }; - DILocalVariable *Variable; - DIExpression *Expression; +protected: DebugLoc DbgLoc; - DIExpression *AddressExpression; + Kind RecordKind; ///< Subclass discriminator. public: - void deleteInstr(); + DbgRecord(Kind RecordKind, DebugLoc DL) + : DbgLoc(DL), RecordKind(RecordKind) {} + + /// Methods that dispatch to subclass implementations. These need to be + /// manually updated when a new subclass is added. + ///@{ + void deleteRecord(); + DbgRecord *clone() const; + void print(raw_ostream &O, bool IsForDebug = false) const; + void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const; + bool isIdenticalToWhenDefined(const DbgRecord &R) const; + bool isEquivalentTo(const DbgRecord &R) const; + ///@} + + Kind getRecordKind() const { return RecordKind; } + + void setMarker(DPMarker *M) { Marker = M; } + + DPMarker *getMarker() { return Marker; } + const DPMarker *getMarker() const { return Marker; } + + BasicBlock *getBlock(); + const BasicBlock *getBlock() const; + + Function *getFunction(); + const Function *getFunction() const; + + Module *getModule(); + const Module *getModule() const; + + LLVMContext &getContext(); + const LLVMContext &getContext() const; const Instruction *getInstruction() const; const BasicBlock *getParent() const; BasicBlock *getParent(); - void dump() const; + void removeFromParent(); void eraseFromParent(); - DPValue *getNextNode() { return &*std::next(getIterator()); } - DPValue *getPrevNode() { return &*std::prev(getIterator()); } + DbgRecord *getNextNode() { return &*std::next(getIterator()); } + DbgRecord *getPrevNode() { return &*std::prev(getIterator()); } + void insertBefore(DbgRecord *InsertBefore); + void insertAfter(DbgRecord *InsertAfter); + void moveBefore(DbgRecord *MoveBefore); + void moveAfter(DbgRecord *MoveAfter); + + DebugLoc getDebugLoc() const { return DbgLoc; } + void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } + + void dump() const; + + using self_iterator = simple_ilist<DbgRecord>::iterator; + using const_self_iterator = simple_ilist<DbgRecord>::const_iterator; - using self_iterator = simple_ilist<DPValue>::iterator; - using const_self_iterator = simple_ilist<DPValue>::const_iterator; +protected: + /// Similarly to Value, we avoid paying the cost of a vtable + /// by protecting the dtor and having deleteRecord dispatch + /// cleanup. + /// Use deleteRecord to delete a generic record. + ~DbgRecord() = default; +}; + +/// Record of a variable value-assignment, aka a non instruction representation +/// of the dbg.value intrinsic. +/// +/// This class inherits from DebugValueUser to allow LLVM's metadata facilities +/// to update our references to metadata beneath our feet. +class DPValue : public DbgRecord, protected DebugValueUser { + friend class DebugValueUser; - enum class LocationType { +public: + enum class LocationType : uint8_t { Declare, Value, Assign, @@ -113,11 +176,18 @@ public: /// Classification of the debug-info record that this DPValue represents. /// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not /// currently supported, but it would be trivial to do so. + /// FIXME: We could use spare padding bits from DbgRecord for this. LocationType Type; - /// Marker that this DPValue is linked into. - DPMarker *Marker = nullptr; + // NB: there is no explicit "Value" field in this class, it's effectively the + // DebugValueUser superclass instead. The referred to Value can either be a + // ValueAsMetadata or a DIArgList. + + DILocalVariable *Variable; + DIExpression *Expression; + DIExpression *AddressExpression; +public: /// Create a new DPValue representing the intrinsic \p DVI, for example the /// assignment represented by a dbg.value. DPValue(const DbgVariableIntrinsic *DVI); @@ -235,9 +305,6 @@ public: bool isAddressOfVariable() const { return Type == LocationType::Declare; } LocationType getType() const { return Type; } - DebugLoc getDebugLoc() const { return DbgLoc; } - void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } - void setKillLocation(); bool isKillLocation() const; @@ -270,12 +337,12 @@ public: /// is described. std::optional<uint64_t> getFragmentSizeInBits() const; - bool isEquivalentTo(const DPValue &Other) { + bool isEquivalentTo(const DPValue &Other) const { return DbgLoc == Other.DbgLoc && isIdenticalToWhenDefined(Other); } // Matches the definition of the Instruction version, equivalent to above but // without checking DbgLoc. - bool isIdenticalToWhenDefined(const DPValue &Other) { + bool isIdenticalToWhenDefined(const DPValue &Other) const { return std::tie(Type, DebugValues, Variable, Expression, AddressExpression) == std::tie(Other.Type, Other.DebugValues, Other.Variable, @@ -314,43 +381,37 @@ public: /// \returns A new dbg.value intrinsic representiung this DPValue. DbgVariableIntrinsic *createDebugIntrinsic(Module *M, Instruction *InsertBefore) const; - void setMarker(DPMarker *M) { Marker = M; } - - DPMarker *getMarker() { return Marker; } - const DPMarker *getMarker() const { return Marker; } - - BasicBlock *getBlock(); - const BasicBlock *getBlock() const; - - Function *getFunction(); - const Function *getFunction() const; - Module *getModule(); - const Module *getModule() const; - - 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 moveBefore(DPValue *MoveBefore); - void moveAfter(DPValue *MoveAfter); + /// Handle changes to the location of the Value(s) that we refer to happening + /// "under our feet". + void handleChangedLocation(Metadata *NewLocation); void print(raw_ostream &O, bool IsForDebug = false) const; void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; + + /// Filter the DbgRecord range to DPValue types only and downcast. + static inline auto + filter(iterator_range<simple_ilist<DbgRecord>::iterator> R) { + return map_range( + make_filter_range(R, [](DbgRecord &E) { return isa<DPValue>(E); }), + [](DbgRecord &E) { return std::ref(cast<DPValue>(E)); }); + } + + /// Support type inquiry through isa, cast, and dyn_cast. + static bool classof(const DbgRecord *E) { + return E->getRecordKind() == ValueKind; + } }; /// Per-instruction record of debug-info. If an Instruction is the position of /// some debugging information, it points at a DPMarker storing that info. Each /// marker points back at the instruction that owns it. Various utilities are -/// provided for manipulating the DPValues contained within this marker. +/// provided for manipulating the DbgRecords contained within this marker. /// -/// This class has a rough surface area, because it's needed to preserve the one -/// arefact that we can't yet eliminate from the intrinsic / dbg.value -/// debug-info design: the order of DPValues/records is significant, and -/// duplicates can exist. Thus, if one has a run of debug-info records such as: +/// This class has a rough surface area, because it's needed to preserve the +/// one arefact that we can't yet eliminate from the intrinsic / dbg.value +/// debug-info design: the order of records is significant, and duplicates can +/// exist. Thus, if one has a run of debug-info records such as: /// dbg.value(... /// %foo = barinst /// dbg.value(... @@ -370,12 +431,11 @@ public: /// operations that move a marker from one instruction to another. Instruction *MarkedInstr = nullptr; - /// List of DPValues, each recording a single variable assignment, the - /// equivalent of a dbg.value intrinsic. There is a one-to-one relationship - /// between each dbg.value in a block and each DPValue once the - /// representation has been converted, and the ordering of DPValues is - /// meaningful in the same was a dbg.values. - simple_ilist<DPValue> StoredDPValues; + /// List of DbgRecords, the non-instruction equivalent of llvm.dbg.* + /// intrinsics. There is a one-to-one relationship between each debug + /// intrinsic in a block and each DbgRecord once the representation has been + /// converted, and the ordering is meaningful in the same way. + simple_ilist<DbgRecord> StoredDPValues; bool empty() const { return StoredDPValues.empty(); } const BasicBlock *getParent() const; @@ -395,8 +455,8 @@ public: void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; /// Produce a range over all the DPValues in this Marker. - iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange(); - iterator_range<simple_ilist<DPValue>::const_iterator> + iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange(); + iterator_range<simple_ilist<DbgRecord>::const_iterator> getDbgValueRange() const; /// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead /// is true, place them before existing DPValues, otherwise afterwards. @@ -404,31 +464,31 @@ public: /// Transfer the DPValues in \p Range from \p Src into this DPMarker. If /// \p InsertAtHead is true, place them before existing DPValues, otherwise // afterwards. - void absorbDebugValues(iterator_range<DPValue::self_iterator> Range, + void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range, DPMarker &Src, bool InsertAtHead); /// 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); + void insertDPValue(DbgRecord *New, bool InsertAtHead); /// Insert a DPValue prior to a DPValue contained within this marker. - void insertDPValue(DPValue *New, DPValue *InsertBefore); + void insertDPValue(DbgRecord *New, DbgRecord *InsertBefore); /// Insert a DPValue after a DPValue contained within this marker. - void insertDPValueAfter(DPValue *New, DPValue *InsertAfter); + void insertDPValueAfter(DbgRecord *New, DbgRecord *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. /// \p FromHere If non-null, copy from FromHere to the end of From's DPValues /// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues /// \returns Range over all the newly cloned DPValues - iterator_range<simple_ilist<DPValue>::iterator> + iterator_range<simple_ilist<DbgRecord>::iterator> cloneDebugInfoFrom(DPMarker *From, - std::optional<simple_ilist<DPValue>::iterator> FromHere, + std::optional<simple_ilist<DbgRecord>::iterator> FromHere, bool InsertAtHead = false); /// Erase all DPValues in this DPMarker. - void dropDPValues(); - /// Erase a single DPValue from this marker. In an ideal future, we would + void dropDbgValues(); + /// Erase a single DbgRecord from this marker. In an ideal future, we would /// never erase an assignment in this way, but it's the equivalent to - /// erasing a dbg.value from a block. - void dropOneDPValue(DPValue *DPV); + /// erasing a debug intrinsic from a block. + void dropOneDbgValue(DbgRecord *DR); /// We generally act like all llvm Instructions have a range of DPValues /// attached to them, but in reality sometimes we don't allocate the DPMarker @@ -438,8 +498,10 @@ public: /// DPValue in that range, but they should be using the Official (TM) API for /// that. static DPMarker EmptyDPMarker; - static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange(){ - return make_range(EmptyDPMarker.StoredDPValues.end(), EmptyDPMarker.StoredDPValues.end()); + static iterator_range<simple_ilist<DbgRecord>::iterator> + getEmptyDPValueRange() { + return make_range(EmptyDPMarker.StoredDPValues.end(), + EmptyDPMarker.StoredDPValues.end()); } }; @@ -457,7 +519,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DPValue &Value) { /// to be inlined as it's frequently called, but also come after the declaration /// of DPMarker. Thus: it's pre-declared by users like Instruction, then an /// inlineable body defined here. -inline iterator_range<simple_ilist<DPValue>::iterator> +inline iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange(DPMarker *DbgMarker) { if (!DbgMarker) return DPMarker::getEmptyDPValueRange(); diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index cd814e2..c0e159a 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -35,12 +35,13 @@ class MDNode; class Module; struct AAMDNodes; class DPMarker; +class DbgRecord; template <> struct ilist_alloc_traits<Instruction> { static inline void deleteNode(Instruction *V); }; -iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange(DPMarker *); +iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange(DPMarker *); class Instruction : public User, public ilist_node_with_parent<Instruction, BasicBlock, @@ -72,20 +73,20 @@ public: /// \p InsertAtHead Whether the cloned DPValues should be placed at the end /// or the beginning of existing DPValues attached to this. /// \returns A range over the newly cloned DPValues. - iterator_range<simple_ilist<DPValue>::iterator> cloneDebugInfoFrom( + iterator_range<simple_ilist<DbgRecord>::iterator> cloneDebugInfoFrom( const Instruction *From, - std::optional<simple_ilist<DPValue>::iterator> FromHere = std::nullopt, + std::optional<simple_ilist<DbgRecord>::iterator> FromHere = std::nullopt, bool InsertAtHead = false); /// Return a range over the DPValues attached to this instruction. - iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange() const { + iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange() const { return llvm::getDbgValueRange(DbgMarker); } /// Return an iterator to the position of the "Next" DPValue after this /// instruction, or std::nullopt. This is the position to pass to /// BasicBlock::reinsertInstInDPValues when re-inserting an instruction. - std::optional<simple_ilist<DPValue>::iterator> getDbgReinsertionPosition(); + std::optional<simple_ilist<DbgRecord>::iterator> getDbgReinsertionPosition(); /// Returns true if any DPValues are attached to this instruction. bool hasDbgValues() const; @@ -100,7 +101,7 @@ public: void dropDbgValues(); /// Erase a single DPValue \p I that is attached to this instruction. - void dropOneDbgValue(DPValue *I); + void dropOneDbgValue(DbgRecord *I); /// Handle the debug-info implications of this instruction being removed. Any /// attached DPValues need to "fall" down onto the next instruction. diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index e1f2796..dd183bc 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -22,7 +22,8 @@ namespace llvm { class Constant; -class DPValue; +class DIBuilder; +class DbgRecord; class Function; class GlobalVariable; class Instruction; @@ -33,7 +34,7 @@ class Type; class Value; using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>; -using DPValueIterator = simple_ilist<DPValue>::iterator; +using DbgRecordIterator = simple_ilist<DbgRecord>::iterator; /// This is a class that can be implemented by clients to remap types when /// cloning constants and instructions. @@ -180,7 +181,7 @@ public: void remapInstruction(Instruction &I); void remapDPValue(Module *M, DPValue &V); - void remapDPValueRange(Module *M, iterator_range<DPValueIterator> Range); + void remapDPValueRange(Module *M, iterator_range<DbgRecordIterator> Range); void remapFunction(Function &F); void remapGlobalObjectMetadata(GlobalObject &GO); @@ -275,7 +276,8 @@ inline void RemapDPValue(Module *M, DPValue *V, ValueToValueMapTy &VM, } /// Remap the Values used in the DPValue \a V using the value map \a VM. -inline void RemapDPValueRange(Module *M, iterator_range<DPValueIterator> Range, +inline void RemapDPValueRange(Module *M, + iterator_range<DbgRecordIterator> Range, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = nullptr, ValueMaterializer *Materializer = nullptr) { diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp index f8ce8f9..7b66a85 100644 --- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp +++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp @@ -82,7 +82,7 @@ template <> struct llvm::DenseMapInfo<VariableID> { } }; -using VarLocInsertPt = PointerUnion<const Instruction *, const DPValue *>; +using VarLocInsertPt = PointerUnion<const Instruction *, const DbgRecord *>; namespace std { template <> struct hash<VarLocInsertPt> { @@ -218,14 +218,14 @@ void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) { // block includes VarLocs for any DPValues attached to that instruction. for (auto &P : Builder.VarLocsBeforeInst) { // Process VarLocs attached to a DPValue alongside their marker Instruction. - if (isa<const DPValue *>(P.first)) + if (isa<const DbgRecord *>(P.first)) continue; const Instruction *I = cast<const Instruction *>(P.first); unsigned BlockStart = VarLocRecords.size(); // Any VarLocInfos attached to a DPValue should now be remapped to their // marker Instruction, in order of DPValue appearance and prior to any // VarLocInfos attached directly to that instruction. - for (const DPValue &DPV : I->getDbgValueRange()) { + for (const DPValue &DPV : DPValue::filter(I->getDbgValueRange())) { // Even though DPV defines a variable location, VarLocsBeforeInst can // still be empty if that VarLoc was redundant. if (!Builder.VarLocsBeforeInst.count(&DPV)) @@ -829,7 +829,11 @@ class MemLocFragmentFill { void process(BasicBlock &BB, VarFragMap &LiveSet) { BBInsertBeforeMap[&BB].clear(); for (auto &I : BB) { - for (auto &DPV : I.getDbgValueRange()) { + for (DbgRecord &DR : I.getDbgValueRange()) { + // FIXME: DPValue::filter usage needs attention in this file; we need + // to make sure dbg.labels are handled correctly in RemoveDIs mode. + // Cast below to ensure this gets fixed when DPLabels are introduced. + DPValue &DPV = cast<DPValue>(DR); if (const auto *Locs = FnVarLocs->getWedge(&DPV)) { for (const VarLocInfo &Loc : *Locs) { addDef(Loc, &DPV, *I.getParent(), LiveSet); @@ -1492,7 +1496,7 @@ const char *locStr(AssignmentTrackingLowering::LocKind Loc) { } #endif -VarLocInsertPt getNextNode(const DPValue *DPV) { +VarLocInsertPt getNextNode(const DbgRecord *DPV) { auto NextIt = ++(DPV->getIterator()); if (NextIt == DPV->getMarker()->getDbgValueRange().end()) return DPV->getMarker()->MarkedInstr; @@ -1507,7 +1511,7 @@ VarLocInsertPt getNextNode(const Instruction *Inst) { VarLocInsertPt getNextNode(VarLocInsertPt InsertPt) { if (isa<const Instruction *>(InsertPt)) return getNextNode(cast<const Instruction *>(InsertPt)); - return getNextNode(cast<const DPValue *>(InsertPt)); + return getNextNode(cast<const DbgRecord *>(InsertPt)); } DbgAssignIntrinsic *CastToDbgAssign(DbgVariableIntrinsic *DVI) { @@ -1915,7 +1919,7 @@ void AssignmentTrackingLowering::process(BasicBlock &BB, BlockInfo *LiveSet) { // attached DPValues, or a non-debug instruction with attached unprocessed // DPValues. if (II != EI && II->hasDbgValues()) { - for (DPValue &DPV : II->getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(II->getDbgValueRange())) { resetInsertionPoint(DPV); processDPValue(DPV, LiveSet); assert(LiveSet->isValid()); @@ -2172,7 +2176,7 @@ static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares( }; for (auto &BB : Fn) { for (auto &I : BB) { - for (auto &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) ProcessDbgRecord(&DPV, DPDeclares); if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) { ProcessDbgRecord(DII, InstDeclares); @@ -2462,7 +2466,7 @@ bool AssignmentTrackingLowering::emitPromotedVarLocs( for (auto &BB : Fn) { for (auto &I : BB) { // Skip instructions other than dbg.values and dbg.assigns. - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) if (DPV.isDbgValue() || DPV.isDbgAssign()) TranslateDbgRecord(&DPV); auto *DVI = dyn_cast<DbgValueInst>(&I); @@ -2564,7 +2568,7 @@ removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB, } }; HandleLocsForWedge(&I); - for (DPValue &DPV : reverse(I.getDbgValueRange())) + for (DPValue &DPV : reverse(DPValue::filter(I.getDbgValueRange()))) HandleLocsForWedge(&DPV); } @@ -2629,7 +2633,7 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB, } }; - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) HandleLocsForWedge(&DPV); HandleLocsForWedge(&I); } @@ -2715,7 +2719,7 @@ removeUndefDbgLocsFromEntryBlock(const BasicBlock *BB, Changed = true; } }; - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) HandleLocsForWedge(&DPV); HandleLocsForWedge(&I); } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 32a25b4..4036f18 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -8505,7 +8505,7 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) { bool CodeGenPrepare::fixupDPValuesOnInst(Instruction &I) { bool AnyChange = false; - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) AnyChange |= fixupDPValue(DPV); return AnyChange; } @@ -8618,7 +8618,8 @@ bool CodeGenPrepare::placeDbgValues(Function &F) { // If this isn't a dbg.value, process any attached DPValue records // attached to this instruction. - for (DPValue &DPV : llvm::make_early_inc_range(Insn.getDbgValueRange())) { + for (DPValue &DPV : llvm::make_early_inc_range( + DPValue::filter(Insn.getDbgValueRange()))) { if (DPV.Type != DPValue::LocationType::Value) continue; DbgProcessor(&DPV, &Insn); diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 24ca6a8..7c95cef 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3275,7 +3275,7 @@ void IRTranslator::translateDbgDeclareRecord(Value *Address, bool HasArgList, void IRTranslator::translateDbgInfo(const Instruction &Inst, MachineIRBuilder &MIRBuilder) { - for (DPValue &DPV : Inst.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(Inst.getDbgValueRange())) { const DILocalVariable *Variable = DPV.getVariable(); const DIExpression *Expression = DPV.getExpression(); Value *V = DPV.getVariableLocationOp(0); diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index f875652..5651498 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1188,10 +1188,12 @@ void FastISel::handleDbgInfo(const Instruction *II) { MIMD = MIMetadata(); // Reverse order of debug records, because fast-isel walks through backwards. - for (DPValue &DPV : llvm::reverse(II->getDbgValueRange())) { + for (DbgRecord &DPR : llvm::reverse(II->getDbgValueRange())) { flushLocalValueMap(); recomputeInsertPt(); + DPValue &DPV = cast<DPValue>(DPR); + Value *V = nullptr; if (!DPV.hasArgList()) V = DPV.getVariableLocationOp(0); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index b2782cb..2bdf486 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1250,7 +1250,8 @@ void SelectionDAGBuilder::visitDbgInfo(const Instruction &I) { // Is there is any debug-info attached to this instruction, in the form of // DPValue non-instruction debug-info records. - for (DPValue &DPV : I.getDbgValueRange()) { + for (DbgRecord &DPR : I.getDbgValueRange()) { + DPValue &DPV = cast<DPValue>(DPR); DILocalVariable *Variable = DPV.getVariable(); DIExpression *Expression = DPV.getExpression(); dropDanglingDebugInfo(Variable, Expression); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index ad5a330..9b5ab42 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1461,9 +1461,8 @@ static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) { if (DI && processDbgDeclare(FuncInfo, DI->getAddress(), DI->getExpression(), DI->getVariable(), DI->getDebugLoc())) FuncInfo.PreprocessedDbgDeclares.insert(DI); - - for (const DPValue &DPV : I.getDbgValueRange()) { - if (DPV.getType() == DPValue::LocationType::Declare && + for (const DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { + if (DPV.Type == DPValue::LocationType::Declare && processDbgDeclare(FuncInfo, DPV.getVariableLocationOp(0), DPV.getExpression(), DPV.getVariable(), DPV.getDebugLoc())) diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index d3c64a5..251485a 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -862,7 +862,7 @@ private: void processInstructionMetadata(const Instruction &I); /// Add all of the metadata from an instruction. - void processDPValueMetadata(const DPValue &DPV); + void processDbgRecordMetadata(const DbgRecord &DPV); }; } // end namespace llvm @@ -1131,18 +1131,21 @@ void SlotTracker::processFunctionMetadata(const Function &F) { processGlobalObjectMetadata(F); for (auto &BB : F) { for (auto &I : BB) { - for (const DPValue &DPV : I.getDbgValueRange()) - processDPValueMetadata(DPV); + for (const DbgRecord &DR : I.getDbgValueRange()) + processDbgRecordMetadata(DR); processInstructionMetadata(I); } } } -void SlotTracker::processDPValueMetadata(const DPValue &DPV) { - CreateMetadataSlot(DPV.getVariable()); - CreateMetadataSlot(DPV.getDebugLoc()); - if (DPV.isDbgAssign()) { - CreateMetadataSlot(DPV.getAssignID()); +void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) { + if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) { + CreateMetadataSlot(DPV->getVariable()); + CreateMetadataSlot(DPV->getDebugLoc()); + if (DPV->isDbgAssign()) + CreateMetadataSlot(DPV->getAssignID()); + } else { + llvm_unreachable("unsupported DbgRecord kind"); } } @@ -2673,6 +2676,7 @@ public: void printInstruction(const Instruction &I); void printDPMarker(const DPMarker &DPI); void printDPValue(const DPValue &DPI); + void printDbgRecord(const DbgRecord &DPI); void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle); void printUseLists(const Function *F); @@ -4561,8 +4565,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { void AssemblyWriter::printDPMarker(const DPMarker &Marker) { // There's no formal representation of a DPMarker -- print purely as a // debugging aid. - for (const DPValue &DPI2 : Marker.StoredDPValues) { - printDPValue(DPI2); + for (const DbgRecord &DPR : Marker.StoredDPValues) { + printDbgRecord(DPR); Out << "\n"; } @@ -4572,6 +4576,13 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) { return; } +void AssemblyWriter::printDbgRecord(const DbgRecord &DR) { + if (auto *DPV = dyn_cast<DPValue>(&DR)) + printDPValue(*DPV); + else + llvm_unreachable("unsupported dbg record"); +} + void AssemblyWriter::printDPValue(const DPValue &Value) { // There's no formal representation of a DPValue -- print purely as a // debugging aid. @@ -5144,7 +5155,7 @@ void DPMarker::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n' // Value::dump - allow easy printing of Values from the debugger. LLVM_DUMP_METHOD -void DPValue::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; } +void DbgRecord::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; } // Type::dump - allow easy printing of Types from the debugger. LLVM_DUMP_METHOD diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index bf02eba..06807544 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -70,7 +70,7 @@ void BasicBlock::convertToNewDbgValues() { // Iterate over all instructions in the instruction list, collecting dbg.value // instructions and converting them to DPValues. Once we find a "real" // instruction, attach all those DPValues to a DPMarker in that instruction. - SmallVector<DPValue *, 4> DPVals; + SmallVector<DbgRecord *, 4> DPVals; for (Instruction &I : make_early_inc_range(InstList)) { assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?"); if (DbgVariableIntrinsic *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) { @@ -88,7 +88,7 @@ void BasicBlock::convertToNewDbgValues() { createMarker(&I); DPMarker *Marker = I.DbgMarker; - for (DPValue *DPV : DPVals) + for (DbgRecord *DPV : DPVals) Marker->insertDPValue(DPV, false); DPVals.clear(); @@ -107,9 +107,13 @@ void BasicBlock::convertFromNewDbgValues() { continue; DPMarker &Marker = *Inst.DbgMarker; - for (DPValue &DPV : Marker.getDbgValueRange()) - InstList.insert(Inst.getIterator(), - DPV.createDebugIntrinsic(getModule(), nullptr)); + for (DbgRecord &DR : Marker.getDbgValueRange()) { + if (auto *DPV = dyn_cast<DPValue>(&DR)) + InstList.insert(Inst.getIterator(), + DPV->createDebugIntrinsic(getModule(), nullptr)); + else + llvm_unreachable("unsupported DbgRecord kind"); + } Marker.eraseFromParent(); }; @@ -163,9 +167,9 @@ bool BasicBlock::validateDbgValues(bool Assert, bool Msg, raw_ostream *OS) { "Debug Marker points to incorrect instruction?"); // Now validate any DPValues in the marker. - for (DPValue &DPV : CurrentDebugMarker->getDbgValueRange()) { + for (DbgRecord &DPR : CurrentDebugMarker->getDbgValueRange()) { // Validate DebugProgramValues. - TestFailure(DPV.getMarker() == CurrentDebugMarker, + TestFailure(DPR.getMarker() == CurrentDebugMarker, "Not pointing at correct next marker!"); // Verify that no DbgValues appear prior to PHIs. @@ -1086,7 +1090,7 @@ void BasicBlock::splice(iterator Dest, BasicBlock *Src, iterator First, flushTerminatorDbgValues(); } -void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) { +void BasicBlock::insertDPValueAfter(DbgRecord *DPV, Instruction *I) { assert(IsNewDbgInfoFormat); assert(I->getParent() == this); @@ -1095,7 +1099,7 @@ void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) { NextMarker->insertDPValue(DPV, true); } -void BasicBlock::insertDPValueBefore(DPValue *DPV, +void BasicBlock::insertDPValueBefore(DbgRecord *DPV, InstListType::iterator Where) { // We should never directly insert at the end of the block, new DPValues // shouldn't be generated at times when there's no terminator. diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index eaa5cb3..a4fec60 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -240,8 +240,8 @@ void DebugInfoFinder::processInstruction(const Module &M, if (auto DbgLoc = I.getDebugLoc()) processLocation(M, DbgLoc.get()); - for (const DPValue &DPV : I.getDbgValueRange()) - processDPValue(M, DPV); + for (const DbgRecord &DPR : I.getDbgValueRange()) + processDbgRecord(M, DPR); } void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) { @@ -256,6 +256,10 @@ void DebugInfoFinder::processDPValue(const Module &M, const DPValue &DPV) { processLocation(M, DPV.getDebugLoc().get()); } +void DebugInfoFinder::processDbgRecord(const Module &M, const DbgRecord &DPR) { + processDPValue(M, cast<DPValue>(DPR)); +} + void DebugInfoFinder::processType(DIType *DT) { if (!addType(DT)) return; @@ -1822,7 +1826,7 @@ void at::deleteAll(Function *F) { SmallVector<DPValue *, 12> DPToDelete; for (BasicBlock &BB : *F) { for (Instruction &I : BB) { - for (auto &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) if (DPV.isDbgAssign()) DPToDelete.push_back(&DPV); if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I)) @@ -2246,7 +2250,7 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) { }; for (auto &BB : F) { for (auto &I : BB) { - for (auto &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { if (DPV.isDbgDeclare()) ProcessDeclare(&DPV, DPVDeclares); } diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index a2640d5..9568b22 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -14,9 +14,10 @@ namespace llvm { DPValue::DPValue(const DbgVariableIntrinsic *DVI) - : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), + : DbgRecord(ValueKind, DVI->getDebugLoc()), + DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), Variable(DVI->getVariable()), Expression(DVI->getExpression()), - DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) { + AddressExpression(nullptr) { switch (DVI->getIntrinsicID()) { case Intrinsic::dbg_value: Type = LocationType::Value; @@ -40,24 +41,78 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI) } DPValue::DPValue(const DPValue &DPV) - : DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()), - Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()), - AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {} + : DbgRecord(ValueKind, DPV.getDebugLoc()), DebugValueUser(DPV.DebugValues), + Type(DPV.getType()), Variable(DPV.getVariable()), + Expression(DPV.getExpression()), + AddressExpression(DPV.AddressExpression) {} DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, const DILocation *DI, LocationType Type) - : DebugValueUser({Location, nullptr, nullptr}), Variable(DV), - Expression(Expr), DbgLoc(DI), Type(Type) {} + : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}), + Type(Type), Variable(DV), Expression(Expr) {} 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) {} + : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), + Type(LocationType::Assign), Variable(Variable), Expression(Expression), + AddressExpression(AddressExpression) {} + +void DbgRecord::deleteRecord() { + switch (RecordKind) { + case ValueKind: + delete cast<DPValue>(this); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); + } +} + +void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { + switch (RecordKind) { + case ValueKind: + cast<DPValue>(this)->print(O, IsForDebug); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); + }; +} + +void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, + bool IsForDebug) const { + switch (RecordKind) { + case ValueKind: + cast<DPValue>(this)->print(O, MST, IsForDebug); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); + }; +} + +bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { + if (RecordKind != R.RecordKind) + return false; + switch (RecordKind) { + case ValueKind: + return cast<DPValue>(this)->isIdenticalToWhenDefined(*cast<DPValue>(&R)); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); + }; +} -void DPValue::deleteInstr() { delete this; } +bool DbgRecord::isEquivalentTo(const DbgRecord &R) const { + if (RecordKind != R.RecordKind) + return false; + switch (RecordKind) { + case ValueKind: + return cast<DPValue>(this)->isEquivalentTo(*cast<DPValue>(&R)); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); + }; +} DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV, DIExpression *Expr, const DILocation *DI) { @@ -255,6 +310,15 @@ std::optional<uint64_t> DPValue::getFragmentSizeInBits() const { return getVariable()->getSizeInBits(); } +DbgRecord *DbgRecord::clone() const { + switch (RecordKind) { + case ValueKind: + return cast<DPValue>(this)->clone(); + default: + llvm_unreachable("unsupported DbgRecord kind"); + }; +} + DPValue *DPValue::clone() const { return new DPValue(*this); } DbgVariableIntrinsic * @@ -338,59 +402,63 @@ bool DPValue::isKillAddress() const { return !Addr || isa<UndefValue>(Addr); } -const Instruction *DPValue::getInstruction() const { +const Instruction *DbgRecord::getInstruction() const { return Marker->MarkedInstr; } -const BasicBlock *DPValue::getParent() const { +const BasicBlock *DbgRecord::getParent() const { return Marker->MarkedInstr->getParent(); } -BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); } +BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); } -BasicBlock *DPValue::getBlock() { return Marker->getParent(); } +BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); } -const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); } +const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); } -Function *DPValue::getFunction() { return getBlock()->getParent(); } +Function *DbgRecord::getFunction() { return getBlock()->getParent(); } -const Function *DPValue::getFunction() const { return getBlock()->getParent(); } +const Function *DbgRecord::getFunction() const { + return getBlock()->getParent(); +} -Module *DPValue::getModule() { return getFunction()->getParent(); } +Module *DbgRecord::getModule() { return getFunction()->getParent(); } -const Module *DPValue::getModule() const { return getFunction()->getParent(); } +const Module *DbgRecord::getModule() const { + return getFunction()->getParent(); +} -LLVMContext &DPValue::getContext() { return getBlock()->getContext(); } +LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); } -const LLVMContext &DPValue::getContext() const { +const LLVMContext &DbgRecord::getContext() const { return getBlock()->getContext(); } -void DPValue::insertBefore(DPValue *InsertBefore) { +void DbgRecord::insertBefore(DbgRecord *InsertBefore) { assert(!getMarker() && - "Cannot insert a DPValue that is already has a DPMarker!"); + "Cannot insert a DbgRecord that is already has a DPMarker!"); assert(InsertBefore->getMarker() && - "Cannot insert a DPValue before a DPValue that does not have a " + "Cannot insert a DbgRecord before a DbgRecord that does not have a " "DPMarker!"); InsertBefore->getMarker()->insertDPValue(this, InsertBefore); } -void DPValue::insertAfter(DPValue *InsertAfter) { +void DbgRecord::insertAfter(DbgRecord *InsertAfter) { assert(!getMarker() && - "Cannot insert a DPValue that is already has a DPMarker!"); + "Cannot insert a DbgRecord that is already has a DPMarker!"); assert(InsertAfter->getMarker() && - "Cannot insert a DPValue after a DPValue that does not have a " + "Cannot insert a DbgRecord after a DbgRecord that does not have a " "DPMarker!"); InsertAfter->getMarker()->insertDPValueAfter(this, InsertAfter); } -void DPValue::moveBefore(DPValue *MoveBefore) { +void DbgRecord::moveBefore(DbgRecord *MoveBefore) { assert(getMarker() && - "Canot move a DPValue that does not currently have a DPMarker!"); + "Canot move a DbgRecord that does not currently have a DPMarker!"); removeFromParent(); insertBefore(MoveBefore); } -void DPValue::moveAfter(DPValue *MoveAfter) { +void DbgRecord::moveAfter(DbgRecord *MoveAfter) { assert(getMarker() && - "Canot move a DPValue that does not currently have a DPMarker!"); + "Canot move a DbgRecord that does not currently have a DPMarker!"); removeFromParent(); insertAfter(MoveAfter); } @@ -401,19 +469,19 @@ void DPValue::moveAfter(DPValue *MoveAfter) { // DPValues. DPMarker DPMarker::EmptyDPMarker; -void DPMarker::dropDPValues() { +void DPMarker::dropDbgValues() { while (!StoredDPValues.empty()) { auto It = StoredDPValues.begin(); - DPValue *DPV = &*It; + DbgRecord *DR = &*It; StoredDPValues.erase(It); - DPV->deleteInstr(); + DR->deleteRecord(); } } -void DPMarker::dropOneDPValue(DPValue *DPV) { - assert(DPV->getMarker() == this); - StoredDPValues.erase(DPV->getIterator()); - DPV->deleteInstr(); +void DPMarker::dropOneDbgValue(DbgRecord *DR) { + assert(DR->getMarker() == this); + StoredDPValues.erase(DR->getIterator()); + DR->deleteRecord(); } const BasicBlock *DPMarker::getParent() const { @@ -462,40 +530,40 @@ void DPMarker::removeFromParent() { void DPMarker::eraseFromParent() { if (MarkedInstr) removeFromParent(); - dropDPValues(); + dropDbgValues(); delete this; } -iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() { +iterator_range<DbgRecord::self_iterator> DPMarker::getDbgValueRange() { return make_range(StoredDPValues.begin(), StoredDPValues.end()); } -iterator_range<DPValue::const_self_iterator> +iterator_range<DbgRecord::const_self_iterator> DPMarker::getDbgValueRange() const { return make_range(StoredDPValues.begin(), StoredDPValues.end()); } -void DPValue::removeFromParent() { +void DbgRecord::removeFromParent() { getMarker()->StoredDPValues.erase(getIterator()); Marker = nullptr; } -void DPValue::eraseFromParent() { +void DbgRecord::eraseFromParent() { removeFromParent(); - deleteInstr(); + deleteRecord(); } -void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) { +void DPMarker::insertDPValue(DbgRecord *New, bool InsertAtHead) { auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end(); StoredDPValues.insert(It, *New); New->setMarker(this); } -void DPMarker::insertDPValue(DPValue *New, DPValue *InsertBefore) { +void DPMarker::insertDPValue(DbgRecord *New, DbgRecord *InsertBefore) { assert(InsertBefore->getMarker() == this && "DPValue 'InsertBefore' must be contained in this DPMarker!"); StoredDPValues.insert(InsertBefore->getIterator(), *New); New->setMarker(this); } -void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) { +void DPMarker::insertDPValueAfter(DbgRecord *New, DbgRecord *InsertAfter) { assert(InsertAfter->getMarker() == this && "DPValue 'InsertAfter' must be contained in this DPMarker!"); StoredDPValues.insert(++(InsertAfter->getIterator()), *New); @@ -504,16 +572,16 @@ void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) { void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) { auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end(); - for (DPValue &DPV : Src.StoredDPValues) + for (DbgRecord &DPV : Src.StoredDPValues) DPV.setMarker(this); StoredDPValues.splice(It, Src.StoredDPValues); } -void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range, +void DPMarker::absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range, DPMarker &Src, bool InsertAtHead) { - for (DPValue &DPV : Range) - DPV.setMarker(this); + for (DbgRecord &DR : Range) + DR.setMarker(this); auto InsertPos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end(); @@ -522,10 +590,10 @@ void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range, Range.end()); } -iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom( - DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here, +iterator_range<simple_ilist<DbgRecord>::iterator> DPMarker::cloneDebugInfoFrom( + DPMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here, bool InsertAtHead) { - DPValue *First = nullptr; + DbgRecord *First = nullptr; // Work out what range of DPValues to clone: normally all the contents of the // "From" marker, optionally we can start from the from_here position down to // end(). @@ -537,8 +605,8 @@ iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom( // Clone each DPValue and insert into StoreDPValues; optionally place them at // the start or the end of the list. auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end(); - for (DPValue &DPV : Range) { - DPValue *New = DPV.clone(); + for (DbgRecord &DR : Range) { + DbgRecord *New = DR.clone(); New->setMarker(this); StoredDPValues.insert(Pos, *New); if (!First) @@ -558,4 +626,3 @@ iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom( } } // end namespace llvm - diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 23a3e72..345b050 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -218,10 +218,9 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, getParent()->flushTerminatorDbgValues(); } -iterator_range<DPValue::self_iterator> -Instruction::cloneDebugInfoFrom(const Instruction *From, - std::optional<DPValue::self_iterator> FromHere, - bool InsertAtHead) { +iterator_range<DbgRecord::self_iterator> Instruction::cloneDebugInfoFrom( + const Instruction *From, std::optional<DbgRecord::self_iterator> FromHere, + bool InsertAtHead) { if (!From->DbgMarker) return DPMarker::getEmptyDPValueRange(); @@ -235,7 +234,8 @@ Instruction::cloneDebugInfoFrom(const Instruction *From, return DbgMarker->cloneDebugInfoFrom(From->DbgMarker, FromHere, InsertAtHead); } -std::optional<DPValue::self_iterator> Instruction::getDbgReinsertionPosition() { +std::optional<DbgRecord::self_iterator> +Instruction::getDbgReinsertionPosition() { // Is there a marker on the next instruction? DPMarker *NextMarker = getParent()->getNextMarker(this); if (!NextMarker) @@ -294,11 +294,11 @@ void Instruction::adoptDbgValues(BasicBlock *BB, BasicBlock::iterator It, void Instruction::dropDbgValues() { if (DbgMarker) - DbgMarker->dropDPValues(); + DbgMarker->dropDbgValues(); } -void Instruction::dropOneDbgValue(DPValue *DPV) { - DbgMarker->dropOneDPValue(DPV); +void Instruction::dropOneDbgValue(DbgRecord *DPV) { + DbgMarker->dropOneDbgValue(DPV); } bool Instruction::comesBefore(const Instruction *Other) const { diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index 994871e..e091ecb 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1925,7 +1925,7 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) { U->replaceUsesOfWith(Def, CurrentReload); // Instructions are added to Def's user list if the attached // debug records use Def. Update those now. - for (auto &DPV : U->getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(U->getDbgValueRange())) DPV.replaceVariableLocationOp(Def, CurrentReload, true); } } diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 47367d0..4d0c221 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -627,7 +627,7 @@ collectDbgVariableIntrinsics(Function &F) { SmallVector<DbgVariableIntrinsic *, 8> Intrinsics; SmallVector<DPValue *> DPValues; for (auto &I : instructions(F)) { - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) DPValues.push_back(&DPV); if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) Intrinsics.push_back(DVI); diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 4af9b22..1428a09 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -643,7 +643,7 @@ void MergeFunctions::filterInstsUnrelatedToPDI( BI != BIE; ++BI) { // Examine DPValues as they happen "before" the instruction. Are they // connected to parameters? - for (DPValue &DPV : BI->getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(BI->getDbgValueRange())) { if (DPV.isDbgValue() || DPV.isDbgAssign()) { ExamineDbgValue(&DPV, PDPVRelated); } else { @@ -686,7 +686,7 @@ void MergeFunctions::filterInstsUnrelatedToPDI( // Collect the set of unrelated instructions and debug records. for (Instruction &I : *GEntryBlock) { - for (auto &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) IsPDIRelated(&DPV, PDPVRelated, PDPVUnrelatedWL); IsPDIRelated(&I, PDIRelated, PDIUnrelatedWL); } diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 4dbb79f..4af455c 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -4484,7 +4484,8 @@ void InstCombinerImpl::tryToSinkInstructionDPValues( // For all instruction/variable pairs needing extra filtering, find the // latest assignment. for (const Instruction *Inst : DupSet) { - for (DPValue &DPV : llvm::reverse(Inst->getDbgValueRange())) { + for (DPValue &DPV : + llvm::reverse(DPValue::filter(Inst->getDbgValueRange()))) { DebugVariable DbgUserVariable = DebugVariable(DPV.getVariable(), DPV.getExpression(), DPV.getDebugLoc()->getInlinedAt()); diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp index 90b544c..95a9527 100644 --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -548,15 +548,15 @@ ADCEChanged AggressiveDeadCodeElimination::removeDeadInstructions() { // attached to this instruction, and drop any for scopes that aren't alive, // like the rest of this loop does. Extending support to assignment tracking // is future work. - for (DPValue &DPV : make_early_inc_range(I.getDbgValueRange())) { + for (DbgRecord &DR : make_early_inc_range(I.getDbgValueRange())) { // Avoid removing a DPV that is linked to instructions because it holds // information about an existing store. - if (DPV.isDbgAssign()) - if (!at::getAssignmentInsts(&DPV).empty()) + if (DPValue *DPV = dyn_cast<DPValue>(&DR); DPV && DPV->isDbgAssign()) + if (!at::getAssignmentInsts(DPV).empty()) continue; - if (AliveScopes.count(DPV.getDebugLoc()->getScope())) + if (AliveScopes.count(DR.getDebugLoc()->getScope())) continue; - I.dropOneDbgValue(&DPV); + I.dropOneDbgValue(&DR); } // Check if the instruction is alive. diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index bb33a5d..5816bf2 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -401,7 +401,7 @@ static bool replaceFoldableUses(Instruction *Cond, Value *ToVal, Changed |= replaceNonLocalUsesWith(Cond, ToVal); for (Instruction &I : reverse(*KnownAtEndOfBB)) { // Replace any debug-info record users of Cond with ToVal. - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) DPV.replaceVariableLocationOp(Cond, ToVal, true); // Reached the Cond whose uses we are trying to replace, so there are no @@ -2082,7 +2082,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, auto CloneAndRemapDbgInfo = [&](Instruction *NewInst, Instruction *From) { auto DPVRange = NewInst->cloneDebugInfoFrom(From); - for (DPValue &DPV : DPVRange) + for (DPValue &DPV : DPValue::filter(DPVRange)) RetargetDPValueIfPossible(&DPV); }; @@ -2117,7 +2117,7 @@ JumpThreadingPass::cloneInstructions(BasicBlock::iterator BI, DPMarker *Marker = RangeBB->getMarker(BE); DPMarker *EndMarker = NewBB->createMarker(NewBB->end()); auto DPVRange = EndMarker->cloneDebugInfoFrom(Marker, std::nullopt); - for (DPValue &DPV : DPVRange) + for (DPValue &DPV : DPValue::filter(DPVRange)) RetargetDPValueIfPossible(&DPV); } diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 6f6d1f9..627c863 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -6712,7 +6712,7 @@ static void DbgGatherSalvagableDVI( SalvageableDVISCEVs.push_back(std::move(NewRec)); return true; }; - for (auto &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { if (DPV.isDbgValue() || DPV.isDbgAssign()) ProcessDbgValue(&DPV); } diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp index 87b0f50..f4f3070 100644 --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp @@ -292,10 +292,11 @@ bool SpeculativeExecutionPass::considerHoistingFromTo( unsigned NotHoistedInstCount = 0; for (const auto &I : FromBlock) { // Make note of any DPValues that need hoisting. - for (DPValue &DPV : I.getDbgValueRange()) + for (DbgRecord &DR : I.getDbgValueRange()) { + DPValue &DPV = cast<DPValue>(DR); if (HasNoUnhoistedInstr(DPV.location_ops())) DPValuesToHoist[DPV.getInstruction()].push_back(&DPV); - + } const InstructionCost Cost = ComputeSpeculationCost(&I, *TTI); if (Cost.isValid() && isSafeToSpeculativelyExecute(&I) && AllPrecedingUsesFromBlockHoisted(&I)) { diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index ec0482a..7fd6759 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -386,7 +386,7 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingBackwardScan(BasicBlock *BB) { SmallVector<DPValue *, 8> ToBeRemoved; SmallDenseSet<DebugVariable> VariableSet; for (auto &I : reverse(*BB)) { - for (DPValue &DPV : reverse(I.getDbgValueRange())) { + for (DPValue &DPV : reverse(DPValue::filter(I.getDbgValueRange()))) { // Skip declare-type records, as the debug intrinsic method only works // on dbg.value intrinsics. if (DPV.getType() == DPValue::LocationType::Declare) { @@ -496,7 +496,7 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { DenseMap<DebugVariable, std::pair<SmallVector<Value *, 4>, DIExpression *>> VariableMap; for (auto &I : *BB) { - for (DPValue &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { if (DPV.getType() == DPValue::LocationType::Declare) continue; DebugVariable Key(DPV.getVariable(), std::nullopt, @@ -545,7 +545,7 @@ static bool DPValuesRemoveUndefDbgAssignsFromEntryBlock(BasicBlock *BB) { // Remove undef dbg.assign intrinsics that are encountered before // any non-undef intrinsics from the entry block. for (auto &I : *BB) { - for (DPValue &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { if (!DPV.isDbgValue() && !DPV.isDbgAssign()) continue; bool IsDbgValueKind = diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 57d3926..8ebcf0c 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1586,7 +1586,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, }; auto UpdateDPValuesOnInst = [&](Instruction &I) -> void { - for (auto &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { // Apply the two updates that dbg.values get: invalid operands, and // variable metadata fixup. if (any_of(DPV.location_ops(), IsInvalidLocation)) { diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index d4d4bf5..78317df 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1710,7 +1710,7 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, }; // Helper-util for updating debug-info records attached to instructions. - auto UpdateDPV = [&](DPValue *DPV) { + auto UpdateDPV = [&](DbgRecord *DPV) { assert(DPV->getDebugLoc() && "Debug Value must have debug loc"); if (NoInlineLineTables) { DPV->setDebugLoc(TheCallDL); @@ -1728,7 +1728,7 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { UpdateInst(*BI); - for (DPValue &DPV : BI->getDbgValueRange()) { + for (DbgRecord &DPV : BI->getDbgValueRange()) { UpdateDPV(&DPV); } } @@ -1829,7 +1829,7 @@ static void fixupAssignments(Function::iterator Start, Function::iterator End) { // attachment or use, replace it with a new version. for (auto BBI = Start; BBI != End; ++BBI) { for (Instruction &I : *BBI) { - for (DPValue &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { if (DPV.isDbgAssign()) DPV.setAssignId(GetNewID(DPV.getAssignID())); } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index e4aa25f..1373f5f 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1911,7 +1911,7 @@ bool llvm::LowerDbgDeclare(Function &F) { for (Instruction &BI : FI) { if (auto *DDI = dyn_cast<DbgDeclareInst>(&BI)) Dbgs.push_back(DDI); - for (DPValue &DPV : BI.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(BI.getDbgValueRange())) { if (DPV.getType() == DPValue::LocationType::Declare) DPVs.push_back(&DPV); } @@ -1996,7 +1996,7 @@ static void insertDPValuesForPHIs(BasicBlock *BB, // Map existing PHI nodes to their DPValues. DenseMap<Value *, DPValue *> DbgValueMap; for (auto &I : *BB) { - for (auto &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { for (Value *V : DPV.location_ops()) if (auto *Loc = dyn_cast_or_null<PHINode>(V)) DbgValueMap.insert({Loc, &DPV}); diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index ec59a07..b12c1b9 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -554,7 +554,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { DbgIntrinsics.insert(makeHash(DII)); // Until RemoveDIs supports dbg.declares in DPValue format, we'll need // to collect DPValues attached to any other debug intrinsics. - for (const DPValue &DPV : DII->getDbgValueRange()) + for (const DPValue &DPV : DPValue::filter(DII->getDbgValueRange())) DbgIntrinsics.insert(makeHash(&DPV)); } else { break; @@ -564,7 +564,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { // Build DPValue hashes for DPValues attached to the terminator, which isn't // considered in the loop above. for (const DPValue &DPV : - OrigPreheader->getTerminator()->getDbgValueRange()) + DPValue::filter(OrigPreheader->getTerminator()->getDbgValueRange())) DbgIntrinsics.insert(makeHash(&DPV)); // Remember the local noalias scope declarations in the header. After the @@ -621,7 +621,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { RemapDPValueRange(M, DbgValueRange, ValueMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); // Erase anything we've seen before. - for (DPValue &DPV : make_early_inc_range(DbgValueRange)) + for (DPValue &DPV : + make_early_inc_range(DPValue::filter(DbgValueRange))) if (DbgIntrinsics.count(makeHash(&DPV))) DPV.eraseFromParent(); } @@ -647,7 +648,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); NextDbgInsts = DPMarker::getEmptyDPValueRange(); // Erase anything we've seen before. - for (DPValue &DPV : make_early_inc_range(Range)) + for (DPValue &DPV : make_early_inc_range(DPValue::filter(Range))) if (DbgIntrinsics.count(makeHash(&DPV))) DPV.eraseFromParent(); } diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 002bc90..a4fdc1f 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -632,8 +632,8 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, // RemoveDIs: do the same as below for DPValues. if (Block->IsNewDbgInfoFormat) { - for (DPValue &DPV : - llvm::make_early_inc_range(I.getDbgValueRange())) { + for (DPValue &DPV : llvm::make_early_inc_range( + DPValue::filter(I.getDbgValueRange()))) { DebugVariable Key(DPV.getVariable(), DPV.getExpression(), DPV.getDebugLoc().get()); if (!DeadDebugSet.insert(Key).second) diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp index 1ffa003..08fdd3b 100644 --- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp +++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp @@ -111,7 +111,8 @@ Instruction *getUntagLocationIfFunctionExit(Instruction &Inst) { void StackInfoBuilder::visit(Instruction &Inst) { // Visit non-intrinsic debug-info records attached to Inst. - for (auto &DPV : Inst.getDbgValueRange()) { + for (DbgRecord &DR : Inst.getDbgValueRange()) { + DPValue &DPV = cast<DPValue>(DR); auto AddIfInteresting = [&](Value *V) { if (auto *AI = dyn_cast_or_null<AllocaInst>(V)) { if (!isInterestingAlloca(*AI)) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 7424fe3..9562d44 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1538,7 +1538,7 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1, if (!I1->hasDbgValues()) return; using CurrentAndEndIt = - std::pair<DPValue::self_iterator, DPValue::self_iterator>; + std::pair<DbgRecord::self_iterator, DbgRecord::self_iterator>; // Vector of {Current, End} iterators. SmallVector<CurrentAndEndIt> Itrs; Itrs.reserve(OtherInsts.size() + 1); @@ -1550,7 +1550,7 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1, // Return true if all Current are identical. auto allIdentical = [](const SmallVector<CurrentAndEndIt> &Itrs) { return all_of(make_first_range(ArrayRef(Itrs).drop_front()), - [&](DPValue::self_iterator I) { + [&](DbgRecord::self_iterator I) { return Itrs[0].first->isIdenticalToWhenDefined(*I); }); }; @@ -1565,18 +1565,18 @@ hoistLockstepIdenticalDPValues(Instruction *TI, Instruction *I1, {Other->getDbgValueRange().begin(), Other->getDbgValueRange().end()}); } - // Iterate in lock-step until any of the DPValue lists are exausted. If - // the lock-step DPValues are identical, hoist all of them to TI. + // Iterate in lock-step until any of the DbgRecord lists are exausted. If + // the lock-step DbgRecord are identical, hoist all of them to TI. // This replicates the dbg.* intrinsic behaviour in // hoistCommonCodeFromSuccessors. while (none_of(Itrs, atEnd)) { bool HoistDPVs = allIdentical(Itrs); for (CurrentAndEndIt &Pair : Itrs) { // Increment Current iterator now as we may be about to move the DPValue. - DPValue &DPV = *Pair.first++; + DbgRecord &DR = *Pair.first++; if (HoistDPVs) { - DPV.removeFromParent(); - TI->getParent()->insertDPValueBefore(&DPV, TI->getIterator()); + DR.removeFromParent(); + TI->getParent()->insertDPValueBefore(&DR, TI->getIterator()); } } } @@ -3207,9 +3207,9 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, // instructions, in the same way that dbg.value intrinsics are dropped at the // end of this block. for (auto &It : make_range(ThenBB->begin(), ThenBB->end())) - for (DPValue &DPV : make_early_inc_range(It.getDbgValueRange())) - if (!DPV.isDbgAssign()) - It.dropOneDbgValue(&DPV); + for (DbgRecord &DR : make_early_inc_range(It.getDbgValueRange())) + if (DPValue *DPV = dyn_cast<DPValue>(&DR); DPV && !DPV->isDbgAssign()) + It.dropOneDbgValue(DPV); BB->splice(BI->getIterator(), ThenBB, ThenBB->begin(), std::prev(ThenBB->end())); @@ -3847,7 +3847,8 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, if (PredBlock->IsNewDbgInfoFormat) { PredBlock->getTerminator()->cloneDebugInfoFrom(BB->getTerminator()); - for (DPValue &DPV : PredBlock->getTerminator()->getDbgValueRange()) { + for (DPValue &DPV : + DPValue::filter(PredBlock->getTerminator()->getDbgValueRange())) { RemapDPValue(M, &DPV, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 93a4c82..6e46469 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -146,7 +146,7 @@ public: Value *mapValue(const Value *V); void remapInstruction(Instruction *I); void remapFunction(Function &F); - void remapDPValue(DPValue &DPV); + void remapDPValue(DbgRecord &DPV); Constant *mapConstant(const Constant *C) { return cast_or_null<Constant>(mapValue(C)); @@ -537,7 +537,8 @@ Value *Mapper::mapValue(const Value *V) { return getVM()[V] = ConstantPointerNull::get(cast<PointerType>(NewTy)); } -void Mapper::remapDPValue(DPValue &V) { +void Mapper::remapDPValue(DbgRecord &DR) { + DPValue &V = cast<DPValue>(DR); // Remap variables and DILocations. auto *MappedVar = mapMetadata(V.getVariable()); auto *MappedDILoc = mapMetadata(V.getDebugLoc()); @@ -1060,8 +1061,8 @@ void Mapper::remapFunction(Function &F) { for (BasicBlock &BB : F) { for (Instruction &I : BB) { remapInstruction(&I); - for (DPValue &DPV : I.getDbgValueRange()) - remapDPValue(DPV); + for (DbgRecord &DR : I.getDbgValueRange()) + remapDPValue(DR); } } } @@ -1232,8 +1233,8 @@ void ValueMapper::remapDPValue(Module *M, DPValue &V) { } void ValueMapper::remapDPValueRange( - Module *M, iterator_range<DPValue::self_iterator> Range) { - for (DPValue &DPV : Range) { + Module *M, iterator_range<DbgRecord::self_iterator> Range) { + for (DPValue &DPV : DPValue::filter(Range)) { remapDPValue(M, DPV); } } diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp index 56e39b8..fa42920 100644 --- a/llvm/tools/llvm-reduce/DeltaManager.cpp +++ b/llvm/tools/llvm-reduce/DeltaManager.cpp @@ -92,7 +92,7 @@ static cl::list<std::string> DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass) \ DELTA_PASS("global-variables", reduceGlobalsDeltaPass) \ DELTA_PASS("di-metadata", reduceDIMetadataDeltaPass) \ - DELTA_PASS("dpvalues", reduceDPValuesDeltaPass) \ + DELTA_PASS("dbg-records", reduceDbgRecordDeltaPass) \ DELTA_PASS("metadata", reduceMetadataDeltaPass) \ DELTA_PASS("named-metadata", reduceNamedMetadataDeltaPass) \ DELTA_PASS("arguments", reduceArgumentsDeltaPass) \ diff --git a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp index 8f5bafd..f0d02a7 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp @@ -29,11 +29,11 @@ static void extractDPValuesFromModule(Oracle &O, ReducerWorkItem &WorkItem) { for (auto &F : M) for (auto &BB : F) for (auto &I : BB) - for (DPValue &DPV : llvm::make_early_inc_range(I.getDbgValueRange())) + for (DbgRecord &DR : llvm::make_early_inc_range(I.getDbgValueRange())) if (!O.shouldKeep()) - DPV.eraseFromParent(); + DR.eraseFromParent(); } -void llvm::reduceDPValuesDeltaPass(TestRunner &Test) { - runDeltaPass(Test, extractDPValuesFromModule, "Reducing DPValues"); +void llvm::reduceDbgRecordDeltaPass(TestRunner &Test) { + runDeltaPass(Test, extractDPValuesFromModule, "Reducing DbgRecords"); } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h index 34ebd27..1d3b8a3 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h +++ b/llvm/tools/llvm-reduce/deltas/ReduceDPValues.h @@ -19,7 +19,7 @@ #include "llvm/IR/DebugProgramInstruction.h" namespace llvm { -void reduceDPValuesDeltaPass(TestRunner &Test); +void reduceDbgRecordDeltaPass(TestRunner &Test); } // namespace llvm #endif diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp index 53b191c..b773bff 100644 --- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp +++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp @@ -163,8 +163,8 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { EXPECT_EQ(Marker2->StoredDPValues.size(), 1u); // Unlink them and try to re-insert them through the basic block. - DPValue *DPV1 = &*Marker1->StoredDPValues.begin(); - DPValue *DPV2 = &*Marker2->StoredDPValues.begin(); + DbgRecord *DPV1 = &*Marker1->StoredDPValues.begin(); + DbgRecord *DPV2 = &*Marker2->StoredDPValues.begin(); DPV1->removeFromParent(); DPV2->removeFromParent(); EXPECT_TRUE(Marker1->StoredDPValues.empty()); @@ -188,8 +188,8 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { EXPECT_EQ(BB.size(), 1u); EXPECT_EQ(Marker2->StoredDPValues.size(), 2u); // They should also be in the correct order. - SmallVector<DPValue *, 2> DPVs; - for (DPValue &DPV : Marker2->getDbgValueRange()) + SmallVector<DbgRecord *, 2> DPVs; + for (DbgRecord &DPV : Marker2->getDbgValueRange()) DPVs.push_back(&DPV); EXPECT_EQ(DPVs[0], DPV1); EXPECT_EQ(DPVs[1], DPV2); @@ -199,13 +199,13 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { EXPECT_EQ(BB.getTrailingDPValues(), nullptr); Instr2->removeFromParent(); EXPECT_TRUE(BB.empty()); - EndMarker = BB.getTrailingDPValues();; + EndMarker = BB.getTrailingDPValues(); ASSERT_NE(EndMarker, nullptr); EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u); // Again, these should arrive in the correct order. DPVs.clear(); - for (DPValue &DPV : EndMarker->getDbgValueRange()) + for (DbgRecord &DPV : EndMarker->getDbgValueRange()) DPVs.push_back(&DPV); EXPECT_EQ(DPVs[0], DPV1); EXPECT_EQ(DPVs[1], DPV2); @@ -226,7 +226,7 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { // Remove Instr1: now the DPValues will fall down again, Instr1->removeFromParent(); - EndMarker = BB.getTrailingDPValues();; + EndMarker = BB.getTrailingDPValues(); EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u); // Inserting a terminator, however it's intended, should dislodge the @@ -391,7 +391,7 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { ASSERT_FALSE(BInst->DbgMarker); ASSERT_TRUE(CInst->DbgMarker); ASSERT_EQ(CInst->DbgMarker->StoredDPValues.size(), 1u); - DPValue *DPV1 = &*CInst->DbgMarker->StoredDPValues.begin(); + DbgRecord *DPV1 = &*CInst->DbgMarker->StoredDPValues.begin(); ASSERT_TRUE(DPV1); EXPECT_FALSE(BInst->hasDbgValues()); @@ -399,7 +399,7 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { // tested in DPMarker test. auto Range1 = BInst->cloneDebugInfoFrom(CInst); EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 1u); - DPValue *DPV2 = &*BInst->DbgMarker->StoredDPValues.begin(); + DbgRecord *DPV2 = &*BInst->DbgMarker->StoredDPValues.begin(); EXPECT_EQ(std::distance(Range1.begin(), Range1.end()), 1u); EXPECT_EQ(&*Range1.begin(), DPV2); EXPECT_NE(DPV1, DPV2); @@ -531,15 +531,15 @@ protected: Branch = &*Last; CInst = &*Dest; - DPVA = &*BInst->DbgMarker->StoredDPValues.begin(); - DPVB = &*Branch->DbgMarker->StoredDPValues.begin(); - DPVConst = &*CInst->DbgMarker->StoredDPValues.begin(); + DPVA = cast<DPValue>(&*BInst->DbgMarker->StoredDPValues.begin()); + DPVB = cast<DPValue>(&*Branch->DbgMarker->StoredDPValues.begin()); + DPVConst = cast<DPValue>(&*CInst->DbgMarker->StoredDPValues.begin()); } void TearDown() override { UseNewDbgInfoFormat = false; } bool InstContainsDPValue(Instruction *I, DPValue *DPV) { - for (DPValue &D : I->getDbgValueRange()) { + for (DbgRecord &D : I->getDbgValueRange()) { if (&D == DPV) { // Confirm too that the links between the records are correct. EXPECT_EQ(DPV->Marker, I->DbgMarker); @@ -551,8 +551,8 @@ protected: } bool CheckDPVOrder(Instruction *I, SmallVector<DPValue *> CheckVals) { - SmallVector<DPValue *> Vals; - for (DPValue &D : I->getDbgValueRange()) + SmallVector<DbgRecord *> Vals; + for (DbgRecord &D : I->getDbgValueRange()) Vals.push_back(&D); EXPECT_EQ(Vals.size(), CheckVals.size()); @@ -1389,8 +1389,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) { ASSERT_TRUE(BInst->hasDbgValues()); EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 2u); SmallVector<DPValue *, 2> DPValues; - for (DPValue &DPV : BInst->getDbgValueRange()) - DPValues.push_back(&DPV); + for (DbgRecord &DPV : BInst->getDbgValueRange()) + DPValues.push_back(cast<DPValue>(&DPV)); EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0)); Value *SecondDPVValue = DPValues[1]->getVariableLocationOp(0); @@ -1459,8 +1459,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) { ASSERT_TRUE(BInst->hasDbgValues()); EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 1u); SmallVector<DPValue *, 2> DPValues; - for (DPValue &DPV : BInst->getDbgValueRange()) - DPValues.push_back(&DPV); + for (DbgRecord &DPV : BInst->getDbgValueRange()) + DPValues.push_back(cast<DPValue>(&DPV)); EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0)); // No trailing DPValues in the entry block now. diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp index be8f590..65db93e 100644 --- a/llvm/unittests/IR/DebugInfoTest.cpp +++ b/llvm/unittests/IR/DebugInfoTest.cpp @@ -955,7 +955,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) { FirstInst->DbgMarker->insertDPValue(DPV1, false); FirstInst->DbgMarker->insertDPValue(DPV2, true); unsigned int ItCount = 0; - for (DPValue &Item : FirstInst->DbgMarker->getDbgValueRange()) { + for (DbgRecord &Item : FirstInst->DbgMarker->getDbgValueRange()) { EXPECT_TRUE((&Item == DPV2 && ItCount == 0) || (&Item == DPV1 && ItCount == 1)); EXPECT_EQ(Item.getMarker(), FirstInst->DbgMarker); @@ -968,17 +968,18 @@ TEST(MetadataTest, ConvertDbgToDPValue) { ItCount = 0; // Check these things store the same information; but that they're not the same // objects. - for (DPValue &Item : RetInst->DbgMarker->getDbgValueRange()) { + for (DPValue &Item : + DPValue::filter(RetInst->DbgMarker->getDbgValueRange())) { EXPECT_TRUE((Item.getRawLocation() == DPV2->getRawLocation() && ItCount == 0) || (Item.getRawLocation() == DPV1->getRawLocation() && ItCount == 1)); - + EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker); EXPECT_NE(&Item, DPV1); EXPECT_NE(&Item, DPV2); ++ItCount; } - RetInst->DbgMarker->dropDPValues(); + RetInst->DbgMarker->dropDbgValues(); EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 0u); // Try cloning one single DPValue. @@ -987,10 +988,12 @@ TEST(MetadataTest, ConvertDbgToDPValue) { EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 1u); // The second DPValue should have been cloned; it should have the same values // as DPV1. - EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.begin()->getRawLocation(), + EXPECT_EQ(cast<DPValue>(RetInst->DbgMarker->StoredDPValues.begin()) + ->getRawLocation(), DPV1->getRawLocation()); // We should be able to drop individual DPValues. - RetInst->DbgMarker->dropOneDPValue(&*RetInst->DbgMarker->StoredDPValues.begin()); + RetInst->DbgMarker->dropOneDbgValue( + &*RetInst->DbgMarker->StoredDPValues.begin()); // "Aborb" a DPMarker: this means pretend that the instruction it's attached // to is disappearing so it needs to be transferred into "this" marker. @@ -998,7 +1001,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) { EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 2u); // Should be the DPV1 and DPV2 objects. ItCount = 0; - for (DPValue &Item : RetInst->DbgMarker->getDbgValueRange()) { + for (DbgRecord &Item : RetInst->DbgMarker->getDbgValueRange()) { EXPECT_TRUE((&Item == DPV2 && ItCount == 0) || (&Item == DPV1 && ItCount == 1)); EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker); @@ -1019,7 +1022,7 @@ TEST(MetadataTest, ConvertDbgToDPValue) { EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u); // Test again that it's those two DPValues, DPV1 and DPV2. ItCount = 0; - for (DPValue &Item : EndMarker->getDbgValueRange()) { + for (DbgRecord &Item : EndMarker->getDbgValueRange()) { EXPECT_TRUE((&Item == DPV2 && ItCount == 0) || (&Item == DPV1 && ItCount == 1)); EXPECT_EQ(Item.getMarker(), EndMarker); @@ -1110,13 +1113,15 @@ TEST(MetadataTest, DPValueConversionRoutines) { EXPECT_EQ(SecondInst, SecondInst->DbgMarker->MarkedInstr); EXPECT_EQ(FirstInst->DbgMarker->StoredDPValues.size(), 1u); - DPValue *DPV1 = &*FirstInst->DbgMarker->getDbgValueRange().begin(); + DPValue *DPV1 = + cast<DPValue>(&*FirstInst->DbgMarker->getDbgValueRange().begin()); EXPECT_EQ(DPV1->getMarker(), FirstInst->DbgMarker); // Should point at %a, an argument. EXPECT_TRUE(isa<Argument>(DPV1->getVariableLocationOp(0))); EXPECT_EQ(SecondInst->DbgMarker->StoredDPValues.size(), 1u); - DPValue *DPV2 = &*SecondInst->DbgMarker->getDbgValueRange().begin(); + DPValue *DPV2 = + cast<DPValue>(&*SecondInst->DbgMarker->getDbgValueRange().begin()); EXPECT_EQ(DPV2->getMarker(), SecondInst->DbgMarker); // Should point at FirstInst. EXPECT_EQ(DPV2->getVariableLocationOp(0), FirstInst); diff --git a/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp index 760b6b6..6146719 100644 --- a/llvm/unittests/IR/ValueTest.cpp +++ b/llvm/unittests/IR/ValueTest.cpp @@ -379,8 +379,8 @@ TEST(ValueTest, replaceUsesOutsideBlockDPValue) { EXPECT_TRUE(Branch->hasDbgValues()); EXPECT_TRUE(Ret->hasDbgValues()); - DPValue *DPV1 = &*Branch->getDbgValueRange().begin(); - DPValue *DPV2 = &*Ret->getDbgValueRange().begin(); + DPValue *DPV1 = cast<DPValue>(&*Branch->getDbgValueRange().begin()); + DPValue *DPV2 = cast<DPValue>(&*Ret->getDbgValueRange().begin()); A->replaceUsesOutsideBlock(B, Entry); // These users are in Entry so shouldn't be changed. |