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