1 | //===-- llvm/CodeGen/DebugHandlerBase.h -----------------------*- C++ -*--===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Common functionality for different debug information format backends. |
10 | // LLVM currently supports DWARF and CodeView. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CODEGEN_DEBUGHANDLERBASE_H |
15 | #define LLVM_CODEGEN_DEBUGHANDLERBASE_H |
16 | |
17 | #include "llvm/CodeGen/AsmPrinterHandler.h" |
18 | #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" |
19 | #include "llvm/CodeGen/LexicalScopes.h" |
20 | #include "llvm/IR/DebugInfoMetadata.h" |
21 | #include "llvm/IR/DebugLoc.h" |
22 | #include <optional> |
23 | |
24 | namespace llvm { |
25 | |
26 | class AsmPrinter; |
27 | class MachineInstr; |
28 | class MachineModuleInfo; |
29 | |
30 | /// Represents the location at which a variable is stored. |
31 | struct DbgVariableLocation { |
32 | /// Base register. |
33 | unsigned Register; |
34 | |
35 | /// Chain of offsetted loads necessary to load the value if it lives in |
36 | /// memory. Every load except for the last is pointer-sized. |
37 | SmallVector<int64_t, 1> LoadChain; |
38 | |
39 | /// Present if the location is part of a larger variable. |
40 | std::optional<llvm::DIExpression::FragmentInfo> FragmentInfo; |
41 | |
42 | /// Extract a VariableLocation from a MachineInstr. |
43 | /// This will only work if Instruction is a debug value instruction |
44 | /// and the associated DIExpression is in one of the supported forms. |
45 | /// If these requirements are not met, the returned Optional will not |
46 | /// have a value. |
47 | static std::optional<DbgVariableLocation> |
48 | (const MachineInstr &Instruction); |
49 | }; |
50 | |
51 | /// Base class for debug information backends. Common functionality related to |
52 | /// tracking which variables and scopes are alive at a given PC live here. |
53 | class DebugHandlerBase { |
54 | protected: |
55 | DebugHandlerBase(AsmPrinter *A); |
56 | |
57 | public: |
58 | virtual ~DebugHandlerBase(); |
59 | |
60 | protected: |
61 | /// Target of debug info emission. |
62 | AsmPrinter *Asm = nullptr; |
63 | |
64 | /// Collected machine module information. |
65 | MachineModuleInfo *MMI = nullptr; |
66 | |
67 | /// Previous instruction's location information. This is used to |
68 | /// determine label location to indicate scope boundaries in debug info. |
69 | /// We track the previous instruction's source location (if not line 0), |
70 | /// whether it was a label, and its parent BB. |
71 | DebugLoc PrevInstLoc; |
72 | MCSymbol *PrevLabel = nullptr; |
73 | const MachineBasicBlock *PrevInstBB = nullptr; |
74 | |
75 | /// This location indicates end of function prologue and beginning of |
76 | /// function body. |
77 | DebugLoc PrologEndLoc; |
78 | |
79 | /// This block includes epilogue instructions. |
80 | const MachineBasicBlock *EpilogBeginBlock = nullptr; |
81 | |
82 | /// If nonnull, stores the current machine instruction we're processing. |
83 | const MachineInstr *CurMI = nullptr; |
84 | |
85 | LexicalScopes LScopes; |
86 | |
87 | /// History of DBG_VALUE and clobber instructions for each user |
88 | /// variable. Variables are listed in order of appearance. |
89 | DbgValueHistoryMap DbgValues; |
90 | |
91 | /// Mapping of inlined labels and DBG_LABEL machine instruction. |
92 | DbgLabelInstrMap DbgLabels; |
93 | |
94 | /// Maps instruction with label emitted before instruction. |
95 | /// FIXME: Make this private from DwarfDebug, we have the necessary accessors |
96 | /// for it. |
97 | DenseMap<const MachineInstr *, MCSymbol *> LabelsBeforeInsn; |
98 | |
99 | /// Maps instruction with label emitted after instruction. |
100 | DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn; |
101 | |
102 | /// Indentify instructions that are marking the beginning of or |
103 | /// ending of a scope. |
104 | void identifyScopeMarkers(); |
105 | |
106 | /// Ensure that a label will be emitted before MI. |
107 | void requestLabelBeforeInsn(const MachineInstr *MI) { |
108 | LabelsBeforeInsn.insert(KV: std::make_pair(x&: MI, y: nullptr)); |
109 | } |
110 | |
111 | /// Ensure that a label will be emitted after MI. |
112 | void requestLabelAfterInsn(const MachineInstr *MI) { |
113 | LabelsAfterInsn.insert(KV: std::make_pair(x&: MI, y: nullptr)); |
114 | } |
115 | |
116 | virtual void beginFunctionImpl(const MachineFunction *MF) = 0; |
117 | virtual void endFunctionImpl(const MachineFunction *MF) = 0; |
118 | virtual void skippedNonDebugFunction() {} |
119 | |
120 | private: |
121 | InstructionOrdering InstOrdering; |
122 | |
123 | public: |
124 | /// For symbols that have a size designated (e.g. common symbols), |
125 | /// this tracks that size. Only used by DWARF. |
126 | virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {} |
127 | |
128 | virtual void beginModule(Module *M); |
129 | virtual void endModule() = 0; |
130 | |
131 | virtual void beginInstruction(const MachineInstr *MI); |
132 | virtual void endInstruction(); |
133 | |
134 | void beginFunction(const MachineFunction *MF); |
135 | void endFunction(const MachineFunction *MF); |
136 | |
137 | void beginBasicBlockSection(const MachineBasicBlock &MBB); |
138 | void endBasicBlockSection(const MachineBasicBlock &MBB); |
139 | |
140 | /// Return Label preceding the instruction. |
141 | MCSymbol *getLabelBeforeInsn(const MachineInstr *MI); |
142 | |
143 | /// Return Label immediately following the instruction. |
144 | MCSymbol *getLabelAfterInsn(const MachineInstr *MI); |
145 | |
146 | /// If this type is derived from a base type then return base type size. |
147 | static uint64_t getBaseTypeSize(const DIType *Ty); |
148 | |
149 | /// Return true if type encoding is unsigned. |
150 | static bool isUnsignedDIType(const DIType *Ty); |
151 | |
152 | const InstructionOrdering &getInstOrdering() const { return InstOrdering; } |
153 | }; |
154 | |
155 | } // namespace llvm |
156 | |
157 | #endif |
158 | |