| //===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===// | 
 | // | 
 | // 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 | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file contains the main function for LLVM's TableGen. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "TableGenBackends.h" // Declares all backends. | 
 | #include "llvm/Support/CommandLine.h" | 
 | #include "llvm/Support/InitLLVM.h" | 
 | #include "llvm/TableGen/Main.h" | 
 | #include "llvm/TableGen/Record.h" | 
 | #include "llvm/TableGen/SetTheory.h" | 
 |  | 
 | using namespace llvm; | 
 |  | 
 | enum ActionType { | 
 |   PrintRecords, | 
 |   PrintDetailedRecords, | 
 |   NullBackend, | 
 |   DumpJSON, | 
 |   GenEmitter, | 
 |   GenCodeBeads, | 
 |   GenRegisterInfo, | 
 |   GenInstrInfo, | 
 |   GenInstrDocs, | 
 |   GenAsmWriter, | 
 |   GenAsmMatcher, | 
 |   GenDisassembler, | 
 |   GenPseudoLowering, | 
 |   GenCompressInst, | 
 |   GenCallingConv, | 
 |   GenDAGISel, | 
 |   GenDFAPacketizer, | 
 |   GenFastISel, | 
 |   GenSubtarget, | 
 |   GenIntrinsicEnums, | 
 |   GenIntrinsicImpl, | 
 |   PrintEnums, | 
 |   PrintSets, | 
 |   GenOptParserDefs, | 
 |   GenOptRST, | 
 |   GenCTags, | 
 |   GenAttributes, | 
 |   GenSearchableTables, | 
 |   GenGlobalISel, | 
 |   GenGICombiner, | 
 |   GenX86EVEX2VEXTables, | 
 |   GenX86FoldTables, | 
 |   GenRegisterBank, | 
 |   GenExegesis, | 
 |   GenAutomata, | 
 |   GenDirectivesEnumDecl, | 
 |   GenDirectivesEnumImpl, | 
 | }; | 
 |  | 
 | namespace llvm { | 
 | cl::opt<bool> EmitLongStrLiterals( | 
 |     "long-string-literals", | 
 |     cl::desc("when emitting large string tables, prefer string literals over " | 
 |              "comma-separated char literals. This can be a readability and " | 
 |              "compile-time performance win, but upsets some compilers"), | 
 |     cl::Hidden, cl::init(true)); | 
 | } // end namespace llvm | 
 |  | 
 | namespace { | 
 | cl::opt<ActionType> Action( | 
 |     cl::desc("Action to perform:"), | 
 |     cl::values( | 
 |         clEnumValN(PrintRecords, "print-records", | 
 |                    "Print all records to stdout (default)"), | 
 |         clEnumValN(PrintDetailedRecords, "print-detailed-records", | 
 |                    "Print full details of all records to stdout"), | 
 |         clEnumValN(NullBackend, "null-backend", | 
 |                    "Do nothing after parsing (useful for timing)"), | 
 |         clEnumValN(DumpJSON, "dump-json", | 
 |                    "Dump all records as machine-readable JSON"), | 
 |         clEnumValN(GenEmitter, "gen-emitter", "Generate machine code emitter"), | 
 |         clEnumValN(GenCodeBeads, "gen-code-beads", | 
 |                    "Generate machine code beads"), | 
 |         clEnumValN(GenRegisterInfo, "gen-register-info", | 
 |                    "Generate registers and register classes info"), | 
 |         clEnumValN(GenInstrInfo, "gen-instr-info", | 
 |                    "Generate instruction descriptions"), | 
 |         clEnumValN(GenInstrDocs, "gen-instr-docs", | 
 |                    "Generate instruction documentation"), | 
 |         clEnumValN(GenCallingConv, "gen-callingconv", | 
 |                    "Generate calling convention descriptions"), | 
 |         clEnumValN(GenAsmWriter, "gen-asm-writer", "Generate assembly writer"), | 
 |         clEnumValN(GenDisassembler, "gen-disassembler", | 
 |                    "Generate disassembler"), | 
 |         clEnumValN(GenPseudoLowering, "gen-pseudo-lowering", | 
 |                    "Generate pseudo instruction lowering"), | 
 |         clEnumValN(GenCompressInst, "gen-compress-inst-emitter", | 
 |                    "Generate RISCV compressed instructions."), | 
 |         clEnumValN(GenAsmMatcher, "gen-asm-matcher", | 
 |                    "Generate assembly instruction matcher"), | 
 |         clEnumValN(GenDAGISel, "gen-dag-isel", | 
 |                    "Generate a DAG instruction selector"), | 
 |         clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer", | 
 |                    "Generate DFA Packetizer for VLIW targets"), | 
 |         clEnumValN(GenFastISel, "gen-fast-isel", | 
 |                    "Generate a \"fast\" instruction selector"), | 
 |         clEnumValN(GenSubtarget, "gen-subtarget", | 
 |                    "Generate subtarget enumerations"), | 
 |         clEnumValN(GenIntrinsicEnums, "gen-intrinsic-enums", | 
 |                    "Generate intrinsic enums"), | 
 |         clEnumValN(GenIntrinsicImpl, "gen-intrinsic-impl", | 
 |                    "Generate intrinsic information"), | 
 |         clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), | 
 |         clEnumValN(PrintSets, "print-sets", | 
 |                    "Print expanded sets for testing DAG exprs"), | 
 |         clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", | 
 |                    "Generate option definitions"), | 
 |         clEnumValN(GenOptRST, "gen-opt-rst", "Generate option RST"), | 
 |         clEnumValN(GenCTags, "gen-ctags", "Generate ctags-compatible index"), | 
 |         clEnumValN(GenAttributes, "gen-attrs", "Generate attributes"), | 
 |         clEnumValN(GenSearchableTables, "gen-searchable-tables", | 
 |                    "Generate generic binary-searchable table"), | 
 |         clEnumValN(GenGlobalISel, "gen-global-isel", | 
 |                    "Generate GlobalISel selector"), | 
 |         clEnumValN(GenGICombiner, "gen-global-isel-combiner", | 
 |                    "Generate GlobalISel combiner"), | 
 |         clEnumValN(GenX86EVEX2VEXTables, "gen-x86-EVEX2VEX-tables", | 
 |                    "Generate X86 EVEX to VEX compress tables"), | 
 |         clEnumValN(GenX86FoldTables, "gen-x86-fold-tables", | 
 |                    "Generate X86 fold tables"), | 
 |         clEnumValN(GenRegisterBank, "gen-register-bank", | 
 |                    "Generate registers bank descriptions"), | 
 |         clEnumValN(GenExegesis, "gen-exegesis", | 
 |                    "Generate llvm-exegesis tables"), | 
 |         clEnumValN(GenAutomata, "gen-automata", "Generate generic automata"), | 
 |         clEnumValN(GenDirectivesEnumDecl, "gen-directive-decl", | 
 |                    "Generate directive related declaration code (header file)"), | 
 |         clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl", | 
 |                    "Generate directive related implementation code"))); | 
 |  | 
 | cl::OptionCategory PrintEnumsCat("Options for -print-enums"); | 
 | cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"), | 
 |                            cl::value_desc("class name"), | 
 |                            cl::cat(PrintEnumsCat)); | 
 |  | 
 | bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { | 
 |   switch (Action) { | 
 |   case PrintRecords: | 
 |     OS << Records;              // No argument, dump all contents | 
 |     break; | 
 |   case PrintDetailedRecords: | 
 |     EmitDetailedRecords(Records, OS); | 
 |     break; | 
 |   case NullBackend:             // No backend at all. | 
 |     break; | 
 |   case DumpJSON: | 
 |     EmitJSON(Records, OS); | 
 |     break; | 
 |   case GenEmitter: | 
 |     EmitCodeEmitter(Records, OS); | 
 |     break; | 
 |   case GenCodeBeads: | 
 |     EmitCodeBeads(Records, OS); | 
 |     break; | 
 |   case GenRegisterInfo: | 
 |     EmitRegisterInfo(Records, OS); | 
 |     break; | 
 |   case GenInstrInfo: | 
 |     EmitInstrInfo(Records, OS); | 
 |     break; | 
 |   case GenInstrDocs: | 
 |     EmitInstrDocs(Records, OS); | 
 |     break; | 
 |   case GenCallingConv: | 
 |     EmitCallingConv(Records, OS); | 
 |     break; | 
 |   case GenAsmWriter: | 
 |     EmitAsmWriter(Records, OS); | 
 |     break; | 
 |   case GenAsmMatcher: | 
 |     EmitAsmMatcher(Records, OS); | 
 |     break; | 
 |   case GenDisassembler: | 
 |     EmitDisassembler(Records, OS); | 
 |     break; | 
 |   case GenPseudoLowering: | 
 |     EmitPseudoLowering(Records, OS); | 
 |     break; | 
 |   case GenCompressInst: | 
 |     EmitCompressInst(Records, OS); | 
 |     break; | 
 |   case GenDAGISel: | 
 |     EmitDAGISel(Records, OS); | 
 |     break; | 
 |   case GenDFAPacketizer: | 
 |     EmitDFAPacketizer(Records, OS); | 
 |     break; | 
 |   case GenFastISel: | 
 |     EmitFastISel(Records, OS); | 
 |     break; | 
 |   case GenSubtarget: | 
 |     EmitSubtarget(Records, OS); | 
 |     break; | 
 |   case GenIntrinsicEnums: | 
 |     EmitIntrinsicEnums(Records, OS); | 
 |     break; | 
 |   case GenIntrinsicImpl: | 
 |     EmitIntrinsicImpl(Records, OS); | 
 |     break; | 
 |   case GenOptParserDefs: | 
 |     EmitOptParser(Records, OS); | 
 |     break; | 
 |   case GenOptRST: | 
 |     EmitOptRST(Records, OS); | 
 |     break; | 
 |   case PrintEnums: | 
 |   { | 
 |     for (Record *Rec : Records.getAllDerivedDefinitions(Class)) | 
 |       OS << Rec->getName() << ", "; | 
 |     OS << "\n"; | 
 |     break; | 
 |   } | 
 |   case PrintSets: | 
 |   { | 
 |     SetTheory Sets; | 
 |     Sets.addFieldExpander("Set", "Elements"); | 
 |     for (Record *Rec : Records.getAllDerivedDefinitions("Set")) { | 
 |       OS << Rec->getName() << " = ["; | 
 |       const std::vector<Record*> *Elts = Sets.expand(Rec); | 
 |       assert(Elts && "Couldn't expand Set instance"); | 
 |       for (Record *Elt : *Elts) | 
 |         OS << ' ' << Elt->getName(); | 
 |       OS << " ]\n"; | 
 |     } | 
 |     break; | 
 |   } | 
 |   case GenCTags: | 
 |     EmitCTags(Records, OS); | 
 |     break; | 
 |   case GenAttributes: | 
 |     EmitAttributes(Records, OS); | 
 |     break; | 
 |   case GenSearchableTables: | 
 |     EmitSearchableTables(Records, OS); | 
 |     break; | 
 |   case GenGlobalISel: | 
 |     EmitGlobalISel(Records, OS); | 
 |     break; | 
 |   case GenGICombiner: | 
 |     EmitGICombiner(Records, OS); | 
 |     break; | 
 |   case GenRegisterBank: | 
 |     EmitRegisterBank(Records, OS); | 
 |     break; | 
 |   case GenX86EVEX2VEXTables: | 
 |     EmitX86EVEX2VEXTables(Records, OS); | 
 |     break; | 
 |   case GenX86FoldTables: | 
 |     EmitX86FoldTables(Records, OS); | 
 |     break; | 
 |   case GenExegesis: | 
 |     EmitExegesis(Records, OS); | 
 |     break; | 
 |   case GenAutomata: | 
 |     EmitAutomata(Records, OS); | 
 |     break; | 
 |   case GenDirectivesEnumDecl: | 
 |     EmitDirectivesDecl(Records, OS); | 
 |     break; | 
 |   case GenDirectivesEnumImpl: | 
 |     EmitDirectivesImpl(Records, OS); | 
 |     break; | 
 |   } | 
 |  | 
 |   return false; | 
 | } | 
 | } | 
 |  | 
 | int main(int argc, char **argv) { | 
 |   InitLLVM X(argc, argv); | 
 |   cl::ParseCommandLineOptions(argc, argv); | 
 |  | 
 |   return TableGenMain(argv[0], &LLVMTableGenMain); | 
 | } | 
 |  | 
 | #ifndef __has_feature | 
 | #define __has_feature(x) 0 | 
 | #endif | 
 |  | 
 | #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) ||       \ | 
 |     __has_feature(leak_sanitizer) | 
 |  | 
 | #include <sanitizer/lsan_interface.h> | 
 | // Disable LeakSanitizer for this binary as it has too many leaks that are not | 
 | // very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h . | 
 | LLVM_ATTRIBUTE_USED int __lsan_is_turned_off() { return 1; } | 
 |  | 
 | #endif |