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