1 //===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===//
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 //
9 // This file contains the main function for LLVM's TableGen.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "TableGenBackends.h" // Declares all backends.
14 #include "llvm/Support/CommandLine.h"
15 #include "llvm/Support/ManagedStatic.h"
16 #include "llvm/Support/PrettyStackTrace.h"
17 #include "llvm/Support/Signals.h"
18 #include "llvm/TableGen/Main.h"
19 #include "llvm/TableGen/Record.h"
20 #include "llvm/TableGen/SetTheory.h"
21 
22 using namespace llvm;
23 
24 enum ActionType {
25   PrintRecords,
26   DumpJSON,
27   GenEmitter,
28   GenRegisterInfo,
29   GenInstrInfo,
30   GenInstrDocs,
31   GenAsmWriter,
32   GenAsmMatcher,
33   GenDisassembler,
34   GenPseudoLowering,
35   GenCompressInst,
36   GenCallingConv,
37   GenDAGISel,
38   GenDFAPacketizer,
39   GenFastISel,
40   GenSubtarget,
41   GenIntrinsicEnums,
42   GenIntrinsicImpl,
43   GenTgtIntrinsicEnums,
44   GenTgtIntrinsicImpl,
45   PrintEnums,
46   PrintSets,
47   GenOptParserDefs,
48   GenCTags,
49   GenAttributes,
50   GenSearchableTables,
51   GenGlobalISel,
52   GenX86EVEX2VEXTables,
53   GenX86FoldTables,
54   GenRegisterBank,
55   GenExegesis,
56 };
57 
58 namespace {
59   cl::opt<ActionType>
60   Action(cl::desc("Action to perform:"),
61          cl::values(clEnumValN(PrintRecords, "print-records",
62                                "Print all records to stdout (default)"),
63                     clEnumValN(DumpJSON, "dump-json",
64                                "Dump all records as machine-readable JSON"),
65                     clEnumValN(GenEmitter, "gen-emitter",
66                                "Generate machine code emitter"),
67                     clEnumValN(GenRegisterInfo, "gen-register-info",
68                                "Generate registers and register classes info"),
69                     clEnumValN(GenInstrInfo, "gen-instr-info",
70                                "Generate instruction descriptions"),
71                     clEnumValN(GenInstrDocs, "gen-instr-docs",
72                                "Generate instruction documentation"),
73                     clEnumValN(GenCallingConv, "gen-callingconv",
74                                "Generate calling convention descriptions"),
75                     clEnumValN(GenAsmWriter, "gen-asm-writer",
76                                "Generate assembly writer"),
77                     clEnumValN(GenDisassembler, "gen-disassembler",
78                                "Generate disassembler"),
79                     clEnumValN(GenPseudoLowering, "gen-pseudo-lowering",
80                                "Generate pseudo instruction lowering"),
81                     clEnumValN(GenCompressInst, "gen-compress-inst-emitter",
82                                "Generate RISCV compressed instructions."),
83                     clEnumValN(GenAsmMatcher, "gen-asm-matcher",
84                                "Generate assembly instruction matcher"),
85                     clEnumValN(GenDAGISel, "gen-dag-isel",
86                                "Generate a DAG instruction selector"),
87                     clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer",
88                                "Generate DFA Packetizer for VLIW targets"),
89                     clEnumValN(GenFastISel, "gen-fast-isel",
90                                "Generate a \"fast\" instruction selector"),
91                     clEnumValN(GenSubtarget, "gen-subtarget",
92                                "Generate subtarget enumerations"),
93                     clEnumValN(GenIntrinsicEnums, "gen-intrinsic-enums",
94                                "Generate intrinsic enums"),
95                     clEnumValN(GenIntrinsicImpl, "gen-intrinsic-impl",
96                                "Generate intrinsic information"),
97                     clEnumValN(GenTgtIntrinsicEnums, "gen-tgt-intrinsic-enums",
98                                "Generate target intrinsic enums"),
99                     clEnumValN(GenTgtIntrinsicImpl, "gen-tgt-intrinsic-impl",
100                                "Generate target intrinsic information"),
101                     clEnumValN(PrintEnums, "print-enums",
102                                "Print enum values for a class"),
103                     clEnumValN(PrintSets, "print-sets",
104                                "Print expanded sets for testing DAG exprs"),
105                     clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
106                                "Generate option definitions"),
107                     clEnumValN(GenCTags, "gen-ctags",
108                                "Generate ctags-compatible index"),
109                     clEnumValN(GenAttributes, "gen-attrs",
110                                "Generate attributes"),
111                     clEnumValN(GenSearchableTables, "gen-searchable-tables",
112                                "Generate generic binary-searchable table"),
113                     clEnumValN(GenGlobalISel, "gen-global-isel",
114                                "Generate GlobalISel selector"),
115                     clEnumValN(GenX86EVEX2VEXTables, "gen-x86-EVEX2VEX-tables",
116                                "Generate X86 EVEX to VEX compress tables"),
117                     clEnumValN(GenX86FoldTables, "gen-x86-fold-tables",
118                                "Generate X86 fold tables"),
119                     clEnumValN(GenRegisterBank, "gen-register-bank",
120                                "Generate registers bank descriptions"),
121                     clEnumValN(GenExegesis, "gen-exegesis",
122                                "Generate llvm-exegesis tables")));
123 
124   cl::OptionCategory PrintEnumsCat("Options for -print-enums");
125   cl::opt<std::string>
126   Class("class", cl::desc("Print Enum list for this class"),
127         cl::value_desc("class name"), cl::cat(PrintEnumsCat));
128 
129 bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
130   switch (Action) {
131   case PrintRecords:
132     OS << Records;           // No argument, dump all contents
133     break;
134   case DumpJSON:
135     EmitJSON(Records, OS);
136     break;
137   case GenEmitter:
138     EmitCodeEmitter(Records, OS);
139     break;
140   case GenRegisterInfo:
141     EmitRegisterInfo(Records, OS);
142     break;
143   case GenInstrInfo:
144     EmitInstrInfo(Records, OS);
145     break;
146   case GenInstrDocs:
147     EmitInstrDocs(Records, OS);
148     break;
149   case GenCallingConv:
150     EmitCallingConv(Records, OS);
151     break;
152   case GenAsmWriter:
153     EmitAsmWriter(Records, OS);
154     break;
155   case GenAsmMatcher:
156     EmitAsmMatcher(Records, OS);
157     break;
158   case GenDisassembler:
159     EmitDisassembler(Records, OS);
160     break;
161   case GenPseudoLowering:
162     EmitPseudoLowering(Records, OS);
163     break;
164   case GenCompressInst:
165     EmitCompressInst(Records, OS);
166     break;
167   case GenDAGISel:
168     EmitDAGISel(Records, OS);
169     break;
170   case GenDFAPacketizer:
171     EmitDFAPacketizer(Records, OS);
172     break;
173   case GenFastISel:
174     EmitFastISel(Records, OS);
175     break;
176   case GenSubtarget:
177     EmitSubtarget(Records, OS);
178     break;
179   case GenIntrinsicEnums:
180     EmitIntrinsicEnums(Records, OS);
181     break;
182   case GenIntrinsicImpl:
183     EmitIntrinsicImpl(Records, OS);
184     break;
185   case GenTgtIntrinsicEnums:
186     EmitIntrinsicEnums(Records, OS, true);
187     break;
188   case GenTgtIntrinsicImpl:
189     EmitIntrinsicImpl(Records, OS, true);
190     break;
191   case GenOptParserDefs:
192     EmitOptParser(Records, OS);
193     break;
194   case PrintEnums:
195   {
196     for (Record *Rec : Records.getAllDerivedDefinitions(Class))
197       OS << Rec->getName() << ", ";
198     OS << "\n";
199     break;
200   }
201   case PrintSets:
202   {
203     SetTheory Sets;
204     Sets.addFieldExpander("Set", "Elements");
205     for (Record *Rec : Records.getAllDerivedDefinitions("Set")) {
206       OS << Rec->getName() << " = [";
207       const std::vector<Record*> *Elts = Sets.expand(Rec);
208       assert(Elts && "Couldn't expand Set instance");
209       for (Record *Elt : *Elts)
210         OS << ' ' << Elt->getName();
211       OS << " ]\n";
212     }
213     break;
214   }
215   case GenCTags:
216     EmitCTags(Records, OS);
217     break;
218   case GenAttributes:
219     EmitAttributes(Records, OS);
220     break;
221   case GenSearchableTables:
222     EmitSearchableTables(Records, OS);
223     break;
224   case GenGlobalISel:
225     EmitGlobalISel(Records, OS);
226     break;
227   case GenRegisterBank:
228     EmitRegisterBank(Records, OS);
229     break;
230   case GenX86EVEX2VEXTables:
231     EmitX86EVEX2VEXTables(Records, OS);
232     break;
233   case GenX86FoldTables:
234     EmitX86FoldTables(Records, OS);
235     break;
236   case GenExegesis:
237     EmitExegesis(Records, OS);
238     break;
239   }
240 
241   return false;
242 }
243 }
244 
245 int main(int argc, char **argv) {
246   sys::PrintStackTraceOnErrorSignal(argv[0]);
247   PrettyStackTraceProgram X(argc, argv);
248   cl::ParseCommandLineOptions(argc, argv);
249 
250   llvm_shutdown_obj Y;
251 
252   return TableGenMain(argv[0], &LLVMTableGenMain);
253 }
254 
255 #ifdef __has_feature
256 #if __has_feature(address_sanitizer)
257 #include <sanitizer/lsan_interface.h>
258 // Disable LeakSanitizer for this binary as it has too many leaks that are not
259 // very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
260 LLVM_ATTRIBUTE_USED int __lsan_is_turned_off() { return 1; }
261 #endif  // __has_feature(address_sanitizer)
262 #endif  // defined(__has_feature)
263