LLVM 23.0.0git
LVIRReader.h
Go to the documentation of this file.
1//===-- LVIRReader.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// This file defines the LVIRReader class, which is used to describe a
10// LLVM IR reader.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H
15#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H
16
20#include <unordered_map>
21
22namespace llvm {
23class DIFile;
24class DINode;
25class DILocation;
26class DIScope;
27class DISubprogram;
28class DIVariable;
29class BasicBlock;
30class Module;
31
32namespace object {
33class IRObjectFile;
34}
35
36namespace logicalview {
37
38class LVElement;
39class LVLine;
41class LVSymbol;
42class LVType;
43struct LVSourceLanguage;
44
45class LLVM_ABI LVIRReader final : public LVReader {
47
48 // Used by the metadata 'dump' functions, so the metadata nodes will be
49 // numbered canonically; otherwise, pointer addresses are substituted.
50 Module *TheModule = nullptr;
51
52 // Symbols with locations for current compile unit.
53 LVSymbols SymbolsWithLocations;
54
55 const DICompileUnit *CUNode = nullptr;
56
57 // The Dwarf version (from the module flags).
58 unsigned DwarfVersion = 0;
59
60 // Location index for global variables.
61 uint64_t PoolAddressIndex = 0;
62
63 // Default lower bound for arrays.
64 int64_t DefaultLowerBound = 0;
65
66 // Whether to emit all linkage names, or just abstract subprograms.
67 bool UseAllLinkageNames = true;
68
69 SSAValueNameMap ValueNameMap;
70 DenseMap<void *, uint64_t> InstrLineAddrMap;
71 std::unique_ptr<DbgValueRangeTable> DbgValueRanges;
72
73 // Record the last assigned file index for each compile unit.
74 // This data structure is to aid mapping DIFiles onto a DWARF-like file table.
75 using LVIndexFiles = std::unordered_map<LVScopeCompileUnit *, size_t>;
76 LVIndexFiles IndexFiles;
77
78 // Store a FileID number for each DIFile seen.
79 using LVCompileUnitFiles = std::unordered_map<const DIFile *, size_t>;
80 LVCompileUnitFiles CompileUnitFiles;
81
82 // Associate the metadata objects to logical elements.
83 using LVMDObjects = std::unordered_map<const MDNode *, LVElement *>;
84 LVMDObjects MDObjects;
85
86 // An anonymous type for index type.
87 LVType *NodeIndexType = nullptr;
88
89 // Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only
90 // difference is setting the 'DICompileUnit::splitDebugFilename' to the
91 // name of the split filename: "xxx.dwo".
92 bool includeMinimalInlineScopes() const;
93 bool useAllLinkageNames() const { return UseAllLinkageNames; }
94
95 int64_t getDefaultLowerBound() const { return DefaultLowerBound; }
96 void setDefaultLowerBound(LVSourceLanguage *SL);
97
98 // We assume a constant instruction-size increase between instructions.
99 static constexpr unsigned OFFSET_INCREASE = 4;
100 void updateLineOffset() { CurrentOffset += OFFSET_INCREASE; }
101
102 void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) {
103 auto [Iter, Inserted] = IndexFiles.try_emplace(CompileUnit, FileIndex);
104 if (!Inserted)
105 Iter->second = FileIndex;
106 }
107
108 // Get the current assigned index file for the given compile unit.
109 size_t getFileIndex(LVScopeCompileUnit *CompileUnit) {
110 LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit);
111 return Iter != IndexFiles.end() ? Iter->second : 0;
112 }
113
114 // For the given 'DIFile', generate a 1-based index to indicate the
115 // source file where the logical element is declared.
116 // The IR reader expects the indexes to be 1-based.
117 // Each compile unit, keeps track of the last assigned index.
118 size_t getOrCreateSourceID(const DIFile *File);
119
120 void addMD(const MDNode *MD, LVElement *Element) {
121 MDObjects.try_emplace(MD, Element);
122 }
123 LVElement *getElementForSeenMD(const MDNode *MD) const {
124 LVMDObjects::const_iterator Iter = MDObjects.find(MD);
125 return Iter != MDObjects.end() ? Iter->second : nullptr;
126 }
127 LVScope *getScopeForSeenMD(const MDNode *MD) const {
128 return static_cast<LVScope *>(getElementForSeenMD(MD));
129 }
130 LVSymbol *getSymbolForSeenMD(const MDNode *MD) const {
131 return static_cast<LVSymbol *>(getElementForSeenMD(MD));
132 }
133 LVType *getTypeForSeenMD(const MDNode *MD) const {
134 return static_cast<LVType *>(getElementForSeenMD(MD));
135 }
136 LVLine *getLineForSeenMD(const MDNode *MD) const {
137 return static_cast<LVLine *>(getElementForSeenMD(MD));
138 }
139
140 const DIFile *getMDFile(const MDNode *MD) const;
141 StringRef getMDName(const DINode *DN) const;
142 const DIScope *getMDScope(const DINode *DN) const;
143
145
146 // Get current metadata DICompileUnit object.
147 const DICompileUnit *getCUNode() const { return CUNode; }
148
149 // Get the parent scope for the given metadata object.
150 LVScope *getParentScopeImpl(const DIScope *Context);
151 LVScope *getParentScope(const DINode *DN);
152 LVScope *getParentScope(const DILocation *DL);
153
154 // Traverse the scope hierarchy and create each node in the hierarchy.
155 LVScope *traverseParentScope(const DIScope *Context);
156
157 // Create the location ranges for the given scope and in the case of
158 // functions, generate an entry in the public names set.
159 void constructRange(LVScope *Scope, LVAddress LowPC, LVAddress HighPC);
160 void constructRange(LVScope *Scope);
161
162 // Generate debug logical lines for the given function.
163 void processBasicBlocks(Function &F);
164
165 // Add accessibility information if available.
166 void addAccess(LVElement *Element, DINode::DIFlags Flags);
167
168 // Add a constant value to a logical element.
169 void addConstantValue(LVElement *Element, const DIExpression *DIExpr);
170 void addConstantValue(LVElement *Element, const ConstantFP *CFP);
171 void addConstantValue(LVElement *Element, const ConstantInt *CI,
172 const DIType *Ty);
173 void addConstantValue(LVElement *Element, const APInt &Value,
174 const DIType *Ty);
175 void addConstantValue(LVElement *Element, const APInt &Value, bool Unsigned);
176 void addConstantValue(LVElement *Element, uint64_t Value, const DIType *Ty);
177 void addConstantValue(LVElement *Element, uint64_t Value, bool Unsigned);
178
179 // Add template parameters to logical element.
180 void addTemplateParams(LVElement *Element, const DINodeArray TParams);
181
182 // Add location information to specified logical element.
183 void addSourceLine(LVElement *Element, unsigned Line, const DIFile *File);
184 void addSourceLine(LVElement *Element, const DIGlobalVariable *GV);
185 void addSourceLine(LVElement *Element, const DIImportedEntity *IE);
186 void addSourceLine(LVElement *Element, const DILabel *L);
187 void addSourceLine(LVElement *Element, const DILocalVariable *LV);
188 void addSourceLine(LVElement *Element, const DILocation *DL);
189 void addSourceLine(LVElement *Element, const DIObjCProperty *OP);
190 void addSourceLine(LVElement *Element, const DISubprogram *SP);
191 void addSourceLine(LVElement *Element, const DIType *Ty);
192
193 void applySubprogramAttributes(LVScope *Function, const DISubprogram *SP,
194 bool SkipSPAttributes = false);
195 bool applySubprogramDefinitionAttributes(LVScope *Function,
196 const DISubprogram *SP,
197 bool Minimal = false);
198
199 void constructAggregate(LVScopeAggregate *Aggregate,
200 const DICompositeType *CTy);
201 void constructArray(LVScopeArray *Array, const DICompositeType *CTy);
202 void constructEnum(LVScopeEnumeration *Enumeration,
203 const DICompositeType *CTy);
204 void constructGenericSubrange(LVScopeArray *Array,
205 const DIGenericSubrange *GSR,
206 LVType *IndexType);
207 void constructImportedEntity(LVElement *Element, const DIImportedEntity *IE);
208
209 void constructLine(LVScope *Scope, const DISubprogram *SP, Instruction &I,
210 bool &GenerateLineBeforePrologue);
211
212 LVSymbol *getOrCreateMember(LVScope *Aggregate, const DIDerivedType *DT);
213 LVSymbol *getOrCreateStaticMember(LVScope *Aggregate,
214 const DIDerivedType *DT);
215
216 LVScope *getOrCreateNamespace(const DINamespace *NS);
217 LVScope *getOrCreateScope(const DIScope *Context);
218 void constructScope(LVElement *Element, const DIScope *Context);
219
220 LVScope *getOrCreateSubprogram(const DISubprogram *SP);
221 LVScope *getOrCreateSubprogram(LVScope *Function, const DISubprogram *SP,
222 bool Minimal = false);
223 void constructSubprogramArguments(LVScope *Function, const DITypeArray Args);
224
225 LVScope *getOrCreateAbstractScope(const DILocation *DL);
226 LVScope *getOrCreateInlinedScope(const DILocation *DL);
227
228 void constructSubrange(LVScopeArray *Array, const DISubrange *SR,
229 LVType *IndexType);
230
231 void constructTemplateTypeParameter(LVElement *Element,
232 const DITemplateTypeParameter *TTP);
233 void constructTemplateValueParameter(LVElement *Element,
234 const DITemplateValueParameter *TVP);
235
236 LVElement *getOrCreateType(const DIType *Ty) {
237 return getOrCreateType(/*Scope=*/nullptr, Ty);
238 }
239 LVElement *getOrCreateType(LVScope *Scope, const DIType *Ty);
240 void constructType(LVScope *Scope, const DICompositeType *CTy);
241 void constructType(LVElement *Element, const DIDerivedType *DT);
242 void constructType(LVScope *Function, const DISubroutineType *SPTy);
243
244 LVSymbol *getOrCreateVariable(const DIGlobalVariableExpression *GVE);
245 LVSymbol *getOrCreateVariable(const DIVariable *Var,
246 const DILocation *DL = nullptr);
247 LVSymbol *getOrCreateInlinedVariable(LVSymbol *OriginSymbol,
248 const DILocation *DL);
249
250 LVElement *constructElement(const DINode *DN);
251
252 // After the scopes have been created, remove empty ones.
253 void removeEmptyScopes();
254
255 // Adjust the inlined lexical scopes to their correct scope.
256 void resolveInlinedLexicalScopes();
257
258 void processLocationGaps();
259 void processScopes();
260
261 // Check if the scopes have been properly constructed (finalized).
262 void checkScopes(LVScope *Scope);
263
264protected:
265 Error createScopes() override;
266 void sortScopes() override;
267
268public:
269 LVIRReader() = delete;
278 LVIRReader(const LVIRReader &) = delete;
279 LVIRReader &operator=(const LVIRReader &) = delete;
280 ~LVIRReader() = default;
281
283 return SymbolsWithLocations;
284 }
285
286 std::string getRegisterName(LVSmall Opcode,
287 ArrayRef<uint64_t> Operands) override;
288
289 void print(raw_ostream &OS) const;
290#ifdef LLVM_DEBUG
291 void printAllInstructions(BasicBlock *BB);
292#else
294#endif
295
296#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
297 void dump() const { print(dbgs()); }
298#endif
299};
300
301} // end namespace logicalview
302} // end namespace llvm
303
304#endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define LLVM_ABI
Definition Compiler.h:215
static Type * getIndexType(Value *In)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
#define OP(OPC)
Definition Instruction.h:46
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
This is the shared class of boolean and integer constants.
Definition Constants.h:87
DWARF expression.
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Debug lexical block.
Tagged DWARF-like metadata node.
DIFlags
Debug info flags.
Base class for scope-like contexts.
Subprogram description. Uses SubclassData1.
Array subrange.
Type array for a subprogram.
Base class for types.
Base class for variables.
Utility class used to find and store the live debug ranges for variables in a module.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Metadata node.
Definition Metadata.h:1069
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
A discriminated union of two or more pointer types, with the discriminator in the low bits of the poi...
Utility class used to store the names of SSA values after their owning modules have been destroyed.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM Value Representation.
Definition Value.h:75
const LVSymbols & GetSymbolsWithLocations() const
Definition LVIRReader.h:282
LVIRReader(StringRef Filename, StringRef FileFormatName, object::IRObjectFile *Obj, ScopedPrinter &W)
Definition LVIRReader.h:270
void printAllInstructions(BasicBlock *BB)
Definition LVIRReader.h:293
LVIRReader & operator=(const LVIRReader &)=delete
LVIRReader(StringRef Filename, StringRef FileFormatName, MemoryBufferRef *Obj, ScopedPrinter &W)
Definition LVIRReader.h:274
LVIRReader(const LVIRReader &)=delete
LVScopeCompileUnit * CompileUnit
Definition LVReader.h:149
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
SmallVector< LVSymbol *, 8 > LVSymbols
Definition LVObject.h:81
uint8_t LVSmall
Definition LVObject.h:42
uint64_t LVAddress
Definition LVObject.h:36
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
A source language supported by any of the debug info representations.