1 //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This tablegen backend is responsible for emitting a description of the target
11 // instruction set for the code generator.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "CodeGenDAGPatterns.h"
16 #include "CodeGenInstruction.h"
17 #include "CodeGenSchedule.h"
18 #include "CodeGenTarget.h"
19 #include "PredicateExpander.h"
20 #include "SequenceToOffsetTable.h"
21 #include "TableGenBackends.h"
22 #include "llvm/ADT/ArrayRef.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 <map>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 using namespace llvm;
37 
38 namespace {
39 
40 class InstrInfoEmitter {
41   RecordKeeper &Records;
42   CodeGenDAGPatterns CDP;
43   const CodeGenSchedModels &SchedModels;
44 
45 public:
InstrInfoEmitter(RecordKeeper & R)46   InstrInfoEmitter(RecordKeeper &R):
47     Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
48 
49   // run - Output the instruction set description.
50   void run(raw_ostream &OS);
51 
52 private:
53   void emitEnums(raw_ostream &OS);
54 
55   typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
56 
57   /// The keys of this map are maps which have OpName enum values as their keys
58   /// and instruction operand indices as their values.  The values of this map
59   /// are lists of instruction names.
60   typedef std::map<std::map<unsigned, unsigned>,
61                    std::vector<std::string>> OpNameMapTy;
62   typedef std::map<std::string, unsigned>::iterator StrUintMapIter;
63 
64   /// Generate member functions in the target-specific GenInstrInfo class.
65   ///
66   /// This method is used to custom expand TIIPredicate definitions.
67   /// See file llvm/Target/TargetInstPredicates.td for a description of what is
68   /// a TIIPredicate and how to use it.
69   void emitTIIHelperMethods(raw_ostream &OS);
70 
71   /// Expand TIIPredicate definitions to functions that accept a const MCInst
72   /// reference.
73   void emitMCIIHelperMethods(raw_ostream &OS);
74   void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
75                   Record *InstrInfo,
76                   std::map<std::vector<Record*>, unsigned> &EL,
77                   const OperandInfoMapTy &OpInfo,
78                   raw_ostream &OS);
79   void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target);
80   void initOperandMapData(
81             ArrayRef<const CodeGenInstruction *> NumberedInstructions,
82             StringRef Namespace,
83             std::map<std::string, unsigned> &Operands,
84             OpNameMapTy &OperandMap);
85   void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
86             ArrayRef<const CodeGenInstruction*> NumberedInstructions);
87 
88   // Operand information.
89   void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
90   std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
91 };
92 
93 } // end anonymous namespace
94 
PrintDefList(const std::vector<Record * > & Uses,unsigned Num,raw_ostream & OS)95 static void PrintDefList(const std::vector<Record*> &Uses,
96                          unsigned Num, raw_ostream &OS) {
97   OS << "static const MCPhysReg ImplicitList" << Num << "[] = { ";
98   for (Record *U : Uses)
99     OS << getQualifiedName(U) << ", ";
100   OS << "0 };\n";
101 }
102 
103 //===----------------------------------------------------------------------===//
104 // Operand Info Emission.
105 //===----------------------------------------------------------------------===//
106 
107 std::vector<std::string>
GetOperandInfo(const CodeGenInstruction & Inst)108 InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
109   std::vector<std::string> Result;
110 
111   for (auto &Op : Inst.Operands) {
112     // Handle aggregate operands and normal operands the same way by expanding
113     // either case into a list of operands for this op.
114     std::vector<CGIOperandList::OperandInfo> OperandList;
115 
116     // This might be a multiple operand thing.  Targets like X86 have
117     // registers in their multi-operand operands.  It may also be an anonymous
118     // operand, which has a single operand, but no declared class for the
119     // operand.
120     DagInit *MIOI = Op.MIOperandInfo;
121 
122     if (!MIOI || MIOI->getNumArgs() == 0) {
123       // Single, anonymous, operand.
124       OperandList.push_back(Op);
125     } else {
126       for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
127         OperandList.push_back(Op);
128 
129         auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
130         OperandList.back().Rec = OpR;
131       }
132     }
133 
134     for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
135       Record *OpR = OperandList[j].Rec;
136       std::string Res;
137 
138       if (OpR->isSubClassOf("RegisterOperand"))
139         OpR = OpR->getValueAsDef("RegClass");
140       if (OpR->isSubClassOf("RegisterClass"))
141         Res += getQualifiedName(OpR) + "RegClassID, ";
142       else if (OpR->isSubClassOf("PointerLikeRegClass"))
143         Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", ";
144       else
145         // -1 means the operand does not have a fixed register class.
146         Res += "-1, ";
147 
148       // Fill in applicable flags.
149       Res += "0";
150 
151       // Ptr value whose register class is resolved via callback.
152       if (OpR->isSubClassOf("PointerLikeRegClass"))
153         Res += "|(1<<MCOI::LookupPtrRegClass)";
154 
155       // Predicate operands.  Check to see if the original unexpanded operand
156       // was of type PredicateOp.
157       if (Op.Rec->isSubClassOf("PredicateOp"))
158         Res += "|(1<<MCOI::Predicate)";
159 
160       // Optional def operands.  Check to see if the original unexpanded operand
161       // was of type OptionalDefOperand.
162       if (Op.Rec->isSubClassOf("OptionalDefOperand"))
163         Res += "|(1<<MCOI::OptionalDef)";
164 
165       // Fill in operand type.
166       Res += ", ";
167       assert(!Op.OperandType.empty() && "Invalid operand type.");
168       Res += Op.OperandType;
169 
170       // Fill in constraint info.
171       Res += ", ";
172 
173       const CGIOperandList::ConstraintInfo &Constraint =
174         Op.Constraints[j];
175       if (Constraint.isNone())
176         Res += "0";
177       else if (Constraint.isEarlyClobber())
178         Res += "(1 << MCOI::EARLY_CLOBBER)";
179       else {
180         assert(Constraint.isTied());
181         Res += "((" + utostr(Constraint.getTiedOperand()) +
182                     " << 16) | (1 << MCOI::TIED_TO))";
183       }
184 
185       Result.push_back(Res);
186     }
187   }
188 
189   return Result;
190 }
191 
EmitOperandInfo(raw_ostream & OS,OperandInfoMapTy & OperandInfoIDs)192 void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
193                                        OperandInfoMapTy &OperandInfoIDs) {
194   // ID #0 is for no operand info.
195   unsigned OperandListNum = 0;
196   OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum;
197 
198   OS << "\n";
199   const CodeGenTarget &Target = CDP.getTargetInfo();
200   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
201     std::vector<std::string> OperandInfo = GetOperandInfo(*Inst);
202     unsigned &N = OperandInfoIDs[OperandInfo];
203     if (N != 0) continue;
204 
205     N = ++OperandListNum;
206     OS << "static const MCOperandInfo OperandInfo" << N << "[] = { ";
207     for (const std::string &Info : OperandInfo)
208       OS << "{ " << Info << " }, ";
209     OS << "};\n";
210   }
211 }
212 
213 /// Initialize data structures for generating operand name mappings.
214 ///
215 /// \param Operands [out] A map used to generate the OpName enum with operand
216 ///        names as its keys and operand enum values as its values.
217 /// \param OperandMap [out] A map for representing the operand name mappings for
218 ///        each instructions.  This is used to generate the OperandMap table as
219 ///        well as the getNamedOperandIdx() function.
initOperandMapData(ArrayRef<const CodeGenInstruction * > NumberedInstructions,StringRef Namespace,std::map<std::string,unsigned> & Operands,OpNameMapTy & OperandMap)220 void InstrInfoEmitter::initOperandMapData(
221         ArrayRef<const CodeGenInstruction *> NumberedInstructions,
222         StringRef Namespace,
223         std::map<std::string, unsigned> &Operands,
224         OpNameMapTy &OperandMap) {
225   unsigned NumOperands = 0;
226   for (const CodeGenInstruction *Inst : NumberedInstructions) {
227     if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable"))
228       continue;
229     std::map<unsigned, unsigned> OpList;
230     for (const auto &Info : Inst->Operands) {
231       StrUintMapIter I = Operands.find(Info.Name);
232 
233       if (I == Operands.end()) {
234         I = Operands.insert(Operands.begin(),
235                     std::pair<std::string, unsigned>(Info.Name, NumOperands++));
236       }
237       OpList[I->second] = Info.MIOperandNo;
238     }
239     OperandMap[OpList].push_back(Namespace.str() + "::" +
240                                  Inst->TheDef->getName().str());
241   }
242 }
243 
244 /// Generate a table and function for looking up the indices of operands by
245 /// name.
246 ///
247 /// This code generates:
248 /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
249 ///   for each operand name.
250 /// - A 2-dimensional table called OperandMap for mapping OpName enum values to
251 ///   operand indices.
252 /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
253 ///   for looking up the operand index for an instruction, given a value from
254 ///   OpName enum
emitOperandNameMappings(raw_ostream & OS,const CodeGenTarget & Target,ArrayRef<const CodeGenInstruction * > NumberedInstructions)255 void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
256            const CodeGenTarget &Target,
257            ArrayRef<const CodeGenInstruction*> NumberedInstructions) {
258   StringRef Namespace = Target.getInstNamespace();
259   std::string OpNameNS = "OpName";
260   // Map of operand names to their enumeration value.  This will be used to
261   // generate the OpName enum.
262   std::map<std::string, unsigned> Operands;
263   OpNameMapTy OperandMap;
264 
265   initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap);
266 
267   OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
268   OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
269   OS << "namespace llvm {\n";
270   OS << "namespace " << Namespace << " {\n";
271   OS << "namespace " << OpNameNS << " {\n";
272   OS << "enum {\n";
273   for (const auto &Op : Operands)
274     OS << "  " << Op.first << " = " << Op.second << ",\n";
275 
276   OS << "OPERAND_LAST";
277   OS << "\n};\n";
278   OS << "} // end namespace OpName\n";
279   OS << "} // end namespace " << Namespace << "\n";
280   OS << "} // end namespace llvm\n";
281   OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
282 
283   OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
284   OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
285   OS << "namespace llvm {\n";
286   OS << "namespace " << Namespace << " {\n";
287   OS << "LLVM_READONLY\n";
288   OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
289   if (!Operands.empty()) {
290     OS << "  static const int16_t OperandMap [][" << Operands.size()
291        << "] = {\n";
292     for (const auto &Entry : OperandMap) {
293       const std::map<unsigned, unsigned> &OpList = Entry.first;
294       OS << "{";
295 
296       // Emit a row of the OperandMap table
297       for (unsigned i = 0, e = Operands.size(); i != e; ++i)
298         OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", ";
299 
300       OS << "},\n";
301     }
302     OS << "};\n";
303 
304     OS << "  switch(Opcode) {\n";
305     unsigned TableIndex = 0;
306     for (const auto &Entry : OperandMap) {
307       for (const std::string &Name : Entry.second)
308         OS << "  case " << Name << ":\n";
309 
310       OS << "    return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
311     }
312     OS << "    default: return -1;\n";
313     OS << "  }\n";
314   } else {
315     // There are no operands, so no need to emit anything
316     OS << "  return -1;\n";
317   }
318   OS << "}\n";
319   OS << "} // end namespace " << Namespace << "\n";
320   OS << "} // end namespace llvm\n";
321   OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
322 }
323 
324 /// Generate an enum for all the operand types for this target, under the
325 /// llvm::TargetNamespace::OpTypes namespace.
326 /// Operand types are all definitions derived of the Operand Target.td class.
emitOperandTypesEnum(raw_ostream & OS,const CodeGenTarget & Target)327 void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS,
328                                             const CodeGenTarget &Target) {
329 
330   StringRef Namespace = Target.getInstNamespace();
331   std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand");
332 
333   OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
334   OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
335   OS << "namespace llvm {\n";
336   OS << "namespace " << Namespace << " {\n";
337   OS << "namespace OpTypes {\n";
338   OS << "enum OperandType {\n";
339 
340   unsigned EnumVal = 0;
341   for (const Record *Op : Operands) {
342     if (!Op->isAnonymous())
343       OS << "  " << Op->getName() << " = " << EnumVal << ",\n";
344     ++EnumVal;
345   }
346 
347   OS << "  OPERAND_TYPE_LIST_END" << "\n};\n";
348   OS << "} // end namespace OpTypes\n";
349   OS << "} // end namespace " << Namespace << "\n";
350   OS << "} // end namespace llvm\n";
351   OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
352 }
353 
emitMCIIHelperMethods(raw_ostream & OS)354 void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) {
355   RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
356   if (TIIPredicates.empty())
357     return;
358 
359   CodeGenTarget &Target = CDP.getTargetInfo();
360   const StringRef TargetName = Target.getName();
361   formatted_raw_ostream FOS(OS);
362 
363   FOS << "#ifdef GET_GENINSTRINFO_MC_DECL\n";
364   FOS << "#undef GET_GENINSTRINFO_MC_DECL\n\n";
365 
366   FOS << "namespace llvm {\n";
367   FOS << "class MCInst;\n\n";
368 
369   FOS << "namespace " << TargetName << "_MC {\n\n";
370 
371   for (const Record *Rec : TIIPredicates) {
372     FOS << "bool " << Rec->getValueAsString("FunctionName")
373         << "(const MCInst &MI);\n";
374   }
375 
376   FOS << "\n} // end " << TargetName << "_MC namespace\n";
377   FOS << "} // end llvm namespace\n\n";
378 
379   FOS << "#endif // GET_GENINSTRINFO_MC_DECL\n\n";
380 
381   FOS << "#ifdef GET_GENINSTRINFO_MC_HELPERS\n";
382   FOS << "#undef GET_GENINSTRINFO_MC_HELPERS\n\n";
383 
384   FOS << "namespace llvm {\n";
385   FOS << "namespace " << TargetName << "_MC {\n\n";
386 
387   PredicateExpander PE;
388   PE.setExpandForMC(true);
389   for (const Record *Rec : TIIPredicates) {
390     FOS << "bool " << Rec->getValueAsString("FunctionName");
391     FOS << "(const MCInst &MI) {\n";
392     FOS << "  return ";
393     PE.expandPredicate(FOS, Rec->getValueAsDef("Pred"));
394     FOS << ";\n}\n";
395   }
396 
397   FOS << "\n} // end " << TargetName << "_MC namespace\n";
398   FOS << "} // end llvm namespace\n\n";
399 
400   FOS << "#endif // GET_GENISTRINFO_MC_HELPERS\n";
401 }
402 
emitTIIHelperMethods(raw_ostream & OS)403 void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS) {
404   RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
405   if (TIIPredicates.empty())
406     return;
407 
408   formatted_raw_ostream FOS(OS);
409   PredicateExpander PE;
410   PE.setExpandForMC(false);
411   PE.setIndentLevel(2);
412 
413   for (const Record *Rec : TIIPredicates) {
414     FOS << "\n  static bool " << Rec->getValueAsString("FunctionName");
415     FOS << "(const MachineInstr &MI) {\n";
416     FOS << "    return ";
417     PE.expandPredicate(FOS, Rec->getValueAsDef("Pred"));
418     FOS << ";\n  }\n";
419   }
420 }
421 
422 //===----------------------------------------------------------------------===//
423 // Main Output.
424 //===----------------------------------------------------------------------===//
425 
426 // run - Emit the main instruction description records for the target...
run(raw_ostream & OS)427 void InstrInfoEmitter::run(raw_ostream &OS) {
428   emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS);
429   emitEnums(OS);
430 
431   OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
432   OS << "#undef GET_INSTRINFO_MC_DESC\n";
433 
434   OS << "namespace llvm {\n\n";
435 
436   CodeGenTarget &Target = CDP.getTargetInfo();
437   const std::string &TargetName = Target.getName();
438   Record *InstrInfo = Target.getInstructionSet();
439 
440   // Keep track of all of the def lists we have emitted already.
441   std::map<std::vector<Record*>, unsigned> EmittedLists;
442   unsigned ListNumber = 0;
443 
444   // Emit all of the instruction's implicit uses and defs.
445   for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
446     Record *Inst = II->TheDef;
447     std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
448     if (!Uses.empty()) {
449       unsigned &IL = EmittedLists[Uses];
450       if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS);
451     }
452     std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
453     if (!Defs.empty()) {
454       unsigned &IL = EmittedLists[Defs];
455       if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
456     }
457   }
458 
459   OperandInfoMapTy OperandInfoIDs;
460 
461   // Emit all of the operand info records.
462   EmitOperandInfo(OS, OperandInfoIDs);
463 
464   // Emit all of the MCInstrDesc records in their ENUM ordering.
465   //
466   OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
467   ArrayRef<const CodeGenInstruction*> NumberedInstructions =
468     Target.getInstructionsByEnumValue();
469 
470   SequenceToOffsetTable<std::string> InstrNames;
471   unsigned Num = 0;
472   for (const CodeGenInstruction *Inst : NumberedInstructions) {
473     // Keep a list of the instruction names.
474     InstrNames.add(Inst->TheDef->getName());
475     // Emit the record into the table.
476     emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS);
477   }
478   OS << "};\n\n";
479 
480   // Emit the array of instruction names.
481   InstrNames.layout();
482   OS << "extern const char " << TargetName << "InstrNameData[] = {\n";
483   InstrNames.emit(OS, printChar);
484   OS << "};\n\n";
485 
486   OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
487   Num = 0;
488   for (const CodeGenInstruction *Inst : NumberedInstructions) {
489     // Newline every eight entries.
490     if (Num % 8 == 0)
491       OS << "\n    ";
492     OS << InstrNames.get(Inst->TheDef->getName()) << "U, ";
493     ++Num;
494   }
495 
496   OS << "\n};\n\n";
497 
498   // MCInstrInfo initialization routine.
499   OS << "static inline void Init" << TargetName
500      << "MCInstrInfo(MCInstrInfo *II) {\n";
501   OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, "
502      << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
503      << NumberedInstructions.size() << ");\n}\n\n";
504 
505   OS << "} // end llvm namespace\n";
506 
507   OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
508 
509   // Create a TargetInstrInfo subclass to hide the MC layer initialization.
510   OS << "#ifdef GET_INSTRINFO_HEADER\n";
511   OS << "#undef GET_INSTRINFO_HEADER\n";
512 
513   std::string ClassName = TargetName + "GenInstrInfo";
514   OS << "namespace llvm {\n";
515   OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
516      << "  explicit " << ClassName
517      << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n"
518      << "  ~" << ClassName << "() override = default;\n";
519 
520   emitTIIHelperMethods(OS);
521 
522   OS << "\n};\n} // end llvm namespace\n";
523 
524   OS << "#endif // GET_INSTRINFO_HEADER\n\n";
525 
526   OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
527   OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
528 
529   OS << "namespace llvm {\n";
530   OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
531   OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
532   OS << "extern const char " << TargetName << "InstrNameData[];\n";
533   OS << ClassName << "::" << ClassName
534      << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int ReturnOpcode)\n"
535      << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, ReturnOpcode) {\n"
536      << "  InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
537      << "InstrNameIndices, " << TargetName << "InstrNameData, "
538      << NumberedInstructions.size() << ");\n}\n";
539   OS << "} // end llvm namespace\n";
540 
541   OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
542 
543   emitOperandNameMappings(OS, Target, NumberedInstructions);
544 
545   emitOperandTypesEnum(OS, Target);
546 
547   emitMCIIHelperMethods(OS);
548 }
549 
emitRecord(const CodeGenInstruction & Inst,unsigned Num,Record * InstrInfo,std::map<std::vector<Record * >,unsigned> & EmittedLists,const OperandInfoMapTy & OpInfo,raw_ostream & OS)550 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
551                                   Record *InstrInfo,
552                          std::map<std::vector<Record*>, unsigned> &EmittedLists,
553                                   const OperandInfoMapTy &OpInfo,
554                                   raw_ostream &OS) {
555   int MinOperands = 0;
556   if (!Inst.Operands.empty())
557     // Each logical operand can be multiple MI operands.
558     MinOperands = Inst.Operands.back().MIOperandNo +
559                   Inst.Operands.back().MINumOperands;
560 
561   OS << "  { ";
562   OS << Num << ",\t" << MinOperands << ",\t"
563      << Inst.Operands.NumDefs << ",\t"
564      << Inst.TheDef->getValueAsInt("Size") << ",\t"
565      << SchedModels.getSchedClassIdx(Inst) << ",\t0";
566 
567   CodeGenTarget &Target = CDP.getTargetInfo();
568 
569   // Emit all of the target independent flags...
570   if (Inst.isPseudo)           OS << "|(1ULL<<MCID::Pseudo)";
571   if (Inst.isReturn)           OS << "|(1ULL<<MCID::Return)";
572   if (Inst.isBranch)           OS << "|(1ULL<<MCID::Branch)";
573   if (Inst.isIndirectBranch)   OS << "|(1ULL<<MCID::IndirectBranch)";
574   if (Inst.isCompare)          OS << "|(1ULL<<MCID::Compare)";
575   if (Inst.isMoveImm)          OS << "|(1ULL<<MCID::MoveImm)";
576   if (Inst.isMoveReg)          OS << "|(1ULL<<MCID::MoveReg)";
577   if (Inst.isBitcast)          OS << "|(1ULL<<MCID::Bitcast)";
578   if (Inst.isAdd)              OS << "|(1ULL<<MCID::Add)";
579   if (Inst.isTrap)             OS << "|(1ULL<<MCID::Trap)";
580   if (Inst.isSelect)           OS << "|(1ULL<<MCID::Select)";
581   if (Inst.isBarrier)          OS << "|(1ULL<<MCID::Barrier)";
582   if (Inst.hasDelaySlot)       OS << "|(1ULL<<MCID::DelaySlot)";
583   if (Inst.isCall)             OS << "|(1ULL<<MCID::Call)";
584   if (Inst.canFoldAsLoad)      OS << "|(1ULL<<MCID::FoldableAsLoad)";
585   if (Inst.mayLoad)            OS << "|(1ULL<<MCID::MayLoad)";
586   if (Inst.mayStore)           OS << "|(1ULL<<MCID::MayStore)";
587   if (Inst.isPredicable)       OS << "|(1ULL<<MCID::Predicable)";
588   if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)";
589   if (Inst.isCommutable)       OS << "|(1ULL<<MCID::Commutable)";
590   if (Inst.isTerminator)       OS << "|(1ULL<<MCID::Terminator)";
591   if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)";
592   if (Inst.isNotDuplicable)    OS << "|(1ULL<<MCID::NotDuplicable)";
593   if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)";
594   if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)";
595   if (Inst.hasPostISelHook)    OS << "|(1ULL<<MCID::HasPostISelHook)";
596   if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)";
597   if (Inst.hasSideEffects)     OS << "|(1ULL<<MCID::UnmodeledSideEffects)";
598   if (Inst.isAsCheapAsAMove)   OS << "|(1ULL<<MCID::CheapAsAMove)";
599   if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq)
600     OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)";
601   if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq)
602     OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)";
603   if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)";
604   if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)";
605   if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)";
606   if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)";
607 
608   // Emit all of the target-specific flags...
609   BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
610   if (!TSF)
611     PrintFatalError("no TSFlags?");
612   uint64_t Value = 0;
613   for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
614     if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
615       Value |= uint64_t(Bit->getValue()) << i;
616     else
617       PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName());
618   }
619   OS << ", 0x";
620   OS.write_hex(Value);
621   OS << "ULL, ";
622 
623   // Emit the implicit uses and defs lists...
624   std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
625   if (UseList.empty())
626     OS << "nullptr, ";
627   else
628     OS << "ImplicitList" << EmittedLists[UseList] << ", ";
629 
630   std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
631   if (DefList.empty())
632     OS << "nullptr, ";
633   else
634     OS << "ImplicitList" << EmittedLists[DefList] << ", ";
635 
636   // Emit the operand info.
637   std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
638   if (OperandInfo.empty())
639     OS << "nullptr";
640   else
641     OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
642 
643   if (Inst.HasComplexDeprecationPredicate)
644     // Emit a function pointer to the complex predicate method.
645     OS << ", -1 "
646        << ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
647   else if (!Inst.DeprecatedReason.empty())
648     // Emit the Subtarget feature.
649     OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
650        << " ,nullptr";
651   else
652     // Instruction isn't deprecated.
653     OS << ", -1 ,nullptr";
654 
655   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
656 }
657 
658 // emitEnums - Print out enum values for all of the instructions.
emitEnums(raw_ostream & OS)659 void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
660   OS << "#ifdef GET_INSTRINFO_ENUM\n";
661   OS << "#undef GET_INSTRINFO_ENUM\n";
662 
663   OS << "namespace llvm {\n\n";
664 
665   CodeGenTarget Target(Records);
666 
667   // We must emit the PHI opcode first...
668   StringRef Namespace = Target.getInstNamespace();
669 
670   if (Namespace.empty())
671     PrintFatalError("No instructions defined!");
672 
673   OS << "namespace " << Namespace << " {\n";
674   OS << "  enum {\n";
675   unsigned Num = 0;
676   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue())
677     OS << "    " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n";
678   OS << "    INSTRUCTION_LIST_END = " << Num << "\n";
679   OS << "  };\n\n";
680   OS << "} // end " << Namespace << " namespace\n";
681   OS << "} // end llvm namespace\n";
682   OS << "#endif // GET_INSTRINFO_ENUM\n\n";
683 
684   OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
685   OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
686   OS << "namespace llvm {\n\n";
687   OS << "namespace " << Namespace << " {\n";
688   OS << "namespace Sched {\n";
689   OS << "  enum {\n";
690   Num = 0;
691   for (const auto &Class : SchedModels.explicit_classes())
692     OS << "    " << Class.Name << "\t= " << Num++ << ",\n";
693   OS << "    SCHED_LIST_END = " << Num << "\n";
694   OS << "  };\n";
695   OS << "} // end Sched namespace\n";
696   OS << "} // end " << Namespace << " namespace\n";
697   OS << "} // end llvm namespace\n";
698 
699   OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
700 }
701 
702 namespace llvm {
703 
EmitInstrInfo(RecordKeeper & RK,raw_ostream & OS)704 void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
705   InstrInfoEmitter(RK).run(OS);
706   EmitMapTable(RK, OS);
707 }
708 
709 } // end llvm namespace
710