//==- include/llvm/CodeGen/AccelTable.h - Accelerator Tables -----*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file contains support for writing accelerator tables. /// //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_ACCELTABLE_H #define LLVM_CODEGEN_ACCELTABLE_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/DIE.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/DJB.h" #include "llvm/Support/Debug.h" #include <cstdint> #include <variant> #include <vector> /// \file /// The DWARF and Apple accelerator tables are an indirect hash table optimized /// for null lookup rather than access to known data. The Apple accelerator /// tables are a precursor of the newer DWARF v5 accelerator tables. Both /// formats share common design ideas. /// /// The Apple accelerator table are output into an on-disk format that looks /// like this: /// /// .------------------. /// | HEADER | /// |------------------| /// | BUCKETS | /// |------------------| /// | HASHES | /// |------------------| /// | OFFSETS | /// |------------------| /// | DATA | /// `------------------' /// /// The header contains a magic number, version, type of hash function, /// the number of buckets, total number of hashes, and room for a special struct /// of data and the length of that struct. /// /// The buckets contain an index (e.g. 6) into the hashes array. The hashes /// section contains all of the 32-bit hash values in contiguous memory, and the /// offsets contain the offset into the data area for the particular hash. /// /// For a lookup example, we could hash a function name and take it modulo the /// number of buckets giving us our bucket. From there we take the bucket value /// as an index into the hashes table and look at each successive hash as long /// as the hash value is still the same modulo result (bucket value) as earlier. /// If we have a match we look at that same entry in the offsets table and grab /// the offset in the data for our final match. /// /// The DWARF v5 accelerator table consists of zero or more name indices that /// are output into an on-disk format that looks like this: /// /// .------------------. /// | HEADER | /// |------------------| /// | CU LIST | /// |------------------| /// | LOCAL TU LIST | /// |------------------| /// | FOREIGN TU LIST | /// |------------------| /// | HASH TABLE | /// |------------------| /// | NAME TABLE | /// |------------------| /// | ABBREV TABLE | /// |------------------| /// | ENTRY POOL | /// `------------------' /// /// For the full documentation please refer to the DWARF 5 standard. /// /// /// This file defines the class template AccelTable, which is represents an /// abstract view of an Accelerator table, without any notion of an on-disk /// layout. This class is parameterized by an entry type, which should derive /// from AccelTableData. This is the type of individual entries in the table, /// and it should store the data necessary to emit them. AppleAccelTableData is /// the base class for Apple Accelerator Table entries, which have a uniform /// structure based on a sequence of Atoms. There are different sub-classes /// derived from AppleAccelTable, which differ in the set of Atoms and how they /// obtain their values. /// /// An Apple Accelerator Table can be serialized by calling emitAppleAccelTable /// function. namespace llvm { class AsmPrinter; class DwarfDebug; class DwarfTypeUnit; class MCSymbol; class raw_ostream; /// Interface which the different types of accelerator table data have to /// conform. It serves as a base class for different values of the template /// argument of the AccelTable class template. class AccelTableData { … }; /// A base class holding non-template-dependant functionality of the AccelTable /// class. Clients should not use this class directly but rather instantiate /// AccelTable with a type derived from AccelTableData. class AccelTableBase { … }; /// This class holds an abstract representation of an Accelerator Table, /// consisting of a sequence of buckets, each bucket containint a sequence of /// HashData entries. The class is parameterized by the type of entries it /// holds. The type template parameter also defines the hash function to use for /// hashing names. template <typename DataT> class AccelTable : public AccelTableBase { … }; template <typename AccelTableDataT> template <typename... Types> void AccelTable<AccelTableDataT>::addName(DwarfStringPoolEntryRef Name, Types &&... Args) { … } /// A base class for different implementations of Data classes for Apple /// Accelerator Tables. The columns in the table are defined by the static Atoms /// variable defined on the subclasses. class AppleAccelTableData : public AccelTableData { … }; /// Helper class to identify an entry in DWARF5AccelTable based on their DIE /// offset and UnitID. struct OffsetAndUnitID { … }; template <> struct DenseMapInfo<OffsetAndUnitID> { … }; /// The Data class implementation for DWARF v5 accelerator table. Unlike the /// Apple Data classes, this class is just a DIE wrapper, and does not know to /// serialize itself. The complete serialization logic is in the /// emitDWARF5AccelTable function. class DWARF5AccelTableData : public AccelTableData { … }; class DebugNamesAbbrev : public FoldingSetNode { … }; struct TypeUnitMetaInfo { … }; TUVectorTy; class DWARF5AccelTable : public AccelTable<DWARF5AccelTableData> { … }; void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, StringRef Prefix, const MCSymbol *SecBegin, ArrayRef<AppleAccelTableData::Atom> Atoms); /// Emit an Apple Accelerator Table consisting of entries in the specified /// AccelTable. The DataT template parameter should be derived from /// AppleAccelTableData. template <typename DataT> void emitAppleAccelTable(AsmPrinter *Asm, AccelTable<DataT> &Contents, StringRef Prefix, const MCSymbol *SecBegin) { … } void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs); /// Emit a DWARFv5 Accelerator Table consisting of entries in the specified /// AccelTable. The \p CUs contains either symbols keeping offsets to the /// start of compilation unit, either offsets to the start of compilation /// unit themselves. void emitDWARF5AccelTable( AsmPrinter *Asm, DWARF5AccelTable &Contents, ArrayRef<std::variant<MCSymbol *, uint64_t>> CUs, llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>( const DWARF5AccelTableData &)> getIndexForEntry); /// Accelerator table data implementation for simple Apple accelerator tables /// with just a DIE reference. class AppleAccelTableOffsetData : public AppleAccelTableData { … }; /// Accelerator table data implementation for Apple type accelerator tables. class AppleAccelTableTypeData : public AppleAccelTableOffsetData { … }; /// Accelerator table data implementation for simple Apple accelerator tables /// with a DIE offset but no actual DIE pointer. class AppleAccelTableStaticOffsetData : public AppleAccelTableData { … }; /// Accelerator table data implementation for type accelerator tables with /// a DIE offset but no actual DIE pointer. class AppleAccelTableStaticTypeData : public AppleAccelTableStaticOffsetData { … }; } // end namespace llvm #endif // LLVM_CODEGEN_ACCELTABLE_H