Home | History | Annotate | Download | only in TableGen
      1 //===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
      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 emits subtarget enumerations.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "CodeGenTarget.h"
     15 #include "CodeGenSchedule.h"
     16 #include "llvm/ADT/STLExtras.h"
     17 #include "llvm/ADT/StringExtras.h"
     18 #include "llvm/MC/MCInstrItineraries.h"
     19 #include "llvm/MC/SubtargetFeature.h"
     20 #include "llvm/Support/Debug.h"
     21 #include "llvm/Support/Format.h"
     22 #include "llvm/TableGen/Error.h"
     23 #include "llvm/TableGen/Record.h"
     24 #include "llvm/TableGen/TableGenBackend.h"
     25 #include <algorithm>
     26 #include <map>
     27 #include <string>
     28 #include <vector>
     29 
     30 using namespace llvm;
     31 
     32 #define DEBUG_TYPE "subtarget-emitter"
     33 
     34 namespace {
     35 class SubtargetEmitter {
     36   // Each processor has a SchedClassDesc table with an entry for each SchedClass.
     37   // The SchedClassDesc table indexes into a global write resource table, write
     38   // latency table, and read advance table.
     39   struct SchedClassTables {
     40     std::vector<std::vector<MCSchedClassDesc> > ProcSchedClasses;
     41     std::vector<MCWriteProcResEntry> WriteProcResources;
     42     std::vector<MCWriteLatencyEntry> WriteLatencies;
     43     std::vector<std::string> WriterNames;
     44     std::vector<MCReadAdvanceEntry> ReadAdvanceEntries;
     45 
     46     // Reserve an invalid entry at index 0
     47     SchedClassTables() {
     48       ProcSchedClasses.resize(1);
     49       WriteProcResources.resize(1);
     50       WriteLatencies.resize(1);
     51       WriterNames.push_back("InvalidWrite");
     52       ReadAdvanceEntries.resize(1);
     53     }
     54   };
     55 
     56   struct LessWriteProcResources {
     57     bool operator()(const MCWriteProcResEntry &LHS,
     58                     const MCWriteProcResEntry &RHS) {
     59       return LHS.ProcResourceIdx < RHS.ProcResourceIdx;
     60     }
     61   };
     62 
     63   RecordKeeper &Records;
     64   CodeGenSchedModels &SchedModels;
     65   std::string Target;
     66 
     67   void Enumeration(raw_ostream &OS, const char *ClassName);
     68   unsigned FeatureKeyValues(raw_ostream &OS);
     69   unsigned CPUKeyValues(raw_ostream &OS);
     70   void FormItineraryStageString(const std::string &Names,
     71                                 Record *ItinData, std::string &ItinString,
     72                                 unsigned &NStages);
     73   void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
     74                                        unsigned &NOperandCycles);
     75   void FormItineraryBypassString(const std::string &Names,
     76                                  Record *ItinData,
     77                                  std::string &ItinString, unsigned NOperandCycles);
     78   void EmitStageAndOperandCycleData(raw_ostream &OS,
     79                                     std::vector<std::vector<InstrItinerary> >
     80                                       &ProcItinLists);
     81   void EmitItineraries(raw_ostream &OS,
     82                        std::vector<std::vector<InstrItinerary> >
     83                          &ProcItinLists);
     84   void EmitProcessorProp(raw_ostream &OS, const Record *R, const char *Name,
     85                          char Separator);
     86   void EmitProcessorResources(const CodeGenProcModel &ProcModel,
     87                               raw_ostream &OS);
     88   Record *FindWriteResources(const CodeGenSchedRW &SchedWrite,
     89                              const CodeGenProcModel &ProcModel);
     90   Record *FindReadAdvance(const CodeGenSchedRW &SchedRead,
     91                           const CodeGenProcModel &ProcModel);
     92   void ExpandProcResources(RecVec &PRVec, std::vector<int64_t> &Cycles,
     93                            const CodeGenProcModel &ProcModel);
     94   void GenSchedClassTables(const CodeGenProcModel &ProcModel,
     95                            SchedClassTables &SchedTables);
     96   void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS);
     97   void EmitProcessorModels(raw_ostream &OS);
     98   void EmitProcessorLookup(raw_ostream &OS);
     99   void EmitSchedModelHelpers(std::string ClassName, raw_ostream &OS);
    100   void EmitSchedModel(raw_ostream &OS);
    101   void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures,
    102                              unsigned NumProcs);
    103 
    104 public:
    105   SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT):
    106     Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {}
    107 
    108   void run(raw_ostream &o);
    109 };
    110 } // end anonymous namespace
    111 
    112 //
    113 // Enumeration - Emit the specified class as an enumeration.
    114 //
    115 void SubtargetEmitter::Enumeration(raw_ostream &OS,
    116                                    const char *ClassName) {
    117   // Get all records of class and sort
    118   std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
    119   std::sort(DefList.begin(), DefList.end(), LessRecord());
    120 
    121   unsigned N = DefList.size();
    122   if (N == 0)
    123     return;
    124   if (N > MAX_SUBTARGET_FEATURES)
    125     PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
    126 
    127   OS << "namespace " << Target << " {\n";
    128 
    129   // Open enumeration. Use a 64-bit underlying type.
    130   OS << "enum : uint64_t {\n";
    131 
    132   // For each record
    133   for (unsigned i = 0; i < N;) {
    134     // Next record
    135     Record *Def = DefList[i];
    136 
    137     // Get and emit name
    138     OS << "  " << Def->getName() << " = " << i;
    139     if (++i < N) OS << ",";
    140 
    141     OS << "\n";
    142   }
    143 
    144   // Close enumeration and namespace
    145   OS << "};\n}\n";
    146 }
    147 
    148 //
    149 // FeatureKeyValues - Emit data of all the subtarget features.  Used by the
    150 // command line.
    151 //
    152 unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
    153   // Gather and sort all the features
    154   std::vector<Record*> FeatureList =
    155                            Records.getAllDerivedDefinitions("SubtargetFeature");
    156 
    157   if (FeatureList.empty())
    158     return 0;
    159 
    160   std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
    161 
    162   // Begin feature table
    163   OS << "// Sorted (by key) array of values for CPU features.\n"
    164      << "extern const llvm::SubtargetFeatureKV " << Target
    165      << "FeatureKV[] = {\n";
    166 
    167   // For each feature
    168   unsigned NumFeatures = 0;
    169   for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
    170     // Next feature
    171     Record *Feature = FeatureList[i];
    172 
    173     const std::string &Name = Feature->getName();
    174     const std::string &CommandLineName = Feature->getValueAsString("Name");
    175     const std::string &Desc = Feature->getValueAsString("Desc");
    176 
    177     if (CommandLineName.empty()) continue;
    178 
    179     // Emit as { "feature", "description", { featureEnum }, { i1 , i2 , ... , in } }
    180     OS << "  { "
    181        << "\"" << CommandLineName << "\", "
    182        << "\"" << Desc << "\", "
    183        << "{ " << Target << "::" << Name << " }, ";
    184 
    185     const std::vector<Record*> &ImpliesList =
    186       Feature->getValueAsListOfDefs("Implies");
    187 
    188     if (ImpliesList.empty()) {
    189       OS << "{ }";
    190     } else {
    191       OS << "{ ";
    192       for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
    193         OS << Target << "::" << ImpliesList[j]->getName();
    194         if (++j < M) OS << ", ";
    195       }
    196       OS << " }";
    197     }
    198 
    199     OS << " }";
    200     ++NumFeatures;
    201 
    202     // Depending on 'if more in the list' emit comma
    203     if ((i + 1) < N) OS << ",";
    204 
    205     OS << "\n";
    206   }
    207 
    208   // End feature table
    209   OS << "};\n";
    210 
    211   return NumFeatures;
    212 }
    213 
    214 //
    215 // CPUKeyValues - Emit data of all the subtarget processors.  Used by command
    216 // line.
    217 //
    218 unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
    219   // Gather and sort processor information
    220   std::vector<Record*> ProcessorList =
    221                           Records.getAllDerivedDefinitions("Processor");
    222   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
    223 
    224   // Begin processor table
    225   OS << "// Sorted (by key) array of values for CPU subtype.\n"
    226      << "extern const llvm::SubtargetFeatureKV " << Target
    227      << "SubTypeKV[] = {\n";
    228 
    229   // For each processor
    230   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
    231     // Next processor
    232     Record *Processor = ProcessorList[i];
    233 
    234     const std::string &Name = Processor->getValueAsString("Name");
    235     const std::vector<Record*> &FeatureList =
    236       Processor->getValueAsListOfDefs("Features");
    237 
    238     // Emit as { "cpu", "description", { f1 , f2 , ... fn } },
    239     OS << "  { "
    240        << "\"" << Name << "\", "
    241        << "\"Select the " << Name << " processor\", ";
    242 
    243     if (FeatureList.empty()) {
    244       OS << "{ }";
    245     } else {
    246       OS << "{ ";
    247       for (unsigned j = 0, M = FeatureList.size(); j < M;) {
    248         OS << Target << "::" << FeatureList[j]->getName();
    249         if (++j < M) OS << ", ";
    250       }
    251       OS << " }";
    252     }
    253 
    254     // The { } is for the "implies" section of this data structure.
    255     OS << ", { } }";
    256 
    257     // Depending on 'if more in the list' emit comma
    258     if (++i < N) OS << ",";
    259 
    260     OS << "\n";
    261   }
    262 
    263   // End processor table
    264   OS << "};\n";
    265 
    266   return ProcessorList.size();
    267 }
    268 
    269 //
    270 // FormItineraryStageString - Compose a string containing the stage
    271 // data initialization for the specified itinerary.  N is the number
    272 // of stages.
    273 //
    274 void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
    275                                                 Record *ItinData,
    276                                                 std::string &ItinString,
    277                                                 unsigned &NStages) {
    278   // Get states list
    279   const std::vector<Record*> &StageList =
    280     ItinData->getValueAsListOfDefs("Stages");
    281 
    282   // For each stage
    283   unsigned N = NStages = StageList.size();
    284   for (unsigned i = 0; i < N;) {
    285     // Next stage
    286     const Record *Stage = StageList[i];
    287 
    288     // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
    289     int Cycles = Stage->getValueAsInt("Cycles");
    290     ItinString += "  { " + itostr(Cycles) + ", ";
    291 
    292     // Get unit list
    293     const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
    294 
    295     // For each unit
    296     for (unsigned j = 0, M = UnitList.size(); j < M;) {
    297       // Add name and bitwise or
    298       ItinString += Name + "FU::" + UnitList[j]->getName();
    299       if (++j < M) ItinString += " | ";
    300     }
    301 
    302     int TimeInc = Stage->getValueAsInt("TimeInc");
    303     ItinString += ", " + itostr(TimeInc);
    304 
    305     int Kind = Stage->getValueAsInt("Kind");
    306     ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
    307 
    308     // Close off stage
    309     ItinString += " }";
    310     if (++i < N) ItinString += ", ";
    311   }
    312 }
    313 
    314 //
    315 // FormItineraryOperandCycleString - Compose a string containing the
    316 // operand cycle initialization for the specified itinerary.  N is the
    317 // number of operands that has cycles specified.
    318 //
    319 void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
    320                          std::string &ItinString, unsigned &NOperandCycles) {
    321   // Get operand cycle list
    322   const std::vector<int64_t> &OperandCycleList =
    323     ItinData->getValueAsListOfInts("OperandCycles");
    324 
    325   // For each operand cycle
    326   unsigned N = NOperandCycles = OperandCycleList.size();
    327   for (unsigned i = 0; i < N;) {
    328     // Next operand cycle
    329     const int OCycle = OperandCycleList[i];
    330 
    331     ItinString += "  " + itostr(OCycle);
    332     if (++i < N) ItinString += ", ";
    333   }
    334 }
    335 
    336 void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
    337                                                  Record *ItinData,
    338                                                  std::string &ItinString,
    339                                                  unsigned NOperandCycles) {
    340   const std::vector<Record*> &BypassList =
    341     ItinData->getValueAsListOfDefs("Bypasses");
    342   unsigned N = BypassList.size();
    343   unsigned i = 0;
    344   for (; i < N;) {
    345     ItinString += Name + "Bypass::" + BypassList[i]->getName();
    346     if (++i < NOperandCycles) ItinString += ", ";
    347   }
    348   for (; i < NOperandCycles;) {
    349     ItinString += " 0";
    350     if (++i < NOperandCycles) ItinString += ", ";
    351   }
    352 }
    353 
    354 //
    355 // EmitStageAndOperandCycleData - Generate unique itinerary stages and operand
    356 // cycle tables. Create a list of InstrItinerary objects (ProcItinLists) indexed
    357 // by CodeGenSchedClass::Index.
    358 //
    359 void SubtargetEmitter::
    360 EmitStageAndOperandCycleData(raw_ostream &OS,
    361                              std::vector<std::vector<InstrItinerary> >
    362                                &ProcItinLists) {
    363 
    364   // Multiple processor models may share an itinerary record. Emit it once.
    365   SmallPtrSet<Record*, 8> ItinsDefSet;
    366 
    367   // Emit functional units for all the itineraries.
    368   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
    369          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
    370 
    371     if (!ItinsDefSet.insert(PI->ItinsDef).second)
    372       continue;
    373 
    374     std::vector<Record*> FUs = PI->ItinsDef->getValueAsListOfDefs("FU");
    375     if (FUs.empty())
    376       continue;
    377 
    378     const std::string &Name = PI->ItinsDef->getName();
    379     OS << "\n// Functional units for \"" << Name << "\"\n"
    380        << "namespace " << Name << "FU {\n";
    381 
    382     for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
    383       OS << "  const unsigned " << FUs[j]->getName()
    384          << " = 1 << " << j << ";\n";
    385 
    386     OS << "}\n";
    387 
    388     std::vector<Record*> BPs = PI->ItinsDef->getValueAsListOfDefs("BP");
    389     if (!BPs.empty()) {
    390       OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
    391          << "\"\n" << "namespace " << Name << "Bypass {\n";
    392 
    393       OS << "  const unsigned NoBypass = 0;\n";
    394       for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
    395         OS << "  const unsigned " << BPs[j]->getName()
    396            << " = 1 << " << j << ";\n";
    397 
    398       OS << "}\n";
    399     }
    400   }
    401 
    402   // Begin stages table
    403   std::string StageTable = "\nextern const llvm::InstrStage " + Target +
    404                            "Stages[] = {\n";
    405   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
    406 
    407   // Begin operand cycle table
    408   std::string OperandCycleTable = "extern const unsigned " + Target +
    409     "OperandCycles[] = {\n";
    410   OperandCycleTable += "  0, // No itinerary\n";
    411 
    412   // Begin pipeline bypass table
    413   std::string BypassTable = "extern const unsigned " + Target +
    414     "ForwardingPaths[] = {\n";
    415   BypassTable += " 0, // No itinerary\n";
    416 
    417   // For each Itinerary across all processors, add a unique entry to the stages,
    418   // operand cycles, and pipepine bypess tables. Then add the new Itinerary
    419   // object with computed offsets to the ProcItinLists result.
    420   unsigned StageCount = 1, OperandCycleCount = 1;
    421   std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
    422   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
    423          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
    424     const CodeGenProcModel &ProcModel = *PI;
    425 
    426     // Add process itinerary to the list.
    427     ProcItinLists.resize(ProcItinLists.size()+1);
    428 
    429     // If this processor defines no itineraries, then leave the itinerary list
    430     // empty.
    431     std::vector<InstrItinerary> &ItinList = ProcItinLists.back();
    432     if (!ProcModel.hasItineraries())
    433       continue;
    434 
    435     const std::string &Name = ProcModel.ItinsDef->getName();
    436 
    437     ItinList.resize(SchedModels.numInstrSchedClasses());
    438     assert(ProcModel.ItinDefList.size() == ItinList.size() && "bad Itins");
    439 
    440     for (unsigned SchedClassIdx = 0, SchedClassEnd = ItinList.size();
    441          SchedClassIdx < SchedClassEnd; ++SchedClassIdx) {
    442 
    443       // Next itinerary data
    444       Record *ItinData = ProcModel.ItinDefList[SchedClassIdx];
    445 
    446       // Get string and stage count
    447       std::string ItinStageString;
    448       unsigned NStages = 0;
    449       if (ItinData)
    450         FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
    451 
    452       // Get string and operand cycle count
    453       std::string ItinOperandCycleString;
    454       unsigned NOperandCycles = 0;
    455       std::string ItinBypassString;
    456       if (ItinData) {
    457         FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
    458                                         NOperandCycles);
    459 
    460         FormItineraryBypassString(Name, ItinData, ItinBypassString,
    461                                   NOperandCycles);
    462       }
    463 
    464       // Check to see if stage already exists and create if it doesn't
    465       unsigned FindStage = 0;
    466       if (NStages > 0) {
    467         FindStage = ItinStageMap[ItinStageString];
    468         if (FindStage == 0) {
    469           // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
    470           StageTable += ItinStageString + ", // " + itostr(StageCount);
    471           if (NStages > 1)
    472             StageTable += "-" + itostr(StageCount + NStages - 1);
    473           StageTable += "\n";
    474           // Record Itin class number.
    475           ItinStageMap[ItinStageString] = FindStage = StageCount;
    476           StageCount += NStages;
    477         }
    478       }
    479 
    480       // Check to see if operand cycle already exists and create if it doesn't
    481       unsigned FindOperandCycle = 0;
    482       if (NOperandCycles > 0) {
    483         std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
    484         FindOperandCycle = ItinOperandMap[ItinOperandString];
    485         if (FindOperandCycle == 0) {
    486           // Emit as  cycle, // index
    487           OperandCycleTable += ItinOperandCycleString + ", // ";
    488           std::string OperandIdxComment = itostr(OperandCycleCount);
    489           if (NOperandCycles > 1)
    490             OperandIdxComment += "-"
    491               + itostr(OperandCycleCount + NOperandCycles - 1);
    492           OperandCycleTable += OperandIdxComment + "\n";
    493           // Record Itin class number.
    494           ItinOperandMap[ItinOperandCycleString] =
    495             FindOperandCycle = OperandCycleCount;
    496           // Emit as bypass, // index
    497           BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
    498           OperandCycleCount += NOperandCycles;
    499         }
    500       }
    501 
    502       // Set up itinerary as location and location + stage count
    503       int NumUOps = ItinData ? ItinData->getValueAsInt("NumMicroOps") : 0;
    504       InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
    505                                     FindOperandCycle,
    506                                     FindOperandCycle + NOperandCycles};
    507 
    508       // Inject - empty slots will be 0, 0
    509       ItinList[SchedClassIdx] = Intinerary;
    510     }
    511   }
    512 
    513   // Closing stage
    514   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End stages\n";
    515   StageTable += "};\n";
    516 
    517   // Closing operand cycles
    518   OperandCycleTable += "  0 // End operand cycles\n";
    519   OperandCycleTable += "};\n";
    520 
    521   BypassTable += " 0 // End bypass tables\n";
    522   BypassTable += "};\n";
    523 
    524   // Emit tables.
    525   OS << StageTable;
    526   OS << OperandCycleTable;
    527   OS << BypassTable;
    528 }
    529 
    530 //
    531 // EmitProcessorData - Generate data for processor itineraries that were
    532 // computed during EmitStageAndOperandCycleData(). ProcItinLists lists all
    533 // Itineraries for each processor. The Itinerary lists are indexed on
    534 // CodeGenSchedClass::Index.
    535 //
    536 void SubtargetEmitter::
    537 EmitItineraries(raw_ostream &OS,
    538                 std::vector<std::vector<InstrItinerary> > &ProcItinLists) {
    539 
    540   // Multiple processor models may share an itinerary record. Emit it once.
    541   SmallPtrSet<Record*, 8> ItinsDefSet;
    542 
    543   // For each processor's machine model
    544   std::vector<std::vector<InstrItinerary> >::iterator
    545       ProcItinListsIter = ProcItinLists.begin();
    546   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
    547          PE = SchedModels.procModelEnd(); PI != PE; ++PI, ++ProcItinListsIter) {
    548 
    549     Record *ItinsDef = PI->ItinsDef;
    550     if (!ItinsDefSet.insert(ItinsDef).second)
    551       continue;
    552 
    553     // Get processor itinerary name
    554     const std::string &Name = ItinsDef->getName();
    555 
    556     // Get the itinerary list for the processor.
    557     assert(ProcItinListsIter != ProcItinLists.end() && "bad iterator");
    558     std::vector<InstrItinerary> &ItinList = *ProcItinListsIter;
    559 
    560     // Empty itineraries aren't referenced anywhere in the tablegen output
    561     // so don't emit them.
    562     if (ItinList.empty())
    563       continue;
    564 
    565     OS << "\n";
    566     OS << "static const llvm::InstrItinerary ";
    567 
    568     // Begin processor itinerary table
    569     OS << Name << "[] = {\n";
    570 
    571     // For each itinerary class in CodeGenSchedClass::Index order.
    572     for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
    573       InstrItinerary &Intinerary = ItinList[j];
    574 
    575       // Emit Itinerary in the form of
    576       // { firstStage, lastStage, firstCycle, lastCycle } // index
    577       OS << "  { " <<
    578         Intinerary.NumMicroOps << ", " <<
    579         Intinerary.FirstStage << ", " <<
    580         Intinerary.LastStage << ", " <<
    581         Intinerary.FirstOperandCycle << ", " <<
    582         Intinerary.LastOperandCycle << " }" <<
    583         ", // " << j << " " << SchedModels.getSchedClass(j).Name << "\n";
    584     }
    585     // End processor itinerary table
    586     OS << "  { 0, ~0U, ~0U, ~0U, ~0U } // end marker\n";
    587     OS << "};\n";
    588   }
    589 }
    590 
    591 // Emit either the value defined in the TableGen Record, or the default
    592 // value defined in the C++ header. The Record is null if the processor does not
    593 // define a model.
    594 void SubtargetEmitter::EmitProcessorProp(raw_ostream &OS, const Record *R,
    595                                          const char *Name, char Separator) {
    596   OS << "  ";
    597   int V = R ? R->getValueAsInt(Name) : -1;
    598   if (V >= 0)
    599     OS << V << Separator << " // " << Name;
    600   else
    601     OS << "MCSchedModel::Default" << Name << Separator;
    602   OS << '\n';
    603 }
    604 
    605 void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel,
    606                                               raw_ostream &OS) {
    607   char Sep = ProcModel.ProcResourceDefs.empty() ? ' ' : ',';
    608 
    609   OS << "\n// {Name, NumUnits, SuperIdx, IsBuffered}\n";
    610   OS << "static const llvm::MCProcResourceDesc "
    611      << ProcModel.ModelName << "ProcResources" << "[] = {\n"
    612      << "  {DBGFIELD(\"InvalidUnit\")     0, 0, 0}" << Sep << "\n";
    613 
    614   for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e; ++i) {
    615     Record *PRDef = ProcModel.ProcResourceDefs[i];
    616 
    617     Record *SuperDef = nullptr;
    618     unsigned SuperIdx = 0;
    619     unsigned NumUnits = 0;
    620     int BufferSize = PRDef->getValueAsInt("BufferSize");
    621     if (PRDef->isSubClassOf("ProcResGroup")) {
    622       RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources");
    623       for (RecIter RUI = ResUnits.begin(), RUE = ResUnits.end();
    624            RUI != RUE; ++RUI) {
    625         NumUnits += (*RUI)->getValueAsInt("NumUnits");
    626       }
    627     }
    628     else {
    629       // Find the SuperIdx
    630       if (PRDef->getValueInit("Super")->isComplete()) {
    631         SuperDef = SchedModels.findProcResUnits(
    632           PRDef->getValueAsDef("Super"), ProcModel);
    633         SuperIdx = ProcModel.getProcResourceIdx(SuperDef);
    634       }
    635       NumUnits = PRDef->getValueAsInt("NumUnits");
    636     }
    637     // Emit the ProcResourceDesc
    638     if (i+1 == e)
    639       Sep = ' ';
    640     OS << "  {DBGFIELD(\"" << PRDef->getName() << "\") ";
    641     if (PRDef->getName().size() < 15)
    642       OS.indent(15 - PRDef->getName().size());
    643     OS << NumUnits << ", " << SuperIdx << ", "
    644        << BufferSize << "}" << Sep << " // #" << i+1;
    645     if (SuperDef)
    646       OS << ", Super=" << SuperDef->getName();
    647     OS << "\n";
    648   }
    649   OS << "};\n";
    650 }
    651 
    652 // Find the WriteRes Record that defines processor resources for this
    653 // SchedWrite.
    654 Record *SubtargetEmitter::FindWriteResources(
    655   const CodeGenSchedRW &SchedWrite, const CodeGenProcModel &ProcModel) {
    656 
    657   // Check if the SchedWrite is already subtarget-specific and directly
    658   // specifies a set of processor resources.
    659   if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes"))
    660     return SchedWrite.TheDef;
    661 
    662   Record *AliasDef = nullptr;
    663   for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end();
    664        AI != AE; ++AI) {
    665     const CodeGenSchedRW &AliasRW =
    666       SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
    667     if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) {
    668       Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
    669       if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
    670         continue;
    671     }
    672     if (AliasDef)
    673       PrintFatalError(AliasRW.TheDef->getLoc(), "Multiple aliases "
    674                     "defined for processor " + ProcModel.ModelName +
    675                     " Ensure only one SchedAlias exists per RW.");
    676     AliasDef = AliasRW.TheDef;
    677   }
    678   if (AliasDef && AliasDef->isSubClassOf("SchedWriteRes"))
    679     return AliasDef;
    680 
    681   // Check this processor's list of write resources.
    682   Record *ResDef = nullptr;
    683   for (RecIter WRI = ProcModel.WriteResDefs.begin(),
    684          WRE = ProcModel.WriteResDefs.end(); WRI != WRE; ++WRI) {
    685     if (!(*WRI)->isSubClassOf("WriteRes"))
    686       continue;
    687     if (AliasDef == (*WRI)->getValueAsDef("WriteType")
    688         || SchedWrite.TheDef == (*WRI)->getValueAsDef("WriteType")) {
    689       if (ResDef) {
    690         PrintFatalError((*WRI)->getLoc(), "Resources are defined for both "
    691                       "SchedWrite and its alias on processor " +
    692                       ProcModel.ModelName);
    693       }
    694       ResDef = *WRI;
    695     }
    696   }
    697   // TODO: If ProcModel has a base model (previous generation processor),
    698   // then call FindWriteResources recursively with that model here.
    699   if (!ResDef) {
    700     PrintFatalError(ProcModel.ModelDef->getLoc(),
    701                   std::string("Processor does not define resources for ")
    702                   + SchedWrite.TheDef->getName());
    703   }
    704   return ResDef;
    705 }
    706 
    707 /// Find the ReadAdvance record for the given SchedRead on this processor or
    708 /// return NULL.
    709 Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
    710                                           const CodeGenProcModel &ProcModel) {
    711   // Check for SchedReads that directly specify a ReadAdvance.
    712   if (SchedRead.TheDef->isSubClassOf("SchedReadAdvance"))
    713     return SchedRead.TheDef;
    714 
    715   // Check this processor's list of aliases for SchedRead.
    716   Record *AliasDef = nullptr;
    717   for (RecIter AI = SchedRead.Aliases.begin(), AE = SchedRead.Aliases.end();
    718        AI != AE; ++AI) {
    719     const CodeGenSchedRW &AliasRW =
    720       SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
    721     if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) {
    722       Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
    723       if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
    724         continue;
    725     }
    726     if (AliasDef)
    727       PrintFatalError(AliasRW.TheDef->getLoc(), "Multiple aliases "
    728                     "defined for processor " + ProcModel.ModelName +
    729                     " Ensure only one SchedAlias exists per RW.");
    730     AliasDef = AliasRW.TheDef;
    731   }
    732   if (AliasDef && AliasDef->isSubClassOf("SchedReadAdvance"))
    733     return AliasDef;
    734 
    735   // Check this processor's ReadAdvanceList.
    736   Record *ResDef = nullptr;
    737   for (RecIter RAI = ProcModel.ReadAdvanceDefs.begin(),
    738          RAE = ProcModel.ReadAdvanceDefs.end(); RAI != RAE; ++RAI) {
    739     if (!(*RAI)->isSubClassOf("ReadAdvance"))
    740       continue;
    741     if (AliasDef == (*RAI)->getValueAsDef("ReadType")
    742         || SchedRead.TheDef == (*RAI)->getValueAsDef("ReadType")) {
    743       if (ResDef) {
    744         PrintFatalError((*RAI)->getLoc(), "Resources are defined for both "
    745                       "SchedRead and its alias on processor " +
    746                       ProcModel.ModelName);
    747       }
    748       ResDef = *RAI;
    749     }
    750   }
    751   // TODO: If ProcModel has a base model (previous generation processor),
    752   // then call FindReadAdvance recursively with that model here.
    753   if (!ResDef && SchedRead.TheDef->getName() != "ReadDefault") {
    754     PrintFatalError(ProcModel.ModelDef->getLoc(),
    755                   std::string("Processor does not define resources for ")
    756                   + SchedRead.TheDef->getName());
    757   }
    758   return ResDef;
    759 }
    760 
    761 // Expand an explicit list of processor resources into a full list of implied
    762 // resource groups and super resources that cover them.
    763 void SubtargetEmitter::ExpandProcResources(RecVec &PRVec,
    764                                            std::vector<int64_t> &Cycles,
    765                                            const CodeGenProcModel &PM) {
    766   // Default to 1 resource cycle.
    767   Cycles.resize(PRVec.size(), 1);
    768   for (unsigned i = 0, e = PRVec.size(); i != e; ++i) {
    769     Record *PRDef = PRVec[i];
    770     RecVec SubResources;
    771     if (PRDef->isSubClassOf("ProcResGroup"))
    772       SubResources = PRDef->getValueAsListOfDefs("Resources");
    773     else {
    774       SubResources.push_back(PRDef);
    775       PRDef = SchedModels.findProcResUnits(PRVec[i], PM);
    776       for (Record *SubDef = PRDef;
    777            SubDef->getValueInit("Super")->isComplete();) {
    778         if (SubDef->isSubClassOf("ProcResGroup")) {
    779           // Disallow this for simplicitly.
    780           PrintFatalError(SubDef->getLoc(), "Processor resource group "
    781                           " cannot be a super resources.");
    782         }
    783         Record *SuperDef =
    784           SchedModels.findProcResUnits(SubDef->getValueAsDef("Super"), PM);
    785         PRVec.push_back(SuperDef);
    786         Cycles.push_back(Cycles[i]);
    787         SubDef = SuperDef;
    788       }
    789     }
    790     for (RecIter PRI = PM.ProcResourceDefs.begin(),
    791            PRE = PM.ProcResourceDefs.end();
    792          PRI != PRE; ++PRI) {
    793       if (*PRI == PRDef || !(*PRI)->isSubClassOf("ProcResGroup"))
    794         continue;
    795       RecVec SuperResources = (*PRI)->getValueAsListOfDefs("Resources");
    796       RecIter SubI = SubResources.begin(), SubE = SubResources.end();
    797       for( ; SubI != SubE; ++SubI) {
    798         if (std::find(SuperResources.begin(), SuperResources.end(), *SubI)
    799             == SuperResources.end()) {
    800           break;
    801         }
    802       }
    803       if (SubI == SubE) {
    804         PRVec.push_back(*PRI);
    805         Cycles.push_back(Cycles[i]);
    806       }
    807     }
    808   }
    809 }
    810 
    811 // Generate the SchedClass table for this processor and update global
    812 // tables. Must be called for each processor in order.
    813 void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
    814                                            SchedClassTables &SchedTables) {
    815   SchedTables.ProcSchedClasses.resize(SchedTables.ProcSchedClasses.size() + 1);
    816   if (!ProcModel.hasInstrSchedModel())
    817     return;
    818 
    819   std::vector<MCSchedClassDesc> &SCTab = SchedTables.ProcSchedClasses.back();
    820   for (CodeGenSchedModels::SchedClassIter SCI = SchedModels.schedClassBegin(),
    821          SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) {
    822     DEBUG(SCI->dump(&SchedModels));
    823 
    824     SCTab.resize(SCTab.size() + 1);
    825     MCSchedClassDesc &SCDesc = SCTab.back();
    826     // SCDesc.Name is guarded by NDEBUG
    827     SCDesc.NumMicroOps = 0;
    828     SCDesc.BeginGroup = false;
    829     SCDesc.EndGroup = false;
    830     SCDesc.WriteProcResIdx = 0;
    831     SCDesc.WriteLatencyIdx = 0;
    832     SCDesc.ReadAdvanceIdx = 0;
    833 
    834     // A Variant SchedClass has no resources of its own.
    835     bool HasVariants = false;
    836     for (std::vector<CodeGenSchedTransition>::const_iterator
    837            TI = SCI->Transitions.begin(), TE = SCI->Transitions.end();
    838          TI != TE; ++TI) {
    839       if (TI->ProcIndices[0] == 0) {
    840         HasVariants = true;
    841         break;
    842       }
    843       IdxIter PIPos = std::find(TI->ProcIndices.begin(),
    844                                 TI->ProcIndices.end(), ProcModel.Index);
    845       if (PIPos != TI->ProcIndices.end()) {
    846         HasVariants = true;
    847         break;
    848       }
    849     }
    850     if (HasVariants) {
    851       SCDesc.NumMicroOps = MCSchedClassDesc::VariantNumMicroOps;
    852       continue;
    853     }
    854 
    855     // Determine if the SchedClass is actually reachable on this processor. If
    856     // not don't try to locate the processor resources, it will fail.
    857     // If ProcIndices contains 0, this class applies to all processors.
    858     assert(!SCI->ProcIndices.empty() && "expect at least one procidx");
    859     if (SCI->ProcIndices[0] != 0) {
    860       IdxIter PIPos = std::find(SCI->ProcIndices.begin(),
    861                                 SCI->ProcIndices.end(), ProcModel.Index);
    862       if (PIPos == SCI->ProcIndices.end())
    863         continue;
    864     }
    865     IdxVec Writes = SCI->Writes;
    866     IdxVec Reads = SCI->Reads;
    867     if (!SCI->InstRWs.empty()) {
    868       // This class has a default ReadWrite list which can be overriden by
    869       // InstRW definitions.
    870       Record *RWDef = nullptr;
    871       for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end();
    872            RWI != RWE; ++RWI) {
    873         Record *RWModelDef = (*RWI)->getValueAsDef("SchedModel");
    874         if (&ProcModel == &SchedModels.getProcModel(RWModelDef)) {
    875           RWDef = *RWI;
    876           break;
    877         }
    878       }
    879       if (RWDef) {
    880         Writes.clear();
    881         Reads.clear();
    882         SchedModels.findRWs(RWDef->getValueAsListOfDefs("OperandReadWrites"),
    883                             Writes, Reads);
    884       }
    885     }
    886     if (Writes.empty()) {
    887       // Check this processor's itinerary class resources.
    888       for (RecIter II = ProcModel.ItinRWDefs.begin(),
    889              IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) {
    890         RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
    891         if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef)
    892             != Matched.end()) {
    893           SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"),
    894                               Writes, Reads);
    895           break;
    896         }
    897       }
    898       if (Writes.empty()) {
    899         DEBUG(dbgs() << ProcModel.ModelName
    900               << " does not have resources for class " << SCI->Name << '\n');
    901       }
    902     }
    903     // Sum resources across all operand writes.
    904     std::vector<MCWriteProcResEntry> WriteProcResources;
    905     std::vector<MCWriteLatencyEntry> WriteLatencies;
    906     std::vector<std::string> WriterNames;
    907     std::vector<MCReadAdvanceEntry> ReadAdvanceEntries;
    908     for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) {
    909       IdxVec WriteSeq;
    910       SchedModels.expandRWSeqForProc(*WI, WriteSeq, /*IsRead=*/false,
    911                                      ProcModel);
    912 
    913       // For each operand, create a latency entry.
    914       MCWriteLatencyEntry WLEntry;
    915       WLEntry.Cycles = 0;
    916       unsigned WriteID = WriteSeq.back();
    917       WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name);
    918       // If this Write is not referenced by a ReadAdvance, don't distinguish it
    919       // from other WriteLatency entries.
    920       if (!SchedModels.hasReadOfWrite(
    921             SchedModels.getSchedWrite(WriteID).TheDef)) {
    922         WriteID = 0;
    923       }
    924       WLEntry.WriteResourceID = WriteID;
    925 
    926       for (IdxIter WSI = WriteSeq.begin(), WSE = WriteSeq.end();
    927            WSI != WSE; ++WSI) {
    928 
    929         Record *WriteRes =
    930           FindWriteResources(SchedModels.getSchedWrite(*WSI), ProcModel);
    931 
    932         // Mark the parent class as invalid for unsupported write types.
    933         if (WriteRes->getValueAsBit("Unsupported")) {
    934           SCDesc.NumMicroOps = MCSchedClassDesc::InvalidNumMicroOps;
    935           break;
    936         }
    937         WLEntry.Cycles += WriteRes->getValueAsInt("Latency");
    938         SCDesc.NumMicroOps += WriteRes->getValueAsInt("NumMicroOps");
    939         SCDesc.BeginGroup |= WriteRes->getValueAsBit("BeginGroup");
    940         SCDesc.EndGroup |= WriteRes->getValueAsBit("EndGroup");
    941 
    942         // Create an entry for each ProcResource listed in WriteRes.
    943         RecVec PRVec = WriteRes->getValueAsListOfDefs("ProcResources");
    944         std::vector<int64_t> Cycles =
    945           WriteRes->getValueAsListOfInts("ResourceCycles");
    946 
    947         ExpandProcResources(PRVec, Cycles, ProcModel);
    948 
    949         for (unsigned PRIdx = 0, PREnd = PRVec.size();
    950              PRIdx != PREnd; ++PRIdx) {
    951           MCWriteProcResEntry WPREntry;
    952           WPREntry.ProcResourceIdx = ProcModel.getProcResourceIdx(PRVec[PRIdx]);
    953           assert(WPREntry.ProcResourceIdx && "Bad ProcResourceIdx");
    954           WPREntry.Cycles = Cycles[PRIdx];
    955           // If this resource is already used in this sequence, add the current
    956           // entry's cycles so that the same resource appears to be used
    957           // serially, rather than multiple parallel uses. This is important for
    958           // in-order machine where the resource consumption is a hazard.
    959           unsigned WPRIdx = 0, WPREnd = WriteProcResources.size();
    960           for( ; WPRIdx != WPREnd; ++WPRIdx) {
    961             if (WriteProcResources[WPRIdx].ProcResourceIdx
    962                 == WPREntry.ProcResourceIdx) {
    963               WriteProcResources[WPRIdx].Cycles += WPREntry.Cycles;
    964               break;
    965             }
    966           }
    967           if (WPRIdx == WPREnd)
    968             WriteProcResources.push_back(WPREntry);
    969         }
    970       }
    971       WriteLatencies.push_back(WLEntry);
    972     }
    973     // Create an entry for each operand Read in this SchedClass.
    974     // Entries must be sorted first by UseIdx then by WriteResourceID.
    975     for (unsigned UseIdx = 0, EndIdx = Reads.size();
    976          UseIdx != EndIdx; ++UseIdx) {
    977       Record *ReadAdvance =
    978         FindReadAdvance(SchedModels.getSchedRead(Reads[UseIdx]), ProcModel);
    979       if (!ReadAdvance)
    980         continue;
    981 
    982       // Mark the parent class as invalid for unsupported write types.
    983       if (ReadAdvance->getValueAsBit("Unsupported")) {
    984         SCDesc.NumMicroOps = MCSchedClassDesc::InvalidNumMicroOps;
    985         break;
    986       }
    987       RecVec ValidWrites = ReadAdvance->getValueAsListOfDefs("ValidWrites");
    988       IdxVec WriteIDs;
    989       if (ValidWrites.empty())
    990         WriteIDs.push_back(0);
    991       else {
    992         for (RecIter VWI = ValidWrites.begin(), VWE = ValidWrites.end();
    993              VWI != VWE; ++VWI) {
    994           WriteIDs.push_back(SchedModels.getSchedRWIdx(*VWI, /*IsRead=*/false));
    995         }
    996       }
    997       std::sort(WriteIDs.begin(), WriteIDs.end());
    998       for(IdxIter WI = WriteIDs.begin(), WE = WriteIDs.end(); WI != WE; ++WI) {
    999         MCReadAdvanceEntry RAEntry;
   1000         RAEntry.UseIdx = UseIdx;
   1001         RAEntry.WriteResourceID = *WI;
   1002         RAEntry.Cycles = ReadAdvance->getValueAsInt("Cycles");
   1003         ReadAdvanceEntries.push_back(RAEntry);
   1004       }
   1005     }
   1006     if (SCDesc.NumMicroOps == MCSchedClassDesc::InvalidNumMicroOps) {
   1007       WriteProcResources.clear();
   1008       WriteLatencies.clear();
   1009       ReadAdvanceEntries.clear();
   1010     }
   1011     // Add the information for this SchedClass to the global tables using basic
   1012     // compression.
   1013     //
   1014     // WritePrecRes entries are sorted by ProcResIdx.
   1015     std::sort(WriteProcResources.begin(), WriteProcResources.end(),
   1016               LessWriteProcResources());
   1017 
   1018     SCDesc.NumWriteProcResEntries = WriteProcResources.size();
   1019     std::vector<MCWriteProcResEntry>::iterator WPRPos =
   1020       std::search(SchedTables.WriteProcResources.begin(),
   1021                   SchedTables.WriteProcResources.end(),
   1022                   WriteProcResources.begin(), WriteProcResources.end());
   1023     if (WPRPos != SchedTables.WriteProcResources.end())
   1024       SCDesc.WriteProcResIdx = WPRPos - SchedTables.WriteProcResources.begin();
   1025     else {
   1026       SCDesc.WriteProcResIdx = SchedTables.WriteProcResources.size();
   1027       SchedTables.WriteProcResources.insert(WPRPos, WriteProcResources.begin(),
   1028                                             WriteProcResources.end());
   1029     }
   1030     // Latency entries must remain in operand order.
   1031     SCDesc.NumWriteLatencyEntries = WriteLatencies.size();
   1032     std::vector<MCWriteLatencyEntry>::iterator WLPos =
   1033       std::search(SchedTables.WriteLatencies.begin(),
   1034                   SchedTables.WriteLatencies.end(),
   1035                   WriteLatencies.begin(), WriteLatencies.end());
   1036     if (WLPos != SchedTables.WriteLatencies.end()) {
   1037       unsigned idx = WLPos - SchedTables.WriteLatencies.begin();
   1038       SCDesc.WriteLatencyIdx = idx;
   1039       for (unsigned i = 0, e = WriteLatencies.size(); i < e; ++i)
   1040         if (SchedTables.WriterNames[idx + i].find(WriterNames[i]) ==
   1041             std::string::npos) {
   1042           SchedTables.WriterNames[idx + i] += std::string("_") + WriterNames[i];
   1043         }
   1044     }
   1045     else {
   1046       SCDesc.WriteLatencyIdx = SchedTables.WriteLatencies.size();
   1047       SchedTables.WriteLatencies.insert(SchedTables.WriteLatencies.end(),
   1048                                         WriteLatencies.begin(),
   1049                                         WriteLatencies.end());
   1050       SchedTables.WriterNames.insert(SchedTables.WriterNames.end(),
   1051                                      WriterNames.begin(), WriterNames.end());
   1052     }
   1053     // ReadAdvanceEntries must remain in operand order.
   1054     SCDesc.NumReadAdvanceEntries = ReadAdvanceEntries.size();
   1055     std::vector<MCReadAdvanceEntry>::iterator RAPos =
   1056       std::search(SchedTables.ReadAdvanceEntries.begin(),
   1057                   SchedTables.ReadAdvanceEntries.end(),
   1058                   ReadAdvanceEntries.begin(), ReadAdvanceEntries.end());
   1059     if (RAPos != SchedTables.ReadAdvanceEntries.end())
   1060       SCDesc.ReadAdvanceIdx = RAPos - SchedTables.ReadAdvanceEntries.begin();
   1061     else {
   1062       SCDesc.ReadAdvanceIdx = SchedTables.ReadAdvanceEntries.size();
   1063       SchedTables.ReadAdvanceEntries.insert(RAPos, ReadAdvanceEntries.begin(),
   1064                                             ReadAdvanceEntries.end());
   1065     }
   1066   }
   1067 }
   1068 
   1069 // Emit SchedClass tables for all processors and associated global tables.
   1070 void SubtargetEmitter::EmitSchedClassTables(SchedClassTables &SchedTables,
   1071                                             raw_ostream &OS) {
   1072   // Emit global WriteProcResTable.
   1073   OS << "\n// {ProcResourceIdx, Cycles}\n"
   1074      << "extern const llvm::MCWriteProcResEntry "
   1075      << Target << "WriteProcResTable[] = {\n"
   1076      << "  { 0,  0}, // Invalid\n";
   1077   for (unsigned WPRIdx = 1, WPREnd = SchedTables.WriteProcResources.size();
   1078        WPRIdx != WPREnd; ++WPRIdx) {
   1079     MCWriteProcResEntry &WPREntry = SchedTables.WriteProcResources[WPRIdx];
   1080     OS << "  {" << format("%2d", WPREntry.ProcResourceIdx) << ", "
   1081        << format("%2d", WPREntry.Cycles) << "}";
   1082     if (WPRIdx + 1 < WPREnd)
   1083       OS << ',';
   1084     OS << " // #" << WPRIdx << '\n';
   1085   }
   1086   OS << "}; // " << Target << "WriteProcResTable\n";
   1087 
   1088   // Emit global WriteLatencyTable.
   1089   OS << "\n// {Cycles, WriteResourceID}\n"
   1090      << "extern const llvm::MCWriteLatencyEntry "
   1091      << Target << "WriteLatencyTable[] = {\n"
   1092      << "  { 0,  0}, // Invalid\n";
   1093   for (unsigned WLIdx = 1, WLEnd = SchedTables.WriteLatencies.size();
   1094        WLIdx != WLEnd; ++WLIdx) {
   1095     MCWriteLatencyEntry &WLEntry = SchedTables.WriteLatencies[WLIdx];
   1096     OS << "  {" << format("%2d", WLEntry.Cycles) << ", "
   1097        << format("%2d", WLEntry.WriteResourceID) << "}";
   1098     if (WLIdx + 1 < WLEnd)
   1099       OS << ',';
   1100     OS << " // #" << WLIdx << " " << SchedTables.WriterNames[WLIdx] << '\n';
   1101   }
   1102   OS << "}; // " << Target << "WriteLatencyTable\n";
   1103 
   1104   // Emit global ReadAdvanceTable.
   1105   OS << "\n// {UseIdx, WriteResourceID, Cycles}\n"
   1106      << "extern const llvm::MCReadAdvanceEntry "
   1107      << Target << "ReadAdvanceTable[] = {\n"
   1108      << "  {0,  0,  0}, // Invalid\n";
   1109   for (unsigned RAIdx = 1, RAEnd = SchedTables.ReadAdvanceEntries.size();
   1110        RAIdx != RAEnd; ++RAIdx) {
   1111     MCReadAdvanceEntry &RAEntry = SchedTables.ReadAdvanceEntries[RAIdx];
   1112     OS << "  {" << RAEntry.UseIdx << ", "
   1113        << format("%2d", RAEntry.WriteResourceID) << ", "
   1114        << format("%2d", RAEntry.Cycles) << "}";
   1115     if (RAIdx + 1 < RAEnd)
   1116       OS << ',';
   1117     OS << " // #" << RAIdx << '\n';
   1118   }
   1119   OS << "}; // " << Target << "ReadAdvanceTable\n";
   1120 
   1121   // Emit a SchedClass table for each processor.
   1122   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
   1123          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
   1124     if (!PI->hasInstrSchedModel())
   1125       continue;
   1126 
   1127     std::vector<MCSchedClassDesc> &SCTab =
   1128       SchedTables.ProcSchedClasses[1 + (PI - SchedModels.procModelBegin())];
   1129 
   1130     OS << "\n// {Name, NumMicroOps, BeginGroup, EndGroup,"
   1131        << " WriteProcResIdx,#, WriteLatencyIdx,#, ReadAdvanceIdx,#}\n";
   1132     OS << "static const llvm::MCSchedClassDesc "
   1133        << PI->ModelName << "SchedClasses[] = {\n";
   1134 
   1135     // The first class is always invalid. We no way to distinguish it except by
   1136     // name and position.
   1137     assert(SchedModels.getSchedClass(0).Name == "NoInstrModel"
   1138            && "invalid class not first");
   1139     OS << "  {DBGFIELD(\"InvalidSchedClass\")  "
   1140        << MCSchedClassDesc::InvalidNumMicroOps
   1141        << ", 0, 0,  0, 0,  0, 0,  0, 0},\n";
   1142 
   1143     for (unsigned SCIdx = 1, SCEnd = SCTab.size(); SCIdx != SCEnd; ++SCIdx) {
   1144       MCSchedClassDesc &MCDesc = SCTab[SCIdx];
   1145       const CodeGenSchedClass &SchedClass = SchedModels.getSchedClass(SCIdx);
   1146       OS << "  {DBGFIELD(\"" << SchedClass.Name << "\") ";
   1147       if (SchedClass.Name.size() < 18)
   1148         OS.indent(18 - SchedClass.Name.size());
   1149       OS << MCDesc.NumMicroOps
   1150          << ", " << MCDesc.BeginGroup << ", " << MCDesc.EndGroup
   1151          << ", " << format("%2d", MCDesc.WriteProcResIdx)
   1152          << ", " << MCDesc.NumWriteProcResEntries
   1153          << ", " << format("%2d", MCDesc.WriteLatencyIdx)
   1154          << ", " << MCDesc.NumWriteLatencyEntries
   1155          << ", " << format("%2d", MCDesc.ReadAdvanceIdx)
   1156          << ", " << MCDesc.NumReadAdvanceEntries << "}";
   1157       if (SCIdx + 1 < SCEnd)
   1158         OS << ',';
   1159       OS << " // #" << SCIdx << '\n';
   1160     }
   1161     OS << "}; // " << PI->ModelName << "SchedClasses\n";
   1162   }
   1163 }
   1164 
   1165 void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
   1166   // For each processor model.
   1167   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
   1168          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
   1169     // Emit processor resource table.
   1170     if (PI->hasInstrSchedModel())
   1171       EmitProcessorResources(*PI, OS);
   1172     else if(!PI->ProcResourceDefs.empty())
   1173       PrintFatalError(PI->ModelDef->getLoc(), "SchedMachineModel defines "
   1174                     "ProcResources without defining WriteRes SchedWriteRes");
   1175 
   1176     // Begin processor itinerary properties
   1177     OS << "\n";
   1178     OS << "static const llvm::MCSchedModel " << PI->ModelName << " = {\n";
   1179     EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ',');
   1180     EmitProcessorProp(OS, PI->ModelDef, "MicroOpBufferSize", ',');
   1181     EmitProcessorProp(OS, PI->ModelDef, "LoopMicroOpBufferSize", ',');
   1182     EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ',');
   1183     EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ',');
   1184     EmitProcessorProp(OS, PI->ModelDef, "MispredictPenalty", ',');
   1185 
   1186     OS << "  " << (bool)(PI->ModelDef ?
   1187                          PI->ModelDef->getValueAsBit("PostRAScheduler") : 0)
   1188        << ", // " << "PostRAScheduler\n";
   1189 
   1190     OS << "  " << (bool)(PI->ModelDef ?
   1191                          PI->ModelDef->getValueAsBit("CompleteModel") : 0)
   1192        << ", // " << "CompleteModel\n";
   1193 
   1194     OS << "  " << PI->Index << ", // Processor ID\n";
   1195     if (PI->hasInstrSchedModel())
   1196       OS << "  " << PI->ModelName << "ProcResources" << ",\n"
   1197          << "  " << PI->ModelName << "SchedClasses" << ",\n"
   1198          << "  " << PI->ProcResourceDefs.size()+1 << ",\n"
   1199          << "  " << (SchedModels.schedClassEnd()
   1200                      - SchedModels.schedClassBegin()) << ",\n";
   1201     else
   1202       OS << "  nullptr, nullptr, 0, 0,"
   1203          << " // No instruction-level machine model.\n";
   1204     if (PI->hasItineraries())
   1205       OS << "  " << PI->ItinsDef->getName() << "};\n";
   1206     else
   1207       OS << "  nullptr}; // No Itinerary\n";
   1208   }
   1209 }
   1210 
   1211 //
   1212 // EmitProcessorLookup - generate cpu name to itinerary lookup table.
   1213 //
   1214 void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
   1215   // Gather and sort processor information
   1216   std::vector<Record*> ProcessorList =
   1217                           Records.getAllDerivedDefinitions("Processor");
   1218   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
   1219 
   1220   // Begin processor table
   1221   OS << "\n";
   1222   OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
   1223      << "extern const llvm::SubtargetInfoKV "
   1224      << Target << "ProcSchedKV[] = {\n";
   1225 
   1226   // For each processor
   1227   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
   1228     // Next processor
   1229     Record *Processor = ProcessorList[i];
   1230 
   1231     const std::string &Name = Processor->getValueAsString("Name");
   1232     const std::string &ProcModelName =
   1233       SchedModels.getModelForProc(Processor).ModelName;
   1234 
   1235     // Emit as { "cpu", procinit },
   1236     OS << "  { \"" << Name << "\", (const void *)&" << ProcModelName << " }";
   1237 
   1238     // Depending on ''if more in the list'' emit comma
   1239     if (++i < N) OS << ",";
   1240 
   1241     OS << "\n";
   1242   }
   1243 
   1244   // End processor table
   1245   OS << "};\n";
   1246 }
   1247 
   1248 //
   1249 // EmitSchedModel - Emits all scheduling model tables, folding common patterns.
   1250 //
   1251 void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) {
   1252   OS << "#ifdef DBGFIELD\n"
   1253      << "#error \"<target>GenSubtargetInfo.inc requires a DBGFIELD macro\"\n"
   1254      << "#endif\n"
   1255      << "#ifndef NDEBUG\n"
   1256      << "#define DBGFIELD(x) x,\n"
   1257      << "#else\n"
   1258      << "#define DBGFIELD(x)\n"
   1259      << "#endif\n";
   1260 
   1261   if (SchedModels.hasItineraries()) {
   1262     std::vector<std::vector<InstrItinerary> > ProcItinLists;
   1263     // Emit the stage data
   1264     EmitStageAndOperandCycleData(OS, ProcItinLists);
   1265     EmitItineraries(OS, ProcItinLists);
   1266   }
   1267   OS << "\n// ===============================================================\n"
   1268      << "// Data tables for the new per-operand machine model.\n";
   1269 
   1270   SchedClassTables SchedTables;
   1271   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
   1272          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
   1273     GenSchedClassTables(*PI, SchedTables);
   1274   }
   1275   EmitSchedClassTables(SchedTables, OS);
   1276 
   1277   // Emit the processor machine model
   1278   EmitProcessorModels(OS);
   1279   // Emit the processor lookup data
   1280   EmitProcessorLookup(OS);
   1281 
   1282   OS << "#undef DBGFIELD";
   1283 }
   1284 
   1285 void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName,
   1286                                              raw_ostream &OS) {
   1287   OS << "unsigned " << ClassName
   1288      << "\n::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI,"
   1289      << " const TargetSchedModel *SchedModel) const {\n";
   1290 
   1291   std::vector<Record*> Prologs = Records.getAllDerivedDefinitions("PredicateProlog");
   1292   std::sort(Prologs.begin(), Prologs.end(), LessRecord());
   1293   for (std::vector<Record*>::const_iterator
   1294          PI = Prologs.begin(), PE = Prologs.end(); PI != PE; ++PI) {
   1295     OS << (*PI)->getValueAsString("Code") << '\n';
   1296   }
   1297   IdxVec VariantClasses;
   1298   for (CodeGenSchedModels::SchedClassIter SCI = SchedModels.schedClassBegin(),
   1299          SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) {
   1300     if (SCI->Transitions.empty())
   1301       continue;
   1302     VariantClasses.push_back(SCI->Index);
   1303   }
   1304   if (!VariantClasses.empty()) {
   1305     OS << "  switch (SchedClass) {\n";
   1306     for (IdxIter VCI = VariantClasses.begin(), VCE = VariantClasses.end();
   1307          VCI != VCE; ++VCI) {
   1308       const CodeGenSchedClass &SC = SchedModels.getSchedClass(*VCI);
   1309       OS << "  case " << *VCI << ": // " << SC.Name << '\n';
   1310       IdxVec ProcIndices;
   1311       for (std::vector<CodeGenSchedTransition>::const_iterator
   1312              TI = SC.Transitions.begin(), TE = SC.Transitions.end();
   1313            TI != TE; ++TI) {
   1314         IdxVec PI;
   1315         std::set_union(TI->ProcIndices.begin(), TI->ProcIndices.end(),
   1316                        ProcIndices.begin(), ProcIndices.end(),
   1317                        std::back_inserter(PI));
   1318         ProcIndices.swap(PI);
   1319       }
   1320       for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end();
   1321            PI != PE; ++PI) {
   1322         OS << "    ";
   1323         if (*PI != 0)
   1324           OS << "if (SchedModel->getProcessorID() == " << *PI << ") ";
   1325         OS << "{ // " << (SchedModels.procModelBegin() + *PI)->ModelName
   1326            << '\n';
   1327         for (std::vector<CodeGenSchedTransition>::const_iterator
   1328                TI = SC.Transitions.begin(), TE = SC.Transitions.end();
   1329              TI != TE; ++TI) {
   1330           if (*PI != 0 && !std::count(TI->ProcIndices.begin(),
   1331                                       TI->ProcIndices.end(), *PI)) {
   1332               continue;
   1333           }
   1334           OS << "      if (";
   1335           for (RecIter RI = TI->PredTerm.begin(), RE = TI->PredTerm.end();
   1336                RI != RE; ++RI) {
   1337             if (RI != TI->PredTerm.begin())
   1338               OS << "\n          && ";
   1339             OS << "(" << (*RI)->getValueAsString("Predicate") << ")";
   1340           }
   1341           OS << ")\n"
   1342              << "        return " << TI->ToClassIdx << "; // "
   1343              << SchedModels.getSchedClass(TI->ToClassIdx).Name << '\n';
   1344         }
   1345         OS << "    }\n";
   1346         if (*PI == 0)
   1347           break;
   1348       }
   1349       if (SC.isInferred())
   1350         OS << "    return " << SC.Index << ";\n";
   1351       OS << "    break;\n";
   1352     }
   1353     OS << "  };\n";
   1354   }
   1355   OS << "  report_fatal_error(\"Expected a variant SchedClass\");\n"
   1356      << "} // " << ClassName << "::resolveSchedClass\n";
   1357 }
   1358 
   1359 //
   1360 // ParseFeaturesFunction - Produces a subtarget specific function for parsing
   1361 // the subtarget features string.
   1362 //
   1363 void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
   1364                                              unsigned NumFeatures,
   1365                                              unsigned NumProcs) {
   1366   std::vector<Record*> Features =
   1367                        Records.getAllDerivedDefinitions("SubtargetFeature");
   1368   std::sort(Features.begin(), Features.end(), LessRecord());
   1369 
   1370   OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
   1371      << "// subtarget options.\n"
   1372      << "void llvm::";
   1373   OS << Target;
   1374   OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n"
   1375      << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
   1376      << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n";
   1377 
   1378   if (Features.empty()) {
   1379     OS << "}\n";
   1380     return;
   1381   }
   1382 
   1383   OS << "  InitMCProcessorInfo(CPU, FS);\n"
   1384      << "  const FeatureBitset& Bits = getFeatureBits();\n";
   1385 
   1386   for (unsigned i = 0; i < Features.size(); i++) {
   1387     // Next record
   1388     Record *R = Features[i];
   1389     const std::string &Instance = R->getName();
   1390     const std::string &Value = R->getValueAsString("Value");
   1391     const std::string &Attribute = R->getValueAsString("Attribute");
   1392 
   1393     if (Value=="true" || Value=="false")
   1394       OS << "  if (Bits[" << Target << "::"
   1395          << Instance << "]) "
   1396          << Attribute << " = " << Value << ";\n";
   1397     else
   1398       OS << "  if (Bits[" << Target << "::"
   1399          << Instance << "] && "
   1400          << Attribute << " < " << Value << ") "
   1401          << Attribute << " = " << Value << ";\n";
   1402   }
   1403 
   1404   OS << "}\n";
   1405 }
   1406 
   1407 //
   1408 // SubtargetEmitter::run - Main subtarget enumeration emitter.
   1409 //
   1410 void SubtargetEmitter::run(raw_ostream &OS) {
   1411   emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
   1412 
   1413   OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
   1414   OS << "#undef GET_SUBTARGETINFO_ENUM\n";
   1415 
   1416   OS << "namespace llvm {\n";
   1417   Enumeration(OS, "SubtargetFeature");
   1418   OS << "} // end llvm namespace\n";
   1419   OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
   1420 
   1421   OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
   1422   OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
   1423 
   1424   OS << "namespace llvm {\n";
   1425 #if 0
   1426   OS << "namespace {\n";
   1427 #endif
   1428   unsigned NumFeatures = FeatureKeyValues(OS);
   1429   OS << "\n";
   1430   unsigned NumProcs = CPUKeyValues(OS);
   1431   OS << "\n";
   1432   EmitSchedModel(OS);
   1433   OS << "\n";
   1434 #if 0
   1435   OS << "}\n";
   1436 #endif
   1437 
   1438   // MCInstrInfo initialization routine.
   1439   OS << "static inline MCSubtargetInfo *create" << Target
   1440      << "MCSubtargetInfoImpl("
   1441      << "const Triple &TT, StringRef CPU, StringRef FS) {\n";
   1442   OS << "  return new MCSubtargetInfo(TT, CPU, FS, ";
   1443   if (NumFeatures)
   1444     OS << Target << "FeatureKV, ";
   1445   else
   1446     OS << "None, ";
   1447   if (NumProcs)
   1448     OS << Target << "SubTypeKV, ";
   1449   else
   1450     OS << "None, ";
   1451   OS << '\n'; OS.indent(22);
   1452   OS << Target << "ProcSchedKV, "
   1453      << Target << "WriteProcResTable, "
   1454      << Target << "WriteLatencyTable, "
   1455      << Target << "ReadAdvanceTable, ";
   1456   if (SchedModels.hasItineraries()) {
   1457     OS << '\n'; OS.indent(22);
   1458     OS << Target << "Stages, "
   1459        << Target << "OperandCycles, "
   1460        << Target << "ForwardingPaths";
   1461   } else
   1462     OS << "0, 0, 0";
   1463   OS << ");\n}\n\n";
   1464 
   1465   OS << "} // end llvm namespace\n";
   1466 
   1467   OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
   1468 
   1469   OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
   1470   OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
   1471 
   1472   OS << "#include \"llvm/Support/Debug.h\"\n";
   1473   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
   1474   ParseFeaturesFunction(OS, NumFeatures, NumProcs);
   1475 
   1476   OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
   1477 
   1478   // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
   1479   OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
   1480   OS << "#undef GET_SUBTARGETINFO_HEADER\n";
   1481 
   1482   std::string ClassName = Target + "GenSubtargetInfo";
   1483   OS << "namespace llvm {\n";
   1484   OS << "class DFAPacketizer;\n";
   1485   OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
   1486      << "  explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
   1487      << "StringRef FS);\n"
   1488      << "public:\n"
   1489      << "  unsigned resolveSchedClass(unsigned SchedClass, "
   1490      << " const MachineInstr *DefMI,"
   1491      << " const TargetSchedModel *SchedModel) const override;\n"
   1492      << "  DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
   1493      << " const;\n"
   1494      << "};\n";
   1495   OS << "} // end llvm namespace\n";
   1496 
   1497   OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
   1498 
   1499   OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
   1500   OS << "#undef GET_SUBTARGETINFO_CTOR\n";
   1501 
   1502   OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n";
   1503   OS << "namespace llvm {\n";
   1504   OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
   1505   OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n";
   1506   OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcSchedKV[];\n";
   1507   OS << "extern const llvm::MCWriteProcResEntry "
   1508      << Target << "WriteProcResTable[];\n";
   1509   OS << "extern const llvm::MCWriteLatencyEntry "
   1510      << Target << "WriteLatencyTable[];\n";
   1511   OS << "extern const llvm::MCReadAdvanceEntry "
   1512      << Target << "ReadAdvanceTable[];\n";
   1513 
   1514   if (SchedModels.hasItineraries()) {
   1515     OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
   1516     OS << "extern const unsigned " << Target << "OperandCycles[];\n";
   1517     OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
   1518   }
   1519 
   1520   OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, "
   1521      << "StringRef FS)\n"
   1522      << "  : TargetSubtargetInfo(TT, CPU, FS, ";
   1523   if (NumFeatures)
   1524     OS << "makeArrayRef(" << Target << "FeatureKV, " << NumFeatures << "), ";
   1525   else
   1526     OS << "None, ";
   1527   if (NumProcs)
   1528     OS << "makeArrayRef(" << Target << "SubTypeKV, " << NumProcs << "), ";
   1529   else
   1530     OS << "None, ";
   1531   OS << '\n'; OS.indent(24);
   1532   OS << Target << "ProcSchedKV, "
   1533      << Target << "WriteProcResTable, "
   1534      << Target << "WriteLatencyTable, "
   1535      << Target << "ReadAdvanceTable, ";
   1536   OS << '\n'; OS.indent(24);
   1537   if (SchedModels.hasItineraries()) {
   1538     OS << Target << "Stages, "
   1539        << Target << "OperandCycles, "
   1540        << Target << "ForwardingPaths";
   1541   } else
   1542     OS << "0, 0, 0";
   1543   OS << ") {}\n\n";
   1544 
   1545   EmitSchedModelHelpers(ClassName, OS);
   1546 
   1547   OS << "} // end llvm namespace\n";
   1548 
   1549   OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
   1550 }
   1551 
   1552 namespace llvm {
   1553 
   1554 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) {
   1555   CodeGenTarget CGTarget(RK);
   1556   SubtargetEmitter(RK, CGTarget).run(OS);
   1557 }
   1558 
   1559 } // end llvm namespace
   1560