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 OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n"; 454 OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n"; 455 OS << "namespace llvm {\n"; 456 OS << "namespace " << Namespace << " {\n"; 457 OS << "LLVM_READONLY\n"; 458 OS << "static int getMemOperandSize(int OpType) {\n"; 459 OS << " switch (OpType) {\n"; 460 std::map<int, std::vector<StringRef>> SizeToOperandName; 461 for (const Record *Op : Operands) { 462 if (!Op->isSubClassOf("X86MemOperand")) 463 continue; 464 if (int Size = Op->getValueAsInt("Size")) 465 SizeToOperandName[Size].push_back(Op->getName()); 466 } 467 OS << " default: return 0;\n"; 468 for (auto KV : SizeToOperandName) { 469 for (const StringRef &OperandName : KV.second) 470 OS << " case OpTypes::" << OperandName << ":\n"; 471 OS << " return " << KV.first << ";\n\n"; 472 } 473 OS << " }\n}\n"; 474 OS << "} // end namespace " << Namespace << "\n"; 475 OS << "} // end namespace llvm\n"; 476 OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n"; 477 } 478 479 void InstrInfoEmitter::emitLogicalOperandSizeMappings( 480 raw_ostream &OS, StringRef Namespace, 481 ArrayRef<const CodeGenInstruction *> NumberedInstructions) { 482 std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap; 483 484 std::map<unsigned, std::vector<std::string>> InstMap; 485 486 size_t LogicalOpListSize = 0U; 487 std::vector<unsigned> LogicalOpList; 488 for (const auto *Inst : NumberedInstructions) { 489 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings")) 490 continue; 491 492 LogicalOpList.clear(); 493 llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList), 494 [](const CGIOperandList::OperandInfo &Op) -> unsigned { 495 auto *MIOI = Op.MIOperandInfo; 496 if (!MIOI || MIOI->getNumArgs() == 0) 497 return 1; 498 return MIOI->getNumArgs(); 499 }); 500 LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize); 501 502 auto I = 503 LogicalOpSizeMap.insert({LogicalOpList, LogicalOpSizeMap.size()}).first; 504 InstMap[I->second].push_back( 505 (Namespace + "::" + Inst->TheDef->getName()).str()); 506 } 507 508 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n"; 509 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n"; 510 OS << "namespace llvm {\n"; 511 OS << "namespace " << Namespace << " {\n"; 512 OS << "LLVM_READONLY static unsigned\n"; 513 OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n"; 514 if (!InstMap.empty()) { 515 std::vector<const std::vector<unsigned> *> LogicalOpSizeList( 516 LogicalOpSizeMap.size()); 517 for (auto &P : LogicalOpSizeMap) { 518 LogicalOpSizeList[P.second] = &P.first; 519 } 520 OS << " static const unsigned SizeMap[][" << LogicalOpListSize 521 << "] = {\n"; 522 for (auto &R : LogicalOpSizeList) { 523 const auto &Row = *R; 524 OS << " {"; 525 int i; 526 for (i = 0; i < static_cast<int>(Row.size()); ++i) { 527 OS << Row[i] << ", "; 528 } 529 for (; i < static_cast<int>(LogicalOpListSize); ++i) { 530 OS << "0, "; 531 } 532 OS << "}, "; 533 OS << "\n"; 534 } 535 OS << " };\n"; 536 537 OS << " switch (Opcode) {\n"; 538 OS << " default: return LogicalOpIdx;\n"; 539 for (auto &P : InstMap) { 540 auto OpMapIdx = P.first; 541 const auto &Insts = P.second; 542 for (const auto &Inst : Insts) { 543 OS << " case " << Inst << ":\n"; 544 } 545 OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n"; 546 } 547 OS << " }\n"; 548 } else { 549 OS << " return LogicalOpIdx;\n"; 550 } 551 OS << "}\n"; 552 553 OS << "LLVM_READONLY static inline unsigned\n"; 554 OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n"; 555 OS << " auto S = 0U;\n"; 556 OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n"; 557 OS << " S += getLogicalOperandSize(Opcode, i);\n"; 558 OS << " return S;\n"; 559 OS << "}\n"; 560 561 OS << "} // end namespace " << Namespace << "\n"; 562 OS << "} // end namespace llvm\n"; 563 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n"; 564 } 565 566 void InstrInfoEmitter::emitLogicalOperandTypeMappings( 567 raw_ostream &OS, StringRef Namespace, 568 ArrayRef<const CodeGenInstruction *> NumberedInstructions) { 569 std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap; 570 571 std::map<unsigned, std::vector<std::string>> InstMap; 572 573 size_t OpTypeListSize = 0U; 574 std::vector<std::string> LogicalOpTypeList; 575 for (const auto *Inst : NumberedInstructions) { 576 if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings")) 577 continue; 578 579 LogicalOpTypeList.clear(); 580 for (const auto &Op : Inst->Operands) { 581 auto *OpR = Op.Rec; 582 if ((OpR->isSubClassOf("Operand") || 583 OpR->isSubClassOf("RegisterOperand") || 584 OpR->isSubClassOf("RegisterClass")) && 585 !OpR->isAnonymous()) { 586 LogicalOpTypeList.push_back( 587 (Namespace + "::OpTypes::" + Op.Rec->getName()).str()); 588 } else { 589 LogicalOpTypeList.push_back("-1"); 590 } 591 } 592 OpTypeListSize = std::max(LogicalOpTypeList.size(), OpTypeListSize); 593 594 auto I = 595 LogicalOpTypeMap.insert({LogicalOpTypeList, LogicalOpTypeMap.size()}) 596 .first; 597 InstMap[I->second].push_back( 598 (Namespace + "::" + Inst->TheDef->getName()).str()); 599 } 600 601 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n"; 602 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n"; 603 OS << "namespace llvm {\n"; 604 OS << "namespace " << Namespace << " {\n"; 605 OS << "LLVM_READONLY static int\n"; 606 OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n"; 607 if (!InstMap.empty()) { 608 std::vector<const std::vector<std::string> *> LogicalOpTypeList( 609 LogicalOpTypeMap.size()); 610 for (auto &P : LogicalOpTypeMap) { 611 LogicalOpTypeList[P.second] = &P.first; 612 } 613 OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n"; 614 for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) { 615 const auto &Row = *LogicalOpTypeList[r]; 616 OS << " {"; 617 int i, s = Row.size(); 618 for (i = 0; i < s; ++i) { 619 if (i > 0) 620 OS << ", "; 621 OS << Row[i]; 622 } 623 for (; i < static_cast<int>(OpTypeListSize); ++i) { 624 if (i > 0) 625 OS << ", "; 626 OS << "-1"; 627 } 628 OS << "}"; 629 if (r != rs - 1) 630 OS << ","; 631 OS << "\n"; 632 } 633 OS << " };\n"; 634 635 OS << " switch (Opcode) {\n"; 636 OS << " default: return -1;\n"; 637 for (auto &P : InstMap) { 638 auto OpMapIdx = P.first; 639 const auto &Insts = P.second; 640 for (const auto &Inst : Insts) { 641 OS << " case " << Inst << ":\n"; 642 } 643 OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n"; 644 } 645 OS << " }\n"; 646 } else { 647 OS << " return -1;\n"; 648 } 649 OS << "}\n"; 650 OS << "} // end namespace " << Namespace << "\n"; 651 OS << "} // end namespace llvm\n"; 652 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n"; 653 } 654 655 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS, 656 StringRef TargetName) { 657 RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); 658 if (TIIPredicates.empty()) 659 return; 660 661 OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n"; 662 OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n"; 663 664 OS << "namespace llvm {\n"; 665 OS << "class MCInst;\n\n"; 666 667 OS << "namespace " << TargetName << "_MC {\n\n"; 668 669 for (const Record *Rec : TIIPredicates) { 670 OS << "bool " << Rec->getValueAsString("FunctionName") 671 << "(const MCInst &MI);\n"; 672 } 673 674 OS << "\n} // end namespace " << TargetName << "_MC\n"; 675 OS << "} // end namespace llvm\n\n"; 676 677 OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n"; 678 679 OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n"; 680 OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n"; 681 682 OS << "namespace llvm {\n"; 683 OS << "namespace " << TargetName << "_MC {\n\n"; 684 685 PredicateExpander PE(TargetName); 686 PE.setExpandForMC(true); 687 688 for (const Record *Rec : TIIPredicates) { 689 OS << "bool " << Rec->getValueAsString("FunctionName"); 690 OS << "(const MCInst &MI) {\n"; 691 692 OS.indent(PE.getIndentLevel() * 2); 693 PE.expandStatement(OS, Rec->getValueAsDef("Body")); 694 OS << "\n}\n\n"; 695 } 696 697 OS << "} // end namespace " << TargetName << "_MC\n"; 698 OS << "} // end namespace llvm\n\n"; 699 700 OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n"; 701 } 702 703 void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, 704 StringRef TargetName, 705 bool ExpandDefinition) { 706 RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); 707 if (TIIPredicates.empty()) 708 return; 709 710 PredicateExpander PE(TargetName); 711 PE.setExpandForMC(false); 712 713 for (const Record *Rec : TIIPredicates) { 714 OS << (ExpandDefinition ? "" : "static ") << "bool "; 715 if (ExpandDefinition) 716 OS << TargetName << "InstrInfo::"; 717 OS << Rec->getValueAsString("FunctionName"); 718 OS << "(const MachineInstr &MI)"; 719 if (!ExpandDefinition) { 720 OS << ";\n"; 721 continue; 722 } 723 724 OS << " {\n"; 725 OS.indent(PE.getIndentLevel() * 2); 726 PE.expandStatement(OS, Rec->getValueAsDef("Body")); 727 OS << "\n}\n\n"; 728 } 729 } 730 731 //===----------------------------------------------------------------------===// 732 // Main Output. 733 //===----------------------------------------------------------------------===// 734 735 // run - Emit the main instruction description records for the target... 736 void InstrInfoEmitter::run(raw_ostream &OS) { 737 emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS); 738 emitEnums(OS); 739 740 OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; 741 OS << "#undef GET_INSTRINFO_MC_DESC\n"; 742 743 OS << "namespace llvm {\n\n"; 744 745 CodeGenTarget &Target = CDP.getTargetInfo(); 746 const std::string &TargetName = std::string(Target.getName()); 747 Record *InstrInfo = Target.getInstructionSet(); 748 749 // Keep track of all of the def lists we have emitted already. 750 std::map<std::vector<Record*>, unsigned> EmittedLists; 751 unsigned ListNumber = 0; 752 753 // Emit all of the instruction's implicit uses and defs. 754 Records.startTimer("Emit uses/defs"); 755 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { 756 Record *Inst = II->TheDef; 757 std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 758 if (!Uses.empty()) { 759 unsigned &IL = EmittedLists[Uses]; 760 if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 761 } 762 std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 763 if (!Defs.empty()) { 764 unsigned &IL = EmittedLists[Defs]; 765 if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 766 } 767 } 768 769 OperandInfoMapTy OperandInfoIDs; 770 771 // Emit all of the operand info records. 772 Records.startTimer("Emit operand info"); 773 EmitOperandInfo(OS, OperandInfoIDs); 774 775 // Emit all of the MCInstrDesc records in their ENUM ordering. 776 // 777 Records.startTimer("Emit InstrDesc records"); 778 OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 779 ArrayRef<const CodeGenInstruction*> NumberedInstructions = 780 Target.getInstructionsByEnumValue(); 781 782 SequenceToOffsetTable<std::string> InstrNames; 783 unsigned Num = 0; 784 for (const CodeGenInstruction *Inst : NumberedInstructions) { 785 // Keep a list of the instruction names. 786 InstrNames.add(std::string(Inst->TheDef->getName())); 787 // Emit the record into the table. 788 emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS); 789 } 790 OS << "};\n\n"; 791 792 // Emit the array of instruction names. 793 Records.startTimer("Emit instruction names"); 794 InstrNames.layout(); 795 InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName + 796 "InstrNameData[]"); 797 798 OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 799 Num = 0; 800 for (const CodeGenInstruction *Inst : NumberedInstructions) { 801 // Newline every eight entries. 802 if (Num % 8 == 0) 803 OS << "\n "; 804 OS << InstrNames.get(std::string(Inst->TheDef->getName())) << "U, "; 805 ++Num; 806 } 807 OS << "\n};\n\n"; 808 809 bool HasDeprecationFeatures = 810 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) { 811 return !Inst->HasComplexDeprecationPredicate && 812 !Inst->DeprecatedReason.empty(); 813 }); 814 if (HasDeprecationFeatures) { 815 OS << "extern const uint8_t " << TargetName 816 << "InstrDeprecationFeatures[] = {"; 817 Num = 0; 818 for (const CodeGenInstruction *Inst : NumberedInstructions) { 819 if (Num % 8 == 0) 820 OS << "\n "; 821 if (!Inst->HasComplexDeprecationPredicate && 822 !Inst->DeprecatedReason.empty()) 823 OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason 824 << ", "; 825 else 826 OS << "uint8_t(-1), "; 827 ++Num; 828 } 829 OS << "\n};\n\n"; 830 } 831 832 bool HasComplexDeprecationInfos = 833 llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) { 834 return Inst->HasComplexDeprecationPredicate; 835 }); 836 if (HasComplexDeprecationInfos) { 837 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName 838 << "InstrComplexDeprecationInfos[] = {"; 839 Num = 0; 840 for (const CodeGenInstruction *Inst : NumberedInstructions) { 841 if (Num % 8 == 0) 842 OS << "\n "; 843 if (Inst->HasComplexDeprecationPredicate) 844 // Emit a function pointer to the complex predicate method. 845 OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, "; 846 else 847 OS << "nullptr, "; 848 ++Num; 849 } 850 OS << "\n};\n\n"; 851 } 852 853 // MCInstrInfo initialization routine. 854 Records.startTimer("Emit initialization routine"); 855 OS << "static inline void Init" << TargetName 856 << "MCInstrInfo(MCInstrInfo *II) {\n"; 857 OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName 858 << "InstrNameIndices, " << TargetName << "InstrNameData, "; 859 if (HasDeprecationFeatures) 860 OS << TargetName << "InstrDeprecationFeatures, "; 861 else 862 OS << "nullptr, "; 863 if (HasComplexDeprecationInfos) 864 OS << TargetName << "InstrComplexDeprecationInfos, "; 865 else 866 OS << "nullptr, "; 867 OS << NumberedInstructions.size() << ");\n}\n\n"; 868 869 OS << "} // end namespace llvm\n"; 870 871 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 872 873 // Create a TargetInstrInfo subclass to hide the MC layer initialization. 874 OS << "#ifdef GET_INSTRINFO_HEADER\n"; 875 OS << "#undef GET_INSTRINFO_HEADER\n"; 876 877 std::string ClassName = TargetName + "GenInstrInfo"; 878 OS << "namespace llvm {\n"; 879 OS << "struct " << ClassName << " : public TargetInstrInfo {\n" 880 << " explicit " << ClassName 881 << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n" 882 << " ~" << ClassName << "() override = default;\n"; 883 884 885 OS << "\n};\n} // end namespace llvm\n"; 886 887 OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 888 889 OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n"; 890 OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n"; 891 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false); 892 OS << "\n"; 893 OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n"; 894 895 OS << "#ifdef GET_INSTRINFO_HELPERS\n"; 896 OS << "#undef GET_INSTRINFO_HELPERS\n\n"; 897 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true); 898 OS << "#endif // GET_INSTRINFO_HELPERS\n\n"; 899 900 OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n"; 901 OS << "#undef GET_INSTRINFO_CTOR_DTOR\n"; 902 903 OS << "namespace llvm {\n"; 904 OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 905 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 906 OS << "extern const char " << TargetName << "InstrNameData[];\n"; 907 if (HasDeprecationFeatures) 908 OS << "extern const uint8_t " << TargetName 909 << "InstrDeprecationFeatures[];\n"; 910 if (HasComplexDeprecationInfos) 911 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName 912 << "InstrComplexDeprecationInfos[];\n"; 913 OS << ClassName << "::" << ClassName 914 << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int " 915 "ReturnOpcode)\n" 916 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, " 917 "ReturnOpcode) {\n" 918 << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName 919 << "InstrNameIndices, " << TargetName << "InstrNameData, "; 920 if (HasDeprecationFeatures) 921 OS << TargetName << "InstrDeprecationFeatures, "; 922 else 923 OS << "nullptr, "; 924 if (HasComplexDeprecationInfos) 925 OS << TargetName << "InstrComplexDeprecationInfos, "; 926 else 927 OS << "nullptr, "; 928 OS << NumberedInstructions.size() << ");\n}\n"; 929 OS << "} // end namespace llvm\n"; 930 931 OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; 932 933 Records.startTimer("Emit operand name mappings"); 934 emitOperandNameMappings(OS, Target, NumberedInstructions); 935 936 Records.startTimer("Emit operand type mappings"); 937 emitOperandTypeMappings(OS, Target, NumberedInstructions); 938 939 Records.startTimer("Emit logical operand size mappings"); 940 emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions); 941 942 Records.startTimer("Emit logical operand type mappings"); 943 emitLogicalOperandTypeMappings(OS, TargetName, NumberedInstructions); 944 945 Records.startTimer("Emit helper methods"); 946 emitMCIIHelperMethods(OS, TargetName); 947 } 948 949 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 950 Record *InstrInfo, 951 std::map<std::vector<Record*>, unsigned> &EmittedLists, 952 const OperandInfoMapTy &OpInfo, 953 raw_ostream &OS) { 954 int MinOperands = 0; 955 if (!Inst.Operands.empty()) 956 // Each logical operand can be multiple MI operands. 957 MinOperands = Inst.Operands.back().MIOperandNo + 958 Inst.Operands.back().MINumOperands; 959 960 OS << " { "; 961 OS << Num << ",\t" << MinOperands << ",\t" 962 << Inst.Operands.NumDefs << ",\t" 963 << Inst.TheDef->getValueAsInt("Size") << ",\t" 964 << SchedModels.getSchedClassIdx(Inst) << ",\t0"; 965 966 CodeGenTarget &Target = CDP.getTargetInfo(); 967 968 // Emit all of the target independent flags... 969 if (Inst.isPreISelOpcode) OS << "|(1ULL<<MCID::PreISelOpcode)"; 970 if (Inst.isPseudo) OS << "|(1ULL<<MCID::Pseudo)"; 971 if (Inst.isMeta) OS << "|(1ULL<<MCID::Meta)"; 972 if (Inst.isReturn) OS << "|(1ULL<<MCID::Return)"; 973 if (Inst.isEHScopeReturn) OS << "|(1ULL<<MCID::EHScopeReturn)"; 974 if (Inst.isBranch) OS << "|(1ULL<<MCID::Branch)"; 975 if (Inst.isIndirectBranch) OS << "|(1ULL<<MCID::IndirectBranch)"; 976 if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)"; 977 if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)"; 978 if (Inst.isMoveReg) OS << "|(1ULL<<MCID::MoveReg)"; 979 if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)"; 980 if (Inst.isAdd) OS << "|(1ULL<<MCID::Add)"; 981 if (Inst.isTrap) OS << "|(1ULL<<MCID::Trap)"; 982 if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)"; 983 if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)"; 984 if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)"; 985 if (Inst.isCall) OS << "|(1ULL<<MCID::Call)"; 986 if (Inst.canFoldAsLoad) OS << "|(1ULL<<MCID::FoldableAsLoad)"; 987 if (Inst.mayLoad) OS << "|(1ULL<<MCID::MayLoad)"; 988 if (Inst.mayStore) OS << "|(1ULL<<MCID::MayStore)"; 989 if (Inst.mayRaiseFPException) OS << "|(1ULL<<MCID::MayRaiseFPException)"; 990 if (Inst.isPredicable) OS << "|(1ULL<<MCID::Predicable)"; 991 if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)"; 992 if (Inst.isCommutable) OS << "|(1ULL<<MCID::Commutable)"; 993 if (Inst.isTerminator) OS << "|(1ULL<<MCID::Terminator)"; 994 if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)"; 995 if (Inst.isNotDuplicable) OS << "|(1ULL<<MCID::NotDuplicable)"; 996 if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)"; 997 if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)"; 998 if (Inst.hasPostISelHook) OS << "|(1ULL<<MCID::HasPostISelHook)"; 999 if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)"; 1000 if (Inst.hasSideEffects) OS << "|(1ULL<<MCID::UnmodeledSideEffects)"; 1001 if (Inst.isAsCheapAsAMove) OS << "|(1ULL<<MCID::CheapAsAMove)"; 1002 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq) 1003 OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)"; 1004 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq) 1005 OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)"; 1006 if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)"; 1007 if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; 1008 if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; 1009 if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; 1010 if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)"; 1011 if (Inst.isAuthenticated) OS << "|(1ULL<<MCID::Authenticated)"; 1012 1013 // Emit all of the target-specific flags... 1014 BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 1015 if (!TSF) 1016 PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?"); 1017 uint64_t Value = 0; 1018 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 1019 if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i))) 1020 Value |= uint64_t(Bit->getValue()) << i; 1021 else 1022 PrintFatalError(Inst.TheDef->getLoc(), 1023 "Invalid TSFlags bit in " + Inst.TheDef->getName()); 1024 } 1025 OS << ", 0x"; 1026 OS.write_hex(Value); 1027 OS << "ULL, "; 1028 1029 // Emit the implicit uses and defs lists... 1030 std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 1031 if (UseList.empty()) 1032 OS << "nullptr, "; 1033 else 1034 OS << "ImplicitList" << EmittedLists[UseList] << ", "; 1035 1036 std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 1037 if (DefList.empty()) 1038 OS << "nullptr, "; 1039 else 1040 OS << "ImplicitList" << EmittedLists[DefList] << ", "; 1041 1042 // Emit the operand info. 1043 std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 1044 if (OperandInfo.empty()) 1045 OS << "nullptr"; 1046 else 1047 OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 1048 1049 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 1050 } 1051 1052 // emitEnums - Print out enum values for all of the instructions. 1053 void InstrInfoEmitter::emitEnums(raw_ostream &OS) { 1054 OS << "#ifdef GET_INSTRINFO_ENUM\n"; 1055 OS << "#undef GET_INSTRINFO_ENUM\n"; 1056 1057 OS << "namespace llvm {\n\n"; 1058 1059 const CodeGenTarget &Target = CDP.getTargetInfo(); 1060 1061 // We must emit the PHI opcode first... 1062 StringRef Namespace = Target.getInstNamespace(); 1063 1064 if (Namespace.empty()) 1065 PrintFatalError("No instructions defined!"); 1066 1067 OS << "namespace " << Namespace << " {\n"; 1068 OS << " enum {\n"; 1069 unsigned Num = 0; 1070 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) 1071 OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; 1072 OS << " INSTRUCTION_LIST_END = " << Num << "\n"; 1073 OS << " };\n\n"; 1074 OS << "} // end namespace " << Namespace << "\n"; 1075 OS << "} // end namespace llvm\n"; 1076 OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 1077 1078 OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n"; 1079 OS << "#undef GET_INSTRINFO_SCHED_ENUM\n"; 1080 OS << "namespace llvm {\n\n"; 1081 OS << "namespace " << Namespace << " {\n"; 1082 OS << "namespace Sched {\n"; 1083 OS << " enum {\n"; 1084 Num = 0; 1085 for (const auto &Class : SchedModels.explicit_classes()) 1086 OS << " " << Class.Name << "\t= " << Num++ << ",\n"; 1087 OS << " SCHED_LIST_END = " << Num << "\n"; 1088 OS << " };\n"; 1089 OS << "} // end namespace Sched\n"; 1090 OS << "} // end namespace " << Namespace << "\n"; 1091 OS << "} // end namespace llvm\n"; 1092 1093 OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n"; 1094 } 1095 1096 namespace llvm { 1097 1098 void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 1099 RK.startTimer("Analyze DAG patterns"); 1100 InstrInfoEmitter(RK).run(OS); 1101 RK.startTimer("Emit map table"); 1102 EmitMapTable(RK, OS); 1103 } 1104 1105 } // end namespace llvm 1106