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