1135 lines · plain
1=================2TableGen BackEnds3=================4 5.. contents::6 :local:7 8Introduction9============10 11TableGen backends are at the core of TableGen's functionality. The source12files provide the classes and records that are parsed and end up as a13collection of record instances, but it's up to the backend to interpret and14print the records in a way that is meaningful to the user (normally a C++15include file or a textual list of warnings, options, and error messages).16 17TableGen is used by both LLVM, Clang, and MLIR with very different goals.18LLVM uses it as a way to automate the generation of massive amounts of19information regarding instructions, schedules, cores, and architecture20features. Some backends generate output that is consumed by more than one21source file, so they need to be created in a way that makes it is easy for22preprocessor tricks to be used. Some backends can also print C++ code23structures, so that they can be directly included as-is.24 25Clang, on the other hand, uses it mainly for diagnostic messages (errors,26warnings, tips) and attributes, so more on the textual end of the scale.27 28MLIR uses TableGen to define operations, operation dialects, and operation29traits.30 31See the :doc:`TableGen Programmer's Reference <./ProgRef>` for an in-depth32description of TableGen, and the :doc:`TableGen Backend Developer's Guide33<./BackGuide>` for a guide to writing a new backend.34 35LLVM BackEnds36=============37 38.. warning::39 This portion is incomplete. Each section below needs three subsections:40 description of its purpose with a list of users, output generated from41 generic input, and finally why it needed a new backend (in case there's42 something similar).43 44Overall, each backend will take the same TableGen file type and transform into45similar output for different targets/uses. There is an implicit contract between46the TableGen files, the back-ends and their users.47 48For instance, a global contract is that each back-end produces macro-guarded49sections. Based on whether the file is included by a header or a source file,50or even in which context of each file the include is being used, you have51to define a macro just before including it, to get the right output:52 53.. code-block:: c++54 55 #define GET_REGINFO_TARGET_DESC56 #include "ARMGenRegisterInfo.inc"57 58And just part of the generated file would be included. This is useful if59you need the same information in multiple formats (instantiation, initialization,60getter/setter functions, etc) from the same source TableGen file without having61to re-compile the TableGen file multiple times.62 63Sometimes, multiple macros might be defined before the same include file to64output multiple blocks:65 66.. code-block:: c++67 68 #define GET_REGISTER_MATCHER69 #define GET_SUBTARGET_FEATURE_NAME70 #define GET_MATCHER_IMPLEMENTATION71 #include "ARMGenAsmMatcher.inc"72 73The macros will be undef'd automatically as they're used, in the include file.74 75On all LLVM back-ends, the ``llvm-tblgen`` binary will be executed on the root76TableGen file ``<Target>.td``, which should include all others. This guarantees77that all information needed is accessible, and that no duplication is needed78in the TableGen files.79 80CodeEmitter81-----------82 83**Purpose**: ``CodeEmitterGen`` uses the descriptions of instructions and their fields to84construct an automated code emitter: a function that, given a ``MachineInstr``,85returns the (currently, 32-bit unsigned) value of the instruction.86 87**Output**: C++ code, implementing the target's CodeEmitter88class by overriding the virtual functions as ``<Target>CodeEmitter::function()``.89 90**Usage**: Used to include directly at the end of ``<Target>MCCodeEmitter.cpp``.91 92RegisterInfo93------------94 95**Purpose**: This tablegen backend is responsible for emitting a description of a target96register file for a code generator. It uses instances of the Register,97RegisterAliases, and RegisterClass classes to gather this information.98 99**Output**: C++ code with enums and structures representing the register mappings,100properties, masks, etc.101 102**Usage**: Both on ``<Target>BaseRegisterInfo`` and ``<Target>MCTargetDesc`` (headers103and source files) with macros defining in which they are for declaration vs.104initialization issues.105 106InstrInfo107---------108 109**Purpose**: This tablegen backend is responsible for emitting a description of the target110instruction set for the code generator. (what are the differences from CodeEmitter?)111 112**Output**: C++ code with enums and structures representing the instruction mappings,113properties, masks, etc.114 115**Usage**: Both on ``<Target>BaseInstrInfo`` and ``<Target>MCTargetDesc`` (headers116and source files) with macros defining in which they are for declaration vs.117initialization issues.118 119AsmWriter120---------121 122**Purpose**: Emits an assembly printer for the current target.123 124**Output**: Implementation of ``<Target>InstPrinter::printInstruction()``, among125other things.126 127**Usage**: Included directly into ``InstPrinter/<Target>InstPrinter.cpp``.128 129AsmMatcher130----------131 132**Purpose**: Emits a target specifier matcher for133converting parsed assembly operands in the ``MCInst`` structures. It also134emits a matcher for custom operand parsing. Extensive documentation is135written on the ``AsmMatcherEmitter.cpp`` file.136 137**Output**: Assembler parsers' matcher functions, declarations, etc.138 139**Usage**: Used in back-ends' ``AsmParser/<Target>AsmParser.cpp`` for140building the AsmParser class.141 142Disassembler143------------144 145**Purpose**: Contains disassembler table emitters for various146architectures. Extensive documentation is written on the147``DisassemblerEmitter.cpp`` file.148 149**Output**: Decoding tables, static decoding functions, etc.150 151**Usage**: Directly included in ``Disassembler/<Target>Disassembler.cpp``152to cater for all default decodings, after all hand-made ones.153 154PseudoLowering155--------------156 157**Purpose**: Generate pseudo instruction lowering.158 159**Output**: Implements ``<Target>AsmPrinter::emitPseudoExpansionLowering()``.160 161**Usage**: Included directly into ``<Target>AsmPrinter.cpp``.162 163CallingConv164-----------165 166**Purpose**: Responsible for emitting descriptions of the calling167conventions supported by this target.168 169**Output**: Implement static functions to deal with calling conventions170chained by matching styles, returning ``false`` on no match.171 172**Usage**: Used in ISelLowering and FastIsel as function pointers to173implementation returned by a CC selection function.174 175DAGISel176-------177 178**Purpose**: Generate a DAG instruction selector.179 180**Output**: Creates huge functions for automating DAG selection.181 182**Usage**: Included in ``<Target>ISelDAGToDAG.cpp`` inside the target's183implementation of ``SelectionDAGISel``.184 185DFAPacketizer186-------------187 188**Purpose**: This class parses the Schedule.td file and produces an API that189can be used to reason about whether an instruction can be added to a packet190on a VLIW architecture. The class internally generates a deterministic finite191automaton (DFA) that models all possible mappings of machine instructions192to functional units as instructions are added to a packet.193 194**Output**: Scheduling tables for GPU back-ends (Hexagon, AMD).195 196**Usage**: Included directly on ``<Target>InstrInfo.cpp``.197 198FastISel199--------200 201**Purpose**: This tablegen backend emits code for use by the "fast"202instruction selection algorithm. See the comments at the top of203``lib/CodeGen/SelectionDAG/FastISel.cpp`` for background. This file204scans through the target's tablegen instruction-info files205and extracts instructions with obvious-looking patterns, and it emits206code to look up these instructions by type and operator.207 208**Output**: Generates ``Predicate`` and ``FastEmit`` methods.209 210**Usage**: Implements private methods of the targets' implementation211of ``FastISel`` class.212 213Subtarget214---------215 216**Purpose**: Generate subtarget enumerations.217 218**Output**: Enums, globals, local tables for sub-target information.219 220**Usage**: Populates ``<Target>Subtarget`` and221``MCTargetDesc/<Target>MCTargetDesc`` files (both headers and source).222 223Intrinsic224---------225 226**Purpose**: Generate (target) intrinsic information.227 228OptParserDefs229-------------230 231**Purpose**: Print enum values for a class.232 233SearchableTables234----------------235 236**Purpose**: Generate custom searchable tables.237 238**Output**: Enums, global tables, and lookup helper functions.239 240**Usage**: This backend allows generating free-form, target-specific tables241from TableGen records. The ARM and AArch64 targets use this backend to generate242tables of system registers; the AMDGPU target uses it to generate meta-data243about complex image and memory buffer instructions.244 245See `SearchableTables Reference`_ for a detailed description.246 247CTags248-----249 250**Purpose**: This tablegen backend emits an index of definitions in ctags(1)251format. A helper script, utils/TableGen/tdtags, provides an easier-to-use252interface; run 'tdtags -H' for documentation.253 254X86EVEX2VEX255-----------256 257**Purpose**: This X86 specific tablegen backend emits tables that map EVEX258encoded instructions to their VEX encoded identical instruction.259 260Clang BackEnds261==============262 263ClangAttrClasses264----------------265 266**Purpose**: Creates Attrs.inc, which contains semantic attribute class267declarations for any attribute in ``Attr.td`` that has not set ``ASTNode = 0``.268This file is included as part of ``Attr.h``.269 270ClangAttrParserStringSwitches271-----------------------------272 273**Purpose**: Creates ``AttrParserStringSwitches.inc``, which contains274``StringSwitch::Case`` statements for parser-related string switches. Each switch275is given its own macro (such as ``CLANG_ATTR_ARG_CONTEXT_LIST``, or276``CLANG_ATTR_IDENTIFIER_ARG_LIST``), which is expected to be defined before277including ``AttrParserStringSwitches.inc``, and undefined after.278 279ClangAttrImpl280-------------281 282**Purpose**: Creates ``AttrImpl.inc``, which contains semantic attribute class283definitions for any attribute in ``Attr.td`` that has not set ``ASTNode = 0``.284This file is included as part of ``AttrImpl.cpp``.285 286ClangAttrList287-------------288 289**Purpose**: Creates ``AttrList.inc``, which is used when a list of semantic290attribute identifiers is required. For instance, ``AttrKinds.h`` includes this291file to generate the list of ``attr::Kind`` enumeration values. This list is292separated out into multiple categories: attributes, inheritable attributes, and293inheritable parameter attributes. This categorization happens automatically294based on information in ``Attr.td`` and is used to implement the ``classof``295functionality required for ``dyn_cast`` and similar APIs.296 297ClangAttrPCHRead298----------------299 300**Purpose**: Creates ``AttrPCHRead.inc``, which is used to deserialize attributes301in the ``ASTReader::ReadAttributes`` function.302 303ClangAttrPCHWrite304-----------------305 306**Purpose**: Creates ``AttrPCHWrite.inc``, which is used to serialize attributes in307the ``ASTWriter::WriteAttributes`` function.308 309ClangAttrSpellings310---------------------311 312**Purpose**: Creates ``AttrSpellings.inc``, which is used to implement the313``__has_attribute`` feature test macro.314 315ClangAttrSpellingListIndex316--------------------------317 318**Purpose**: Creates ``AttrSpellingListIndex.inc``, which is used to map parsed319attribute spellings (including which syntax or scope was used) to an attribute320spelling list index. These spelling list index values are internal321implementation details exposed via322``AttributeList::getAttributeSpellingListIndex``.323 324ClangAttrVisitor325-------------------326 327**Purpose**: Creates ``AttrVisitor.inc``, which is used when implementing328recursive AST visitors.329 330ClangAttrTemplateInstantiate331----------------------------332 333**Purpose**: Creates ``AttrTemplateInstantiate.inc``, which implements the334``instantiateTemplateAttribute`` function, used when instantiating a template335that requires an attribute to be cloned.336 337ClangAttrParsedAttrList338-----------------------339 340**Purpose**: Creates ``AttrParsedAttrList.inc``, which is used to generate the341``AttributeList::Kind`` parsed attribute enumeration.342 343ClangAttrParsedAttrImpl344-----------------------345 346**Purpose**: Creates ``AttrParsedAttrImpl.inc``, which is used by347``AttributeList.cpp`` to implement several functions on the ``AttributeList``348class. This functionality is implemented via the ``AttrInfoMap ParsedAttrInfo``349array, which contains one element per parsed attribute object.350 351ClangAttrParsedAttrKinds352------------------------353 354**Purpose**: Creates ``AttrParsedAttrKinds.inc``, which is used to implement the355``AttributeList::getKind`` function, mapping a string (and syntax) to a parsed356attribute ``AttributeList::Kind`` enumeration.357 358ClangAttrIsTypeDependent359------------------------360 361**Purpose**: Creates ``AttrIsTypeDependent.inc``, which is used to implement the362``Sema::CheckAttributesOnDeducedType`` function, mapping an attribute kind to a363Sema function if it exists.364 365ClangAttrDump366-------------367 368**Purpose**: Creates ``AttrDump.inc``, which dumps information about an attribute.369It is used to implement ``ASTDumper::dumpAttr``.370 371ClangDiagsDefs372--------------373 374Generate Clang diagnostics definitions.375 376ClangDiagGroups377---------------378 379Generate Clang diagnostic groups.380 381ClangDiagsIndexName382-------------------383 384Generate Clang diagnostic name index.385 386ClangCommentNodes387-----------------388 389Generate Clang AST comment nodes.390 391ClangDeclNodes392--------------393 394Generate Clang AST declaration nodes.395 396ClangStmtNodes397--------------398 399Generate Clang AST statement nodes.400 401ClangSACheckers402---------------403 404Generate Clang Static Analyzer checkers.405 406ClangCommentHTMLTags407--------------------408 409Generate efficient matchers for HTML tag names that are used in documentation comments.410 411ClangCommentHTMLTagsProperties412------------------------------413 414Generate efficient matchers for HTML tag properties.415 416ClangCommentHTMLNamedCharacterReferences417----------------------------------------418 419Generate function to translate named character references to UTF-8 sequences.420 421ClangCommentCommandInfo422-----------------------423 424Generate command properties for commands that are used in documentation comments.425 426ClangCommentCommandList427-----------------------428 429Generate list of commands that are used in documentation comments.430 431ArmNeon432-------433 434Generate ``arm_neon.h`` for clang.435 436ArmNeonSema437-----------438 439Generate ARM NEON sema support for clang.440 441ArmNeonTest442-----------443 444Generate ARM NEON tests for clang.445 446AttrDocs447--------448 449**Purpose**: Creates ``AttributeReference.rst`` from ``AttrDocs.td``, and is450used for documenting user-facing attributes.451 452General BackEnds453================454 455Print Records456-------------457 458The TableGen command option ``--print-records`` invokes a simple backend459that prints all the classes and records defined in the source files. This is460the default backend option. See the :doc:`TableGen Backend Developer's Guide461<./BackGuide>` for more information.462 463Print Detailed Records464----------------------465 466The TableGen command option ``--print-detailed-records`` invokes a backend467that prints all the global variables, classes, and records defined in the468source files, with more detail than the default record printer. See the469:doc:`TableGen Backend Developer's Guide <./BackGuide>` for more470information.471 472JSON Reference473--------------474 475**Purpose**: Output all the values in every ``def``, as a JSON data476structure that can be easily parsed by a variety of languages. Useful477for writing custom backends without having to modify TableGen itself,478or for performing auxiliary analysis on the same TableGen data passed479to a built-in backend.480 481**Output**:482 483The root of the output file is a JSON object (i.e., dictionary),484containing the following fixed keys:485 486* ``!tablegen_json_version``: a numeric version field that will487 increase if an incompatible change is ever made to the structure of488 this data. The format described here corresponds to version 1.489 490* ``!instanceof``: a dictionary whose keys are the class names defined491 in the TableGen input. For each key, the corresponding value is an492 array of strings giving the names of ``def`` records that derive493 from that class. So ``root["!instanceof"]["Instruction"]``, for494 example, would list the names of all the records deriving from the495 class ``Instruction``.496 497For each ``def`` record, the root object also has a key for the record498name. The corresponding value is a subsidiary object containing the499following fixed keys:500 501* ``!superclasses``: an array of strings giving the names of all the502 classes that this record derives from.503 504* ``!fields``: an array of strings giving the names of all the variables505 in this record that were defined with the ``field`` keyword.506 507* ``!name``: a string giving the name of the record. This is always508 identical to the key in the JSON root object corresponding to this509 record's dictionary. (If the record is anonymous, the name is510 arbitrary.)511 512* ``!anonymous``: a boolean indicating whether the record's name was513 specified by the TableGen input (if it is ``false``), or invented by514 TableGen itself (if ``true``).515 516* ``!locs``: an array of strings giving the source locations associated with517 this record. For records instantiated from a ``multiclass``, this gives the518 location of each ``def`` or ``defm``, starting with the inner-most519 ``multiclass``, and ending with the top-level ``defm``. Each string contains520 the file name and line number, separated by a colon.521 522For each variable defined in a record, the ``def`` object for that523record also has a key for the variable name. The corresponding value524is a translation into JSON of the variable's value, using the525conventions described below.526 527Some TableGen data types are translated directly into the528corresponding JSON type:529 530* A completely undefined value (e.g., for a variable declared without531 initializer in some superclass of this record, and never initialized532 by the record itself or any other superclass) is emitted as the JSON533 ``null`` value.534 535* ``int`` and ``bit`` values are emitted as numbers. Note that536 TableGen ``int`` values are capable of holding integers too large to537 be exactly representable in IEEE double precision. The integer538 literal in the JSON output will show the full exact integer value.539 So if you need to retrieve large integers with full precision, you540 should use a JSON reader capable of translating such literals back541 into 64-bit integers without losing precision, such as Python's542 standard ``json`` module.543 544* ``string`` and ``code`` values are emitted as JSON strings.545 546* ``list<T>`` values, for any element type ``T``, are emitted as JSON547 arrays. Each element of the array is represented in turn using these548 same conventions.549 550* ``bits`` values are also emitted as arrays. A ``bits`` array is551 ordered from least-significant bit to most-significant. So the552 element with index ``i`` corresponds to the bit described as553 ``x{i}`` in TableGen source. However, note that this means that554 scripting languages are likely to *display* the array in the555 opposite order from the way it appears in the TableGen source or in556 the diagnostic ``-print-records`` output.557 558All other TableGen value types are emitted as a JSON object,559containing two standard fields: ``kind`` is a discriminator describing560which kind of value the object represents, and ``printable`` is a561string giving the same representation of the value that would appear562in ``-print-records``.563 564* A reference to a ``def`` object has ``kind=="def"``, and has an565 extra field ``def`` giving the name of the object referred to.566 567* A reference to another variable in the same record has568 ``kind=="var"``, and has an extra field ``var`` giving the name of569 the variable referred to.570 571* A reference to a specific bit of a ``bits``-typed variable in the572 same record has ``kind=="varbit"``, and has two extra fields:573 ``var`` gives the name of the variable referred to, and ``index``574 gives the index of the bit.575 576* A value of type ``dag`` has ``kind=="dag"``, and has two extra577 fields. ``operator`` gives the initial value after the opening578 parenthesis of the dag initializer; ``args`` is an array giving the579 following arguments. The elements of ``args`` are arrays of length580 2, giving the value of each argument followed by its colon-suffixed581 name (if any). For example, in the JSON representation of the dag582 value ``(Op 22, "hello":$foo)`` (assuming that ``Op`` is the name of583 a record defined elsewhere with a ``def`` statement):584 585 * ``operator`` will be an object in which ``kind=="def"`` and586 ``def=="Op"``587 588 * ``args`` will be the array ``[[22, null], ["hello", "foo"]]``.589 590* If any other kind of value or complicated expression appears in the591 output, it will have ``kind=="complex"``, and no additional fields.592 These values are not expected to be needed by backends. The standard593 ``printable`` field can be used to extract a representation of them594 in TableGen source syntax if necessary.595 596SearchableTables Reference597--------------------------598 599A TableGen include file, ``SearchableTable.td``, provides classes for600generating C++ searchable tables. These tables are described in the601following sections. To generate the C++ code, run ``llvm-tblgen`` with the602``--gen-searchable-tables`` option, which invokes the backend that generates603the tables from the records you provide.604 605Each of the data structures generated for searchable tables is guarded by an606``#ifdef``. This allows you to include the generated ``.inc`` file and select only607certain data structures for inclusion. The examples below show the macro608names used in these guards.609 610Generic Enumerated Types611~~~~~~~~~~~~~~~~~~~~~~~~612 613The ``GenericEnum`` class makes it easy to define a C++ enumerated type and614the enumerated *elements* of that type. To define the type, define a record615whose parent class is ``GenericEnum`` and whose name is the desired enum616type. This class provides three fields, which you can set in the record617using the ``let`` statement.618 619* ``string FilterClass``. The enum type will have one element for each record620 that derives from this class. These records are collected to assemble the621 complete set of elements.622 623* ``string NameField``. The name of a field *in the collected records* that specifies624 the name of the element. If a record has no such field, the record's625 name will be used.626 627* ``string ValueField``. The name of a field *in the collected records* that628 specifies the numerical value of the element. If a record has no such629 field, it will be assigned an integer value. Values are assigned in630 alphabetical order starting with 0.631 632Here is an example where the values of the elements are specified633explicitly, as a template argument to the ``BEntry`` class. The resulting634C++ code is shown.635 636.. code-block:: text637 638 def BValues : GenericEnum {639 let FilterClass = "BEntry";640 let NameField = "Name";641 let ValueField = "Encoding";642 }643 644 class BEntry<bits<16> enc> {645 string Name = NAME;646 bits<16> Encoding = enc;647 }648 649 def BFoo : BEntry<0xac>;650 def BBar : BEntry<0x14>;651 def BZoo : BEntry<0x80>;652 def BSnork : BEntry<0x4c>;653 654.. code-block:: text655 656 #ifdef GET_BValues_DECL657 enum BValues {658 BBar = 20,659 BFoo = 172,660 BSnork = 76,661 BZoo = 128,662 };663 #endif664 665In the following example, the values of the elements are assigned666automatically. Note that values are assigned from 0, in alphabetical order667by element name.668 669.. code-block:: text670 671 def CEnum : GenericEnum {672 let FilterClass = "CEnum";673 }674 675 class CEnum;676 677 def CFoo : CEnum;678 def CBar : CEnum;679 def CBaz : CEnum;680 681.. code-block:: text682 683 #ifdef GET_CEnum_DECL684 enum CEnum {685 CBar = 0,686 CBaz = 1,687 CFoo = 2,688 };689 #endif690 691 692Generic Tables693~~~~~~~~~~~~~~694 695The ``GenericTable`` class is used to define a searchable generic table.696TableGen produces C++ code to define the table entries and also produces697the declaration and definition of a function to search the table based on a698primary key. To define the table, define a record whose parent class is699``GenericTable`` and whose name is the name of the global table of entries.700This class provides six fields.701 702* ``string FilterClass``. The table will have one entry for each record703 that derives from this class.704 705* ``string FilterClassField``. This is an optional field of ``FilterClass``706 which should be `bit` type. If specified, only those records with this field707 being true will have corresponding entries in the table. This field won't be708 included in generated C++ fields if it isn't included in ``Fields`` list.709 710* ``string CppTypeName``. The name of the C++ struct/class type of the711 table that holds the entries. If unspecified, the ``FilterClass`` name is712 used.713 714* ``list<string> Fields``. A list of the names of the fields *in the715 collected records* that contain the data for the table entries. The order of716 this list determines the order of the values in the C++ initializers. See717 below for information about the types of these fields.718 719* ``list<string> PrimaryKey``. The list of fields that make up the720 primary key.721 722* ``string PrimaryKeyName``. The name of the generated C++ function723 that performs a lookup on the primary key.724 725* ``bit PrimaryKeyEarlyOut``. See the third example below.726 727* ``bit PrimaryKeyReturnRange``. when set to 1, modifies the lookup function’s728 definition to return a range of results rather than a single pointer to the729 object. This feature proves useful when multiple objects meet the criteria730 specified by the lookup function. Currently, it is supported only for primary731 lookup functions. Refer to the second example below for further details.732 733TableGen attempts to deduce the type of each of the table fields so that it734can format the C++ initializers in the emitted table. It can deduce ``bit``,735``bits<n>``, ``string``, ``Intrinsic``, and ``Instruction``. These can be736used in the primary key. Any other field types must be specified737explicitly; this is done as shown in the second example below. Such fields738cannot be used in the primary key.739 740One special case of the field type has to do with code. Arbitrary code is741represented by a string, but has to be emitted as a C++ initializer without742quotes. If the code field was defined using a code literal (``[{...}]``),743then TableGen will know to emit it without quotes. However, if it was744defined using a string literal or complex string expression, then TableGen745will not know. In this case, you can force TableGen to treat the field as746code by including the following line in the ``GenericTable`` record, where747*xxx* is the code field name.748 749.. code-block:: text750 751 string TypeOf_xxx = "code";752 753Here is an example where TableGen can deduce the field types. Note that the754table entry records are anonymous; the names of entry records are755irrelevant.756 757.. code-block:: text758 759 def ATable : GenericTable {760 let FilterClass = "AEntry";761 let FilterClassField = "IsNeeded";762 let Fields = ["Str", "Val1", "Val2"];763 let PrimaryKey = ["Val1", "Val2"];764 let PrimaryKeyName = "lookupATableByValues";765 }766 767 class AEntry<string str, int val1, int val2, bit isNeeded> {768 string Str = str;769 bits<8> Val1 = val1;770 bits<10> Val2 = val2;771 bit IsNeeded = isNeeded;772 }773 774 def : AEntry<"Bob", 5, 3, 1>;775 def : AEntry<"Carol", 2, 6, 1>;776 def : AEntry<"Ted", 4, 4, 1>;777 def : AEntry<"Alice", 4, 5, 1>;778 def : AEntry<"Costa", 2, 1, 1>;779 def : AEntry<"Dale", 2, 1, 0>;780 781Here is the generated C++ code. The declaration of ``lookupATableByValues``782is guarded by ``GET_ATable_DECL``, while the definitions are guarded by783``GET_ATable_IMPL``.784 785.. code-block:: text786 787 #ifdef GET_ATable_DECL788 const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2);789 #endif790 791 #ifdef GET_ATable_IMPL792 constexpr AEntry ATable[] = {793 { "Costa", 0x2, 0x1 }, // 0794 { "Carol", 0x2, 0x6 }, // 1795 { "Ted", 0x4, 0x4 }, // 2796 { "Alice", 0x4, 0x5 }, // 3797 { "Bob", 0x5, 0x3 }, // 4798 /* { "Dale", 0x2, 0x1 }, // 5 */ // We don't generate this line as `IsNeeded` is 0.799 };800 801 const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {802 struct KeyType {803 uint8_t Val1;804 uint16_t Val2;805 };806 KeyType Key = { Val1, Val2 };807 auto Table = ArrayRef(ATable);808 auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,809 [](const AEntry &LHS, const KeyType &RHS) {810 if (LHS.Val1 < RHS.Val1)811 return true;812 if (LHS.Val1 > RHS.Val1)813 return false;814 if (LHS.Val2 < RHS.Val2)815 return true;816 if (LHS.Val2 > RHS.Val2)817 return false;818 return false;819 });820 821 if (Idx == Table.end() ||822 Key.Val1 != Idx->Val1 ||823 Key.Val2 != Idx->Val2)824 return nullptr;825 return &*Idx;826 }827 #endif828 829The table entries in ``ATable`` are sorted in order by ``Val1``, and within830each of those values, by ``Val2``. This allows a binary search of the table,831which is performed in the lookup function by ``std::lower_bound``. The832lookup function returns a reference to the found table entry, or the null833pointer if no entry is found. If the table has a single primary key field834which is integral and densely numbered, a direct lookup is generated rather835than a binary search.836 837This example includes a field whose type TableGen cannot deduce. The ``Kind``838field uses the enumerated type ``CEnum`` defined above. To inform TableGen839of the type, the record derived from ``GenericTable`` must include a string field840named ``TypeOf_``\ *field*, where *field* is the name of the field whose type841is required.842 843.. code-block:: text844 845 def CTable : GenericTable {846 let FilterClass = "CEntry";847 let Fields = ["Name", "Kind", "Encoding"];848 string TypeOf_Kind = "CEnum";849 let PrimaryKey = ["Encoding"];850 let PrimaryKeyName = "lookupCEntryByEncoding";851 }852 853 class CEntry<string name, CEnum kind, int enc> {854 string Name = name;855 CEnum Kind = kind;856 bits<16> Encoding = enc;857 }858 859 def : CEntry<"Apple", CFoo, 10>;860 def : CEntry<"Pear", CBaz, 15>;861 def : CEntry<"Apple", CBar, 13>;862 863Here is the generated C++ code.864 865.. code-block:: text866 867 #ifdef GET_CTable_DECL868 const CEntry *lookupCEntryByEncoding(uint16_t Encoding);869 #endif870 871 #ifdef GET_CTable_IMPL872 constexpr CEntry CTable[] = {873 { "Apple", CFoo, 0xA }, // 0874 { "Apple", CBar, 0xD }, // 1875 { "Pear", CBaz, 0xF }, // 2876 };877 878 const CEntry *lookupCEntryByEncoding(uint16_t Encoding) {879 struct KeyType {880 uint16_t Encoding;881 };882 KeyType Key = { Encoding };883 auto Table = ArrayRef(CTable);884 auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,885 [](const CEntry &LHS, const KeyType &RHS) {886 if (LHS.Encoding < RHS.Encoding)887 return true;888 if (LHS.Encoding > RHS.Encoding)889 return false;890 return false;891 });892 893 if (Idx == Table.end() ||894 Key.Encoding != Idx->Encoding)895 return nullptr;896 return &*Idx;897 }898 899In the above example, lets add one more record with encoding same as that of900record ``CEntry<"Pear", CBaz, 15>``.901 902.. code-block:: text903 904 def CFoobar : CEnum;905 def : CEntry<"Banana", CFoobar, 15>;906 907Below is the new generated ``CTable``908 909.. code-block:: text910 911 #ifdef GET_Table_IMPL912 constexpr CEntry Table[] = {913 { "Apple", CFoo, 0xA }, // 0914 { "Apple", CBar, 0xD }, // 1915 { "Banana", CFoobar, 0xF }, // 2916 { "Pear", CBaz, 0xF }, // 3917 };918 919Since ``Banana`` lexicographically appears first, therefore in the ``CEntry``920table, record with name ``Banana`` will come before the record with name921``Pear``. Because of this, the ``lookupCEntryByEncoding`` function will always922return a pointer to the record with name ``Banana`` even though in some cases923the correct result can be the record with name ``Pear``. Such kind of scenario924makes the existing lookup function insufficient because they always return a925pointer to a single entry from the table, but instead it should return a range926of results because multiple entries match the criteria sought by the lookup927function. In this case, the definition of the lookup function needs to be928modified to return a range of results which can be done by setting929``PrimaryKeyReturnRange``.930 931.. code-block:: text932 933 def CTable : GenericTable {934 let FilterClass = "CEntry";935 let Fields = ["Name", "Kind", "Encoding"];936 string TypeOf_Kind = "CEnum";937 let PrimaryKey = ["Encoding"];938 let PrimaryKeyName = "lookupCEntryByEncoding";939 let PrimaryKeyReturnRange = true;940 }941 942Here is the modified lookup function.943 944.. code-block:: text945 946 llvm::iterator_range<const CEntry *> lookupCEntryByEncoding(uint16_t Encoding) {947 struct KeyType {948 uint16_t Encoding;949 };950 KeyType Key = {Encoding};951 struct Comp {952 bool operator()(const CEntry &LHS, const KeyType &RHS) const {953 if (LHS.Encoding < RHS.Encoding)954 return true;955 if (LHS.Encoding > RHS.Encoding)956 return false;957 return false;958 }959 bool operator()(const KeyType &LHS, const CEntry &RHS) const {960 if (LHS.Encoding < RHS.Encoding)961 return true;962 if (LHS.Encoding > RHS.Encoding)963 return false;964 return false;965 }966 };967 auto Table = ArrayRef(Table);968 auto It = std::equal_range(Table.begin(), Table.end(), Key, Comp());969 return llvm::make_range(It.first, It.second);970 }971 972The new lookup function will return an iterator range with first pointer to the973first result and the last pointer to the last matching result from the table.974However, please note that the support for emitting a modified definition exists975for ``PrimaryKeyName`` only.976 977The ``PrimaryKeyEarlyOut`` field, when set to 1, modifies the lookup978function so that it tests the first field of the primary key to determine979whether it is within the range of the collected records' primary keys. If980not, the function returns the null pointer without performing the binary981search. This is useful for tables that provide data for only some of the982elements of a larger enum-based space. The first field of the primary key983must be an integral type; it cannot be a string.984 985Adding ``let PrimaryKeyEarlyOut = 1`` to the ``ATable`` above:986 987.. code-block:: text988 989 def ATable : GenericTable {990 let FilterClass = "AEntry";991 let Fields = ["Str", "Val1", "Val2"];992 let PrimaryKey = ["Val1", "Val2"];993 let PrimaryKeyName = "lookupATableByValues";994 let PrimaryKeyEarlyOut = 1;995 }996 997causes the lookup function to change as follows:998 999.. code-block:: text1000 1001 const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {1002 if ((Val1 < 0x2) ||1003 (Val1 > 0x5))1004 return nullptr;1005 1006 struct KeyType {1007 ...1008 1009We can construct two GenericTables with the same ``FilterClass``, so that they1010select from the same overall set of records, but assign them with different1011``FilterClassField`` values so that they include different subsets of the1012records of that class.1013 1014For example, we can create two tables that contain only even or odd records.1015Fields ``IsEven`` and ``IsOdd`` won't be included in generated C++ fields1016because they aren't included in ``Fields`` list.1017 1018.. code-block:: text1019 1020 class EEntry<bits<8> value> {1021 bits<8> Value = value;1022 bit IsEven = !eq(!and(value, 1), 0);1023 bit IsOdd = !not(IsEven);1024 }1025 1026 foreach i = {1-10} in {1027 def : EEntry<i>;1028 }1029 1030 def EEntryEvenTable : GenericTable {1031 let FilterClass = "EEntry";1032 let FilterClassField = "IsEven";1033 let Fields = ["Value"];1034 let PrimaryKey = ["Value"];1035 let PrimaryKeyName = "lookupEEntryEvenTableByValue";1036 }1037 1038 def EEntryOddTable : GenericTable {1039 let FilterClass = "EEntry";1040 let FilterClassField = "IsOdd";1041 let Fields = ["Value"];1042 let PrimaryKey = ["Value"];1043 let PrimaryKeyName = "lookupEEntryOddTableByValue";1044 }1045 1046The generated tables are:1047 1048.. code-block:: text1049 1050 constexpr EEntry EEntryEvenTable[] = {1051 { 0x2 }, // 01052 { 0x4 }, // 11053 { 0x6 }, // 21054 { 0x8 }, // 31055 { 0xA }, // 41056 };1057 1058 constexpr EEntry EEntryOddTable[] = {1059 { 0x1 }, // 01060 { 0x3 }, // 11061 { 0x5 }, // 21062 { 0x7 }, // 31063 { 0x9 }, // 41064 };1065 1066Search Indexes1067~~~~~~~~~~~~~~1068 1069The ``SearchIndex`` class is used to define additional lookup functions for1070generic tables. To define an additional function, define a record whose parent1071class is ``SearchIndex`` and whose name is the name of the desired lookup1072function. This class provides three fields.1073 1074* ``GenericTable Table``. The name of the table that is to receive another1075 lookup function.1076 1077* ``list<string> Key``. The list of fields that make up the secondary key.1078 1079* ``bit EarlyOut``. See the third example in `Generic Tables`_.1080 1081Here is an example of a secondary key added to the ``CTable`` above. The1082generated function looks up entries based on the ``Name`` and ``Kind`` fields.1083 1084.. code-block:: text1085 1086 def lookupCEntry : SearchIndex {1087 let Table = CTable;1088 let Key = ["Name", "Kind"];1089 }1090 1091This use of ``SearchIndex`` generates the following additional C++ code.1092 1093.. code-block:: text1094 1095 const CEntry *lookupCEntry(StringRef Name, unsigned Kind);1096 1097 ...1098 1099 const CEntry *lookupCEntryByName(StringRef Name, unsigned Kind) {1100 struct IndexType {1101 const char * Name;1102 unsigned Kind;1103 unsigned _index;1104 };1105 static const struct IndexType Index[] = {1106 { "APPLE", CBar, 1 },1107 { "APPLE", CFoo, 0 },1108 { "PEAR", CBaz, 2 },1109 };1110 1111 struct KeyType {1112 std::string Name;1113 unsigned Kind;1114 };1115 KeyType Key = { Name.upper(), Kind };1116 auto Table = ArrayRef(Index);1117 auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,1118 [](const IndexType &LHS, const KeyType &RHS) {1119 int CmpName = StringRef(LHS.Name).compare(RHS.Name);1120 if (CmpName < 0) return true;1121 if (CmpName > 0) return false;1122 if ((unsigned)LHS.Kind < (unsigned)RHS.Kind)1123 return true;1124 if ((unsigned)LHS.Kind > (unsigned)RHS.Kind)1125 return false;1126 return false;1127 });1128 1129 if (Idx == Table.end() ||1130 Key.Name != Idx->Name ||1131 Key.Kind != Idx->Kind)1132 return nullptr;1133 return &CTable[Idx->_index];1134 }1135