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