16122f3e6SDimitry Andric //===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
106122f3e6SDimitry Andric // This file contains the main function for LLVM's TableGen.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
147ae0e2c9SDimitry Andric #include "TableGenBackends.h" // Declares all backends.
15f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h"
164d0b32cdSDimitry Andric #include "llvm/Support/ManagedStatic.h"
17f22ef01cSRoman Divacky #include "llvm/Support/PrettyStackTrace.h"
182754fe60SDimitry Andric #include "llvm/Support/Signals.h"
196122f3e6SDimitry Andric #include "llvm/TableGen/Main.h"
206122f3e6SDimitry Andric #include "llvm/TableGen/Record.h"
2191bc56edSDimitry Andric #include "llvm/TableGen/SetTheory.h"
226122f3e6SDimitry Andric
23f22ef01cSRoman Divacky using namespace llvm;
24f22ef01cSRoman Divacky
25f22ef01cSRoman Divacky enum ActionType {
26f22ef01cSRoman Divacky PrintRecords,
274ba319b5SDimitry Andric DumpJSON,
28f22ef01cSRoman Divacky GenEmitter,
2917a519f9SDimitry Andric GenRegisterInfo,
3017a519f9SDimitry Andric GenInstrInfo,
312cab237bSDimitry Andric GenInstrDocs,
3217a519f9SDimitry Andric GenAsmWriter,
3317a519f9SDimitry Andric GenAsmMatcher,
34f22ef01cSRoman Divacky GenDisassembler,
3517a519f9SDimitry Andric GenPseudoLowering,
364ba319b5SDimitry Andric GenCompressInst,
37f22ef01cSRoman Divacky GenCallingConv,
38f22ef01cSRoman Divacky GenDAGISel,
39dff0c46cSDimitry Andric GenDFAPacketizer,
40f22ef01cSRoman Divacky GenFastISel,
41f22ef01cSRoman Divacky GenSubtarget,
424ba319b5SDimitry Andric GenIntrinsicEnums,
434ba319b5SDimitry Andric GenIntrinsicImpl,
444ba319b5SDimitry Andric GenTgtIntrinsicEnums,
454ba319b5SDimitry Andric GenTgtIntrinsicImpl,
46bd5abe19SDimitry Andric PrintEnums,
47139f7f9bSDimitry Andric PrintSets,
48139f7f9bSDimitry Andric GenOptParserDefs,
497d523365SDimitry Andric GenCTags,
503ca95b02SDimitry Andric GenAttributes,
513ca95b02SDimitry Andric GenSearchableTables,
52d88c1a5aSDimitry Andric GenGlobalISel,
537a7e6055SDimitry Andric GenX86EVEX2VEXTables,
542cab237bSDimitry Andric GenX86FoldTables,
557a7e6055SDimitry Andric GenRegisterBank,
56*b5893f02SDimitry Andric GenExegesis,
57f22ef01cSRoman Divacky };
58f22ef01cSRoman Divacky
59f22ef01cSRoman Divacky namespace {
60f22ef01cSRoman Divacky cl::opt<ActionType>
61f22ef01cSRoman Divacky Action(cl::desc("Action to perform:"),
62f22ef01cSRoman Divacky cl::values(clEnumValN(PrintRecords, "print-records",
63f22ef01cSRoman Divacky "Print all records to stdout (default)"),
644ba319b5SDimitry Andric clEnumValN(DumpJSON, "dump-json",
654ba319b5SDimitry Andric "Dump all records as machine-readable JSON"),
66f22ef01cSRoman Divacky clEnumValN(GenEmitter, "gen-emitter",
67f22ef01cSRoman Divacky "Generate machine code emitter"),
6817a519f9SDimitry Andric clEnumValN(GenRegisterInfo, "gen-register-info",
6917a519f9SDimitry Andric "Generate registers and register classes info"),
7017a519f9SDimitry Andric clEnumValN(GenInstrInfo, "gen-instr-info",
71f22ef01cSRoman Divacky "Generate instruction descriptions"),
722cab237bSDimitry Andric clEnumValN(GenInstrDocs, "gen-instr-docs",
732cab237bSDimitry Andric "Generate instruction documentation"),
74f22ef01cSRoman Divacky clEnumValN(GenCallingConv, "gen-callingconv",
75f22ef01cSRoman Divacky "Generate calling convention descriptions"),
76f22ef01cSRoman Divacky clEnumValN(GenAsmWriter, "gen-asm-writer",
77f22ef01cSRoman Divacky "Generate assembly writer"),
78f22ef01cSRoman Divacky clEnumValN(GenDisassembler, "gen-disassembler",
79f22ef01cSRoman Divacky "Generate disassembler"),
8017a519f9SDimitry Andric clEnumValN(GenPseudoLowering, "gen-pseudo-lowering",
8117a519f9SDimitry Andric "Generate pseudo instruction lowering"),
824ba319b5SDimitry Andric clEnumValN(GenCompressInst, "gen-compress-inst-emitter",
834ba319b5SDimitry Andric "Generate RISCV compressed instructions."),
84f22ef01cSRoman Divacky clEnumValN(GenAsmMatcher, "gen-asm-matcher",
85f22ef01cSRoman Divacky "Generate assembly instruction matcher"),
86f22ef01cSRoman Divacky clEnumValN(GenDAGISel, "gen-dag-isel",
87f22ef01cSRoman Divacky "Generate a DAG instruction selector"),
88dff0c46cSDimitry Andric clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer",
89dff0c46cSDimitry Andric "Generate DFA Packetizer for VLIW targets"),
90f22ef01cSRoman Divacky clEnumValN(GenFastISel, "gen-fast-isel",
91f22ef01cSRoman Divacky "Generate a \"fast\" instruction selector"),
92f22ef01cSRoman Divacky clEnumValN(GenSubtarget, "gen-subtarget",
93f22ef01cSRoman Divacky "Generate subtarget enumerations"),
944ba319b5SDimitry Andric clEnumValN(GenIntrinsicEnums, "gen-intrinsic-enums",
954ba319b5SDimitry Andric "Generate intrinsic enums"),
964ba319b5SDimitry Andric clEnumValN(GenIntrinsicImpl, "gen-intrinsic-impl",
97f22ef01cSRoman Divacky "Generate intrinsic information"),
984ba319b5SDimitry Andric clEnumValN(GenTgtIntrinsicEnums, "gen-tgt-intrinsic-enums",
994ba319b5SDimitry Andric "Generate target intrinsic enums"),
1004ba319b5SDimitry Andric clEnumValN(GenTgtIntrinsicImpl, "gen-tgt-intrinsic-impl",
101f22ef01cSRoman Divacky "Generate target intrinsic information"),
102f22ef01cSRoman Divacky clEnumValN(PrintEnums, "print-enums",
103f22ef01cSRoman Divacky "Print enum values for a class"),
104bd5abe19SDimitry Andric clEnumValN(PrintSets, "print-sets",
105bd5abe19SDimitry Andric "Print expanded sets for testing DAG exprs"),
106139f7f9bSDimitry Andric clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
107139f7f9bSDimitry Andric "Generate option definitions"),
108139f7f9bSDimitry Andric clEnumValN(GenCTags, "gen-ctags",
109139f7f9bSDimitry Andric "Generate ctags-compatible index"),
1107d523365SDimitry Andric clEnumValN(GenAttributes, "gen-attrs",
1117d523365SDimitry Andric "Generate attributes"),
1123ca95b02SDimitry Andric clEnumValN(GenSearchableTables, "gen-searchable-tables",
1133ca95b02SDimitry Andric "Generate generic binary-searchable table"),
114d88c1a5aSDimitry Andric clEnumValN(GenGlobalISel, "gen-global-isel",
1157a7e6055SDimitry Andric "Generate GlobalISel selector"),
1167a7e6055SDimitry Andric clEnumValN(GenX86EVEX2VEXTables, "gen-x86-EVEX2VEX-tables",
1177a7e6055SDimitry Andric "Generate X86 EVEX to VEX compress tables"),
1182cab237bSDimitry Andric clEnumValN(GenX86FoldTables, "gen-x86-fold-tables",
1192cab237bSDimitry Andric "Generate X86 fold tables"),
1207a7e6055SDimitry Andric clEnumValN(GenRegisterBank, "gen-register-bank",
121*b5893f02SDimitry Andric "Generate registers bank descriptions"),
122*b5893f02SDimitry Andric clEnumValN(GenExegesis, "gen-exegesis",
123*b5893f02SDimitry Andric "Generate llvm-exegesis tables")));
124f22ef01cSRoman Divacky
1257a7e6055SDimitry Andric cl::OptionCategory PrintEnumsCat("Options for -print-enums");
126f22ef01cSRoman Divacky cl::opt<std::string>
127f22ef01cSRoman Divacky Class("class", cl::desc("Print Enum list for this class"),
1287a7e6055SDimitry Andric cl::value_desc("class name"), cl::cat(PrintEnumsCat));
129f22ef01cSRoman Divacky
LLVMTableGenMain(raw_ostream & OS,RecordKeeper & Records)1303861d79fSDimitry Andric bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
131f22ef01cSRoman Divacky switch (Action) {
132f22ef01cSRoman Divacky case PrintRecords:
1336122f3e6SDimitry Andric OS << Records; // No argument, dump all contents
134f22ef01cSRoman Divacky break;
1354ba319b5SDimitry Andric case DumpJSON:
1364ba319b5SDimitry Andric EmitJSON(Records, OS);
1374ba319b5SDimitry Andric break;
138f22ef01cSRoman Divacky case GenEmitter:
1397ae0e2c9SDimitry Andric EmitCodeEmitter(Records, OS);
140f22ef01cSRoman Divacky break;
14117a519f9SDimitry Andric case GenRegisterInfo:
1427ae0e2c9SDimitry Andric EmitRegisterInfo(Records, OS);
143f22ef01cSRoman Divacky break;
14417a519f9SDimitry Andric case GenInstrInfo:
1457ae0e2c9SDimitry Andric EmitInstrInfo(Records, OS);
146f22ef01cSRoman Divacky break;
1472cab237bSDimitry Andric case GenInstrDocs:
1482cab237bSDimitry Andric EmitInstrDocs(Records, OS);
1492cab237bSDimitry Andric break;
150f22ef01cSRoman Divacky case GenCallingConv:
1517ae0e2c9SDimitry Andric EmitCallingConv(Records, OS);
152f22ef01cSRoman Divacky break;
153f22ef01cSRoman Divacky case GenAsmWriter:
1547ae0e2c9SDimitry Andric EmitAsmWriter(Records, OS);
155f22ef01cSRoman Divacky break;
156f22ef01cSRoman Divacky case GenAsmMatcher:
1577ae0e2c9SDimitry Andric EmitAsmMatcher(Records, OS);
1582754fe60SDimitry Andric break;
159f22ef01cSRoman Divacky case GenDisassembler:
1607ae0e2c9SDimitry Andric EmitDisassembler(Records, OS);
161f22ef01cSRoman Divacky break;
16217a519f9SDimitry Andric case GenPseudoLowering:
1637ae0e2c9SDimitry Andric EmitPseudoLowering(Records, OS);
164f22ef01cSRoman Divacky break;
1654ba319b5SDimitry Andric case GenCompressInst:
1664ba319b5SDimitry Andric EmitCompressInst(Records, OS);
1674ba319b5SDimitry Andric break;
168f22ef01cSRoman Divacky case GenDAGISel:
1697ae0e2c9SDimitry Andric EmitDAGISel(Records, OS);
170f22ef01cSRoman Divacky break;
171dff0c46cSDimitry Andric case GenDFAPacketizer:
1727ae0e2c9SDimitry Andric EmitDFAPacketizer(Records, OS);
173dff0c46cSDimitry Andric break;
174f22ef01cSRoman Divacky case GenFastISel:
1757ae0e2c9SDimitry Andric EmitFastISel(Records, OS);
176f22ef01cSRoman Divacky break;
177f22ef01cSRoman Divacky case GenSubtarget:
1787ae0e2c9SDimitry Andric EmitSubtarget(Records, OS);
179f22ef01cSRoman Divacky break;
1804ba319b5SDimitry Andric case GenIntrinsicEnums:
1814ba319b5SDimitry Andric EmitIntrinsicEnums(Records, OS);
182f22ef01cSRoman Divacky break;
1834ba319b5SDimitry Andric case GenIntrinsicImpl:
1844ba319b5SDimitry Andric EmitIntrinsicImpl(Records, OS);
1854ba319b5SDimitry Andric break;
1864ba319b5SDimitry Andric case GenTgtIntrinsicEnums:
1874ba319b5SDimitry Andric EmitIntrinsicEnums(Records, OS, true);
1884ba319b5SDimitry Andric break;
1894ba319b5SDimitry Andric case GenTgtIntrinsicImpl:
1904ba319b5SDimitry Andric EmitIntrinsicImpl(Records, OS, true);
191f22ef01cSRoman Divacky break;
192139f7f9bSDimitry Andric case GenOptParserDefs:
193139f7f9bSDimitry Andric EmitOptParser(Records, OS);
1942754fe60SDimitry Andric break;
195f22ef01cSRoman Divacky case PrintEnums:
196f22ef01cSRoman Divacky {
19739d628a0SDimitry Andric for (Record *Rec : Records.getAllDerivedDefinitions(Class))
19839d628a0SDimitry Andric OS << Rec->getName() << ", ";
1996122f3e6SDimitry Andric OS << "\n";
200f22ef01cSRoman Divacky break;
201f22ef01cSRoman Divacky }
202bd5abe19SDimitry Andric case PrintSets:
203bd5abe19SDimitry Andric {
204bd5abe19SDimitry Andric SetTheory Sets;
205bd5abe19SDimitry Andric Sets.addFieldExpander("Set", "Elements");
20639d628a0SDimitry Andric for (Record *Rec : Records.getAllDerivedDefinitions("Set")) {
20739d628a0SDimitry Andric OS << Rec->getName() << " = [";
20839d628a0SDimitry Andric const std::vector<Record*> *Elts = Sets.expand(Rec);
209bd5abe19SDimitry Andric assert(Elts && "Couldn't expand Set instance");
21039d628a0SDimitry Andric for (Record *Elt : *Elts)
21139d628a0SDimitry Andric OS << ' ' << Elt->getName();
2126122f3e6SDimitry Andric OS << " ]\n";
213bd5abe19SDimitry Andric }
214bd5abe19SDimitry Andric break;
215bd5abe19SDimitry Andric }
216139f7f9bSDimitry Andric case GenCTags:
217139f7f9bSDimitry Andric EmitCTags(Records, OS);
218139f7f9bSDimitry Andric break;
2197d523365SDimitry Andric case GenAttributes:
2207d523365SDimitry Andric EmitAttributes(Records, OS);
2217d523365SDimitry Andric break;
2223ca95b02SDimitry Andric case GenSearchableTables:
2233ca95b02SDimitry Andric EmitSearchableTables(Records, OS);
2243ca95b02SDimitry Andric break;
225d88c1a5aSDimitry Andric case GenGlobalISel:
226d88c1a5aSDimitry Andric EmitGlobalISel(Records, OS);
227d88c1a5aSDimitry Andric break;
2287a7e6055SDimitry Andric case GenRegisterBank:
2297a7e6055SDimitry Andric EmitRegisterBank(Records, OS);
2307a7e6055SDimitry Andric break;
2317a7e6055SDimitry Andric case GenX86EVEX2VEXTables:
2327a7e6055SDimitry Andric EmitX86EVEX2VEXTables(Records, OS);
2337a7e6055SDimitry Andric break;
2342cab237bSDimitry Andric case GenX86FoldTables:
2352cab237bSDimitry Andric EmitX86FoldTables(Records, OS);
2362cab237bSDimitry Andric break;
237*b5893f02SDimitry Andric case GenExegesis:
238*b5893f02SDimitry Andric EmitExegesis(Records, OS);
239*b5893f02SDimitry Andric break;
240f22ef01cSRoman Divacky }
241f22ef01cSRoman Divacky
2426122f3e6SDimitry Andric return false;
243f22ef01cSRoman Divacky }
244dff0c46cSDimitry Andric }
245f22ef01cSRoman Divacky
main(int argc,char ** argv)2466122f3e6SDimitry Andric int main(int argc, char **argv) {
2473ca95b02SDimitry Andric sys::PrintStackTraceOnErrorSignal(argv[0]);
2486122f3e6SDimitry Andric PrettyStackTraceProgram X(argc, argv);
2496122f3e6SDimitry Andric cl::ParseCommandLineOptions(argc, argv);
2506122f3e6SDimitry Andric
2514d0b32cdSDimitry Andric llvm_shutdown_obj Y;
2524d0b32cdSDimitry Andric
2533861d79fSDimitry Andric return TableGenMain(argv[0], &LLVMTableGenMain);
254f22ef01cSRoman Divacky }
25591bc56edSDimitry Andric
25691bc56edSDimitry Andric #ifdef __has_feature
25791bc56edSDimitry Andric #if __has_feature(address_sanitizer)
25891bc56edSDimitry Andric #include <sanitizer/lsan_interface.h>
25991bc56edSDimitry Andric // Disable LeakSanitizer for this binary as it has too many leaks that are not
26091bc56edSDimitry Andric // very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
__lsan_is_turned_off()2612cab237bSDimitry Andric LLVM_ATTRIBUTE_USED int __lsan_is_turned_off() { return 1; }
26291bc56edSDimitry Andric #endif // __has_feature(address_sanitizer)
26391bc56edSDimitry Andric #endif // defined(__has_feature)
264