diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index a72b68d867f36e..ed25cb96ae9645 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -130,10 +130,10 @@ class BasicBlock final : public Value, // Basic blocks are data objects also 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 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// 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 Pos); + std::optional Pos); private: void setParent(Function *parent); @@ -194,8 +194,9 @@ class BasicBlock final : public Value, // Basic blocks are data objects also friend void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, bool Preserve); - friend iterator_range Instruction::cloneDebugInfoFrom( - const Instruction *From, std::optional FromHere, + friend iterator_range + Instruction::cloneDebugInfoFrom( + const Instruction *From, std::optional FromHere, bool InsertAtHead); /// Creates a new BasicBlock. diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h index 36ef77f9505bc1..5b0620de61586b 100644 --- a/llvm/include/llvm/IR/DebugInfo.h +++ b/llvm/include/llvm/IR/DebugInfo.h @@ -109,6 +109,8 @@ class DebugInfoFinder { 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 8230070343e0c1..873303143e4983 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -47,10 +47,12 @@ #ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H #define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H -#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/iterator.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/Support/Casting.h" namespace llvm { @@ -63,38 +65,92 @@ 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, 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() +/// both print methods +class DbgRecord : public ilist_node { +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; + Kind RecordKind; ///< Subclass discriminator. public: - void deleteInstr(); + DbgRecord(Kind RecordKind, DebugLoc DL) + : DbgLoc(DL), RecordKind(RecordKind) {} + + /// Methods requiring subclass implementations. + ///@{ + void deleteRecord(); + DbgRecord *clone() const; + void print(raw_ostream &O, bool IsForDebug = false) const; + void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) 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 BasicBlock *getParent() const; BasicBlock *getParent(); - void dump() const; + void removeFromParent(); void eraseFromParent(); - using self_iterator = simple_ilist::iterator; - using const_self_iterator = simple_ilist::const_iterator; + DebugLoc getDebugLoc() const { return DbgLoc; } + void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } + + void dump() const; - enum class LocationType { + using self_iterator = simple_ilist::iterator; + using const_self_iterator = simple_ilist::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; + +public: + enum class LocationType : uint8_t { Declare, Value, @@ -104,11 +160,17 @@ class DPValue : public ilist_node, private DebugValueUser { /// 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; + +public: /// Create a new DPValue representing the intrinsic \p DVI, for example the /// assignment represented by a dbg.value. DPValue(const DbgVariableIntrinsic *DVI); @@ -197,9 +259,6 @@ class DPValue : public ilist_node, private DebugValueUser { bool isAddressOfVariable() const { return Type != LocationType::Value; } LocationType getType() const { return Type; } - DebugLoc getDebugLoc() const { return DbgLoc; } - void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } - void setKillLocation(); bool isKillLocation() const; @@ -230,40 +289,37 @@ class DPValue : public ilist_node, private DebugValueUser { /// \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; } - 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; - 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::iterator> R) { + return map_range( + make_filter_range(R, [](DbgRecord &E) { return isa(E); }), + [](DbgRecord &E) { return std::ref(cast(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(... @@ -283,12 +339,11 @@ class DPMarker { /// 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 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 StoredDPValues; bool empty() const { return StoredDPValues.empty(); } const BasicBlock *getParent() const; @@ -308,34 +363,34 @@ class DPMarker { void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; /// Produce a range over all the DPValues in this Marker. - iterator_range::iterator> getDbgValueRange(); + iterator_range::iterator> getDbgValueRange(); /// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead /// is true, place them before existing DPValues, otherwise afterwards. void absorbDebugValues(DPMarker &Src, bool InsertAtHead); /// 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 Range, + void absorbDebugValues(iterator_range 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); /// 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::iterator> + iterator_range::iterator> cloneDebugInfoFrom(DPMarker *From, - std::optional::iterator> FromHere, + std::optional::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 *DPE); /// 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 @@ -345,8 +400,10 @@ class DPMarker { /// DPValue in that range, but they should be using the Official (TM) API for /// that. static DPMarker EmptyDPMarker; - static iterator_range::iterator> getEmptyDPValueRange(){ - return make_range(EmptyDPMarker.StoredDPValues.end(), EmptyDPMarker.StoredDPValues.end()); + static iterator_range::iterator> + getEmptyDPValueRange() { + return make_range(EmptyDPMarker.StoredDPValues.end(), + EmptyDPMarker.StoredDPValues.end()); } }; diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index 0211b5076131ce..736c774ca3122f 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -35,6 +35,7 @@ class MDNode; class Module; struct AAMDNodes; class DPMarker; +class DbgRecord; template <> struct ilist_alloc_traits { static inline void deleteNode(Instruction *V); @@ -70,18 +71,18 @@ class Instruction : public User, /// \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::iterator> cloneDebugInfoFrom( + iterator_range::iterator> cloneDebugInfoFrom( const Instruction *From, - std::optional::iterator> FromHere = std::nullopt, + std::optional::iterator> FromHere = std::nullopt, bool InsertAtHead = false); /// Return a range over the DPValues attached to this instruction. - iterator_range::iterator> getDbgValueRange() const; + iterator_range::iterator> getDbgValueRange() const; /// 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::iterator> getDbgReinsertionPosition(); + std::optional::iterator> getDbgReinsertionPosition(); /// Returns true if any DPValues are attached to this instruction. bool hasDbgValues() const; @@ -90,7 +91,7 @@ class Instruction : public User, 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/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index 4498423c4c460d..bb5d479b26ce49 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -44,6 +44,7 @@ class Module; class ModuleSlotTracker; class raw_ostream; class DPValue; +class DbgRecord; template class StringMapEntry; template class StringMapEntryStorage; class Type; diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index e1f2796d97ceb1..dd183bc04f0c24 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; -using DPValueIterator = simple_ilist::iterator; +using DbgRecordIterator = simple_ilist::iterator; /// This is a class that can be implemented by clients to remap types when /// cloning constants and instructions. @@ -180,7 +181,7 @@ class ValueMapper { void remapInstruction(Instruction &I); void remapDPValue(Module *M, DPValue &V); - void remapDPValueRange(Module *M, iterator_range Range); + void remapDPValueRange(Module *M, iterator_range 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 Range, +inline void RemapDPValueRange(Module *M, + iterator_range Range, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = nullptr, ValueMaterializer *Materializer = nullptr) { diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 5bd4c6b067d796..9e310d85110a89 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -8400,7 +8400,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; } @@ -8512,7 +8512,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/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 6d80b282a1ed21..2c731eca49f06f 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(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 78ebd2d33459a7..2e26e212768085 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1231,7 +1231,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(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 99bb3d875d4fa5..9cdf21fe803acf 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 278cdfce411050..1dc779719220e8 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -861,7 +861,7 @@ class SlotTracker : public AbstractSlotTrackerStorage { 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 @@ -1130,16 +1130,20 @@ 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 &DPV : I.getDbgValueRange()) + processDbgRecordMetadata(DPV); processInstructionMetadata(I); } } } -void SlotTracker::processDPValueMetadata(const DPValue &DPV) { - CreateMetadataSlot(DPV.getVariable()); - CreateMetadataSlot(DPV.getDebugLoc()); +void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) { + if (const DPValue *DPV = dyn_cast(&DR)) { + CreateMetadataSlot(DPV->getVariable()); + CreateMetadataSlot(DPV->getDebugLoc()); + } else { + llvm_unreachable("unsupported DbgRecord kind"); + } } void SlotTracker::processInstructionMetadata(const Instruction &I) { @@ -2663,6 +2667,7 @@ class AssemblyWriter { 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 &Shuffle); void printUseLists(const Function *F); @@ -4557,8 +4562,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"; } @@ -4568,6 +4573,13 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) { return; } +void AssemblyWriter::printDbgRecord(const DbgRecord &DR) { + if (auto *DPV = dyn_cast(&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. @@ -5116,7 +5128,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 03b74b0480f071..643e9c87b87ce8 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 DPVals; + SmallVector DPVals; for (Instruction &I : make_early_inc_range(InstList)) { assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?"); if (DbgVariableIntrinsic *DVI = dyn_cast(&I)) { @@ -89,7 +89,7 @@ void BasicBlock::convertToNewDbgValues() { createMarker(&I); DPMarker *Marker = I.DbgMarker; - for (DPValue *DPV : DPVals) + for (DbgRecord *DPV : DPVals) Marker->insertDPValue(DPV, false); DPVals.clear(); @@ -108,9 +108,13 @@ void BasicBlock::convertFromNewDbgValues() { continue; DPMarker &Marker = *Inst.DbgMarker; - for (DPValue &DPV : Marker.getDbgValueRange()) - InstList.insert(Inst.getIterator(), - DPV.createDebugIntrinsic(getModule(), nullptr)); + for (DbgRecord &DPR : Marker.getDbgValueRange()) { + if (auto *DPV = dyn_cast(&DPR)) + InstList.insert(Inst.getIterator(), + DPV->createDebugIntrinsic(getModule(), nullptr)); + else + llvm_unreachable("unsupported entity kind"); + } Marker.eraseFromParent(); }; @@ -164,9 +168,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. @@ -1074,7 +1078,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); @@ -1085,7 +1089,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 c6dc42e8ac88c6..d2a44b89772c9f 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -89,10 +89,11 @@ static void findDbgIntrinsics(SmallVectorImpl &Result, Value *V, if (!DPValues) continue; DIArgList *DI = cast(AL); - for (DPValue *DPV : DI->getAllDPValueUsers()) + for (DPValue *DPV : DI->getAllDPValueUsers()) { if (Type == DPValue::LocationType::Any || DPV->getType() == Type) if (EncounteredDPValues.insert(DPV).second) DPValues->push_back(DPV); + } } } } @@ -198,8 +199,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) { @@ -214,6 +215,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(DPR)); +} + void DebugInfoFinder::processType(DIType *DT) { if (!addType(DT)) return; diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 7b709a2de0335f..1074953c005f39 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()) { + : DbgRecord(ValueKind, DVI->getDebugLoc()), + DebugValueUser(DVI->getRawLocation()), Variable(DVI->getVariable()), + Expression(DVI->getExpression()) { switch (DVI->getIntrinsicID()) { case Intrinsic::dbg_value: Type = LocationType::Value; @@ -30,16 +31,45 @@ 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()) {} + : DbgRecord(ValueKind, DPV.getDebugLoc()), + DebugValueUser(DPV.getRawLocation()), Type(DPV.getType()), + Variable(DPV.getVariable()), Expression(DPV.getExpression()) {} DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, const DILocation *DI, LocationType Type) - : DebugValueUser(Location), Variable(DV), Expression(Expr), DbgLoc(DI), - Type(Type) {} + : DbgRecord(ValueKind, DI), DebugValueUser(Location), Type(Type), + Variable(DV), Expression(Expr) {} -void DPValue::deleteInstr() { delete this; } +void DbgRecord::deleteRecord() { + switch (RecordKind) { + case ValueKind: + delete cast(this); + break; + default: + llvm_unreachable("unsupported record kind"); + } +} + +void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { + switch (RecordKind) { + case ValueKind: + cast(this)->print(O, IsForDebug); + break; + default: + llvm_unreachable("unsupported record kind"); + }; +} + +void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, + bool IsForDebug) const { + switch (RecordKind) { + case ValueKind: + cast(this)->print(O, MST, IsForDebug); + break; + default: + llvm_unreachable("unsupported record kind"); + }; +} iterator_range DPValue::location_ops() const { auto *MD = getRawLocation(); @@ -180,6 +210,15 @@ std::optional DPValue::getFragmentSizeInBits() const { return getVariable()->getSizeInBits(); } +DbgRecord *DbgRecord::clone() const { + switch (RecordKind) { + case ValueKind: + return cast(this)->clone(); + default: + llvm_unreachable("unsupported record kind"); + }; +} + DPValue *DPValue::clone() const { return new DPValue(*this); } DbgVariableIntrinsic * @@ -225,27 +264,31 @@ void DPValue::handleChangedLocation(Metadata *NewLocation) { resetDebugValue(NewLocation); } -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(); } @@ -255,19 +298,19 @@ const LLVMContext &DPValue::getContext() const { // DPValues. DPMarker DPMarker::EmptyDPMarker; -void DPMarker::dropDPValues() { +void DPMarker::dropDbgValues() { while (!StoredDPValues.empty()) { auto It = StoredDPValues.begin(); - DPValue *DPV = &*It; + DbgRecord *DPE = &*It; StoredDPValues.erase(It); - DPV->deleteInstr(); + DPE->deleteRecord(); } } -void DPMarker::dropOneDPValue(DPValue *DPV) { - assert(DPV->getMarker() == this); - StoredDPValues.erase(DPV->getIterator()); - DPV->deleteInstr(); +void DPMarker::dropOneDbgValue(DbgRecord *DPE) { + assert(DPE->getMarker() == this); + StoredDPValues.erase(DPE->getIterator()); + DPE->deleteRecord(); } const BasicBlock *DPMarker::getParent() const { @@ -306,24 +349,24 @@ void DPMarker::removeFromParent() { void DPMarker::eraseFromParent() { if (MarkedInstr) removeFromParent(); - dropDPValues(); + dropDbgValues(); delete this; } -iterator_range DPMarker::getDbgValueRange() { +iterator_range DPMarker::getDbgValueRange() { return make_range(StoredDPValues.begin(), StoredDPValues.end()); } -void DPValue::removeFromParent() { +void DbgRecord::removeFromParent() { getMarker()->StoredDPValues.erase(getIterator()); } -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); @@ -331,16 +374,16 @@ void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) { 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 Range, +void DPMarker::absorbDebugValues(iterator_range Range, DPMarker &Src, bool InsertAtHead) { - for (DPValue &DPV : Range) - DPV.setMarker(this); + for (DbgRecord &DPE : Range) + DPE.setMarker(this); auto InsertPos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end(); @@ -349,10 +392,10 @@ void DPMarker::absorbDebugValues(iterator_range Range, Range.end()); } -iterator_range::iterator> DPMarker::cloneDebugInfoFrom( - DPMarker *From, std::optional::iterator> from_here, +iterator_range::iterator> DPMarker::cloneDebugInfoFrom( + DPMarker *From, std::optional::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(). @@ -364,8 +407,8 @@ iterator_range::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 &DPE : Range) { + DbgRecord *New = DPE.clone(); New->setMarker(this); StoredDPValues.insert(Pos, *New); if (!First) @@ -385,4 +428,3 @@ iterator_range::iterator> DPMarker::cloneDebugInfoFrom( } } // end namespace llvm - diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 717e33f1857b8a..6e4fc5160a8cd4 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -226,10 +226,9 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, getParent()->flushTerminatorDbgValues(); } -iterator_range -Instruction::cloneDebugInfoFrom(const Instruction *From, - std::optional FromHere, - bool InsertAtHead) { +iterator_range Instruction::cloneDebugInfoFrom( + const Instruction *From, std::optional FromHere, + bool InsertAtHead) { if (!From->DbgMarker) return DPMarker::getEmptyDPValueRange(); @@ -243,8 +242,7 @@ Instruction::cloneDebugInfoFrom(const Instruction *From, return DbgMarker->cloneDebugInfoFrom(From->DbgMarker, FromHere, InsertAtHead); } -iterator_range -Instruction::getDbgValueRange() const { +iterator_range Instruction::getDbgValueRange() const { BasicBlock *Parent = const_cast(getParent()); assert(Parent && "Instruction must be inserted to have DPValues"); (void)Parent; @@ -255,7 +253,8 @@ Instruction::getDbgValueRange() const { return DbgMarker->getDbgValueRange(); } -std::optional Instruction::getDbgReinsertionPosition() { +std::optional +Instruction::getDbgReinsertionPosition() { // Is there a marker on the next instruction? DPMarker *NextMarker = getParent()->getNextMarker(this); if (!NextMarker) @@ -272,11 +271,11 @@ bool Instruction::hasDbgValues() const { return !getDbgValueRange().empty(); } 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 89a1ad2243c849..1ea7e46be143b1 100644 --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -1931,7 +1931,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 7758b52abc2046..61d58f31c082ad 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -730,7 +730,7 @@ collectDbgVariableIntrinsics(Function &F) { SmallVector Intrinsics; SmallVector 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(&I)) Intrinsics.push_back(DVI); diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp index 9af275a9f4e204..ba51e012c46f63 100644 --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -548,10 +548,10 @@ 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())) { - if (AliveScopes.count(DPV.getDebugLoc()->getScope())) + for (DbgRecord &DPE : make_early_inc_range(I.getDbgValueRange())) { + if (AliveScopes.count(DPE.getDebugLoc()->getScope())) continue; - I.dropOneDbgValue(&DPV); + I.dropOneDbgValue(&DPE); } // Check if the instruction is alive. diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 8603c5cf9c022c..3a5f95564729a8 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 @@ -2081,7 +2081,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); }; @@ -2116,7 +2116,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/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index 8b5a6d61841209..7800653b54de44 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 ToBeRemoved; SmallDenseSet 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) { @@ -489,7 +489,7 @@ static bool DPValuesRemoveRedundantDbgInstrsUsingForwardScan(BasicBlock *BB) { DenseMap, 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, diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index f5abed0dd51786..d7797669d294d9 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. // FIXME: support dbg.assign form of DPValues. diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 39d5f6e53c1de4..8120bbc848dcd5 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); } } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index c76cc9db16d7e7..56d0674ff94546 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1925,7 +1925,7 @@ bool llvm::LowerDbgDeclare(Function &F) { for (Instruction &BI : FI) { if (auto *DDI = dyn_cast(&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); } @@ -2010,7 +2010,7 @@ static void insertDPValuesForPHIs(BasicBlock *BB, // Map existing PHI nodes to their DPValues. DenseMap 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(V)) DbgValueMap.insert({Loc, &DPV}); diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 504f4430dc2ca6..99bb685ffe410d 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 @@ -617,7 +617,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(); } @@ -641,7 +642,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); NextDbgInst = std::nullopt; // 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 59485126b280ab..ecdb60f35e2c73 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/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 61d891d65346bd..9ba04395b80c3d 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3771,7 +3771,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 71d0f09e47713b..9850c7a3e05bbe 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -1219,8 +1219,8 @@ void ValueMapper::remapDPValue(Module *M, DPValue &V) { } void ValueMapper::remapDPValueRange( - Module *M, iterator_range Range) { - for (DPValue &DPV : Range) { + Module *M, iterator_range Range) { + for (DPValue &DPV : DPValue::filter(Range)) { remapDPValue(M, DPV); } } diff --git a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp index fb4847fc0a8262..a09595642d944f 100644 --- a/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp +++ b/llvm/unittests/IR/BasicBlockDbgInfoTest.cpp @@ -168,8 +168,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()); @@ -193,8 +193,8 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) { EXPECT_EQ(BB.size(), 1u); EXPECT_EQ(Marker2->StoredDPValues.size(), 2u); // They should also be in the correct order. - SmallVector DPVs; - for (DPValue &DPV : Marker2->getDbgValueRange()) + SmallVector DPVs; + for (DbgRecord &DPV : Marker2->getDbgValueRange()) DPVs.push_back(&DPV); EXPECT_EQ(DPVs[0], DPV1); EXPECT_EQ(DPVs[1], DPV2); @@ -204,13 +204,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); @@ -232,7 +232,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 @@ -397,7 +397,7 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) { ASSERT_TRUE(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_EQ(BInst->DbgMarker->StoredDPValues.size(), 0u); @@ -405,7 +405,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); @@ -537,15 +537,15 @@ class DbgSpliceTest : public ::testing::Test { Branch = &*Last; CInst = &*Dest; - DPVA = &*BInst->DbgMarker->StoredDPValues.begin(); - DPVB = &*Branch->DbgMarker->StoredDPValues.begin(); - DPVConst = &*CInst->DbgMarker->StoredDPValues.begin(); + DPVA = cast(&*BInst->DbgMarker->StoredDPValues.begin()); + DPVB = cast(&*Branch->DbgMarker->StoredDPValues.begin()); + DPVConst = cast(&*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); @@ -557,8 +557,8 @@ class DbgSpliceTest : public ::testing::Test { } bool CheckDPVOrder(Instruction *I, SmallVector CheckVals) { - SmallVector Vals; - for (DPValue &D : I->getDbgValueRange()) + SmallVector Vals; + for (DbgRecord &D : I->getDbgValueRange()) Vals.push_back(&D); EXPECT_EQ(Vals.size(), CheckVals.size()); @@ -1395,8 +1395,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty1) { ASSERT_TRUE(BInst->hasDbgValues()); EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 2u); SmallVector DPValues; - for (DPValue &DPV : BInst->getDbgValueRange()) - DPValues.push_back(&DPV); + for (DbgRecord &DPV : BInst->getDbgValueRange()) + DPValues.push_back(cast(&DPV)); EXPECT_EQ(DPValues[0]->getVariableLocationOp(0), F.getArg(0)); Value *SecondDPVValue = DPValues[1]->getVariableLocationOp(0); @@ -1465,8 +1465,8 @@ TEST(BasicBlockDbgInfoTest, DbgSpliceToEmpty2) { ASSERT_TRUE(BInst->hasDbgValues()); EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 1u); SmallVector DPValues; - for (DPValue &DPV : BInst->getDbgValueRange()) - DPValues.push_back(&DPV); + for (DbgRecord &DPV : BInst->getDbgValueRange()) + DPValues.push_back(cast(&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 be8f590a27eb4d..65db93e537f7df 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(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(&*FirstInst->DbgMarker->getDbgValueRange().begin()); EXPECT_EQ(DPV1->getMarker(), FirstInst->DbgMarker); // Should point at %a, an argument. EXPECT_TRUE(isa(DPV1->getVariableLocationOp(0))); EXPECT_EQ(SecondInst->DbgMarker->StoredDPValues.size(), 1u); - DPValue *DPV2 = &*SecondInst->DbgMarker->getDbgValueRange().begin(); + DPValue *DPV2 = + cast(&*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 760b6b603c6a53..6146719bb29627 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(&*Branch->getDbgValueRange().begin()); + DPValue *DPV2 = cast(&*Ret->getDbgValueRange().begin()); A->replaceUsesOutsideBlock(B, Entry); // These users are in Entry so shouldn't be changed.