From 356f5b472d423e23b2d2588594b9846001932a1d Mon Sep 17 00:00:00 2001 From: OCHyams Date: Fri, 12 Jan 2024 16:16:26 +0000 Subject: [PATCH 1/8] [RemoveDIs][NFC] Introduce DbgRecord base class [1/3] --- llvm/include/llvm/IR/BasicBlock.h | 11 +- llvm/include/llvm/IR/DebugInfo.h | 2 + .../include/llvm/IR/DebugProgramInstruction.h | 202 +++++++++++------- llvm/include/llvm/IR/Instruction.h | 11 +- llvm/include/llvm/IR/Metadata.h | 1 + .../llvm/Transforms/Utils/ValueMapper.h | 10 +- llvm/lib/CodeGen/CodeGenPrepare.cpp | 5 +- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 4 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 3 +- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 5 +- llvm/lib/IR/AsmWriter.cpp | 31 ++- llvm/lib/IR/BasicBlock.cpp | 22 +- llvm/lib/IR/DebugInfo.cpp | 11 +- llvm/lib/IR/DebugProgramInstruction.cpp | 135 +++++++----- llvm/lib/IR/Instruction.cpp | 16 +- llvm/lib/Transforms/Coroutines/CoroFrame.cpp | 2 +- llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 2 +- llvm/lib/Transforms/Scalar/ADCE.cpp | 10 +- llvm/lib/Transforms/Scalar/JumpThreading.cpp | 6 +- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 4 +- llvm/lib/Transforms/Utils/CodeExtractor.cpp | 2 +- llvm/lib/Transforms/Utils/InlineFunction.cpp | 4 +- llvm/lib/Transforms/Utils/Local.cpp | 4 +- .../Transforms/Utils/LoopRotationUtils.cpp | 9 +- llvm/lib/Transforms/Utils/LoopUtils.cpp | 4 +- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 3 +- llvm/lib/Transforms/Utils/ValueMapper.cpp | 4 +- llvm/unittests/IR/BasicBlockDbgInfoTest.cpp | 38 ++-- llvm/unittests/IR/DebugInfoTest.cpp | 25 ++- llvm/unittests/IR/ValueTest.cpp | 4 +- 30 files changed, 360 insertions(+), 230 deletions(-) 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 b2f079393400b7..022df64880aebd 100644 --- a/llvm/include/llvm/IR/DebugInfo.h +++ b/llvm/include/llvm/IR/DebugInfo.h @@ -111,6 +111,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 594f613aa8ed8b..1c1dd31d9c3c80 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -50,9 +50,11 @@ #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/IR/Instruction.h" #include "llvm/IR/SymbolTableListTraits.h" +#include "llvm/Support/Casting.h" namespace llvm { @@ -66,43 +68,99 @@ 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; - DIExpression *AddressExpression; + 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 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()); } - using self_iterator = simple_ilist::iterator; - using const_self_iterator = simple_ilist::const_iterator; + DPValue *getNextNode() { return &*std::next(getIterator()); } + DPValue *getPrevNode() { return &*std::prev(getIterator()); } + + DebugLoc getDebugLoc() const { return DbgLoc; } + void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } + + void dump() const; + + 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; +}; - enum class LocationType { +/// 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, Assign, @@ -113,11 +171,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); @@ -235,9 +299,6 @@ class DPValue : public ilist_node, private DebugValueUser { 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; @@ -314,43 +375,37 @@ class DPValue : public ilist_node, private DebugValueUser { /// \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::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(... @@ -370,12 +425,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; @@ -395,8 +449,8 @@ 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::const_iterator> + iterator_range::iterator> getDbgValueRange(); + iterator_range::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 +458,31 @@ class DPMarker { /// 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); /// Insert a DPValue prior to a DPValue contained within this marker. - void insertDPValue(DPValue *New, DPValue *InsertBefore); + void insertDPValue(DbgRecord *New, DPValue *InsertBefore); /// Insert a DPValue after a DPValue contained within this marker. - void insertDPValueAfter(DPValue *New, DPValue *InsertAfter); + void insertDPValueAfter(DbgRecord *New, DPValue *InsertAfter); /// Clone all DPMarkers from \p From into this marker. There are numerous /// options to customise the source/destination, due to gnarliness, see class /// comment. /// \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 @@ -438,8 +492,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 cd814e21be1ae1..c1a5a3d6c60941 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); @@ -72,20 +73,20 @@ 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 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::iterator> getDbgReinsertionPosition(); + std::optional::iterator> getDbgReinsertionPosition(); /// Returns true if any DPValues are attached to this instruction. bool hasDbgValues() const; @@ -100,7 +101,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 da6744fdd09166..715d0fa6e028d2 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 32a25b49b4e4b0..4036f18dbc6794 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/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index f8756527da87f6..5651498dd3f5aa 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 b2782cbdc73e86..2bdf48643edc3b 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(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 ad5a3302230c86..9b5ab4267b80e9 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 d3c64a57f7fdfd..d96f0469fbbcd8 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -862,7 +862,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 @@ -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 &DPV : I.getDbgValueRange()) + processDbgRecordMetadata(DPV); processInstructionMetadata(I); } } } void SlotTracker::processDPValueMetadata(const DPValue &DPV) { - CreateMetadataSlot(DPV.getVariable()); - CreateMetadataSlot(DPV.getDebugLoc()); - if (DPV.isDbgAssign()) { - CreateMetadataSlot(DPV.getAssignID()); + if (const DPValue *DPV = dyn_cast(&DR)) { + CreateMetadataSlot(DPV->getVariable()); + CreateMetadataSlot(DPV->getDebugLoc()); + if (DPV.isDbgAssign()) { + CreateMetadataSlot(DPV.getAssignID()); + } else { + llvm_unreachable("unsupported DbgRecord kind"); } } @@ -2673,6 +2676,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); @@ -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(&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 bf02eba9fb448d..4e36c258d5e947 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)) { @@ -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 &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(); }; @@ -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 eaa5cb36a49c14..17c7e8e787350e 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -125,10 +125,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); + } } } } @@ -240,8 +241,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 +257,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 a2640d59242ac2..a72c6408766045 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -14,9 +14,9 @@ namespace llvm { DPValue::DPValue(const DbgVariableIntrinsic *DVI) - : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), - Variable(DVI->getVariable()), Expression(DVI->getExpression()), - DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) { + : DbgRecord(ValueKind, DVI->getDebugLoc()), + DebugValueUser(DVI->getRawLocation(), nullptr, nullptr), Variable(DVI->getVariable()), + Expression(DVI->getExpression()) { switch (DVI->getIntrinsicID()) { case Intrinsic::dbg_value: Type = LocationType::Value; @@ -40,24 +40,45 @@ 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, nullptr, nullptr}), 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), 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) {} +void DbgRecord::deleteRecord() { + switch (RecordKind) { + case ValueKind: + delete cast(this); + break; + default: + llvm_unreachable("unsupported record kind"); + } +} -void DPValue::deleteInstr() { delete this; } +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"); + }; +} DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV, DIExpression *Expr, const DILocation *DI) { @@ -255,6 +276,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 * @@ -342,27 +372,31 @@ const Instruction *DPValue::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(); } @@ -401,19 +435,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 *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 { @@ -462,11 +496,15 @@ 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()); +} +iterator_range +DPMarker::getDbgValueRange() const { return make_range(StoredDPValues.begin(), StoredDPValues.end()); } iterator_range @@ -474,17 +512,17 @@ 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); @@ -504,16 +542,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 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(); @@ -522,10 +560,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(). @@ -537,8 +575,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) @@ -558,4 +596,3 @@ iterator_range::iterator> DPMarker::cloneDebugInfoFrom( } } // end namespace llvm - diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 23a3e72da51d44..345b050b7077a9 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 -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(); @@ -235,7 +234,8 @@ Instruction::cloneDebugInfoFrom(const Instruction *From, return DbgMarker->cloneDebugInfoFrom(From->DbgMarker, FromHere, InsertAtHead); } -std::optional Instruction::getDbgReinsertionPosition() { +std::optional +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 e69c718f0ae3ac..c3c4de4278b9cc 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 aed4cd027d0338..e802b5789b4dcb 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -627,7 +627,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 90b544c8922623..ab6513884d646e 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 (DR.isDbgAssign()) + if (!at::getAssignmentInsts(&DR).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 bb33a5da288ce9..5816bf2a22598d 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/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp index ec0482ac2cdeb4..4eee3387647be2 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) { @@ -496,7 +496,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 57d3926515993f..8ebcf0c04fd5a9 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 d4d4bf5ebdf36e..f888cc336d937d 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 e4aa25f7ac6ad3..1373f5f7f4490c 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(&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 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 ec59a077302037..b12c1b9bb9d5e4 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 002bc90c9b5677..a4fdc1f8c12e50 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 7424fe31945dc7..b7099d8947a909 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -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 93a4c829df06cb..37585446bfd37c 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -1232,8 +1232,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 53b191c6883841..b773bffd7a03fc 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 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); @@ -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 @@ 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); @@ -551,8 +551,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()); @@ -1389,8 +1389,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); @@ -1459,8 +1459,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. From d92252bef5008301e58391f462578365ec629a89 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Mon, 19 Feb 2024 17:13:23 +0000 Subject: [PATCH 2/8] rebase fallout --- .../include/llvm/IR/DebugProgramInstruction.h | 30 +++++--- llvm/include/llvm/IR/Instruction.h | 2 +- .../CodeGen/AssignmentTrackingAnalysis.cpp | 24 +++--- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 +- llvm/lib/IR/AsmWriter.cpp | 10 +-- llvm/lib/IR/DebugInfo.cpp | 4 +- llvm/lib/IR/DebugProgramInstruction.cpp | 76 ++++++++++++------- llvm/lib/Transforms/IPO/MergeFunctions.cpp | 4 +- .../InstCombine/InstructionCombining.cpp | 3 +- llvm/lib/Transforms/Scalar/ADCE.cpp | 4 +- .../Transforms/Scalar/LoopStrengthReduce.cpp | 2 +- .../Scalar/SpeculativeExecution.cpp | 5 +- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 2 +- llvm/lib/Transforms/Utils/InlineFunction.cpp | 2 +- .../Transforms/Utils/MemoryTaggingSupport.cpp | 3 +- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 20 ++--- llvm/lib/Transforms/Utils/ValueMapper.cpp | 9 ++- 17 files changed, 117 insertions(+), 85 deletions(-) diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index 1c1dd31d9c3c80..a66efdf0dc0fca 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -77,8 +77,10 @@ class raw_ostream; /// 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() +/// deleteRecord +/// clone +/// isIdenticalToWhenDefined +/// isEquivalentTo /// both print methods class DbgRecord : public ilist_node { public: @@ -101,6 +103,8 @@ class DbgRecord : public ilist_node { 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; } @@ -129,11 +133,12 @@ class DbgRecord : public ilist_node { void removeFromParent(); void eraseFromParent(); - DPValue *getNextNode() { return &*std::next(getIterator()); } - DPValue *getPrevNode() { return &*std::prev(getIterator()); } - - 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); } @@ -180,6 +185,7 @@ class DPValue : public DbgRecord, protected DebugValueUser { DILocalVariable *Variable; DIExpression *Expression; + DIExpression *AddressExpression; public: /// Create a new DPValue representing the intrinsic \p DVI, for example the @@ -331,12 +337,12 @@ class DPValue : public DbgRecord, protected DebugValueUser { /// is described. std::optional 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, @@ -464,9 +470,9 @@ class DPMarker { /// \p InsertAtHead is true, at the start. void insertDPValue(DbgRecord *New, bool InsertAtHead); /// Insert a DPValue prior to a DPValue contained within this marker. - void insertDPValue(DbgRecord *New, DPValue *InsertBefore); + void insertDPValue(DbgRecord *New, DbgRecord *InsertBefore); /// Insert a DPValue after a DPValue contained within this marker. - void insertDPValueAfter(DbgRecord *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. @@ -513,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::iterator> +inline iterator_range::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 c1a5a3d6c60941..c0e159a342d5b5 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -41,7 +41,7 @@ template <> struct ilist_alloc_traits { static inline void deleteNode(Instruction *V); }; -iterator_range::iterator> getDbgValueRange(DPMarker *); +iterator_range::iterator> getDbgValueRange(DPMarker *); class Instruction : public User, public ilist_node_with_parent struct llvm::DenseMapInfo { } }; -using VarLocInsertPt = PointerUnion; +using VarLocInsertPt = PointerUnion; namespace std { template <> struct hash { @@ -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(P.first)) + if (isa(P.first)) continue; const Instruction *I = cast(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,7 @@ class MemLocFragmentFill { void process(BasicBlock &BB, VarFragMap &LiveSet) { BBInsertBeforeMap[&BB].clear(); for (auto &I : BB) { - for (auto &DPV : I.getDbgValueRange()) { + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) { if (const auto *Locs = FnVarLocs->getWedge(&DPV)) { for (const VarLocInfo &Loc : *Locs) { addDef(Loc, &DPV, *I.getParent(), LiveSet); @@ -1492,7 +1492,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 +1507,7 @@ VarLocInsertPt getNextNode(const Instruction *Inst) { VarLocInsertPt getNextNode(VarLocInsertPt InsertPt) { if (isa(InsertPt)) return getNextNode(cast(InsertPt)); - return getNextNode(cast(InsertPt)); + return getNextNode(cast(InsertPt)); } DbgAssignIntrinsic *CastToDbgAssign(DbgVariableIntrinsic *DVI) { @@ -1915,7 +1915,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 +2172,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(&I)) { ProcessDbgRecord(DII, InstDeclares); @@ -2462,7 +2462,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(&I); @@ -2564,7 +2564,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 +2629,7 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB, } }; - for (DPValue &DPV : I.getDbgValueRange()) + for (DPValue &DPV : DPValue::filter(I.getDbgValueRange())) HandleLocsForWedge(&DPV); HandleLocsForWedge(&I); } @@ -2715,7 +2715,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/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 311dd9d9739a6d..cd012068993100 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3274,7 +3274,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/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index d96f0469fbbcd8..251485a403fee6 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1131,19 +1131,19 @@ void SlotTracker::processFunctionMetadata(const Function &F) { processGlobalObjectMetadata(F); for (auto &BB : F) { for (auto &I : BB) { - for (const DbgRecord &DPV : I.getDbgValueRange()) - processDbgRecordMetadata(DPV); + for (const DbgRecord &DR : I.getDbgValueRange()) + processDbgRecordMetadata(DR); processInstructionMetadata(I); } } } -void SlotTracker::processDPValueMetadata(const DPValue &DPV) { +void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) { if (const DPValue *DPV = dyn_cast(&DR)) { CreateMetadataSlot(DPV->getVariable()); CreateMetadataSlot(DPV->getDebugLoc()); - if (DPV.isDbgAssign()) { - CreateMetadataSlot(DPV.getAssignID()); + if (DPV->isDbgAssign()) + CreateMetadataSlot(DPV->getAssignID()); } else { llvm_unreachable("unsupported DbgRecord kind"); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 17c7e8e787350e..8b82d19b4aa894 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1827,7 +1827,7 @@ void at::deleteAll(Function *F) { SmallVector 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(&I)) @@ -2251,7 +2251,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 a72c6408766045..f09a2a9f7ce00c 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -15,8 +15,9 @@ namespace llvm { DPValue::DPValue(const DbgVariableIntrinsic *DVI) : DbgRecord(ValueKind, DVI->getDebugLoc()), - DebugValueUser(DVI->getRawLocation(), nullptr, nullptr), Variable(DVI->getVariable()), - Expression(DVI->getExpression()) { + DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), + Variable(DVI->getVariable()), Expression(DVI->getExpression()), + AddressExpression(nullptr) { switch (DVI->getIntrinsicID()) { case Intrinsic::dbg_value: Type = LocationType::Value; @@ -40,14 +41,15 @@ DPValue::DPValue(const DbgVariableIntrinsic *DVI) } DPValue::DPValue(const DPValue &DPV) - : DbgRecord(ValueKind, DPV.getDebugLoc()), - DebugValueUser({DPV.DebugValues, nullptr, nullptr}), Type(DPV.getType()), - Variable(DPV.getVariable()), Expression(DPV.getExpression()), AddressExpression(DPV.AddressExpression) {} + : 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) - : DbgRecord(ValueKind, DI), DebugValueUser(Location), Type(Type), - Variable(DV), Expression(Expr) {} + : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}), + Type(Type), Variable(DV), Expression(Expr) {} void DbgRecord::deleteRecord() { switch (RecordKind) { @@ -65,7 +67,7 @@ void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { cast(this)->print(O, IsForDebug); break; default: - llvm_unreachable("unsupported record kind"); + llvm_unreachable("unsupported DbgRecord kind"); }; } @@ -76,7 +78,31 @@ void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, cast(this)->print(O, MST, IsForDebug); break; default: - llvm_unreachable("unsupported record kind"); + llvm_unreachable("unsupported DbgRecord kind"); + }; +} + +bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { + if (RecordKind != R.RecordKind) + return false; + switch (RecordKind) { + case ValueKind: + cast(this)->isIdenticalToWhenDefined(*cast(&R)); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); + }; +} + +bool DbgRecord::isEquivalentTo(const DbgRecord &R) const { + if (RecordKind != R.RecordKind) + return false; + switch (RecordKind) { + case ValueKind: + cast(this)->isEquivalentTo(*cast(&R)); + break; + default: + llvm_unreachable("unsupported DbgRecord kind"); }; } @@ -368,7 +394,7 @@ bool DPValue::isKillAddress() const { return !Addr || isa(Addr); } -const Instruction *DPValue::getInstruction() const { +const Instruction *DbgRecord::getInstruction() const { return Marker->MarkedInstr; } @@ -400,31 +426,31 @@ 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); } @@ -503,11 +529,7 @@ void DPMarker::eraseFromParent() { iterator_range DPMarker::getDbgValueRange() { return make_range(StoredDPValues.begin(), StoredDPValues.end()); } -iterator_range -DPMarker::getDbgValueRange() const { - return make_range(StoredDPValues.begin(), StoredDPValues.end()); -} -iterator_range +iterator_range DPMarker::getDbgValueRange() const { return make_range(StoredDPValues.begin(), StoredDPValues.end()); } @@ -527,13 +549,13 @@ void DPMarker::insertDPValue(DbgRecord *New, bool InsertAtHead) { 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); diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 4af9b2206745e2..1428a09040a34b 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 7450f39c1e7641..87b52e420f4825 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 ab6513884d646e..95a9527126c112 100644 --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -551,8 +551,8 @@ ADCEChanged AggressiveDeadCodeElimination::removeDeadInstructions() { 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 (DR.isDbgAssign()) - if (!at::getAssignmentInsts(&DR).empty()) + if (DPValue *DPV = dyn_cast(&DR); DPV && DPV->isDbgAssign()) + if (!at::getAssignmentInsts(DPV).empty()) continue; if (AliveScopes.count(DR.getDebugLoc()->getScope())) continue; diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 6f6d1f9c760689..627c863f7091fc 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 87b0f50860e1b5..f4f3070d11c7bb 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(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 4eee3387647be2..7fd6759a61fbae 100644 --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -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/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index f888cc336d937d..78317df8a9caec 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -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/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp index 1ffa003db7d569..08fdd3b75ffcbd 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(DR); auto AddIfInteresting = [&](Value *V) { if (auto *AI = dyn_cast_or_null(V)) { if (!isInterestingAlloca(*AI)) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index b7099d8947a909..9562d44400448b 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; + std::pair; // Vector of {Current, End} iterators. SmallVector 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 &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(&DR); DPV && !DPV->isDbgAssign()) + It.dropOneDbgValue(DPV); BB->splice(BI->getIterator(), ThenBB, ThenBB->begin(), std::prev(ThenBB->end())); diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 37585446bfd37c..6e46469f5a601e 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -146,7 +146,7 @@ class Mapper { 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(mapValue(C)); @@ -537,7 +537,8 @@ Value *Mapper::mapValue(const Value *V) { return getVM()[V] = ConstantPointerNull::get(cast(NewTy)); } -void Mapper::remapDPValue(DPValue &V) { +void Mapper::remapDPValue(DbgRecord &DR) { + DPValue &V = cast(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); } } } From e3334474cb01a24b569f5ae8dceb5803359fc538 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 20 Feb 2024 11:01:15 +0000 Subject: [PATCH 3/8] rebase fallout: add missing ctor --- llvm/lib/IR/DebugProgramInstruction.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index f09a2a9f7ce00c..9438bd211cdf79 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -51,6 +51,14 @@ DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, : 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) + : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), + Variable(Variable), Expression(Expression), + AddressExpression(AddressExpression), Type(LocationType::Assign) {} + void DbgRecord::deleteRecord() { switch (RecordKind) { case ValueKind: From f3ade8ba3516aeb718aeacdba52ad22045fa8709 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 20 Feb 2024 11:06:34 +0000 Subject: [PATCH 4/8] Add FIXME --- llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp index 2f51540d4d9312..7b66a851db2527 100644 --- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp +++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp @@ -829,7 +829,11 @@ class MemLocFragmentFill { void process(BasicBlock &BB, VarFragMap &LiveSet) { BBInsertBeforeMap[&BB].clear(); for (auto &I : BB) { - for (DPValue &DPV : DPValue::filter(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(DR); if (const auto *Locs = FnVarLocs->getWedge(&DPV)) { for (const VarLocInfo &Loc : *Locs) { addDef(Loc, &DPV, *I.getParent(), LiveSet); From c410dcd8f6fde59b8419a634a8e216671e506f6f Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 20 Feb 2024 11:11:48 +0000 Subject: [PATCH 5/8] fix warnings --- llvm/lib/IR/DebugProgramInstruction.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 9438bd211cdf79..58a0da284c2cee 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -56,8 +56,8 @@ DPValue::DPValue(Metadata *Value, DILocalVariable *Variable, Metadata *Address, DIExpression *AddressExpression, const DILocation *DI) : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), - Variable(Variable), Expression(Expression), - AddressExpression(AddressExpression), Type(LocationType::Assign) {} + Type(LocationType::Assign), Variable(Variable), Expression(Expression), + AddressExpression(AddressExpression) {} void DbgRecord::deleteRecord() { switch (RecordKind) { @@ -95,7 +95,7 @@ bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { return false; switch (RecordKind) { case ValueKind: - cast(this)->isIdenticalToWhenDefined(*cast(&R)); + return cast(this)->isIdenticalToWhenDefined(*cast(&R)); break; default: llvm_unreachable("unsupported DbgRecord kind"); @@ -107,7 +107,7 @@ bool DbgRecord::isEquivalentTo(const DbgRecord &R) const { return false; switch (RecordKind) { case ValueKind: - cast(this)->isEquivalentTo(*cast(&R)); + return cast(this)->isEquivalentTo(*cast(&R)); break; default: llvm_unreachable("unsupported DbgRecord kind"); From 4931e65666c0778d70a9297f975ab30e8fc0b68e Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 20 Feb 2024 11:34:40 +0000 Subject: [PATCH 6/8] address feedback --- .../include/llvm/IR/DebugProgramInstruction.h | 5 ++-- llvm/lib/IR/BasicBlock.cpp | 6 ++--- llvm/lib/IR/DebugInfo.cpp | 3 +-- llvm/lib/IR/DebugProgramInstruction.cpp | 24 +++++++++---------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index a66efdf0dc0fca..0976dd87881f5f 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -97,7 +97,8 @@ class DbgRecord : public ilist_node { DbgRecord(Kind RecordKind, DebugLoc DL) : DbgLoc(DL), RecordKind(RecordKind) {} - /// Methods requiring subclass implementations. + /// Methods that dispatch to subclass implementations. These need to be + /// manually updated when a new subclass is added. ///@{ void deleteRecord(); DbgRecord *clone() const; @@ -488,7 +489,7 @@ class DPMarker { /// 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 debug intrinsic from a block. - void dropOneDbgValue(DbgRecord *DPE); + 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 diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index 4e36c258d5e947..0680754444f17f 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -107,12 +107,12 @@ void BasicBlock::convertFromNewDbgValues() { continue; DPMarker &Marker = *Inst.DbgMarker; - for (DbgRecord &DPR : Marker.getDbgValueRange()) { - if (auto *DPV = dyn_cast(&DPR)) + for (DbgRecord &DR : Marker.getDbgValueRange()) { + if (auto *DPV = dyn_cast(&DR)) InstList.insert(Inst.getIterator(), DPV->createDebugIntrinsic(getModule(), nullptr)); else - llvm_unreachable("unsupported entity kind"); + llvm_unreachable("unsupported DbgRecord kind"); } Marker.eraseFromParent(); diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 8b82d19b4aa894..a4fec601908503 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -125,11 +125,10 @@ 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); - } } } } diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 58a0da284c2cee..9568b2257e61a0 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -65,7 +65,7 @@ void DbgRecord::deleteRecord() { delete cast(this); break; default: - llvm_unreachable("unsupported record kind"); + llvm_unreachable("unsupported DbgRecord kind"); } } @@ -315,7 +315,7 @@ DbgRecord *DbgRecord::clone() const { case ValueKind: return cast(this)->clone(); default: - llvm_unreachable("unsupported record kind"); + llvm_unreachable("unsupported DbgRecord kind"); }; } @@ -472,16 +472,16 @@ DPMarker DPMarker::EmptyDPMarker; void DPMarker::dropDbgValues() { while (!StoredDPValues.empty()) { auto It = StoredDPValues.begin(); - DbgRecord *DPE = &*It; + DbgRecord *DR = &*It; StoredDPValues.erase(It); - DPE->deleteRecord(); + DR->deleteRecord(); } } -void DPMarker::dropOneDbgValue(DbgRecord *DPE) { - assert(DPE->getMarker() == this); - StoredDPValues.erase(DPE->getIterator()); - DPE->deleteRecord(); +void DPMarker::dropOneDbgValue(DbgRecord *DR) { + assert(DR->getMarker() == this); + StoredDPValues.erase(DR->getIterator()); + DR->deleteRecord(); } const BasicBlock *DPMarker::getParent() const { @@ -580,8 +580,8 @@ void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) { void DPMarker::absorbDebugValues(iterator_range Range, DPMarker &Src, bool InsertAtHead) { - for (DbgRecord &DPE : Range) - DPE.setMarker(this); + for (DbgRecord &DR : Range) + DR.setMarker(this); auto InsertPos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end(); @@ -605,8 +605,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 (DbgRecord &DPE : Range) { - DbgRecord *New = DPE.clone(); + for (DbgRecord &DR : Range) { + DbgRecord *New = DR.clone(); New->setMarker(this); StoredDPValues.insert(Pos, *New); if (!First) From c22d33894ce280e995989280ae880844e25f8e9b Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 20 Feb 2024 15:05:22 +0000 Subject: [PATCH 7/8] llvm-reduce changes --- llvm/tools/llvm-reduce/DeltaManager.cpp | 2 +- llvm/tools/llvm-reduce/deltas/ReduceDPValues.cpp | 8 ++++---- llvm/tools/llvm-reduce/deltas/ReduceDPValues.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp index 56e39b8f9316fa..fa42920ee91296 100644 --- a/llvm/tools/llvm-reduce/DeltaManager.cpp +++ b/llvm/tools/llvm-reduce/DeltaManager.cpp @@ -92,7 +92,7 @@ static cl::list 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 8f5bafd950e34b..f0d02a78ac6acf 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 34ebd271b4f24e..1d3b8a35daa34b 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 From ad0dfa5f50c122937ecfc01dbfaebee115814fb0 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Tue, 20 Feb 2024 15:26:25 +0000 Subject: [PATCH 8/8] remove include and fwd decl --- llvm/include/llvm/IR/DebugProgramInstruction.h | 1 - llvm/include/llvm/IR/Metadata.h | 1 - 2 files changed, 2 deletions(-) diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h index 0976dd87881f5f..1fa6b6f519640e 100644 --- a/llvm/include/llvm/IR/DebugProgramInstruction.h +++ b/llvm/include/llvm/IR/DebugProgramInstruction.h @@ -50,7 +50,6 @@ #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/IR/Instruction.h" #include "llvm/IR/SymbolTableListTraits.h" diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index 715d0fa6e028d2..da6744fdd09166 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -44,7 +44,6 @@ class Module; class ModuleSlotTracker; class raw_ostream; class DPValue; -class DbgRecord; template class StringMapEntry; template class StringMapEntryStorage; class Type;