1 //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===// 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 tablegen backend is responsible for emitting a description of the target 10 // instruction set for the code generator. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CodeGenDAGPatterns.h" 15 #include "CodeGenInstruction.h" 16 #include "CodeGenSchedule.h" 17 #include "CodeGenTarget.h" 18 #include "PredicateExpander.h" 19 #include "SequenceToOffsetTable.h" 20 #include "TableGenBackends.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/ADT/StringExtras.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include "llvm/TableGen/Error.h" 27 #include "llvm/TableGen/Record.h" 28 #include "llvm/TableGen/TableGenBackend.h" 29 #include <cassert> 30 #include <cstdint> 31 #include <iterator> 32 #include <map> 33 #include <string> 34 #include <utility> 35 #include <vector> 36 37 using namespace llvm; 38 39 namespace { 40 41 class InstrInfoEmitter { 42 RecordKeeper &Records; 43 CodeGenDAGPatterns CDP; 44 const CodeGenSchedModels &SchedModels; 45 46 public: 47 InstrInfoEmitter(RecordKeeper &R): 48 Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {} 49 50 // run - Output the instruction set description. 51 void run(raw_ostream &OS); 52 53 private: 54 void emitEnums(raw_ostream &OS); 55 56 typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; 57 58 /// The keys of this map are maps which have OpName enum values as their keys 59 /// and instruction operand indices as their values. The values of this map 60 /// are lists of instruction names. 61 typedef std::map<std::map<unsigned, unsigned>, 62 std::vector<std::string>> OpNameMapTy; 63 typedef std::map<std::string, unsigned>::iterator StrUintMapIter; 64 65 /// Generate member functions in the target-specific GenInstrInfo class. 66 /// 67 /// This method is used to custom expand TIIPredicate definitions. 68 /// See file llvm/Target/TargetInstPredicates.td for a description of what is 69 /// a TIIPredicate and how to use it. 70 void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName, 71 bool ExpandDefinition = true); 72 73 /// Expand TIIPredicate definitions to functions that accept a const MCInst 74 /// reference. 75 void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName); 76 void emitRecord(const CodeGenInstruction &Inst, unsigned Num, 77 Record *InstrInfo, 78 std::map<std::vector<Record*>, unsigned> &EL, 79 const OperandInfoMapTy &OpInfo, 80 raw_ostream &OS); 81 void emitOperandTypeMappings( 82 raw_ostream &OS, const CodeGenTarget &Target, 83 ArrayRef<const CodeGenInstruction *> NumberedInstructions); 84 void initOperandMapData( 85 ArrayRef<const CodeGenInstruction *> NumberedInstructions, 86 StringRef Namespace, 87 std::map<std::string, unsigned> &Operands, 88 OpNameMapTy &OperandMap); 89 void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, 90 ArrayRef<const CodeGenInstruction*> NumberedInstructions); 91 92 void emitLogicalOperandSizeMappings( 93 raw_ostream &OS, StringRef Namespace, 94 ArrayRef<const CodeGenInstruction *> NumberedInstructions); 95 void emitLogicalOperandTypeMappings( 96 raw_ostream &OS, StringRef Namespace, 97 ArrayRef<const CodeGenInstruction *> NumberedInstructions); 98 99 // Operand information. 100 void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); 101 std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); 102 }; 103 104 } // end anonymous namespace 105 106 static void PrintDefList(const std::vector<Record*> &Uses, 107 unsigned Num, raw_ostream &OS) { 108 OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; 109 for (Record *U : Uses) 110 OS << getQualifiedName(U) << ", "; 111 OS << "0 };\n"; 112 } 113 114 //===----------------------------------------------------------------------===// 115 // Operand Info Emission. 116 //===----------------------------------------------------------------------===// 117 118 std::vector<std::string> 119 InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 120 std::vector<std::string> Result; 121 122 for (auto &Op : Inst.Operands) { 123 // Handle aggregate operands and normal operands the same way by expanding 124 // either case into a list of operands for this op. 125 std::vector<CGIOperandList::OperandInfo> OperandList; 126 127 // This might be a multiple operand thing. Targets like X86 have 128 // registers in their multi-operand operands. It may also be an anonymous 129 // operand, which has a single operand, but no declared class for the 130 // operand. 131 DagInit *MIOI = Op.MIOperandInfo; 132 133 if (!MIOI || MIOI->getNumArgs() == 0) { 134 // Single, anonymous, operand. 135 OperandList.push_back(Op); 136 } else { 137 for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) { 138 OperandList.push_back(Op); 139 140 auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef(); 141 OperandList.back().Rec = OpR; 142 } 143 } 144 145 for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 146 Record *OpR = OperandList[j].Rec; 147 std::string Res; 148 149 if (OpR->isSubClassOf("RegisterOperand")) 150 OpR = OpR->getValueAsDef("RegClass"); 151 if (OpR->isSubClassOf("RegisterClass")) 152 Res += getQualifiedName(OpR) + "RegClassID, "; 153 else if (OpR->isSubClassOf("PointerLikeRegClass")) 154 Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 155 else 156 // -1 means the operand does not have a fixed register class. 157 Res += "-1, "; 158 159 // Fill in applicable flags. 160 Res += "0"; 161 162 // Ptr value whose register class is resolved via callback. 163 if (OpR->isSubClassOf("PointerLikeRegClass")) 164 Res += "|(1<<MCOI::LookupPtrRegClass)"; 165 166 // Predicate operands. Check to see if the original unexpanded operand 167 // was of type PredicateOp. 168 if (Op.Rec->isSubClassOf("PredicateOp")) 169 Res += "|(1<<MCOI::Predicate)"; 170 171 // Optional def operands. Check to see if the original unexpanded operand 172 // was of type OptionalDefOperand. 173 if (Op.Rec->isSubClassOf("OptionalDefOperand")) 174 Res += "|(1<<MCOI::OptionalDef)"; 175 176 // Branch target operands. Check to see if the original unexpanded 177 // operand was of type BranchTargetOperand. 178 if (Op.Rec->isSubClassOf("BranchTargetOperand")) 179 Res += "|(1<<MCOI::BranchTarget)"; 180 181 // Fill in operand type. 182 Res += ", "; 183 assert(!Op.OperandType.empty() && "Invalid operand type."); 184 Res += Op.OperandType; 185 186 // Fill in constraint info. 187 Res += ", "; 188 189 const CGIOperandList::ConstraintInfo &Constraint = 190 Op.Constraints[j]; 191 if (Constraint.isNone()) 192 Res += "0"; 193 else if (Constraint.isEarlyClobber()) 194 Res += "MCOI_EARLY_CLOBBER"; 195 else { 196 assert(Constraint.isTied()); 197 Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")"; 198 } 199 200 Result.push_back(Res); 201 } 202 } 203 204 return Result; 205 } 206 207 void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 208 OperandInfoMapTy &OperandInfoIDs) { 209 // ID #0 is for no operand info. 210 unsigned OperandListNum = 0; 211 OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 212 213 OS << "\n"; 214 const CodeGenTarget &Target = CDP.getTargetInfo(); 215 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { 216 std::vector<std::string> OperandInfo = GetOperandInfo(*Inst); 217 unsigned &N = OperandInfoIDs[OperandInfo]; 218 if (N != 0) continue; 219 220 N = ++OperandListNum; 221 OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 222 for (const std::string &Info : OperandInfo) 223 OS << "{ " << Info << " }, "; 224 OS << "};\n"; 225 } 226 } 227 228 /// Initialize data structures for generating operand name mappings. 229 /// 230 /// \param Operands [out] A map used to generate the OpName enum with operand 231 /// names as its keys and operand enum values as its values. 232 /// \param OperandMap [out] A map for representing the operand name mappings for 233 /// each instructions. This is used to generate the OperandMap table as 234 /// well as the getNamedOperandIdx() function. 235 void InstrInfoEmitter::initOperandMapData( 236 ArrayRef<const CodeGenInstruction *> NumberedInstructions, 237 StringRef Namespace, 238 std::map<std::string, unsigned> &Operands, 239 OpNameMapTy &OperandMap) { 240 unsigned NumOperands = 0; 241 for (const CodeGenInstruction *Inst : NumberedInstructions) { 242 if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) 243 continue; 244 std::map<unsigned, unsigned> OpList; 245 for (const auto &Info : Inst->Operands) { 246 StrUintMapIter I = Operands.find(Info.Name); 247 248 if (I == Operands.end()) { 249 I = Operands.insert(Operands.begin(), 250 std::pair<std::string, unsigned>(Info.Name, NumOperands++)); 251 } 252 OpList[I->second] = Info.MIOperandNo; 253 } 254 OperandMap[OpList].push_back(Namespace.str() + "::" + 255 Inst->TheDef->getName().str()); 256 } 257 } 258 259 /// Generate a table and function for looking up the indices of operands by 260 /// name. 261 /// 262 /// This code generates: 263 /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry 264 /// for each operand name. 265 /// - A 2-dimensional table called OperandMap for mapping OpName enum values to 266 /// operand indices. 267 /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) 268 /// for looking up the operand index for an instruction, given a value from 269 /// OpName enum 270 void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, 271 const CodeGenTarget &Target, 272 ArrayRef<const CodeGenInstruction*> NumberedInstructions) { 273 StringRef Namespace = Target.getInstNamespace(); 274 std::string OpNameNS = "OpName"; 275 // Map of operand names to their enumeration value. This will be used to 276 // generate the OpName enum. 277 std::map<std::string, unsigned> Operands; 278 OpNameMapTy OperandMap; 279 280 initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); 281 282 OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; 283 OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; 284 OS << "namespace llvm {\n"; 285 OS << "namespace " << Namespace << " {\n"; 286 OS << "namespace " << OpNameNS << " {\n"; 287 OS << "enum {\n"; 288 for (const auto &Op : Operands) 289 OS << " " << Op.first << " = " << Op.second << ",\n"; 290 291 OS << " OPERAND_LAST"; 292 OS << "\n};\n"; 293 OS << "} // end namespace OpName\n"; 294 OS << "} // end namespace " << Namespace << "\n"; 295 OS << "} // end namespace llvm\n"; 296 OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n"; 297 298 OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; 299 OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; 300 OS << "namespace llvm {\n"; 301 OS << "namespace " << Namespace << " {\n"; 302 OS << "LLVM_READONLY\n"; 303 OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; 304 if (!Operands.empty()) { 305 OS << " static const int16_t OperandMap [][" << Operands.size() 306 << "] = {\n"; 307 for (const auto &Entry : OperandMap) { 308 const std::map<unsigned, unsigned> &OpList = Entry.first; 309 OS << "{"; 310 311 // Emit a row of the OperandMap table 312 for (unsigned i = 0, e = Operands.size(); i != e; ++i) 313 OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", "; 314 315 OS << "},\n"; 316 } 317 OS << "};\n"; 318 319 OS << " switch(Opcode) {\n"; 320 unsigned TableIndex = 0; 321 for (const auto &Entry : OperandMap) { 322 for (const std::string &Name : Entry.second) 323 OS << " case " << Name << ":\n"; 324 325 OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; 326 } 327 OS << " default: return -1;\n"; 328 OS << " }\n"; 329 } else { 330 // There are no operands, so no need to emit anything 331 OS << " return -1;\n"; 332 } 333 OS << "}\n"; 334 OS << "} // end namespace " << Namespace << "\n"; 335 OS << "} // end namespace llvm\n"; 336 OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n"; 337 } 338 339 /// Generate an enum for all the operand types for this target, under the 340 /// llvm::TargetNamespace::OpTypes namespace. 341 /// Operand types are all definitions derived of the Operand Target.td class. 342 void InstrInfoEmitter::emitOperandTypeMappings( 343 raw_ostream &OS, const CodeGenTarget &Target, 344 ArrayRef<const CodeGenInstruction *> NumberedInstructions) { 345 346 StringRef Namespace = Target.getInstNamespace(); 347 std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand"); 348 std::vector<Record *> RegisterOperands = 349 Records.getAllDerivedDefinitions("RegisterOperand"); 350 std::vector<Record *> RegisterClasses = 351 Records.getAllDerivedDefinitions("RegisterClass"); 352 353 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 354 OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 355 OS << "namespace llvm {\n"; 356 OS << "namespace " << Namespace << " {\n"; 357 OS << "namespace OpTypes {\n"; 358 OS << "enum OperandType {\n"; 359 360 unsigned EnumVal = 0; 361 for (const std::vector<Record *> *RecordsToAdd : 362 {&Operands, &RegisterOperands, &RegisterClasses}) { 363 for (const Record *Op : *RecordsToAdd) { 364 if (!Op->isAnonymous()) 365 OS << " " << Op->getName() << " = " << EnumVal << ",\n"; 366 ++EnumVal; 367 } 368 } 369 370 OS << " OPERAND_TYPE_LIST_END" << "\n};\n"; 371 OS << "} // end namespace OpTypes\n"; 372 OS << "} // end namespace " << Namespace << "\n"; 373 OS << "} // end namespace llvm\n"; 374 OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n"; 375 376 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n"; 377 OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n"; 378 OS << "namespace llvm {\n"; 379 OS << "namespace " << Namespace << " {\n"; 380 OS << "LLVM_READONLY\n"; 381 OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n"; 382 // TODO: Factor out duplicate operand lists to compress the tables. 383 if (!NumberedInstructions.empty()) { 384 std::vector<int> OperandOffsets; 385 std::vector<Record *> OperandRecords; 386 int CurrentOffset = 0; 387 for (const CodeGenInstruction *Inst : NumberedInstructions) { 388 OperandOffsets.push_back(CurrentOffset); 389 for (const auto &Op : Inst->Operands) { 390 const DagInit *MIOI = Op.MIOperandInfo; 391 if (!MIOI || MIOI->getNumArgs() == 0) { 392 // Single, anonymous, operand. 393 OperandRecords.push_back(Op.Rec); 394 ++CurrentOffset; 395 } else { 396 for (Init *Arg : MIOI->getArgs()) { 397 OperandRecords.push_back(cast<DefInit>(Arg)->getDef()); 398 ++CurrentOffset; 399 } 400 } 401 } 402 } 403 404 // Emit the table of offsets (indexes) into the operand type table. 405 // Size the unsigned integer offset to save space. 406 assert(OperandRecords.size() <= UINT32_MAX && 407 "Too many operands for offset table"); 408 OS << ((OperandRecords.size() <= UINT16_MAX) ? " const uint16_t" 409 : " const uint32_t"); 410 OS << " Offsets[] = {\n"; 411 for (int I = 0, E = OperandOffsets.size(); I != E; ++I) 412 OS << " " << OperandOffsets[I] << ",\n"; 413 OS << " };\n"; 414 415 // Add an entry for the end so that we don't need to special case it below. 416 OperandOffsets.push_back(OperandRecords.size()); 417 418 // Emit the actual operand types in a flat table. 419 // Size the signed integer operand type to save space. 420 assert(EnumVal <= INT16_MAX && 421 "Too many operand types for operand types table"); 422 OS << ((EnumVal <= INT8_MAX) ? " const int8_t" : " const int16_t"); 423 OS << " OpcodeOperandTypes[] = {\n "; 424 for (int I = 0, E = OperandRecords.size(), CurOffset = 1; I != E; ++I) { 425 // We print each Opcode's operands in its own row. 426 if (I == OperandOffsets[CurOffset]) { 427 OS << "\n "; 428 // If there are empty rows, mark them with an empty comment. 429 while (OperandOffsets[++CurOffset] == I) 430 OS << "/**/\n "; 431 } 432 Record *OpR = OperandRecords[I]; 433 if ((OpR->isSubClassOf("Operand") || 434 OpR->isSubClassOf("RegisterOperand") || 435 OpR->isSubClassOf("RegisterClass")) && 436 !OpR->isAnonymous()) 437 OS << "OpTypes::" << OpR->getName(); 438 else 439 OS << -1; 440 OS << ", "; 441 } 442 OS << "\n };\n"; 443 444 OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n"; 445 } else { 446 OS << " llvm_unreachable(\"No instructions defined\");\n"; 447 } 448 OS << "}\n"; 449 OS << "} // end namespace " << Namespace << "\n"; 450 OS << "} // end namespace llvm\n"; 451 OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n"; 452 } 453 454 void InstrInfoEmitter::emitLogicalOperandSizeMappings( 455 raw_ostream &OS, StringRef Namespace, 456 ArrayRef<const CodeGenInstruction *> NumberedInstructions) { 457 std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap; 458 459 std::map<unsigned, std::vector<std::string>> InstMap; 460 461 size_t LogicalOpListSize = 0U; 462 std::vector<unsigned> LogicalOpList; 463 for (const auto *Inst : NumberedInstructions) { 464 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings")) 465 continue; 466 467 LogicalOpList.clear(); 468 llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList), 469 [](const CGIOperandList::OperandInfo &Op) -> unsigned { 470 auto *MIOI = Op.MIOperandInfo; 471 if (!MIOI || MIOI->getNumArgs() == 0) 472 return 1; 473 return MIOI->getNumArgs(); 474 }); 475 LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize); 476 477 auto I = 478 LogicalOpSizeMap.insert({LogicalOpList, LogicalOpSizeMap.size()}).first; 479 InstMap[I->second].push_back( 480 (Namespace + "::" + Inst->TheDef->getName()).str()); 481 } 482 483 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n"; 484 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n"; 485 OS << "namespace llvm {\n"; 486 OS << "namespace " << Namespace << " {\n"; 487 OS << "LLVM_READONLY static unsigned\n"; 488 OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n"; 489 if (!InstMap.empty()) { 490 std::vector<const std::vector<unsigned> *> LogicalOpSizeList( 491 LogicalOpSizeMap.size()); 492 for (auto &P : LogicalOpSizeMap) { 493 LogicalOpSizeList[P.second] = &P.first; 494 } 495 OS << " static const unsigned SizeMap[][" << LogicalOpListSize 496 << "] = {\n"; 497 for (auto &R : LogicalOpSizeList) { 498 const auto &Row = *R; 499 OS << " {"; 500 int i; 501 for (i = 0; i < static_cast<int>(Row.size()); ++i) { 502 OS << Row[i] << ", "; 503 } 504 for (; i < static_cast<int>(LogicalOpListSize); ++i) { 505 OS << "0, "; 506 } 507 OS << "}, "; 508 OS << "\n"; 509 } 510 OS << " };\n"; 511 512 OS << " switch (Opcode) {\n"; 513 OS << " default: return LogicalOpIdx;\n"; 514 for (auto &P : InstMap) { 515 auto OpMapIdx = P.first; 516 const auto &Insts = P.second; 517 for (const auto &Inst : Insts) { 518 OS << " case " << Inst << ":\n"; 519 } 520 OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n"; 521 } 522 OS << " }\n"; 523 } else { 524 OS << " return LogicalOpIdx;\n"; 525 } 526 OS << "}\n"; 527 528 OS << "LLVM_READONLY static inline unsigned\n"; 529 OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n"; 530 OS << " auto S = 0U;\n"; 531 OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n"; 532 OS << " S += getLogicalOperandSize(Opcode, i);\n"; 533 OS << " return S;\n"; 534 OS << "}\n"; 535 536 OS << "} // end namespace " << Namespace << "\n"; 537 OS << "} // end namespace llvm\n"; 538 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n"; 539 } 540 541 void InstrInfoEmitter::emitLogicalOperandTypeMappings( 542 raw_ostream &OS, StringRef Namespace, 543 ArrayRef<const CodeGenInstruction *> NumberedInstructions) { 544 std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap; 545 546 std::map<unsigned, std::vector<std::string>> InstMap; 547 548 size_t OpTypeListSize = 0U; 549 std::vector<std::string> LogicalOpTypeList; 550 for (const auto *Inst : NumberedInstructions) { 551 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings")) 552 continue; 553 554 LogicalOpTypeList.clear(); 555 for (const auto &Op : Inst->Operands) { 556 auto *OpR = Op.Rec; 557 if ((OpR->isSubClassOf("Operand") || 558 OpR->isSubClassOf("RegisterOperand") || 559 OpR->isSubClassOf("RegisterClass")) && 560 !OpR->isAnonymous()) { 561 LogicalOpTypeList.push_back( 562 (Namespace + "::OpTypes::" + Op.Rec->getName()).str()); 563 } else { 564 LogicalOpTypeList.push_back("-1"); 565 } 566 } 567 OpTypeListSize = std::max(LogicalOpTypeList.size(), OpTypeListSize); 568 569 auto I = 570 LogicalOpTypeMap.insert({LogicalOpTypeList, LogicalOpTypeMap.size()}) 571 .first; 572 InstMap[I->second].push_back( 573 (Namespace + "::" + Inst->TheDef->getName()).str()); 574 } 575 576 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n"; 577 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n"; 578 OS << "namespace llvm {\n"; 579 OS << "namespace " << Namespace << " {\n"; 580 OS << "LLVM_READONLY static int\n"; 581 OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n"; 582 if (!InstMap.empty()) { 583 std::vector<const std::vector<std::string> *> LogicalOpTypeList( 584 LogicalOpTypeMap.size()); 585 for (auto &P : LogicalOpTypeMap) { 586 LogicalOpTypeList[P.second] = &P.first; 587 } 588 OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n"; 589 for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) { 590 const auto &Row = *LogicalOpTypeList[r]; 591 OS << " {"; 592 int i, s = Row.size(); 593 for (i = 0; i < s; ++i) { 594 if (i > 0) 595 OS << ", "; 596 OS << Row[i]; 597 } 598 for (; i < static_cast<int>(OpTypeListSize); ++i) { 599 if (i > 0) 600 OS << ", "; 601 OS << "-1"; 602 } 603 OS << "}"; 604 if (r != rs - 1) 605 OS << ","; 606 OS << "\n"; 607 } 608 OS << " };\n"; 609 610 OS << " switch (Opcode) {\n"; 611 OS << " default: return -1;\n"; 612 for (auto &P : InstMap) { 613 auto OpMapIdx = P.first; 614 const auto &Insts = P.second; 615 for (const auto &Inst : Insts) { 616 OS << " case " << Inst << ":\n"; 617 } 618 OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n"; 619 } 620 OS << " }\n"; 621 } else { 622 OS << " return -1;\n"; 623 } 624 OS << "}\n"; 625 OS << "} // end namespace " << Namespace << "\n"; 626 OS << "} // end namespace llvm\n"; 627 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n"; 628 } 629 630 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS, 631 StringRef TargetName) { 632 RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); 633 if (TIIPredicates.empty()) 634 return; 635 636 OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n"; 637 OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n"; 638 639 OS << "namespace llvm {\n"; 640 OS << "class MCInst;\n\n"; 641 642 OS << "namespace " << TargetName << "_MC {\n\n"; 643 644 for (const Record *Rec : TIIPredicates) { 645 OS << "bool " << Rec->getValueAsString("FunctionName") 646 << "(const MCInst &MI);\n"; 647 } 648 649 OS << "\n} // end namespace " << TargetName << "_MC\n"; 650 OS << "} // end namespace llvm\n\n"; 651 652 OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n"; 653 654 OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n"; 655 OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n"; 656 657 OS << "namespace llvm {\n"; 658 OS << "namespace " << TargetName << "_MC {\n\n"; 659 660 PredicateExpander PE(TargetName); 661 PE.setExpandForMC(true); 662 663 for (const Record *Rec : TIIPredicates) { 664 OS << "bool " << Rec->getValueAsString("FunctionName"); 665 OS << "(const MCInst &MI) {\n"; 666 667 OS.indent(PE.getIndentLevel() * 2); 668 PE.expandStatement(OS, Rec->getValueAsDef("Body")); 669 OS << "\n}\n\n"; 670 } 671 672 OS << "} // end namespace " << TargetName << "_MC\n"; 673 OS << "} // end namespace llvm\n\n"; 674 675 OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n"; 676 } 677 678 void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, 679 StringRef TargetName, 680 bool ExpandDefinition) { 681 RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); 682 if (TIIPredicates.empty()) 683 return; 684 685 PredicateExpander PE(TargetName); 686 PE.setExpandForMC(false); 687 688 for (const Record *Rec : TIIPredicates) { 689 OS << (ExpandDefinition ? "" : "static ") << "bool "; 690 if (ExpandDefinition) 691 OS << TargetName << "InstrInfo::"; 692 OS << Rec->getValueAsString("FunctionName"); 693 OS << "(const MachineInstr &MI)"; 694 if (!ExpandDefinition) { 695 OS << ";\n"; 696 continue; 697 } 698 699 OS << " {\n"; 700 OS.indent(PE.getIndentLevel() * 2); 701 PE.expandStatement(OS, Rec->getValueAsDef("Body")); 702 OS << "\n}\n\n"; 703 } 704 } 705 706 //===----------------------------------------------------------------------===// 707 // Main Output. 708 //===----------------------------------------------------------------------===// 709 710 // run - Emit the main instruction description records for the target... 711 void InstrInfoEmitter::run(raw_ostream &OS) { 712 emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS); 713 emitEnums(OS); 714 715 OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; 716 OS << "#undef GET_INSTRINFO_MC_DESC\n"; 717 718 OS << "namespace llvm {\n\n"; 719 720 CodeGenTarget &Target = CDP.getTargetInfo(); 721 const std::string &TargetName = std::string(Target.getName()); 722 Record *InstrInfo = Target.getInstructionSet(); 723 724 // Keep track of all of the def lists we have emitted already. 725 std::map<std::vector<Record*>, unsigned> EmittedLists; 726 unsigned ListNumber = 0; 727 728 // Emit all of the instruction's implicit uses and defs. 729 Records.startTimer("Emit uses/defs"); 730 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { 731 Record *Inst = II->TheDef; 732 std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 733 if (!Uses.empty()) { 734 unsigned &IL = EmittedLists[Uses]; 735 if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 736 } 737 std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 738 if (!Defs.empty()) { 739 unsigned &IL = EmittedLists[Defs]; 740 if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 741 } 742 } 743 744 OperandInfoMapTy OperandInfoIDs; 745 746 // Emit all of the operand info records. 747 Records.startTimer("Emit operand info"); 748 EmitOperandInfo(OS, OperandInfoIDs); 749 750 // Emit all of the MCInstrDesc records in their ENUM ordering. 751 // 752 Records.startTimer("Emit InstrDesc records"); 753 OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 754 ArrayRef<const CodeGenInstruction*> NumberedInstructions = 755 Target.getInstructionsByEnumValue(); 756 757 SequenceToOffsetTable<std::string> InstrNames; 758 unsigned Num = 0; 759 for (const CodeGenInstruction *Inst : NumberedInstructions) { 760 // Keep a list of the instruction names. 761 InstrNames.add(std::string(Inst->TheDef->getName())); 762 // Emit the record into the table. 763 emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS); 764 } 765 OS << "};\n\n"; 766 767 // Emit the array of instruction names. 768 Records.startTimer("Emit instruction names"); 769 InstrNames.layout(); 770 InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName + 771 "InstrNameData[]"); 772 773 OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 774 Num = 0; 775 for (const CodeGenInstruction *Inst : NumberedInstructions) { 776 // Newline every eight entries. 777 if (Num % 8 == 0) 778 OS << "\n "; 779 OS << InstrNames.get(std::string(Inst->TheDef->getName())) << "U, "; 780 ++Num; 781 } 782 OS << "\n};\n\n"; 783 784 bool HasDeprecationFeatures = 785 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) { 786 return !Inst->HasComplexDeprecationPredicate && 787 !Inst->DeprecatedReason.empty(); 788 }); 789 if (HasDeprecationFeatures) { 790 OS << "extern const uint8_t " << TargetName 791 << "InstrDeprecationFeatures[] = {"; 792 Num = 0; 793 for (const CodeGenInstruction *Inst : NumberedInstructions) { 794 if (Num % 8 == 0) 795 OS << "\n "; 796 if (!Inst->HasComplexDeprecationPredicate && 797 !Inst->DeprecatedReason.empty()) 798 OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason 799 << ", "; 800 else 801 OS << "uint8_t(-1), "; 802 ++Num; 803 } 804 OS << "\n};\n\n"; 805 } 806 807 bool HasComplexDeprecationInfos = 808 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) { 809 return Inst->HasComplexDeprecationPredicate; 810 }); 811 if (HasComplexDeprecationInfos) { 812 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName 813 << "InstrComplexDeprecationInfos[] = {"; 814 Num = 0; 815 for (const CodeGenInstruction *Inst : NumberedInstructions) { 816 if (Num % 8 == 0) 817 OS << "\n "; 818 if (Inst->HasComplexDeprecationPredicate) 819 // Emit a function pointer to the complex predicate method. 820 OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, "; 821 else 822 OS << "nullptr, "; 823 ++Num; 824 } 825 OS << "\n};\n\n"; 826 } 827 828 // MCInstrInfo initialization routine. 829 Records.startTimer("Emit initialization routine"); 830 OS << "static inline void Init" << TargetName 831 << "MCInstrInfo(MCInstrInfo *II) {\n"; 832 OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName 833 << "InstrNameIndices, " << TargetName << "InstrNameData, "; 834 if (HasDeprecationFeatures) 835 OS << TargetName << "InstrDeprecationFeatures, "; 836 else 837 OS << "nullptr, "; 838 if (HasComplexDeprecationInfos) 839 OS << TargetName << "InstrComplexDeprecationInfos, "; 840 else 841 OS << "nullptr, "; 842 OS << NumberedInstructions.size() << ");\n}\n\n"; 843 844 OS << "} // end namespace llvm\n"; 845 846 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 847 848 // Create a TargetInstrInfo subclass to hide the MC layer initialization. 849 OS << "#ifdef GET_INSTRINFO_HEADER\n"; 850 OS << "#undef GET_INSTRINFO_HEADER\n"; 851 852 std::string ClassName = TargetName + "GenInstrInfo"; 853 OS << "namespace llvm {\n"; 854 OS << "struct " << ClassName << " : public TargetInstrInfo {\n" 855 << " explicit " << ClassName 856 << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n" 857 << " ~" << ClassName << "() override = default;\n"; 858 859 860 OS << "\n};\n} // end namespace llvm\n"; 861 862 OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 863 864 OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n"; 865 OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n"; 866 emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */false); 867 OS << "\n"; 868 OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n"; 869 870 OS << "#ifdef GET_INSTRINFO_HELPERS\n"; 871 OS << "#undef GET_INSTRINFO_HELPERS\n\n"; 872 emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */true); 873 OS << "#endif // GET_INSTRINFO_HELPERS\n\n"; 874 875 OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n"; 876 OS << "#undef GET_INSTRINFO_CTOR_DTOR\n"; 877 878 OS << "namespace llvm {\n"; 879 OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 880 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 881 OS << "extern const char " << TargetName << "InstrNameData[];\n"; 882 if (HasDeprecationFeatures) 883 OS << "extern const uint8_t " << TargetName 884 << "InstrDeprecationFeatures[];\n"; 885 if (HasComplexDeprecationInfos) 886 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName 887 << "InstrComplexDeprecationInfos[];\n"; 888 OS << ClassName << "::" << ClassName 889 << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int " 890 "ReturnOpcode)\n" 891 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, " 892 "ReturnOpcode) {\n" 893 << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName 894 << "InstrNameIndices, " << TargetName << "InstrNameData, "; 895 if (HasDeprecationFeatures) 896 OS << TargetName << "InstrDeprecationFeatures, "; 897 else 898 OS << "nullptr, "; 899 if (HasComplexDeprecationInfos) 900 OS << TargetName << "InstrComplexDeprecationInfos, "; 901 else 902 OS << "nullptr, "; 903 OS << NumberedInstructions.size() << ");\n}\n"; 904 OS << "} // end namespace llvm\n"; 905 906 OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; 907 908 Records.startTimer("Emit operand name mappings"); 909 emitOperandNameMappings(OS, Target, NumberedInstructions); 910 911 Records.startTimer("Emit operand type mappings"); 912 emitOperandTypeMappings(OS, Target, NumberedInstructions); 913 914 Records.startTimer("Emit logical operand size mappings"); 915 emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions); 916 917 Records.startTimer("Emit logical operand type mappings"); 918 emitLogicalOperandTypeMappings(OS, TargetName, NumberedInstructions); 919 920 Records.startTimer("Emit helper methods"); 921 emitMCIIHelperMethods(OS, TargetName); 922 } 923 924 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 925 Record *InstrInfo, 926 std::map<std::vector<Record*>, unsigned> &EmittedLists, 927 const OperandInfoMapTy &OpInfo, 928 raw_ostream &OS) { 929 int MinOperands = 0; 930 if (!Inst.Operands.empty()) 931 // Each logical operand can be multiple MI operands. 932 MinOperands = Inst.Operands.back().MIOperandNo + 933 Inst.Operands.back().MINumOperands; 934 935 OS << " { "; 936 OS << Num << ",\t" << MinOperands << ",\t" 937 << Inst.Operands.NumDefs << ",\t" 938 << Inst.TheDef->getValueAsInt("Size") << ",\t" 939 << SchedModels.getSchedClassIdx(Inst) << ",\t0"; 940 941 CodeGenTarget &Target = CDP.getTargetInfo(); 942 943 // Emit all of the target independent flags... 944 if (Inst.isPreISelOpcode) OS << "|(1ULL<<MCID::PreISelOpcode)"; 945 if (Inst.isPseudo) OS << "|(1ULL<<MCID::Pseudo)"; 946 if (Inst.isReturn) OS << "|(1ULL<<MCID::Return)"; 947 if (Inst.isEHScopeReturn) OS << "|(1ULL<<MCID::EHScopeReturn)"; 948 if (Inst.isBranch) OS << "|(1ULL<<MCID::Branch)"; 949 if (Inst.isIndirectBranch) OS << "|(1ULL<<MCID::IndirectBranch)"; 950 if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)"; 951 if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)"; 952 if (Inst.isMoveReg) OS << "|(1ULL<<MCID::MoveReg)"; 953 if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)"; 954 if (Inst.isAdd) OS << "|(1ULL<<MCID::Add)"; 955 if (Inst.isTrap) OS << "|(1ULL<<MCID::Trap)"; 956 if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)"; 957 if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)"; 958 if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)"; 959 if (Inst.isCall) OS << "|(1ULL<<MCID::Call)"; 960 if (Inst.canFoldAsLoad) OS << "|(1ULL<<MCID::FoldableAsLoad)"; 961 if (Inst.mayLoad) OS << "|(1ULL<<MCID::MayLoad)"; 962 if (Inst.mayStore) OS << "|(1ULL<<MCID::MayStore)"; 963 if (Inst.mayRaiseFPException) OS << "|(1ULL<<MCID::MayRaiseFPException)"; 964 if (Inst.isPredicable) OS << "|(1ULL<<MCID::Predicable)"; 965 if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)"; 966 if (Inst.isCommutable) OS << "|(1ULL<<MCID::Commutable)"; 967 if (Inst.isTerminator) OS << "|(1ULL<<MCID::Terminator)"; 968 if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)"; 969 if (Inst.isNotDuplicable) OS << "|(1ULL<<MCID::NotDuplicable)"; 970 if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)"; 971 if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)"; 972 if (Inst.hasPostISelHook) OS << "|(1ULL<<MCID::HasPostISelHook)"; 973 if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)"; 974 if (Inst.hasSideEffects) OS << "|(1ULL<<MCID::UnmodeledSideEffects)"; 975 if (Inst.isAsCheapAsAMove) OS << "|(1ULL<<MCID::CheapAsAMove)"; 976 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq) 977 OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)"; 978 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq) 979 OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)"; 980 if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)"; 981 if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; 982 if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; 983 if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; 984 if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)"; 985 if (Inst.isAuthenticated) OS << "|(1ULL<<MCID::Authenticated)"; 986 987 // Emit all of the target-specific flags... 988 BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 989 if (!TSF) 990 PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?"); 991 uint64_t Value = 0; 992 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 993 if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i))) 994 Value |= uint64_t(Bit->getValue()) << i; 995 else 996 PrintFatalError(Inst.TheDef->getLoc(), 997 "Invalid TSFlags bit in " + Inst.TheDef->getName()); 998 } 999 OS << ", 0x"; 1000 OS.write_hex(Value); 1001 OS << "ULL, "; 1002 1003 // Emit the implicit uses and defs lists... 1004 std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 1005 if (UseList.empty()) 1006 OS << "nullptr, "; 1007 else 1008 OS << "ImplicitList" << EmittedLists[UseList] << ", "; 1009 1010 std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 1011 if (DefList.empty()) 1012 OS << "nullptr, "; 1013 else 1014 OS << "ImplicitList" << EmittedLists[DefList] << ", "; 1015 1016 // Emit the operand info. 1017 std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 1018 if (OperandInfo.empty()) 1019 OS << "nullptr"; 1020 else 1021 OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 1022 1023 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 1024 } 1025 1026 // emitEnums - Print out enum values for all of the instructions. 1027 void InstrInfoEmitter::emitEnums(raw_ostream &OS) { 1028 OS << "#ifdef GET_INSTRINFO_ENUM\n"; 1029 OS << "#undef GET_INSTRINFO_ENUM\n"; 1030 1031 OS << "namespace llvm {\n\n"; 1032 1033 const CodeGenTarget &Target = CDP.getTargetInfo(); 1034 1035 // We must emit the PHI opcode first... 1036 StringRef Namespace = Target.getInstNamespace(); 1037 1038 if (Namespace.empty()) 1039 PrintFatalError("No instructions defined!"); 1040 1041 OS << "namespace " << Namespace << " {\n"; 1042 OS << " enum {\n"; 1043 unsigned Num = 0; 1044 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) 1045 OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; 1046 OS << " INSTRUCTION_LIST_END = " << Num << "\n"; 1047 OS << " };\n\n"; 1048 OS << "} // end namespace " << Namespace << "\n"; 1049 OS << "} // end namespace llvm\n"; 1050 OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 1051 1052 OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n"; 1053 OS << "#undef GET_INSTRINFO_SCHED_ENUM\n"; 1054 OS << "namespace llvm {\n\n"; 1055 OS << "namespace " << Namespace << " {\n"; 1056 OS << "namespace Sched {\n"; 1057 OS << " enum {\n"; 1058 Num = 0; 1059 for (const auto &Class : SchedModels.explicit_classes()) 1060 OS << " " << Class.Name << "\t= " << Num++ << ",\n"; 1061 OS << " SCHED_LIST_END = " << Num << "\n"; 1062 OS << " };\n"; 1063 OS << "} // end namespace Sched\n"; 1064 OS << "} // end namespace " << Namespace << "\n"; 1065 OS << "} // end namespace llvm\n"; 1066 1067 OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n"; 1068 } 1069 1070 namespace llvm { 1071 1072 void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 1073 RK.startTimer("Analyze DAG patterns"); 1074 InstrInfoEmitter(RK).run(OS); 1075 RK.startTimer("Emit map table"); 1076 EmitMapTable(RK, OS); 1077 } 1078 1079 } // end namespace llvm 1080