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