1*0fca6ea1SDimitry Andric //===-- llvm/DebugProgramInstruction.h - Stream of debug info ---*- C++ -*-===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric //
95f757f3fSDimitry Andric // Data structures for storing variable assignment information in LLVM. In the
105f757f3fSDimitry Andric // dbg.value design, a dbg.value intrinsic specifies the position in a block
115f757f3fSDimitry Andric // a source variable take on an LLVM Value:
125f757f3fSDimitry Andric //
135f757f3fSDimitry Andric // %foo = add i32 1, %0
145f757f3fSDimitry Andric // dbg.value(metadata i32 %foo, ...)
155f757f3fSDimitry Andric // %bar = void call @ext(%foo);
165f757f3fSDimitry Andric //
175f757f3fSDimitry Andric // and all information is stored in the Value / Metadata hierachy defined
18*0fca6ea1SDimitry Andric // elsewhere in LLVM. In the "DbgRecord" design, each instruction /may/ have a
19*0fca6ea1SDimitry Andric // connection with a DbgMarker, which identifies a position immediately before
20*0fca6ea1SDimitry Andric // the instruction, and each DbgMarker /may/ then have connections to DbgRecords
21*0fca6ea1SDimitry Andric // which record the variable assignment information. To illustrate:
225f757f3fSDimitry Andric //
235f757f3fSDimitry Andric // %foo = add i32 1, %0
24*0fca6ea1SDimitry Andric // ; foo->DebugMarker == nullptr
255f757f3fSDimitry Andric // ;; There are no variable assignments / debug records "in front" of
26*0fca6ea1SDimitry Andric // ;; the instruction for %foo, therefore it has no DebugMarker.
275f757f3fSDimitry Andric // %bar = void call @ext(%foo)
28*0fca6ea1SDimitry Andric // ; bar->DebugMarker = {
29*0fca6ea1SDimitry Andric // ; StoredDbgRecords = {
30*0fca6ea1SDimitry Andric // ; DbgVariableRecord(metadata i32 %foo, ...)
315f757f3fSDimitry Andric // ; }
325f757f3fSDimitry Andric // ; }
335f757f3fSDimitry Andric // ;; There is a debug-info record in front of the %bar instruction,
34*0fca6ea1SDimitry Andric // ;; thus it points at a DbgMarker object. That DbgMarker contains a
35*0fca6ea1SDimitry Andric // ;; DbgVariableRecord in its ilist, storing the equivalent information
36*0fca6ea1SDimitry Andric // ;; to the dbg.value above: the Value, DILocalVariable, etc.
375f757f3fSDimitry Andric //
385f757f3fSDimitry Andric // This structure separates the two concerns of the position of the debug-info
395f757f3fSDimitry Andric // in the function, and the Value that it refers to. It also creates a new
405f757f3fSDimitry Andric // "place" in-between the Value / Metadata hierachy where we can customise
415f757f3fSDimitry Andric // storage and allocation techniques to better suite debug-info workloads.
425f757f3fSDimitry Andric // NB: as of the initial prototype, none of that has actually been attempted
435f757f3fSDimitry Andric // yet.
445f757f3fSDimitry Andric //
455f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
465f757f3fSDimitry Andric
475f757f3fSDimitry Andric #ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
485f757f3fSDimitry Andric #define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
495f757f3fSDimitry Andric
505f757f3fSDimitry Andric #include "llvm/ADT/ilist.h"
517a6dacacSDimitry Andric #include "llvm/ADT/ilist_node.h"
525f757f3fSDimitry Andric #include "llvm/ADT/iterator.h"
53*0fca6ea1SDimitry Andric #include "llvm/IR/DbgVariableFragmentInfo.h"
545f757f3fSDimitry Andric #include "llvm/IR/DebugLoc.h"
557a6dacacSDimitry Andric #include "llvm/IR/Instruction.h"
567a6dacacSDimitry Andric #include "llvm/IR/SymbolTableListTraits.h"
57*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h"
585f757f3fSDimitry Andric
595f757f3fSDimitry Andric namespace llvm {
605f757f3fSDimitry Andric
615f757f3fSDimitry Andric class Instruction;
625f757f3fSDimitry Andric class BasicBlock;
635f757f3fSDimitry Andric class MDNode;
645f757f3fSDimitry Andric class Module;
655f757f3fSDimitry Andric class DbgVariableIntrinsic;
66*0fca6ea1SDimitry Andric class DbgInfoIntrinsic;
67*0fca6ea1SDimitry Andric class DbgLabelInst;
687a6dacacSDimitry Andric class DIAssignID;
69*0fca6ea1SDimitry Andric class DbgMarker;
70*0fca6ea1SDimitry Andric class DbgVariableRecord;
715f757f3fSDimitry Andric class raw_ostream;
725f757f3fSDimitry Andric
73*0fca6ea1SDimitry Andric /// A typed tracking MDNode reference that does not require a definition for its
74*0fca6ea1SDimitry Andric /// parameter type. Necessary to avoid including DebugInfoMetadata.h, which has
75*0fca6ea1SDimitry Andric /// a significant impact on compile times if included in this file.
76*0fca6ea1SDimitry Andric template <typename T> class DbgRecordParamRef {
77*0fca6ea1SDimitry Andric TrackingMDNodeRef Ref;
785f757f3fSDimitry Andric
795f757f3fSDimitry Andric public:
80*0fca6ea1SDimitry Andric public:
81*0fca6ea1SDimitry Andric DbgRecordParamRef() = default;
825f757f3fSDimitry Andric
83*0fca6ea1SDimitry Andric /// Construct from the templated type.
84*0fca6ea1SDimitry Andric DbgRecordParamRef(const T *Param);
85*0fca6ea1SDimitry Andric
86*0fca6ea1SDimitry Andric /// Construct from an \a MDNode.
87*0fca6ea1SDimitry Andric ///
88*0fca6ea1SDimitry Andric /// Note: if \c Param does not have the template type, a verifier check will
89*0fca6ea1SDimitry Andric /// fail, and accessors will crash. However, construction from other nodes
90*0fca6ea1SDimitry Andric /// is supported in order to handle forward references when reading textual
91*0fca6ea1SDimitry Andric /// IR.
92*0fca6ea1SDimitry Andric explicit DbgRecordParamRef(const MDNode *Param);
93*0fca6ea1SDimitry Andric
94*0fca6ea1SDimitry Andric /// Get the underlying type.
95*0fca6ea1SDimitry Andric ///
96*0fca6ea1SDimitry Andric /// \pre !*this or \c isa<T>(getAsMDNode()).
97*0fca6ea1SDimitry Andric /// @{
98*0fca6ea1SDimitry Andric T *get() const;
99*0fca6ea1SDimitry Andric operator T *() const { return get(); }
100*0fca6ea1SDimitry Andric T *operator->() const { return get(); }
101*0fca6ea1SDimitry Andric T &operator*() const { return *get(); }
102*0fca6ea1SDimitry Andric /// @}
103*0fca6ea1SDimitry Andric
104*0fca6ea1SDimitry Andric /// Check for null.
105*0fca6ea1SDimitry Andric ///
106*0fca6ea1SDimitry Andric /// Check for null in a way that is safe with broken debug info.
107*0fca6ea1SDimitry Andric explicit operator bool() const { return Ref; }
108*0fca6ea1SDimitry Andric
109*0fca6ea1SDimitry Andric /// Return \c this as a \a MDNode.
getAsMDNode()110*0fca6ea1SDimitry Andric MDNode *getAsMDNode() const { return Ref; }
111*0fca6ea1SDimitry Andric
112*0fca6ea1SDimitry Andric bool operator==(const DbgRecordParamRef &Other) const {
113*0fca6ea1SDimitry Andric return Ref == Other.Ref;
114*0fca6ea1SDimitry Andric }
115*0fca6ea1SDimitry Andric bool operator!=(const DbgRecordParamRef &Other) const {
116*0fca6ea1SDimitry Andric return Ref != Other.Ref;
117*0fca6ea1SDimitry Andric }
118*0fca6ea1SDimitry Andric };
119*0fca6ea1SDimitry Andric
120*0fca6ea1SDimitry Andric /// Base class for non-instruction debug metadata records that have positions
121*0fca6ea1SDimitry Andric /// within IR. Features various methods copied across from the Instruction
122*0fca6ea1SDimitry Andric /// class to aid ease-of-use. DbgRecords should always be linked into a
123*0fca6ea1SDimitry Andric /// DbgMarker's StoredDbgRecords list. The marker connects a DbgRecord back to
124*0fca6ea1SDimitry Andric /// its position in the BasicBlock.
125*0fca6ea1SDimitry Andric ///
126*0fca6ea1SDimitry Andric /// We need a discriminator for dyn/isa casts. In order to avoid paying for a
127*0fca6ea1SDimitry Andric /// vtable for "virtual" functions too, subclasses must add a new discriminator
128*0fca6ea1SDimitry Andric /// value (RecordKind) and cases to a few functions in the base class:
129*0fca6ea1SDimitry Andric /// deleteRecord
130*0fca6ea1SDimitry Andric /// clone
131*0fca6ea1SDimitry Andric /// isIdenticalToWhenDefined
132*0fca6ea1SDimitry Andric /// both print methods
133*0fca6ea1SDimitry Andric /// createDebugIntrinsic
134*0fca6ea1SDimitry Andric class DbgRecord : public ilist_node<DbgRecord> {
135*0fca6ea1SDimitry Andric public:
136*0fca6ea1SDimitry Andric /// Marker that this DbgRecord is linked into.
137*0fca6ea1SDimitry Andric DbgMarker *Marker = nullptr;
138*0fca6ea1SDimitry Andric /// Subclass discriminator.
139*0fca6ea1SDimitry Andric enum Kind : uint8_t { ValueKind, LabelKind };
140*0fca6ea1SDimitry Andric
141*0fca6ea1SDimitry Andric protected:
142*0fca6ea1SDimitry Andric DebugLoc DbgLoc;
143*0fca6ea1SDimitry Andric Kind RecordKind; ///< Subclass discriminator.
144*0fca6ea1SDimitry Andric
145*0fca6ea1SDimitry Andric public:
DbgRecord(Kind RecordKind,DebugLoc DL)146*0fca6ea1SDimitry Andric DbgRecord(Kind RecordKind, DebugLoc DL)
147*0fca6ea1SDimitry Andric : DbgLoc(DL), RecordKind(RecordKind) {}
148*0fca6ea1SDimitry Andric
149*0fca6ea1SDimitry Andric /// Methods that dispatch to subclass implementations. These need to be
150*0fca6ea1SDimitry Andric /// manually updated when a new subclass is added.
151*0fca6ea1SDimitry Andric ///@{
152*0fca6ea1SDimitry Andric void deleteRecord();
153*0fca6ea1SDimitry Andric DbgRecord *clone() const;
154*0fca6ea1SDimitry Andric void print(raw_ostream &O, bool IsForDebug = false) const;
155*0fca6ea1SDimitry Andric void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const;
156*0fca6ea1SDimitry Andric bool isIdenticalToWhenDefined(const DbgRecord &R) const;
157*0fca6ea1SDimitry Andric /// Convert this DbgRecord back into an appropriate llvm.dbg.* intrinsic.
158*0fca6ea1SDimitry Andric /// \p InsertBefore Optional position to insert this intrinsic.
159*0fca6ea1SDimitry Andric /// \returns A new llvm.dbg.* intrinsic representiung this DbgRecord.
160*0fca6ea1SDimitry Andric DbgInfoIntrinsic *createDebugIntrinsic(Module *M,
161*0fca6ea1SDimitry Andric Instruction *InsertBefore) const;
162*0fca6ea1SDimitry Andric ///@}
163*0fca6ea1SDimitry Andric
164*0fca6ea1SDimitry Andric /// Same as isIdenticalToWhenDefined but checks DebugLoc too.
165*0fca6ea1SDimitry Andric bool isEquivalentTo(const DbgRecord &R) const;
166*0fca6ea1SDimitry Andric
getRecordKind()167*0fca6ea1SDimitry Andric Kind getRecordKind() const { return RecordKind; }
168*0fca6ea1SDimitry Andric
setMarker(DbgMarker * M)169*0fca6ea1SDimitry Andric void setMarker(DbgMarker *M) { Marker = M; }
170*0fca6ea1SDimitry Andric
getMarker()171*0fca6ea1SDimitry Andric DbgMarker *getMarker() { return Marker; }
getMarker()172*0fca6ea1SDimitry Andric const DbgMarker *getMarker() const { return Marker; }
173*0fca6ea1SDimitry Andric
174*0fca6ea1SDimitry Andric BasicBlock *getBlock();
175*0fca6ea1SDimitry Andric const BasicBlock *getBlock() const;
176*0fca6ea1SDimitry Andric
177*0fca6ea1SDimitry Andric Function *getFunction();
178*0fca6ea1SDimitry Andric const Function *getFunction() const;
179*0fca6ea1SDimitry Andric
180*0fca6ea1SDimitry Andric Module *getModule();
181*0fca6ea1SDimitry Andric const Module *getModule() const;
182*0fca6ea1SDimitry Andric
183*0fca6ea1SDimitry Andric LLVMContext &getContext();
184*0fca6ea1SDimitry Andric const LLVMContext &getContext() const;
185*0fca6ea1SDimitry Andric
186*0fca6ea1SDimitry Andric const Instruction *getInstruction() const;
1875f757f3fSDimitry Andric const BasicBlock *getParent() const;
1885f757f3fSDimitry Andric BasicBlock *getParent();
189*0fca6ea1SDimitry Andric
1905f757f3fSDimitry Andric void removeFromParent();
1915f757f3fSDimitry Andric void eraseFromParent();
1925f757f3fSDimitry Andric
getNextNode()193*0fca6ea1SDimitry Andric DbgRecord *getNextNode() { return &*std::next(getIterator()); }
getPrevNode()194*0fca6ea1SDimitry Andric DbgRecord *getPrevNode() { return &*std::prev(getIterator()); }
195*0fca6ea1SDimitry Andric void insertBefore(DbgRecord *InsertBefore);
196*0fca6ea1SDimitry Andric void insertAfter(DbgRecord *InsertAfter);
197*0fca6ea1SDimitry Andric void moveBefore(DbgRecord *MoveBefore);
198*0fca6ea1SDimitry Andric void moveAfter(DbgRecord *MoveAfter);
1997a6dacacSDimitry Andric
getDebugLoc()200*0fca6ea1SDimitry Andric DebugLoc getDebugLoc() const { return DbgLoc; }
setDebugLoc(DebugLoc Loc)201*0fca6ea1SDimitry Andric void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
2025f757f3fSDimitry Andric
203*0fca6ea1SDimitry Andric void dump() const;
204*0fca6ea1SDimitry Andric
205*0fca6ea1SDimitry Andric using self_iterator = simple_ilist<DbgRecord>::iterator;
206*0fca6ea1SDimitry Andric using const_self_iterator = simple_ilist<DbgRecord>::const_iterator;
207*0fca6ea1SDimitry Andric
208*0fca6ea1SDimitry Andric protected:
209*0fca6ea1SDimitry Andric /// Similarly to Value, we avoid paying the cost of a vtable
210*0fca6ea1SDimitry Andric /// by protecting the dtor and having deleteRecord dispatch
211*0fca6ea1SDimitry Andric /// cleanup.
212*0fca6ea1SDimitry Andric /// Use deleteRecord to delete a generic record.
213*0fca6ea1SDimitry Andric ~DbgRecord() = default;
214*0fca6ea1SDimitry Andric };
215*0fca6ea1SDimitry Andric
216*0fca6ea1SDimitry Andric inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) {
217*0fca6ea1SDimitry Andric R.print(OS);
218*0fca6ea1SDimitry Andric return OS;
219*0fca6ea1SDimitry Andric }
220*0fca6ea1SDimitry Andric
221*0fca6ea1SDimitry Andric /// Records a position in IR for a source label (DILabel). Corresponds to the
222*0fca6ea1SDimitry Andric /// llvm.dbg.label intrinsic.
223*0fca6ea1SDimitry Andric class DbgLabelRecord : public DbgRecord {
224*0fca6ea1SDimitry Andric DbgRecordParamRef<DILabel> Label;
225*0fca6ea1SDimitry Andric
226*0fca6ea1SDimitry Andric /// This constructor intentionally left private, so that it is only called via
227*0fca6ea1SDimitry Andric /// "createUnresolvedDbgLabelRecord", which clearly expresses that it is for
228*0fca6ea1SDimitry Andric /// parsing only.
229*0fca6ea1SDimitry Andric DbgLabelRecord(MDNode *Label, MDNode *DL);
230*0fca6ea1SDimitry Andric
231*0fca6ea1SDimitry Andric public:
232*0fca6ea1SDimitry Andric DbgLabelRecord(DILabel *Label, DebugLoc DL);
233*0fca6ea1SDimitry Andric
234*0fca6ea1SDimitry Andric /// For use during parsing; creates a DbgLabelRecord from as-of-yet unresolved
235*0fca6ea1SDimitry Andric /// MDNodes. Trying to access the resulting DbgLabelRecord's fields before
236*0fca6ea1SDimitry Andric /// they are resolved, or if they resolve to the wrong type, will result in a
237*0fca6ea1SDimitry Andric /// crash.
238*0fca6ea1SDimitry Andric static DbgLabelRecord *createUnresolvedDbgLabelRecord(MDNode *Label,
239*0fca6ea1SDimitry Andric MDNode *DL);
240*0fca6ea1SDimitry Andric
241*0fca6ea1SDimitry Andric DbgLabelRecord *clone() const;
242*0fca6ea1SDimitry Andric void print(raw_ostream &O, bool IsForDebug = false) const;
243*0fca6ea1SDimitry Andric void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
244*0fca6ea1SDimitry Andric DbgLabelInst *createDebugIntrinsic(Module *M,
245*0fca6ea1SDimitry Andric Instruction *InsertBefore) const;
246*0fca6ea1SDimitry Andric
setLabel(DILabel * NewLabel)247*0fca6ea1SDimitry Andric void setLabel(DILabel *NewLabel) { Label = NewLabel; }
getLabel()248*0fca6ea1SDimitry Andric DILabel *getLabel() const { return Label.get(); }
getRawLabel()249*0fca6ea1SDimitry Andric MDNode *getRawLabel() const { return Label.getAsMDNode(); };
250*0fca6ea1SDimitry Andric
251*0fca6ea1SDimitry Andric /// Support type inquiry through isa, cast, and dyn_cast.
classof(const DbgRecord * E)252*0fca6ea1SDimitry Andric static bool classof(const DbgRecord *E) {
253*0fca6ea1SDimitry Andric return E->getRecordKind() == LabelKind;
254*0fca6ea1SDimitry Andric }
255*0fca6ea1SDimitry Andric };
256*0fca6ea1SDimitry Andric
257*0fca6ea1SDimitry Andric /// Record of a variable value-assignment, aka a non instruction representation
258*0fca6ea1SDimitry Andric /// of the dbg.value intrinsic.
259*0fca6ea1SDimitry Andric ///
260*0fca6ea1SDimitry Andric /// This class inherits from DebugValueUser to allow LLVM's metadata facilities
261*0fca6ea1SDimitry Andric /// to update our references to metadata beneath our feet.
262*0fca6ea1SDimitry Andric class DbgVariableRecord : public DbgRecord, protected DebugValueUser {
263*0fca6ea1SDimitry Andric friend class DebugValueUser;
264*0fca6ea1SDimitry Andric
265*0fca6ea1SDimitry Andric public:
266*0fca6ea1SDimitry Andric enum class LocationType : uint8_t {
2675f757f3fSDimitry Andric Declare,
2685f757f3fSDimitry Andric Value,
2697a6dacacSDimitry Andric Assign,
2705f757f3fSDimitry Andric
2715f757f3fSDimitry Andric End, ///< Marks the end of the concrete types.
2725f757f3fSDimitry Andric Any, ///< To indicate all LocationTypes in searches.
2735f757f3fSDimitry Andric };
274*0fca6ea1SDimitry Andric /// Classification of the debug-info record that this DbgVariableRecord
275*0fca6ea1SDimitry Andric /// represents. Essentially, "does this correspond to a dbg.value,
276*0fca6ea1SDimitry Andric /// dbg.declare, or dbg.assign?".
277*0fca6ea1SDimitry Andric /// FIXME: We could use spare padding bits from DbgRecord for this.
2785f757f3fSDimitry Andric LocationType Type;
2795f757f3fSDimitry Andric
280*0fca6ea1SDimitry Andric // NB: there is no explicit "Value" field in this class, it's effectively the
281*0fca6ea1SDimitry Andric // DebugValueUser superclass instead. The referred to Value can either be a
282*0fca6ea1SDimitry Andric // ValueAsMetadata or a DIArgList.
2835f757f3fSDimitry Andric
284*0fca6ea1SDimitry Andric DbgRecordParamRef<DILocalVariable> Variable;
285*0fca6ea1SDimitry Andric DbgRecordParamRef<DIExpression> Expression;
286*0fca6ea1SDimitry Andric DbgRecordParamRef<DIExpression> AddressExpression;
2877a6dacacSDimitry Andric
288*0fca6ea1SDimitry Andric public:
289*0fca6ea1SDimitry Andric /// Create a new DbgVariableRecord representing the intrinsic \p DVI, for
290*0fca6ea1SDimitry Andric /// example the assignment represented by a dbg.value.
291*0fca6ea1SDimitry Andric DbgVariableRecord(const DbgVariableIntrinsic *DVI);
292*0fca6ea1SDimitry Andric DbgVariableRecord(const DbgVariableRecord &DVR);
293*0fca6ea1SDimitry Andric /// Directly construct a new DbgVariableRecord representing a dbg.value
294*0fca6ea1SDimitry Andric /// intrinsic assigning \p Location to the DV / Expr / DI variable.
295*0fca6ea1SDimitry Andric DbgVariableRecord(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
296*0fca6ea1SDimitry Andric const DILocation *DI,
297*0fca6ea1SDimitry Andric LocationType Type = LocationType::Value);
298*0fca6ea1SDimitry Andric DbgVariableRecord(Metadata *Value, DILocalVariable *Variable,
299*0fca6ea1SDimitry Andric DIExpression *Expression, DIAssignID *AssignID,
300*0fca6ea1SDimitry Andric Metadata *Address, DIExpression *AddressExpression,
3017a6dacacSDimitry Andric const DILocation *DI);
3027a6dacacSDimitry Andric
303*0fca6ea1SDimitry Andric private:
304*0fca6ea1SDimitry Andric /// Private constructor for creating new instances during parsing only. Only
305*0fca6ea1SDimitry Andric /// called through `createUnresolvedDbgVariableRecord` below, which makes
306*0fca6ea1SDimitry Andric /// clear that this is used for parsing only, and will later return a subclass
307*0fca6ea1SDimitry Andric /// depending on which Type is passed.
308*0fca6ea1SDimitry Andric DbgVariableRecord(LocationType Type, Metadata *Val, MDNode *Variable,
309*0fca6ea1SDimitry Andric MDNode *Expression, MDNode *AssignID, Metadata *Address,
310*0fca6ea1SDimitry Andric MDNode *AddressExpression, MDNode *DI);
311*0fca6ea1SDimitry Andric
312*0fca6ea1SDimitry Andric public:
313*0fca6ea1SDimitry Andric /// Used to create DbgVariableRecords during parsing, where some metadata
314*0fca6ea1SDimitry Andric /// references may still be unresolved. Although for some fields a generic
315*0fca6ea1SDimitry Andric /// `Metadata*` argument is accepted for forward type-references, the verifier
316*0fca6ea1SDimitry Andric /// and accessors will reject incorrect types later on. The function is used
317*0fca6ea1SDimitry Andric /// for all types of DbgVariableRecords for simplicity while parsing, but
318*0fca6ea1SDimitry Andric /// asserts if any necessary fields are empty or unused fields are not empty,
319*0fca6ea1SDimitry Andric /// i.e. if the #dbg_assign fields are used for a non-dbg-assign type.
320*0fca6ea1SDimitry Andric static DbgVariableRecord *
321*0fca6ea1SDimitry Andric createUnresolvedDbgVariableRecord(LocationType Type, Metadata *Val,
322*0fca6ea1SDimitry Andric MDNode *Variable, MDNode *Expression,
323*0fca6ea1SDimitry Andric MDNode *AssignID, Metadata *Address,
324*0fca6ea1SDimitry Andric MDNode *AddressExpression, MDNode *DI);
325*0fca6ea1SDimitry Andric
326*0fca6ea1SDimitry Andric static DbgVariableRecord *
327*0fca6ea1SDimitry Andric createDVRAssign(Value *Val, DILocalVariable *Variable,
328*0fca6ea1SDimitry Andric DIExpression *Expression, DIAssignID *AssignID,
329*0fca6ea1SDimitry Andric Value *Address, DIExpression *AddressExpression,
330*0fca6ea1SDimitry Andric const DILocation *DI);
331*0fca6ea1SDimitry Andric static DbgVariableRecord *
332*0fca6ea1SDimitry Andric createLinkedDVRAssign(Instruction *LinkedInstr, Value *Val,
333*0fca6ea1SDimitry Andric DILocalVariable *Variable, DIExpression *Expression,
334*0fca6ea1SDimitry Andric Value *Address, DIExpression *AddressExpression,
335*0fca6ea1SDimitry Andric const DILocation *DI);
336*0fca6ea1SDimitry Andric
337*0fca6ea1SDimitry Andric static DbgVariableRecord *createDbgVariableRecord(Value *Location,
338*0fca6ea1SDimitry Andric DILocalVariable *DV,
339*0fca6ea1SDimitry Andric DIExpression *Expr,
340*0fca6ea1SDimitry Andric const DILocation *DI);
341*0fca6ea1SDimitry Andric static DbgVariableRecord *
342*0fca6ea1SDimitry Andric createDbgVariableRecord(Value *Location, DILocalVariable *DV,
3437a6dacacSDimitry Andric DIExpression *Expr, const DILocation *DI,
344*0fca6ea1SDimitry Andric DbgVariableRecord &InsertBefore);
345*0fca6ea1SDimitry Andric static DbgVariableRecord *createDVRDeclare(Value *Address,
346*0fca6ea1SDimitry Andric DILocalVariable *DV,
347*0fca6ea1SDimitry Andric DIExpression *Expr,
348*0fca6ea1SDimitry Andric const DILocation *DI);
349*0fca6ea1SDimitry Andric static DbgVariableRecord *
350*0fca6ea1SDimitry Andric createDVRDeclare(Value *Address, DILocalVariable *DV, DIExpression *Expr,
351*0fca6ea1SDimitry Andric const DILocation *DI, DbgVariableRecord &InsertBefore);
3525f757f3fSDimitry Andric
3535f757f3fSDimitry Andric /// Iterator for ValueAsMetadata that internally uses direct pointer iteration
3545f757f3fSDimitry Andric /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
3555f757f3fSDimitry Andric /// ValueAsMetadata .
3565f757f3fSDimitry Andric class location_op_iterator
3575f757f3fSDimitry Andric : public iterator_facade_base<location_op_iterator,
3585f757f3fSDimitry Andric std::bidirectional_iterator_tag, Value *> {
3595f757f3fSDimitry Andric PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
3605f757f3fSDimitry Andric
3615f757f3fSDimitry Andric public:
location_op_iterator(ValueAsMetadata * SingleIter)3625f757f3fSDimitry Andric location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
location_op_iterator(ValueAsMetadata ** MultiIter)3635f757f3fSDimitry Andric location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
3645f757f3fSDimitry Andric
location_op_iterator(const location_op_iterator & R)3655f757f3fSDimitry Andric location_op_iterator(const location_op_iterator &R) : I(R.I) {}
3665f757f3fSDimitry Andric location_op_iterator &operator=(const location_op_iterator &R) {
3675f757f3fSDimitry Andric I = R.I;
3685f757f3fSDimitry Andric return *this;
3695f757f3fSDimitry Andric }
3705f757f3fSDimitry Andric bool operator==(const location_op_iterator &RHS) const {
3715f757f3fSDimitry Andric return I == RHS.I;
3725f757f3fSDimitry Andric }
3735f757f3fSDimitry Andric const Value *operator*() const {
3745f757f3fSDimitry Andric ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
3755f757f3fSDimitry Andric ? I.get<ValueAsMetadata *>()
3765f757f3fSDimitry Andric : *I.get<ValueAsMetadata **>();
3775f757f3fSDimitry Andric return VAM->getValue();
3785f757f3fSDimitry Andric };
3795f757f3fSDimitry Andric Value *operator*() {
3805f757f3fSDimitry Andric ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
3815f757f3fSDimitry Andric ? I.get<ValueAsMetadata *>()
3825f757f3fSDimitry Andric : *I.get<ValueAsMetadata **>();
3835f757f3fSDimitry Andric return VAM->getValue();
3845f757f3fSDimitry Andric }
3855f757f3fSDimitry Andric location_op_iterator &operator++() {
3865f757f3fSDimitry Andric if (I.is<ValueAsMetadata *>())
3875f757f3fSDimitry Andric I = I.get<ValueAsMetadata *>() + 1;
3885f757f3fSDimitry Andric else
3895f757f3fSDimitry Andric I = I.get<ValueAsMetadata **>() + 1;
3905f757f3fSDimitry Andric return *this;
3915f757f3fSDimitry Andric }
3925f757f3fSDimitry Andric location_op_iterator &operator--() {
3935f757f3fSDimitry Andric if (I.is<ValueAsMetadata *>())
3945f757f3fSDimitry Andric I = I.get<ValueAsMetadata *>() - 1;
3955f757f3fSDimitry Andric else
3965f757f3fSDimitry Andric I = I.get<ValueAsMetadata **>() - 1;
3975f757f3fSDimitry Andric return *this;
3985f757f3fSDimitry Andric }
3995f757f3fSDimitry Andric };
4005f757f3fSDimitry Andric
isDbgDeclare()4017a6dacacSDimitry Andric bool isDbgDeclare() { return Type == LocationType::Declare; }
isDbgValue()4027a6dacacSDimitry Andric bool isDbgValue() { return Type == LocationType::Value; }
4037a6dacacSDimitry Andric
4045f757f3fSDimitry Andric /// Get the locations corresponding to the variable referenced by the debug
4055f757f3fSDimitry Andric /// info intrinsic. Depending on the intrinsic, this could be the
4065f757f3fSDimitry Andric /// variable's value or its address.
4075f757f3fSDimitry Andric iterator_range<location_op_iterator> location_ops() const;
4085f757f3fSDimitry Andric
4095f757f3fSDimitry Andric Value *getVariableLocationOp(unsigned OpIdx) const;
4105f757f3fSDimitry Andric
4115f757f3fSDimitry Andric void replaceVariableLocationOp(Value *OldValue, Value *NewValue,
4125f757f3fSDimitry Andric bool AllowEmpty = false);
4135f757f3fSDimitry Andric void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
4145f757f3fSDimitry Andric /// Adding a new location operand will always result in this intrinsic using
4155f757f3fSDimitry Andric /// an ArgList, and must always be accompanied by a new expression that uses
4165f757f3fSDimitry Andric /// the new operand.
4175f757f3fSDimitry Andric void addVariableLocationOps(ArrayRef<Value *> NewValues,
4185f757f3fSDimitry Andric DIExpression *NewExpr);
4195f757f3fSDimitry Andric
4205f757f3fSDimitry Andric unsigned getNumVariableLocationOps() const;
4215f757f3fSDimitry Andric
hasArgList()4225f757f3fSDimitry Andric bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
423*0fca6ea1SDimitry Andric /// Returns true if this DbgVariableRecord has no empty MDNodes in its
424*0fca6ea1SDimitry Andric /// location list.
hasValidLocation()4255f757f3fSDimitry Andric bool hasValidLocation() const { return getVariableLocationOp(0) != nullptr; }
4265f757f3fSDimitry Andric
4275f757f3fSDimitry Andric /// Does this describe the address of a local variable. True for dbg.addr
4285f757f3fSDimitry Andric /// and dbg.declare, but not dbg.value, which describes its value.
isAddressOfVariable()4297a6dacacSDimitry Andric bool isAddressOfVariable() const { return Type == LocationType::Declare; }
getType()4305f757f3fSDimitry Andric LocationType getType() const { return Type; }
4315f757f3fSDimitry Andric
4325f757f3fSDimitry Andric void setKillLocation();
4335f757f3fSDimitry Andric bool isKillLocation() const;
4345f757f3fSDimitry Andric
setVariable(DILocalVariable * NewVar)435*0fca6ea1SDimitry Andric void setVariable(DILocalVariable *NewVar) { Variable = NewVar; }
getVariable()436*0fca6ea1SDimitry Andric DILocalVariable *getVariable() const { return Variable.get(); };
getRawVariable()437*0fca6ea1SDimitry Andric MDNode *getRawVariable() const { return Variable.getAsMDNode(); }
4385f757f3fSDimitry Andric
setExpression(DIExpression * NewExpr)439*0fca6ea1SDimitry Andric void setExpression(DIExpression *NewExpr) { Expression = NewExpr; }
getExpression()440*0fca6ea1SDimitry Andric DIExpression *getExpression() const { return Expression.get(); }
getRawExpression()441*0fca6ea1SDimitry Andric MDNode *getRawExpression() const { return Expression.getAsMDNode(); }
4425f757f3fSDimitry Andric
4437a6dacacSDimitry Andric /// Returns the metadata operand for the first location description. i.e.,
4447a6dacacSDimitry Andric /// dbg intrinsic dbg.value,declare operand and dbg.assign 1st location
4457a6dacacSDimitry Andric /// operand (the "value componenet"). Note the operand (singular) may be
4467a6dacacSDimitry Andric /// a DIArgList which is a list of values.
getRawLocation()4477a6dacacSDimitry Andric Metadata *getRawLocation() const { return DebugValues[0]; }
4487a6dacacSDimitry Andric
4497a6dacacSDimitry Andric Value *getValue(unsigned OpIdx = 0) const {
4507a6dacacSDimitry Andric return getVariableLocationOp(OpIdx);
4517a6dacacSDimitry Andric }
4525f757f3fSDimitry Andric
4535f757f3fSDimitry Andric /// Use of this should generally be avoided; instead,
4545f757f3fSDimitry Andric /// replaceVariableLocationOp and addVariableLocationOps should be used where
4555f757f3fSDimitry Andric /// possible to avoid creating invalid state.
setRawLocation(Metadata * NewLocation)4565f757f3fSDimitry Andric void setRawLocation(Metadata *NewLocation) {
457*0fca6ea1SDimitry Andric assert((isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) ||
4585f757f3fSDimitry Andric isa<MDNode>(NewLocation)) &&
459*0fca6ea1SDimitry Andric "Location for a DbgVariableRecord must be either ValueAsMetadata or "
460*0fca6ea1SDimitry Andric "DIArgList");
4617a6dacacSDimitry Andric resetDebugValue(0, NewLocation);
4625f757f3fSDimitry Andric }
4635f757f3fSDimitry Andric
464*0fca6ea1SDimitry Andric std::optional<DbgVariableFragmentInfo> getFragment() const;
465*0fca6ea1SDimitry Andric /// Get the FragmentInfo for the variable if it exists, otherwise return a
466*0fca6ea1SDimitry Andric /// FragmentInfo that covers the entire variable if the variable size is
467*0fca6ea1SDimitry Andric /// known, otherwise return a zero-sized fragment.
getFragmentOrEntireVariable()468*0fca6ea1SDimitry Andric DbgVariableFragmentInfo getFragmentOrEntireVariable() const {
469*0fca6ea1SDimitry Andric if (auto Frag = getFragment())
470*0fca6ea1SDimitry Andric return *Frag;
471*0fca6ea1SDimitry Andric if (auto Sz = getFragmentSizeInBits())
472*0fca6ea1SDimitry Andric return {*Sz, 0};
473*0fca6ea1SDimitry Andric return {0, 0};
474*0fca6ea1SDimitry Andric }
4755f757f3fSDimitry Andric /// Get the size (in bits) of the variable, or fragment of the variable that
4765f757f3fSDimitry Andric /// is described.
4775f757f3fSDimitry Andric std::optional<uint64_t> getFragmentSizeInBits() const;
4785f757f3fSDimitry Andric
isEquivalentTo(const DbgVariableRecord & Other)479*0fca6ea1SDimitry Andric bool isEquivalentTo(const DbgVariableRecord &Other) const {
480*0fca6ea1SDimitry Andric return DbgLoc == Other.DbgLoc && isIdenticalToWhenDefined(Other);
4817a6dacacSDimitry Andric }
4827a6dacacSDimitry Andric // Matches the definition of the Instruction version, equivalent to above but
4837a6dacacSDimitry Andric // without checking DbgLoc.
isIdenticalToWhenDefined(const DbgVariableRecord & Other)484*0fca6ea1SDimitry Andric bool isIdenticalToWhenDefined(const DbgVariableRecord &Other) const {
485*0fca6ea1SDimitry Andric return std::tie(Type, DebugValues, Variable, Expression,
486*0fca6ea1SDimitry Andric AddressExpression) ==
4877a6dacacSDimitry Andric std::tie(Other.Type, Other.DebugValues, Other.Variable,
488*0fca6ea1SDimitry Andric Other.Expression, Other.AddressExpression);
4897a6dacacSDimitry Andric }
4907a6dacacSDimitry Andric
4917a6dacacSDimitry Andric /// @name DbgAssign Methods
4927a6dacacSDimitry Andric /// @{
isDbgAssign()4937a6dacacSDimitry Andric bool isDbgAssign() const { return getType() == LocationType::Assign; }
4947a6dacacSDimitry Andric
4957a6dacacSDimitry Andric Value *getAddress() const;
getRawAddress()4967a6dacacSDimitry Andric Metadata *getRawAddress() const {
4977a6dacacSDimitry Andric return isDbgAssign() ? DebugValues[1] : DebugValues[0];
4987a6dacacSDimitry Andric }
getRawAssignID()4997a6dacacSDimitry Andric Metadata *getRawAssignID() const { return DebugValues[2]; }
5007a6dacacSDimitry Andric DIAssignID *getAssignID() const;
getAddressExpression()501*0fca6ea1SDimitry Andric DIExpression *getAddressExpression() const { return AddressExpression.get(); }
getRawAddressExpression()502*0fca6ea1SDimitry Andric MDNode *getRawAddressExpression() const {
503*0fca6ea1SDimitry Andric return AddressExpression.getAsMDNode();
504*0fca6ea1SDimitry Andric }
setAddressExpression(DIExpression * NewExpr)5057a6dacacSDimitry Andric void setAddressExpression(DIExpression *NewExpr) {
5067a6dacacSDimitry Andric AddressExpression = NewExpr;
5077a6dacacSDimitry Andric }
5087a6dacacSDimitry Andric void setAssignId(DIAssignID *New);
setAddress(Value * V)5097a6dacacSDimitry Andric void setAddress(Value *V) { resetDebugValue(1, ValueAsMetadata::get(V)); }
5107a6dacacSDimitry Andric /// Kill the address component.
5117a6dacacSDimitry Andric void setKillAddress();
5127a6dacacSDimitry Andric /// Check whether this kills the address component. This doesn't take into
5137a6dacacSDimitry Andric /// account the position of the intrinsic, therefore a returned value of false
5147a6dacacSDimitry Andric /// does not guarentee the address is a valid location for the variable at the
5157a6dacacSDimitry Andric /// intrinsic's position in IR.
5167a6dacacSDimitry Andric bool isKillAddress() const;
5177a6dacacSDimitry Andric
5187a6dacacSDimitry Andric /// @}
5197a6dacacSDimitry Andric
520*0fca6ea1SDimitry Andric DbgVariableRecord *clone() const;
521*0fca6ea1SDimitry Andric /// Convert this DbgVariableRecord back into a dbg.value intrinsic.
5225f757f3fSDimitry Andric /// \p InsertBefore Optional position to insert this intrinsic.
523*0fca6ea1SDimitry Andric /// \returns A new dbg.value intrinsic representiung this DbgVariableRecord.
5245f757f3fSDimitry Andric DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
5255f757f3fSDimitry Andric Instruction *InsertBefore) const;
5265f757f3fSDimitry Andric
527*0fca6ea1SDimitry Andric /// Handle changes to the location of the Value(s) that we refer to happening
528*0fca6ea1SDimitry Andric /// "under our feet".
529*0fca6ea1SDimitry Andric void handleChangedLocation(Metadata *NewLocation);
5307a6dacacSDimitry Andric
5315f757f3fSDimitry Andric void print(raw_ostream &O, bool IsForDebug = false) const;
5325f757f3fSDimitry Andric void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
533*0fca6ea1SDimitry Andric
534*0fca6ea1SDimitry Andric /// Support type inquiry through isa, cast, and dyn_cast.
classof(const DbgRecord * E)535*0fca6ea1SDimitry Andric static bool classof(const DbgRecord *E) {
536*0fca6ea1SDimitry Andric return E->getRecordKind() == ValueKind;
537*0fca6ea1SDimitry Andric }
5385f757f3fSDimitry Andric };
5395f757f3fSDimitry Andric
540*0fca6ea1SDimitry Andric /// Filter the DbgRecord range to DbgVariableRecord types only and downcast.
541*0fca6ea1SDimitry Andric static inline auto
filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R)542*0fca6ea1SDimitry Andric filterDbgVars(iterator_range<simple_ilist<DbgRecord>::iterator> R) {
543*0fca6ea1SDimitry Andric return map_range(
544*0fca6ea1SDimitry Andric make_filter_range(R,
545*0fca6ea1SDimitry Andric [](DbgRecord &E) { return isa<DbgVariableRecord>(E); }),
546*0fca6ea1SDimitry Andric [](DbgRecord &E) { return std::ref(cast<DbgVariableRecord>(E)); });
547*0fca6ea1SDimitry Andric }
548*0fca6ea1SDimitry Andric
5495f757f3fSDimitry Andric /// Per-instruction record of debug-info. If an Instruction is the position of
550*0fca6ea1SDimitry Andric /// some debugging information, it points at a DbgMarker storing that info. Each
5515f757f3fSDimitry Andric /// marker points back at the instruction that owns it. Various utilities are
552*0fca6ea1SDimitry Andric /// provided for manipulating the DbgRecords contained within this marker.
5535f757f3fSDimitry Andric ///
554*0fca6ea1SDimitry Andric /// This class has a rough surface area, because it's needed to preserve the
555*0fca6ea1SDimitry Andric /// one arefact that we can't yet eliminate from the intrinsic / dbg.value
556*0fca6ea1SDimitry Andric /// debug-info design: the order of records is significant, and duplicates can
557*0fca6ea1SDimitry Andric /// exist. Thus, if one has a run of debug-info records such as:
5585f757f3fSDimitry Andric /// dbg.value(...
5595f757f3fSDimitry Andric /// %foo = barinst
5605f757f3fSDimitry Andric /// dbg.value(...
5615f757f3fSDimitry Andric /// and remove barinst, then the dbg.values must be preserved in the correct
5625f757f3fSDimitry Andric /// order. Hence, the use of iterators to select positions to insert things
5635f757f3fSDimitry Andric /// into, or the occasional InsertAtHead parameter indicating that new records
5645f757f3fSDimitry Andric /// should go at the start of the list.
5655f757f3fSDimitry Andric ///
5665f757f3fSDimitry Andric /// There are only five or six places in LLVM that truly rely on this ordering,
5675f757f3fSDimitry Andric /// which we can improve in the future. Additionally, many improvements in the
5685f757f3fSDimitry Andric /// way that debug-info is stored can be achieved in this class, at a future
5695f757f3fSDimitry Andric /// date.
570*0fca6ea1SDimitry Andric class DbgMarker {
5715f757f3fSDimitry Andric public:
DbgMarker()572*0fca6ea1SDimitry Andric DbgMarker() {}
5735f757f3fSDimitry Andric /// Link back to the Instruction that owns this marker. Can be null during
5745f757f3fSDimitry Andric /// operations that move a marker from one instruction to another.
5755f757f3fSDimitry Andric Instruction *MarkedInstr = nullptr;
5765f757f3fSDimitry Andric
577*0fca6ea1SDimitry Andric /// List of DbgRecords, the non-instruction equivalent of llvm.dbg.*
578*0fca6ea1SDimitry Andric /// intrinsics. There is a one-to-one relationship between each debug
579*0fca6ea1SDimitry Andric /// intrinsic in a block and each DbgRecord once the representation has been
580*0fca6ea1SDimitry Andric /// converted, and the ordering is meaningful in the same way.
581*0fca6ea1SDimitry Andric simple_ilist<DbgRecord> StoredDbgRecords;
empty()582*0fca6ea1SDimitry Andric bool empty() const { return StoredDbgRecords.empty(); }
5835f757f3fSDimitry Andric
5845f757f3fSDimitry Andric const BasicBlock *getParent() const;
5855f757f3fSDimitry Andric BasicBlock *getParent();
5865f757f3fSDimitry Andric
5875f757f3fSDimitry Andric /// Handle the removal of a marker: the position of debug-info has gone away,
5885f757f3fSDimitry Andric /// but the stored debug records should not. Drop them onto the next
5895f757f3fSDimitry Andric /// instruction, or otherwise work out what to do with them.
5905f757f3fSDimitry Andric void removeMarker();
5915f757f3fSDimitry Andric void dump() const;
5925f757f3fSDimitry Andric
5935f757f3fSDimitry Andric void removeFromParent();
5945f757f3fSDimitry Andric void eraseFromParent();
5955f757f3fSDimitry Andric
596*0fca6ea1SDimitry Andric /// Implement operator<< on DbgMarker.
5975f757f3fSDimitry Andric void print(raw_ostream &O, bool IsForDebug = false) const;
5985f757f3fSDimitry Andric void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
5995f757f3fSDimitry Andric
600*0fca6ea1SDimitry Andric /// Produce a range over all the DbgRecords in this Marker.
601*0fca6ea1SDimitry Andric iterator_range<simple_ilist<DbgRecord>::iterator> getDbgRecordRange();
602*0fca6ea1SDimitry Andric iterator_range<simple_ilist<DbgRecord>::const_iterator>
603*0fca6ea1SDimitry Andric getDbgRecordRange() const;
604*0fca6ea1SDimitry Andric /// Transfer any DbgRecords from \p Src into this DbgMarker. If \p
605*0fca6ea1SDimitry Andric /// InsertAtHead is true, place them before existing DbgRecords, otherwise
606*0fca6ea1SDimitry Andric /// afterwards.
607*0fca6ea1SDimitry Andric void absorbDebugValues(DbgMarker &Src, bool InsertAtHead);
608*0fca6ea1SDimitry Andric /// Transfer the DbgRecords in \p Range from \p Src into this DbgMarker. If
609*0fca6ea1SDimitry Andric /// \p InsertAtHead is true, place them before existing DbgRecords, otherwise
6105f757f3fSDimitry Andric // afterwards.
611*0fca6ea1SDimitry Andric void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
612*0fca6ea1SDimitry Andric DbgMarker &Src, bool InsertAtHead);
613*0fca6ea1SDimitry Andric /// Insert a DbgRecord into this DbgMarker, at the end of the list. If
6145f757f3fSDimitry Andric /// \p InsertAtHead is true, at the start.
615*0fca6ea1SDimitry Andric void insertDbgRecord(DbgRecord *New, bool InsertAtHead);
616*0fca6ea1SDimitry Andric /// Insert a DbgRecord prior to a DbgRecord contained within this marker.
617*0fca6ea1SDimitry Andric void insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore);
618*0fca6ea1SDimitry Andric /// Insert a DbgRecord after a DbgRecord contained within this marker.
619*0fca6ea1SDimitry Andric void insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter);
620*0fca6ea1SDimitry Andric /// Clone all DbgMarkers from \p From into this marker. There are numerous
6215f757f3fSDimitry Andric /// options to customise the source/destination, due to gnarliness, see class
6225f757f3fSDimitry Andric /// comment.
623*0fca6ea1SDimitry Andric /// \p FromHere If non-null, copy from FromHere to the end of From's
624*0fca6ea1SDimitry Andric /// DbgRecords
625*0fca6ea1SDimitry Andric /// \p InsertAtHead Place the cloned DbgRecords at the start of
626*0fca6ea1SDimitry Andric /// StoredDbgRecords
627*0fca6ea1SDimitry Andric /// \returns Range over all the newly cloned DbgRecords
628*0fca6ea1SDimitry Andric iterator_range<simple_ilist<DbgRecord>::iterator>
629*0fca6ea1SDimitry Andric cloneDebugInfoFrom(DbgMarker *From,
630*0fca6ea1SDimitry Andric std::optional<simple_ilist<DbgRecord>::iterator> FromHere,
6315f757f3fSDimitry Andric bool InsertAtHead = false);
632*0fca6ea1SDimitry Andric /// Erase all DbgRecords in this DbgMarker.
633*0fca6ea1SDimitry Andric void dropDbgRecords();
634*0fca6ea1SDimitry Andric /// Erase a single DbgRecord from this marker. In an ideal future, we would
6355f757f3fSDimitry Andric /// never erase an assignment in this way, but it's the equivalent to
636*0fca6ea1SDimitry Andric /// erasing a debug intrinsic from a block.
637*0fca6ea1SDimitry Andric void dropOneDbgRecord(DbgRecord *DR);
6385f757f3fSDimitry Andric
639*0fca6ea1SDimitry Andric /// We generally act like all llvm Instructions have a range of DbgRecords
640*0fca6ea1SDimitry Andric /// attached to them, but in reality sometimes we don't allocate the DbgMarker
641*0fca6ea1SDimitry Andric /// to save time and memory, but still have to return ranges of DbgRecords.
642*0fca6ea1SDimitry Andric /// When we need to describe such an unallocated DbgRecord range, use this
643*0fca6ea1SDimitry Andric /// static markers range instead. This will bite us if someone tries to insert
644*0fca6ea1SDimitry Andric /// a DbgRecord in that range, but they should be using the Official (TM) API
645*0fca6ea1SDimitry Andric /// for that.
646*0fca6ea1SDimitry Andric static DbgMarker EmptyDbgMarker;
647*0fca6ea1SDimitry Andric static iterator_range<simple_ilist<DbgRecord>::iterator>
getEmptyDbgRecordRange()648*0fca6ea1SDimitry Andric getEmptyDbgRecordRange() {
649*0fca6ea1SDimitry Andric return make_range(EmptyDbgMarker.StoredDbgRecords.end(),
650*0fca6ea1SDimitry Andric EmptyDbgMarker.StoredDbgRecords.end());
6515f757f3fSDimitry Andric }
6525f757f3fSDimitry Andric };
6535f757f3fSDimitry Andric
654*0fca6ea1SDimitry Andric inline raw_ostream &operator<<(raw_ostream &OS, const DbgMarker &Marker) {
6555f757f3fSDimitry Andric Marker.print(OS);
6565f757f3fSDimitry Andric return OS;
6575f757f3fSDimitry Andric }
6585f757f3fSDimitry Andric
659*0fca6ea1SDimitry Andric /// Inline helper to return a range of DbgRecords attached to a marker. It needs
660*0fca6ea1SDimitry Andric /// to be inlined as it's frequently called, but also come after the declaration
661*0fca6ea1SDimitry Andric /// of DbgMarker. Thus: it's pre-declared by users like Instruction, then an
662*0fca6ea1SDimitry Andric /// inlineable body defined here.
663*0fca6ea1SDimitry Andric inline iterator_range<simple_ilist<DbgRecord>::iterator>
getDbgRecordRange(DbgMarker * DebugMarker)664*0fca6ea1SDimitry Andric getDbgRecordRange(DbgMarker *DebugMarker) {
665*0fca6ea1SDimitry Andric if (!DebugMarker)
666*0fca6ea1SDimitry Andric return DbgMarker::getEmptyDbgRecordRange();
667*0fca6ea1SDimitry Andric return DebugMarker->getDbgRecordRange();
6685f757f3fSDimitry Andric }
6695f757f3fSDimitry Andric
DEFINE_ISA_CONVERSION_FUNCTIONS(DbgRecord,LLVMDbgRecordRef)670*0fca6ea1SDimitry Andric DEFINE_ISA_CONVERSION_FUNCTIONS(DbgRecord, LLVMDbgRecordRef)
671*0fca6ea1SDimitry Andric
672*0fca6ea1SDimitry Andric /// Used to temporarily set the debug info format of a function, module, or
673*0fca6ea1SDimitry Andric /// basic block for the duration of this object's lifetime, after which the
674*0fca6ea1SDimitry Andric /// prior state will be restored.
675*0fca6ea1SDimitry Andric template <typename T> class ScopedDbgInfoFormatSetter {
676*0fca6ea1SDimitry Andric T &Obj;
677*0fca6ea1SDimitry Andric bool OldState;
678*0fca6ea1SDimitry Andric
679*0fca6ea1SDimitry Andric public:
680*0fca6ea1SDimitry Andric ScopedDbgInfoFormatSetter(T &Obj, bool NewState)
681*0fca6ea1SDimitry Andric : Obj(Obj), OldState(Obj.IsNewDbgInfoFormat) {
682*0fca6ea1SDimitry Andric Obj.setIsNewDbgInfoFormat(NewState);
683*0fca6ea1SDimitry Andric }
684*0fca6ea1SDimitry Andric ~ScopedDbgInfoFormatSetter() { Obj.setIsNewDbgInfoFormat(OldState); }
685*0fca6ea1SDimitry Andric };
686*0fca6ea1SDimitry Andric
687*0fca6ea1SDimitry Andric template <typename T>
688*0fca6ea1SDimitry Andric ScopedDbgInfoFormatSetter(T &Obj,
689*0fca6ea1SDimitry Andric bool NewState) -> ScopedDbgInfoFormatSetter<T>;
690*0fca6ea1SDimitry Andric
6915f757f3fSDimitry Andric } // namespace llvm
6925f757f3fSDimitry Andric
6935f757f3fSDimitry Andric #endif // LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
694