LLVM 18.0.0git
AccelTable.h
Go to the documentation of this file.
1//==- include/llvm/CodeGen/AccelTable.h - Accelerator Tables -----*- 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/// \file
9/// This file contains support for writing accelerator tables.
10///
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_ACCELTABLE_H
14#define LLVM_CODEGEN_ACCELTABLE_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/MapVector.h"
19#include "llvm/ADT/StringMap.h"
20#include "llvm/ADT/StringRef.h"
22#include "llvm/CodeGen/DIE.h"
25#include "llvm/Support/DJB.h"
26#include "llvm/Support/Debug.h"
27#include <cstdint>
28#include <vector>
29
30/// \file
31/// The DWARF and Apple accelerator tables are an indirect hash table optimized
32/// for null lookup rather than access to known data. The Apple accelerator
33/// tables are a precursor of the newer DWARF v5 accelerator tables. Both
34/// formats share common design ideas.
35///
36/// The Apple accelerator table are output into an on-disk format that looks
37/// like this:
38///
39/// .------------------.
40/// | HEADER |
41/// |------------------|
42/// | BUCKETS |
43/// |------------------|
44/// | HASHES |
45/// |------------------|
46/// | OFFSETS |
47/// |------------------|
48/// | DATA |
49/// `------------------'
50///
51/// The header contains a magic number, version, type of hash function,
52/// the number of buckets, total number of hashes, and room for a special struct
53/// of data and the length of that struct.
54///
55/// The buckets contain an index (e.g. 6) into the hashes array. The hashes
56/// section contains all of the 32-bit hash values in contiguous memory, and the
57/// offsets contain the offset into the data area for the particular hash.
58///
59/// For a lookup example, we could hash a function name and take it modulo the
60/// number of buckets giving us our bucket. From there we take the bucket value
61/// as an index into the hashes table and look at each successive hash as long
62/// as the hash value is still the same modulo result (bucket value) as earlier.
63/// If we have a match we look at that same entry in the offsets table and grab
64/// the offset in the data for our final match.
65///
66/// The DWARF v5 accelerator table consists of zero or more name indices that
67/// are output into an on-disk format that looks like this:
68///
69/// .------------------.
70/// | HEADER |
71/// |------------------|
72/// | CU LIST |
73/// |------------------|
74/// | LOCAL TU LIST |
75/// |------------------|
76/// | FOREIGN TU LIST |
77/// |------------------|
78/// | HASH TABLE |
79/// |------------------|
80/// | NAME TABLE |
81/// |------------------|
82/// | ABBREV TABLE |
83/// |------------------|
84/// | ENTRY POOL |
85/// `------------------'
86///
87/// For the full documentation please refer to the DWARF 5 standard.
88///
89///
90/// This file defines the class template AccelTable, which is represents an
91/// abstract view of an Accelerator table, without any notion of an on-disk
92/// layout. This class is parameterized by an entry type, which should derive
93/// from AccelTableData. This is the type of individual entries in the table,
94/// and it should store the data necessary to emit them. AppleAccelTableData is
95/// the base class for Apple Accelerator Table entries, which have a uniform
96/// structure based on a sequence of Atoms. There are different sub-classes
97/// derived from AppleAccelTable, which differ in the set of Atoms and how they
98/// obtain their values.
99///
100/// An Apple Accelerator Table can be serialized by calling emitAppleAccelTable
101/// function.
102
103namespace llvm {
104
105class AsmPrinter;
106class DwarfCompileUnit;
107class DwarfDebug;
108class MCSymbol;
109class raw_ostream;
110
111/// Interface which the different types of accelerator table data have to
112/// conform. It serves as a base class for different values of the template
113/// argument of the AccelTable class template.
115public:
116 virtual ~AccelTableData() = default;
117
118 bool operator<(const AccelTableData &Other) const {
119 return order() < Other.order();
120 }
121
122 // Subclasses should implement:
123 // static uint32_t hash(StringRef Name);
124
125#ifndef NDEBUG
126 virtual void print(raw_ostream &OS) const = 0;
127#endif
128protected:
129 virtual uint64_t order() const = 0;
130};
131
132/// A base class holding non-template-dependant functionality of the AccelTable
133/// class. Clients should not use this class directly but rather instantiate
134/// AccelTable with a type derived from AccelTableData.
136public:
138
139 /// Represents a group of entries with identical name (and hence, hash value).
140 struct HashData {
143 std::vector<AccelTableData *> Values;
145
146#ifndef NDEBUG
147 void print(raw_ostream &OS) const;
148 void dump() const { print(dbgs()); }
149#endif
150 };
151 using HashList = std::vector<HashData *>;
152 using BucketList = std::vector<HashList>;
153
154protected:
155 /// Allocator for HashData and Values.
157
160
164
167
168 void computeBucketCount();
169
171
172public:
173 void finalize(AsmPrinter *Asm, StringRef Prefix);
178
179#ifndef NDEBUG
180 void print(raw_ostream &OS) const;
181 void dump() const { print(dbgs()); }
182#endif
183
185 void operator=(const AccelTableBase &) = delete;
186};
187
188/// This class holds an abstract representation of an Accelerator Table,
189/// consisting of a sequence of buckets, each bucket containint a sequence of
190/// HashData entries. The class is parameterized by the type of entries it
191/// holds. The type template parameter also defines the hash function to use for
192/// hashing names.
193template <typename DataT> class AccelTable : public AccelTableBase {
194public:
195 AccelTable() : AccelTableBase(DataT::hash) {}
196
197 template <typename... Types>
198 void addName(DwarfStringPoolEntryRef Name, Types &&... Args);
199};
200
201template <typename AccelTableDataT>
202template <typename... Types>
204 Types &&... Args) {
205 assert(Buckets.empty() && "Already finalized!");
206 // If the string is in the list already then add this die to the list
207 // otherwise add a new one.
208 auto &It = Entries[Name.getString()];
209 if (It.Values.empty()) {
210 It.Name = Name;
211 It.HashValue = Hash(Name.getString());
212 }
213 It.Values.push_back(new (Allocator)
214 AccelTableDataT(std::forward<Types>(Args)...));
215}
216
217/// A base class for different implementations of Data classes for Apple
218/// Accelerator Tables. The columns in the table are defined by the static Atoms
219/// variable defined on the subclasses.
221public:
222 /// An Atom defines the form of the data in an Apple accelerator table.
223 /// Conceptually it is a column in the accelerator consisting of a type and a
224 /// specification of the form of its data.
225 struct Atom {
226 /// Atom Type.
228 /// DWARF Form.
230
232
233#ifndef NDEBUG
234 void print(raw_ostream &OS) const;
235 void dump() const { print(dbgs()); }
236#endif
237 };
238 // Subclasses should define:
239 // static constexpr Atom Atoms[];
240
241 virtual void emit(AsmPrinter *Asm) const = 0;
242
243 static uint32_t hash(StringRef Buffer) { return djbHash(Buffer); }
244};
245
246/// The Data class implementation for DWARF v5 accelerator table. Unlike the
247/// Apple Data classes, this class is just a DIE wrapper, and does not know to
248/// serialize itself. The complete serialization logic is in the
249/// emitDWARF5AccelTable function.
251public:
253
255
256#ifndef NDEBUG
257 void print(raw_ostream &OS) const override;
258#endif
259
260 const DIE &getDie() const { return Die; }
261 uint64_t getDieOffset() const { return Die.getOffset(); }
262 unsigned getDieTag() const { return Die.getTag(); }
263
264protected:
265 const DIE &Die;
266
267 uint64_t order() const override { return Die.getOffset(); }
268};
269
271public:
273
275 unsigned CUIndex)
277
278#ifndef NDEBUG
279 void print(raw_ostream &OS) const override;
280#endif
281
282 uint64_t getDieOffset() const { return DieOffset; }
283 unsigned getDieTag() const { return DieTag; }
284 unsigned getCUIndex() const { return CUIndex; }
285
286protected:
288 unsigned DieTag;
289 unsigned CUIndex;
290
291 uint64_t order() const override { return DieOffset; }
292};
293
294void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
295 StringRef Prefix, const MCSymbol *SecBegin,
296 ArrayRef<AppleAccelTableData::Atom> Atoms);
297
298/// Emit an Apple Accelerator Table consisting of entries in the specified
299/// AccelTable. The DataT template parameter should be derived from
300/// AppleAccelTableData.
301template <typename DataT>
303 StringRef Prefix, const MCSymbol *SecBegin) {
304 static_assert(std::is_convertible<DataT *, AppleAccelTableData *>::value);
305 emitAppleAccelTableImpl(Asm, Contents, Prefix, SecBegin, DataT::Atoms);
306}
307
308void emitDWARF5AccelTable(AsmPrinter *Asm,
309 AccelTable<DWARF5AccelTableData> &Contents,
310 const DwarfDebug &DD,
311 ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs);
312
314 AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents,
315 ArrayRef<MCSymbol *> CUs,
316 llvm::function_ref<unsigned(const DWARF5AccelTableStaticData &)>
317 getCUIndexForEntry);
318
319/// Accelerator table data implementation for simple Apple accelerator tables
320/// with just a DIE reference.
322public:
324
325 void emit(AsmPrinter *Asm) const override;
326
327 static constexpr Atom Atoms[] = {
328 Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)};
329
330#ifndef NDEBUG
331 void print(raw_ostream &OS) const override;
332#endif
333protected:
334 uint64_t order() const override { return Die.getOffset(); }
335
336 const DIE &Die;
337};
338
339/// Accelerator table data implementation for Apple type accelerator tables.
341public:
343
344 void emit(AsmPrinter *Asm) const override;
345
346 static constexpr Atom Atoms[] = {
347 Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
348 Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
349 Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)};
350
351#ifndef NDEBUG
352 void print(raw_ostream &OS) const override;
353#endif
354};
355
356/// Accelerator table data implementation for simple Apple accelerator tables
357/// with a DIE offset but no actual DIE pointer.
359public:
361
362 void emit(AsmPrinter *Asm) const override;
363
364 static constexpr Atom Atoms[] = {
365 Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)};
366
367#ifndef NDEBUG
368 void print(raw_ostream &OS) const override;
369#endif
370protected:
371 uint64_t order() const override { return Offset; }
372
374};
375
376/// Accelerator table data implementation for type accelerator tables with
377/// a DIE offset but no actual DIE pointer.
379public:
386
387 void emit(AsmPrinter *Asm) const override;
388
389 static constexpr Atom Atoms[] = {
390 Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
391 Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
392 Atom(5, dwarf::DW_FORM_data1), Atom(6, dwarf::DW_FORM_data4)};
393
394#ifndef NDEBUG
395 void print(raw_ostream &OS) const override;
396#endif
397protected:
398 uint64_t order() const override { return Offset; }
399
403};
404
405} // end namespace llvm
406
407#endif // LLVM_CODEGEN_ACCELTABLE_H
This file defines the StringMap class.
arc branch finalize
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
dxil metadata emit
This file contains constants used for implementing Dwarf debug support.
std::string Name
This file implements a map that provides insertion order iteration.
Basic Register Allocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
A base class holding non-template-dependant functionality of the AccelTable class.
Definition: AccelTable.h:135
BucketList Buckets
Definition: AccelTable.h:166
uint32_t getUniqueNameCount() const
Definition: AccelTable.h:177
std::vector< HashData * > HashList
Definition: AccelTable.h:151
std::vector< HashList > BucketList
Definition: AccelTable.h:152
BumpPtrAllocator Allocator
Allocator for HashData and Values.
Definition: AccelTable.h:156
void operator=(const AccelTableBase &)=delete
uint32_t getUniqueHashCount() const
Definition: AccelTable.h:176
void print(raw_ostream &OS) const
Definition: AccelTable.cpp:664
void dump() const
Definition: AccelTable.h:181
AccelTableBase(const AccelTableBase &)=delete
AccelTableBase(HashFn *Hash)
Definition: AccelTable.h:170
ArrayRef< HashList > getBuckets() const
Definition: AccelTable.h:174
uint32_t getBucketCount() const
Definition: AccelTable.h:175
uint32_t(StringRef) HashFn
Definition: AccelTable.h:137
uint32_t UniqueHashCount
Definition: AccelTable.h:163
StringEntries Entries
Definition: AccelTable.h:159
Interface which the different types of accelerator table data have to conform.
Definition: AccelTable.h:114
virtual uint64_t order() const =0
virtual ~AccelTableData()=default
virtual void print(raw_ostream &OS) const =0
bool operator<(const AccelTableData &Other) const
Definition: AccelTable.h:118
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:193
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
Definition: AccelTable.h:203
A base class for different implementations of Data classes for Apple Accelerator Tables.
Definition: AccelTable.h:220
virtual void emit(AsmPrinter *Asm) const =0
static uint32_t hash(StringRef Buffer)
Definition: AccelTable.h:243
Accelerator table data implementation for simple Apple accelerator tables with just a DIE reference.
Definition: AccelTable.h:321
uint64_t order() const override
Definition: AccelTable.h:334
void print(raw_ostream &OS) const override
Definition: AccelTable.cpp:693
static constexpr Atom Atoms[]
Definition: AccelTable.h:327
AppleAccelTableOffsetData(const DIE &D)
Definition: AccelTable.h:323
Accelerator table data implementation for simple Apple accelerator tables with a DIE offset but no ac...
Definition: AccelTable.h:358
AppleAccelTableStaticOffsetData(uint32_t Offset)
Definition: AccelTable.h:360
static constexpr Atom Atoms[]
Definition: AccelTable.h:364
void print(raw_ostream &OS) const override
Definition: AccelTable.cpp:702
uint64_t order() const override
Definition: AccelTable.h:371
Accelerator table data implementation for type accelerator tables with a DIE offset but no actual DIE...
Definition: AccelTable.h:378
void print(raw_ostream &OS) const override
Definition: AccelTable.cpp:706
static constexpr Atom Atoms[]
Definition: AccelTable.h:389
uint64_t order() const override
Definition: AccelTable.h:398
AppleAccelTableStaticTypeData(uint32_t Offset, uint16_t Tag, bool ObjCClassIsImplementation, uint32_t QualifiedNameHash)
Definition: AccelTable.h:380
Accelerator table data implementation for Apple type accelerator tables.
Definition: AccelTable.h:340
void print(raw_ostream &OS) const override
Definition: AccelTable.cpp:697
AppleAccelTableTypeData(const DIE &D)
Definition: AccelTable.h:342
static constexpr Atom Atoms[]
Definition: AccelTable.h:346
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:85
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
A structured debug information entry.
Definition: DIE.h:819
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Definition: DIE.h:857
dwarf::Tag getTag() const
Definition: DIE.h:855
The Data class implementation for DWARF v5 accelerator table.
Definition: AccelTable.h:250
static uint32_t hash(StringRef Name)
Definition: AccelTable.h:252
void print(raw_ostream &OS) const override
Definition: AccelTable.cpp:683
DWARF5AccelTableData(const DIE &Die)
Definition: AccelTable.h:254
unsigned getDieTag() const
Definition: AccelTable.h:262
const DIE & getDie() const
Definition: AccelTable.h:260
uint64_t order() const override
Definition: AccelTable.h:267
uint64_t getDieOffset() const
Definition: AccelTable.h:261
static uint32_t hash(StringRef Name)
Definition: AccelTable.h:272
DWARF5AccelTableStaticData(uint64_t DieOffset, unsigned DieTag, unsigned CUIndex)
Definition: AccelTable.h:274
void print(raw_ostream &OS) const override
Definition: AccelTable.cpp:688
uint64_t order() const override
Definition: AccelTable.h:291
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
size_type size() const
Definition: MapVector.h:60
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
@ DW_ATOM_type_flags
Definition: Dwarf.h:599
@ DW_ATOM_die_tag
Definition: Dwarf.h:598
@ DW_ATOM_die_offset
Marker as the end of a list of atoms.
Definition: Dwarf.h:595
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, StringRef Prefix, const MCSymbol *SecBegin, ArrayRef< AppleAccelTableData::Atom > Atoms)
Definition: AccelTable.cpp:538
void emitDWARF5AccelTable(AsmPrinter *Asm, AccelTable< DWARF5AccelTableData > &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
Definition: AccelTable.cpp:545
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
@ Other
Any other memory.
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
Definition: AccelTable.h:302
uint32_t caseFoldingDjbHash(StringRef Buffer, uint32_t H=5381)
Computes the Bernstein hash after folding the input according to the Dwarf 5 standard case folding ru...
Definition: DJB.cpp:72
uint32_t djbHash(StringRef Buffer, uint32_t H=5381)
The Bernstein hash function used by the DWARF accelerator tables.
Definition: DJB.h:21
Represents a group of entries with identical name (and hence, hash value).
Definition: AccelTable.h:140
void print(raw_ostream &OS) const
Definition: AccelTable.cpp:651
DwarfStringPoolEntryRef Name
Definition: AccelTable.h:141
std::vector< AccelTableData * > Values
Definition: AccelTable.h:143
An Atom defines the form of the data in an Apple accelerator table.
Definition: AccelTable.h:225
const uint16_t Form
DWARF Form.
Definition: AccelTable.h:229
void print(raw_ostream &OS) const
Definition: AccelTable.cpp:633
const uint16_t Type
Atom Type.
Definition: AccelTable.h:227
constexpr Atom(uint16_t Type, uint16_t Form)
Definition: AccelTable.h:231