| //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This tablegen backend is responsible for emitting a description of the target | 
 | // instruction set for the code generator. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "CodeGenDAGPatterns.h" | 
 | #include "CodeGenInstruction.h" | 
 | #include "CodeGenSchedule.h" | 
 | #include "CodeGenTarget.h" | 
 | #include "PredicateExpander.h" | 
 | #include "SequenceToOffsetTable.h" | 
 | #include "TableGenBackends.h" | 
 | #include "llvm/ADT/ArrayRef.h" | 
 | #include "llvm/ADT/StringExtras.h" | 
 | #include "llvm/Support/Casting.h" | 
 | #include "llvm/Support/raw_ostream.h" | 
 | #include "llvm/TableGen/Error.h" | 
 | #include "llvm/TableGen/Record.h" | 
 | #include "llvm/TableGen/TableGenBackend.h" | 
 | #include <cassert> | 
 | #include <cstdint> | 
 | #include <map> | 
 | #include <string> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | using namespace llvm; | 
 |  | 
 | namespace { | 
 |  | 
 | class InstrInfoEmitter { | 
 |   RecordKeeper &Records; | 
 |   CodeGenDAGPatterns CDP; | 
 |   const CodeGenSchedModels &SchedModels; | 
 |  | 
 | public: | 
 |   InstrInfoEmitter(RecordKeeper &R): | 
 |     Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {} | 
 |  | 
 |   // run - Output the instruction set description. | 
 |   void run(raw_ostream &OS); | 
 |  | 
 | private: | 
 |   void emitEnums(raw_ostream &OS); | 
 |  | 
 |   typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; | 
 |  | 
 |   /// The keys of this map are maps which have OpName enum values as their keys | 
 |   /// and instruction operand indices as their values.  The values of this map | 
 |   /// are lists of instruction names. | 
 |   typedef std::map<std::map<unsigned, unsigned>, | 
 |                    std::vector<std::string>> OpNameMapTy; | 
 |   typedef std::map<std::string, unsigned>::iterator StrUintMapIter; | 
 |  | 
 |   /// Generate member functions in the target-specific GenInstrInfo class. | 
 |   /// | 
 |   /// This method is used to custom expand TIIPredicate definitions. | 
 |   /// See file llvm/Target/TargetInstPredicates.td for a description of what is | 
 |   /// a TIIPredicate and how to use it. | 
 |   void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName, | 
 |                             bool ExpandDefinition = true); | 
 |  | 
 |   /// Expand TIIPredicate definitions to functions that accept a const MCInst | 
 |   /// reference. | 
 |   void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName); | 
 |   void emitRecord(const CodeGenInstruction &Inst, unsigned Num, | 
 |                   Record *InstrInfo, | 
 |                   std::map<std::vector<Record*>, unsigned> &EL, | 
 |                   const OperandInfoMapTy &OpInfo, | 
 |                   raw_ostream &OS); | 
 |   void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target); | 
 |   void initOperandMapData( | 
 |             ArrayRef<const CodeGenInstruction *> NumberedInstructions, | 
 |             StringRef Namespace, | 
 |             std::map<std::string, unsigned> &Operands, | 
 |             OpNameMapTy &OperandMap); | 
 |   void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, | 
 |             ArrayRef<const CodeGenInstruction*> NumberedInstructions); | 
 |  | 
 |   // Operand information. | 
 |   void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); | 
 |   std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); | 
 | }; | 
 |  | 
 | } // end anonymous namespace | 
 |  | 
 | static void PrintDefList(const std::vector<Record*> &Uses, | 
 |                          unsigned Num, raw_ostream &OS) { | 
 |   OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; | 
 |   for (Record *U : Uses) | 
 |     OS << getQualifiedName(U) << ", "; | 
 |   OS << "0 };\n"; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Operand Info Emission. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | std::vector<std::string> | 
 | InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { | 
 |   std::vector<std::string> Result; | 
 |  | 
 |   for (auto &Op : Inst.Operands) { | 
 |     // Handle aggregate operands and normal operands the same way by expanding | 
 |     // either case into a list of operands for this op. | 
 |     std::vector<CGIOperandList::OperandInfo> OperandList; | 
 |  | 
 |     // This might be a multiple operand thing.  Targets like X86 have | 
 |     // registers in their multi-operand operands.  It may also be an anonymous | 
 |     // operand, which has a single operand, but no declared class for the | 
 |     // operand. | 
 |     DagInit *MIOI = Op.MIOperandInfo; | 
 |  | 
 |     if (!MIOI || MIOI->getNumArgs() == 0) { | 
 |       // Single, anonymous, operand. | 
 |       OperandList.push_back(Op); | 
 |     } else { | 
 |       for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) { | 
 |         OperandList.push_back(Op); | 
 |  | 
 |         auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef(); | 
 |         OperandList.back().Rec = OpR; | 
 |       } | 
 |     } | 
 |  | 
 |     for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { | 
 |       Record *OpR = OperandList[j].Rec; | 
 |       std::string Res; | 
 |  | 
 |       if (OpR->isSubClassOf("RegisterOperand")) | 
 |         OpR = OpR->getValueAsDef("RegClass"); | 
 |       if (OpR->isSubClassOf("RegisterClass")) | 
 |         Res += getQualifiedName(OpR) + "RegClassID, "; | 
 |       else if (OpR->isSubClassOf("PointerLikeRegClass")) | 
 |         Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; | 
 |       else | 
 |         // -1 means the operand does not have a fixed register class. | 
 |         Res += "-1, "; | 
 |  | 
 |       // Fill in applicable flags. | 
 |       Res += "0"; | 
 |  | 
 |       // Ptr value whose register class is resolved via callback. | 
 |       if (OpR->isSubClassOf("PointerLikeRegClass")) | 
 |         Res += "|(1<<MCOI::LookupPtrRegClass)"; | 
 |  | 
 |       // Predicate operands.  Check to see if the original unexpanded operand | 
 |       // was of type PredicateOp. | 
 |       if (Op.Rec->isSubClassOf("PredicateOp")) | 
 |         Res += "|(1<<MCOI::Predicate)"; | 
 |  | 
 |       // Optional def operands.  Check to see if the original unexpanded operand | 
 |       // was of type OptionalDefOperand. | 
 |       if (Op.Rec->isSubClassOf("OptionalDefOperand")) | 
 |         Res += "|(1<<MCOI::OptionalDef)"; | 
 |  | 
 |       // Fill in operand type. | 
 |       Res += ", "; | 
 |       assert(!Op.OperandType.empty() && "Invalid operand type."); | 
 |       Res += Op.OperandType; | 
 |  | 
 |       // Fill in constraint info. | 
 |       Res += ", "; | 
 |  | 
 |       const CGIOperandList::ConstraintInfo &Constraint = | 
 |         Op.Constraints[j]; | 
 |       if (Constraint.isNone()) | 
 |         Res += "0"; | 
 |       else if (Constraint.isEarlyClobber()) | 
 |         Res += "(1 << MCOI::EARLY_CLOBBER)"; | 
 |       else { | 
 |         assert(Constraint.isTied()); | 
 |         Res += "((" + utostr(Constraint.getTiedOperand()) + | 
 |                     " << 16) | (1 << MCOI::TIED_TO))"; | 
 |       } | 
 |  | 
 |       Result.push_back(Res); | 
 |     } | 
 |   } | 
 |  | 
 |   return Result; | 
 | } | 
 |  | 
 | void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, | 
 |                                        OperandInfoMapTy &OperandInfoIDs) { | 
 |   // ID #0 is for no operand info. | 
 |   unsigned OperandListNum = 0; | 
 |   OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; | 
 |  | 
 |   OS << "\n"; | 
 |   const CodeGenTarget &Target = CDP.getTargetInfo(); | 
 |   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { | 
 |     std::vector<std::string> OperandInfo = GetOperandInfo(*Inst); | 
 |     unsigned &N = OperandInfoIDs[OperandInfo]; | 
 |     if (N != 0) continue; | 
 |  | 
 |     N = ++OperandListNum; | 
 |     OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; | 
 |     for (const std::string &Info : OperandInfo) | 
 |       OS << "{ " << Info << " }, "; | 
 |     OS << "};\n"; | 
 |   } | 
 | } | 
 |  | 
 | /// Initialize data structures for generating operand name mappings. | 
 | ///  | 
 | /// \param Operands [out] A map used to generate the OpName enum with operand | 
 | ///        names as its keys and operand enum values as its values. | 
 | /// \param OperandMap [out] A map for representing the operand name mappings for | 
 | ///        each instructions.  This is used to generate the OperandMap table as | 
 | ///        well as the getNamedOperandIdx() function. | 
 | void InstrInfoEmitter::initOperandMapData( | 
 |         ArrayRef<const CodeGenInstruction *> NumberedInstructions, | 
 |         StringRef Namespace, | 
 |         std::map<std::string, unsigned> &Operands, | 
 |         OpNameMapTy &OperandMap) { | 
 |   unsigned NumOperands = 0; | 
 |   for (const CodeGenInstruction *Inst : NumberedInstructions) { | 
 |     if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) | 
 |       continue; | 
 |     std::map<unsigned, unsigned> OpList; | 
 |     for (const auto &Info : Inst->Operands) { | 
 |       StrUintMapIter I = Operands.find(Info.Name); | 
 |  | 
 |       if (I == Operands.end()) { | 
 |         I = Operands.insert(Operands.begin(), | 
 |                     std::pair<std::string, unsigned>(Info.Name, NumOperands++)); | 
 |       } | 
 |       OpList[I->second] = Info.MIOperandNo; | 
 |     } | 
 |     OperandMap[OpList].push_back(Namespace.str() + "::" + | 
 |                                  Inst->TheDef->getName().str()); | 
 |   } | 
 | } | 
 |  | 
 | /// Generate a table and function for looking up the indices of operands by | 
 | /// name. | 
 | /// | 
 | /// This code generates: | 
 | /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry | 
 | ///   for each operand name. | 
 | /// - A 2-dimensional table called OperandMap for mapping OpName enum values to | 
 | ///   operand indices. | 
 | /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) | 
 | ///   for looking up the operand index for an instruction, given a value from | 
 | ///   OpName enum | 
 | void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, | 
 |            const CodeGenTarget &Target, | 
 |            ArrayRef<const CodeGenInstruction*> NumberedInstructions) { | 
 |   StringRef Namespace = Target.getInstNamespace(); | 
 |   std::string OpNameNS = "OpName"; | 
 |   // Map of operand names to their enumeration value.  This will be used to | 
 |   // generate the OpName enum. | 
 |   std::map<std::string, unsigned> Operands; | 
 |   OpNameMapTy OperandMap; | 
 |  | 
 |   initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; | 
 |   OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "namespace " << Namespace << " {\n"; | 
 |   OS << "namespace " << OpNameNS << " {\n"; | 
 |   OS << "enum {\n"; | 
 |   for (const auto &Op : Operands) | 
 |     OS << "  " << Op.first << " = " << Op.second << ",\n"; | 
 |  | 
 |   OS << "OPERAND_LAST"; | 
 |   OS << "\n};\n"; | 
 |   OS << "} // end namespace OpName\n"; | 
 |   OS << "} // end namespace " << Namespace << "\n"; | 
 |   OS << "} // end namespace llvm\n"; | 
 |   OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n"; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; | 
 |   OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "namespace " << Namespace << " {\n"; | 
 |   OS << "LLVM_READONLY\n"; | 
 |   OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; | 
 |   if (!Operands.empty()) { | 
 |     OS << "  static const int16_t OperandMap [][" << Operands.size() | 
 |        << "] = {\n"; | 
 |     for (const auto &Entry : OperandMap) { | 
 |       const std::map<unsigned, unsigned> &OpList = Entry.first; | 
 |       OS << "{"; | 
 |  | 
 |       // Emit a row of the OperandMap table | 
 |       for (unsigned i = 0, e = Operands.size(); i != e; ++i) | 
 |         OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", "; | 
 |  | 
 |       OS << "},\n"; | 
 |     } | 
 |     OS << "};\n"; | 
 |  | 
 |     OS << "  switch(Opcode) {\n"; | 
 |     unsigned TableIndex = 0; | 
 |     for (const auto &Entry : OperandMap) { | 
 |       for (const std::string &Name : Entry.second) | 
 |         OS << "  case " << Name << ":\n"; | 
 |  | 
 |       OS << "    return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; | 
 |     } | 
 |     OS << "    default: return -1;\n"; | 
 |     OS << "  }\n"; | 
 |   } else { | 
 |     // There are no operands, so no need to emit anything | 
 |     OS << "  return -1;\n"; | 
 |   } | 
 |   OS << "}\n"; | 
 |   OS << "} // end namespace " << Namespace << "\n"; | 
 |   OS << "} // end namespace llvm\n"; | 
 |   OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n"; | 
 | } | 
 |  | 
 | /// Generate an enum for all the operand types for this target, under the | 
 | /// llvm::TargetNamespace::OpTypes namespace. | 
 | /// Operand types are all definitions derived of the Operand Target.td class. | 
 | void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS, | 
 |                                             const CodeGenTarget &Target) { | 
 |  | 
 |   StringRef Namespace = Target.getInstNamespace(); | 
 |   std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand"); | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; | 
 |   OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "namespace " << Namespace << " {\n"; | 
 |   OS << "namespace OpTypes {\n"; | 
 |   OS << "enum OperandType {\n"; | 
 |  | 
 |   unsigned EnumVal = 0; | 
 |   for (const Record *Op : Operands) { | 
 |     if (!Op->isAnonymous()) | 
 |       OS << "  " << Op->getName() << " = " << EnumVal << ",\n"; | 
 |     ++EnumVal; | 
 |   } | 
 |  | 
 |   OS << "  OPERAND_TYPE_LIST_END" << "\n};\n"; | 
 |   OS << "} // end namespace OpTypes\n"; | 
 |   OS << "} // end namespace " << Namespace << "\n"; | 
 |   OS << "} // end namespace llvm\n"; | 
 |   OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n"; | 
 | } | 
 |  | 
 | void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS, | 
 |                                              StringRef TargetName) { | 
 |   RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); | 
 |   if (TIIPredicates.empty()) | 
 |     return; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n"; | 
 |   OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n"; | 
 |  | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "class MCInst;\n\n"; | 
 |  | 
 |   OS << "namespace " << TargetName << "_MC {\n\n"; | 
 |  | 
 |   for (const Record *Rec : TIIPredicates) { | 
 |     OS << "bool " << Rec->getValueAsString("FunctionName") | 
 |         << "(const MCInst &MI);\n"; | 
 |   } | 
 |  | 
 |   OS << "\n} // end " << TargetName << "_MC namespace\n"; | 
 |   OS << "} // end llvm namespace\n\n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n"; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n"; | 
 |   OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n"; | 
 |  | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "namespace " << TargetName << "_MC {\n\n"; | 
 |  | 
 |   PredicateExpander PE(TargetName); | 
 |   PE.setExpandForMC(true); | 
 |  | 
 |   for (const Record *Rec : TIIPredicates) { | 
 |     OS << "bool " << Rec->getValueAsString("FunctionName"); | 
 |     OS << "(const MCInst &MI) {\n"; | 
 |  | 
 |     OS.indent(PE.getIndentLevel() * 2); | 
 |     PE.expandStatement(OS, Rec->getValueAsDef("Body")); | 
 |     OS << "\n}\n\n"; | 
 |   } | 
 |  | 
 |   OS << "} // end " << TargetName << "_MC namespace\n"; | 
 |   OS << "} // end llvm namespace\n\n"; | 
 |  | 
 |   OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n"; | 
 | } | 
 |  | 
 | void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, | 
 |                                             StringRef TargetName, | 
 |                                             bool ExpandDefinition) { | 
 |   RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); | 
 |   if (TIIPredicates.empty()) | 
 |     return; | 
 |  | 
 |   PredicateExpander PE(TargetName); | 
 |   PE.setExpandForMC(false); | 
 |  | 
 |   for (const Record *Rec : TIIPredicates) { | 
 |     OS << (ExpandDefinition ? "" : "static ") << "bool "; | 
 |     if (ExpandDefinition) | 
 |       OS << TargetName << "InstrInfo::"; | 
 |     OS << Rec->getValueAsString("FunctionName"); | 
 |     OS << "(const MachineInstr &MI)"; | 
 |     if (!ExpandDefinition) { | 
 |       OS << ";\n"; | 
 |       continue; | 
 |     } | 
 |  | 
 |     OS << " {\n"; | 
 |     OS.indent(PE.getIndentLevel() * 2); | 
 |     PE.expandStatement(OS, Rec->getValueAsDef("Body")); | 
 |     OS << "\n}\n\n"; | 
 |   } | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Main Output. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | // run - Emit the main instruction description records for the target... | 
 | void InstrInfoEmitter::run(raw_ostream &OS) { | 
 |   emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS); | 
 |   emitEnums(OS); | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; | 
 |   OS << "#undef GET_INSTRINFO_MC_DESC\n"; | 
 |  | 
 |   OS << "namespace llvm {\n\n"; | 
 |  | 
 |   CodeGenTarget &Target = CDP.getTargetInfo(); | 
 |   const std::string &TargetName = Target.getName(); | 
 |   Record *InstrInfo = Target.getInstructionSet(); | 
 |  | 
 |   // Keep track of all of the def lists we have emitted already. | 
 |   std::map<std::vector<Record*>, unsigned> EmittedLists; | 
 |   unsigned ListNumber = 0; | 
 |  | 
 |   // Emit all of the instruction's implicit uses and defs. | 
 |   for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { | 
 |     Record *Inst = II->TheDef; | 
 |     std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); | 
 |     if (!Uses.empty()) { | 
 |       unsigned &IL = EmittedLists[Uses]; | 
 |       if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); | 
 |     } | 
 |     std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); | 
 |     if (!Defs.empty()) { | 
 |       unsigned &IL = EmittedLists[Defs]; | 
 |       if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); | 
 |     } | 
 |   } | 
 |  | 
 |   OperandInfoMapTy OperandInfoIDs; | 
 |  | 
 |   // Emit all of the operand info records. | 
 |   EmitOperandInfo(OS, OperandInfoIDs); | 
 |  | 
 |   // Emit all of the MCInstrDesc records in their ENUM ordering. | 
 |   // | 
 |   OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; | 
 |   ArrayRef<const CodeGenInstruction*> NumberedInstructions = | 
 |     Target.getInstructionsByEnumValue(); | 
 |  | 
 |   SequenceToOffsetTable<std::string> InstrNames; | 
 |   unsigned Num = 0; | 
 |   for (const CodeGenInstruction *Inst : NumberedInstructions) { | 
 |     // Keep a list of the instruction names. | 
 |     InstrNames.add(Inst->TheDef->getName()); | 
 |     // Emit the record into the table. | 
 |     emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS); | 
 |   } | 
 |   OS << "};\n\n"; | 
 |  | 
 |   // Emit the array of instruction names. | 
 |   InstrNames.layout(); | 
 |   OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; | 
 |   InstrNames.emit(OS, printChar); | 
 |   OS << "};\n\n"; | 
 |  | 
 |   OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; | 
 |   Num = 0; | 
 |   for (const CodeGenInstruction *Inst : NumberedInstructions) { | 
 |     // Newline every eight entries. | 
 |     if (Num % 8 == 0) | 
 |       OS << "\n    "; | 
 |     OS << InstrNames.get(Inst->TheDef->getName()) << "U, "; | 
 |     ++Num; | 
 |   } | 
 |  | 
 |   OS << "\n};\n\n"; | 
 |  | 
 |   // MCInstrInfo initialization routine. | 
 |   OS << "static inline void Init" << TargetName | 
 |      << "MCInstrInfo(MCInstrInfo *II) {\n"; | 
 |   OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, " | 
 |      << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " | 
 |      << NumberedInstructions.size() << ");\n}\n\n"; | 
 |  | 
 |   OS << "} // end llvm namespace\n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; | 
 |  | 
 |   // Create a TargetInstrInfo subclass to hide the MC layer initialization. | 
 |   OS << "#ifdef GET_INSTRINFO_HEADER\n"; | 
 |   OS << "#undef GET_INSTRINFO_HEADER\n"; | 
 |  | 
 |   std::string ClassName = TargetName + "GenInstrInfo"; | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "struct " << ClassName << " : public TargetInstrInfo {\n" | 
 |      << "  explicit " << ClassName | 
 |      << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n" | 
 |      << "  ~" << ClassName << "() override = default;\n"; | 
 |  | 
 |  | 
 |   OS << "\n};\n} // end llvm namespace\n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_HEADER\n\n"; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n"; | 
 |   OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n"; | 
 |   emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */false); | 
 |   OS << "\n"; | 
 |   OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n"; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_HELPERS\n"; | 
 |   OS << "#undef GET_INSTRINFO_HELPERS\n\n"; | 
 |   emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */true); | 
 |   OS << "#endif // GET_INSTRINFO_HELPERS\n\n"; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n"; | 
 |   OS << "#undef GET_INSTRINFO_CTOR_DTOR\n"; | 
 |  | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; | 
 |   OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; | 
 |   OS << "extern const char " << TargetName << "InstrNameData[];\n"; | 
 |   OS << ClassName << "::" << ClassName | 
 |      << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int ReturnOpcode)\n" | 
 |      << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, ReturnOpcode) {\n" | 
 |      << "  InitMCInstrInfo(" << TargetName << "Insts, " << TargetName | 
 |      << "InstrNameIndices, " << TargetName << "InstrNameData, " | 
 |      << NumberedInstructions.size() << ");\n}\n"; | 
 |   OS << "} // end llvm namespace\n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; | 
 |  | 
 |   emitOperandNameMappings(OS, Target, NumberedInstructions); | 
 |  | 
 |   emitOperandTypesEnum(OS, Target); | 
 |  | 
 |   emitMCIIHelperMethods(OS, TargetName); | 
 | } | 
 |  | 
 | void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, | 
 |                                   Record *InstrInfo, | 
 |                          std::map<std::vector<Record*>, unsigned> &EmittedLists, | 
 |                                   const OperandInfoMapTy &OpInfo, | 
 |                                   raw_ostream &OS) { | 
 |   int MinOperands = 0; | 
 |   if (!Inst.Operands.empty()) | 
 |     // Each logical operand can be multiple MI operands. | 
 |     MinOperands = Inst.Operands.back().MIOperandNo + | 
 |                   Inst.Operands.back().MINumOperands; | 
 |  | 
 |   OS << "  { "; | 
 |   OS << Num << ",\t" << MinOperands << ",\t" | 
 |      << Inst.Operands.NumDefs << ",\t" | 
 |      << Inst.TheDef->getValueAsInt("Size") << ",\t" | 
 |      << SchedModels.getSchedClassIdx(Inst) << ",\t0"; | 
 |  | 
 |   CodeGenTarget &Target = CDP.getTargetInfo(); | 
 |  | 
 |   // Emit all of the target independent flags... | 
 |   if (Inst.isPseudo)           OS << "|(1ULL<<MCID::Pseudo)"; | 
 |   if (Inst.isReturn)           OS << "|(1ULL<<MCID::Return)"; | 
 |   if (Inst.isEHScopeReturn)    OS << "|(1ULL<<MCID::EHScopeReturn)"; | 
 |   if (Inst.isBranch)           OS << "|(1ULL<<MCID::Branch)"; | 
 |   if (Inst.isIndirectBranch)   OS << "|(1ULL<<MCID::IndirectBranch)"; | 
 |   if (Inst.isCompare)          OS << "|(1ULL<<MCID::Compare)"; | 
 |   if (Inst.isMoveImm)          OS << "|(1ULL<<MCID::MoveImm)"; | 
 |   if (Inst.isMoveReg)          OS << "|(1ULL<<MCID::MoveReg)"; | 
 |   if (Inst.isBitcast)          OS << "|(1ULL<<MCID::Bitcast)"; | 
 |   if (Inst.isAdd)              OS << "|(1ULL<<MCID::Add)"; | 
 |   if (Inst.isTrap)             OS << "|(1ULL<<MCID::Trap)"; | 
 |   if (Inst.isSelect)           OS << "|(1ULL<<MCID::Select)"; | 
 |   if (Inst.isBarrier)          OS << "|(1ULL<<MCID::Barrier)"; | 
 |   if (Inst.hasDelaySlot)       OS << "|(1ULL<<MCID::DelaySlot)"; | 
 |   if (Inst.isCall)             OS << "|(1ULL<<MCID::Call)"; | 
 |   if (Inst.canFoldAsLoad)      OS << "|(1ULL<<MCID::FoldableAsLoad)"; | 
 |   if (Inst.mayLoad)            OS << "|(1ULL<<MCID::MayLoad)"; | 
 |   if (Inst.mayStore)           OS << "|(1ULL<<MCID::MayStore)"; | 
 |   if (Inst.isPredicable)       OS << "|(1ULL<<MCID::Predicable)"; | 
 |   if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)"; | 
 |   if (Inst.isCommutable)       OS << "|(1ULL<<MCID::Commutable)"; | 
 |   if (Inst.isTerminator)       OS << "|(1ULL<<MCID::Terminator)"; | 
 |   if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)"; | 
 |   if (Inst.isNotDuplicable)    OS << "|(1ULL<<MCID::NotDuplicable)"; | 
 |   if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)"; | 
 |   if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)"; | 
 |   if (Inst.hasPostISelHook)    OS << "|(1ULL<<MCID::HasPostISelHook)"; | 
 |   if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)"; | 
 |   if (Inst.hasSideEffects)     OS << "|(1ULL<<MCID::UnmodeledSideEffects)"; | 
 |   if (Inst.isAsCheapAsAMove)   OS << "|(1ULL<<MCID::CheapAsAMove)"; | 
 |   if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq) | 
 |     OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)"; | 
 |   if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq) | 
 |     OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)"; | 
 |   if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)"; | 
 |   if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; | 
 |   if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; | 
 |   if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; | 
 |   if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)"; | 
 |  | 
 |   // Emit all of the target-specific flags... | 
 |   BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); | 
 |   if (!TSF) | 
 |     PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?"); | 
 |   uint64_t Value = 0; | 
 |   for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { | 
 |     if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i))) | 
 |       Value |= uint64_t(Bit->getValue()) << i; | 
 |     else | 
 |       PrintFatalError(Inst.TheDef->getLoc(), | 
 |                       "Invalid TSFlags bit in " + Inst.TheDef->getName()); | 
 |   } | 
 |   OS << ", 0x"; | 
 |   OS.write_hex(Value); | 
 |   OS << "ULL, "; | 
 |  | 
 |   // Emit the implicit uses and defs lists... | 
 |   std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); | 
 |   if (UseList.empty()) | 
 |     OS << "nullptr, "; | 
 |   else | 
 |     OS << "ImplicitList" << EmittedLists[UseList] << ", "; | 
 |  | 
 |   std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); | 
 |   if (DefList.empty()) | 
 |     OS << "nullptr, "; | 
 |   else | 
 |     OS << "ImplicitList" << EmittedLists[DefList] << ", "; | 
 |  | 
 |   // Emit the operand info. | 
 |   std::vector<std::string> OperandInfo = GetOperandInfo(Inst); | 
 |   if (OperandInfo.empty()) | 
 |     OS << "nullptr"; | 
 |   else | 
 |     OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; | 
 |  | 
 |   if (Inst.HasComplexDeprecationPredicate) | 
 |     // Emit a function pointer to the complex predicate method. | 
 |     OS << ", -1 " | 
 |        << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; | 
 |   else if (!Inst.DeprecatedReason.empty()) | 
 |     // Emit the Subtarget feature. | 
 |     OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason | 
 |        << " ,nullptr"; | 
 |   else | 
 |     // Instruction isn't deprecated. | 
 |     OS << ", -1 ,nullptr"; | 
 |  | 
 |   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; | 
 | } | 
 |  | 
 | // emitEnums - Print out enum values for all of the instructions. | 
 | void InstrInfoEmitter::emitEnums(raw_ostream &OS) { | 
 |   OS << "#ifdef GET_INSTRINFO_ENUM\n"; | 
 |   OS << "#undef GET_INSTRINFO_ENUM\n"; | 
 |  | 
 |   OS << "namespace llvm {\n\n"; | 
 |  | 
 |   CodeGenTarget Target(Records); | 
 |  | 
 |   // We must emit the PHI opcode first... | 
 |   StringRef Namespace = Target.getInstNamespace(); | 
 |  | 
 |   if (Namespace.empty()) | 
 |     PrintFatalError("No instructions defined!"); | 
 |  | 
 |   OS << "namespace " << Namespace << " {\n"; | 
 |   OS << "  enum {\n"; | 
 |   unsigned Num = 0; | 
 |   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) | 
 |     OS << "    " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; | 
 |   OS << "    INSTRUCTION_LIST_END = " << Num << "\n"; | 
 |   OS << "  };\n\n"; | 
 |   OS << "} // end " << Namespace << " namespace\n"; | 
 |   OS << "} // end llvm namespace\n"; | 
 |   OS << "#endif // GET_INSTRINFO_ENUM\n\n"; | 
 |  | 
 |   OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n"; | 
 |   OS << "#undef GET_INSTRINFO_SCHED_ENUM\n"; | 
 |   OS << "namespace llvm {\n\n"; | 
 |   OS << "namespace " << Namespace << " {\n"; | 
 |   OS << "namespace Sched {\n"; | 
 |   OS << "  enum {\n"; | 
 |   Num = 0; | 
 |   for (const auto &Class : SchedModels.explicit_classes()) | 
 |     OS << "    " << Class.Name << "\t= " << Num++ << ",\n"; | 
 |   OS << "    SCHED_LIST_END = " << Num << "\n"; | 
 |   OS << "  };\n"; | 
 |   OS << "} // end Sched namespace\n"; | 
 |   OS << "} // end " << Namespace << " namespace\n"; | 
 |   OS << "} // end llvm namespace\n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n"; | 
 | } | 
 |  | 
 | namespace llvm { | 
 |  | 
 | void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { | 
 |   InstrInfoEmitter(RK).run(OS); | 
 |   EmitMapTable(RK, OS); | 
 | } | 
 |  | 
 | } // end llvm namespace |