1//===- CodeGenSchedule.h - Scheduling Machine Models ------------*- 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 file defines structures to encapsulate the machine model as decribed in 11// the target description. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef CODEGEN_SCHEDULE_H 16#define CODEGEN_SCHEDULE_H 17 18#include "llvm/TableGen/Record.h" 19#include "llvm/Support/ErrorHandling.h" 20#include "llvm/ADT/DenseMap.h" 21#include "llvm/ADT/StringMap.h" 22 23namespace llvm { 24 25class CodeGenTarget; 26 27// Scheduling class. 28// 29// Each instruction description will be mapped to a scheduling class. It may be 30// an explicitly defined itinerary class, or an inferred class in which case 31// ItinClassDef == NULL. 32struct CodeGenSchedClass { 33 std::string Name; 34 unsigned Index; 35 Record *ItinClassDef; 36 37 CodeGenSchedClass(): Index(0), ItinClassDef(0) {} 38 CodeGenSchedClass(Record *rec): Index(0), ItinClassDef(rec) { 39 Name = rec->getName(); 40 } 41}; 42 43// Processor model. 44// 45// ModelName is a unique name used to name an instantiation of MCSchedModel. 46// 47// ModelDef is NULL for inferred Models. This happens when a processor defines 48// an itinerary but no machine model. If the processer defines neither a machine 49// model nor itinerary, then ModelDef remains pointing to NoModel. NoModel has 50// the special "NoModel" field set to true. 51// 52// ItinsDef always points to a valid record definition, but may point to the 53// default NoItineraries. NoItineraries has an empty list of InstrItinData 54// records. 55// 56// ItinDefList orders this processor's InstrItinData records by SchedClass idx. 57struct CodeGenProcModel { 58 std::string ModelName; 59 Record *ModelDef; 60 Record *ItinsDef; 61 62 // Array of InstrItinData records indexed by CodeGenSchedClass::Index. 63 // The list is empty if the subtarget has no itineraries. 64 std::vector<Record *> ItinDefList; 65 66 CodeGenProcModel(const std::string &Name, Record *MDef, Record *IDef): 67 ModelName(Name), ModelDef(MDef), ItinsDef(IDef) {} 68}; 69 70// Top level container for machine model data. 71class CodeGenSchedModels { 72 RecordKeeper &Records; 73 const CodeGenTarget &Target; 74 75 // List of unique SchedClasses. 76 std::vector<CodeGenSchedClass> SchedClasses; 77 78 // Map SchedClass name to itinerary index. 79 // These are either explicit itinerary classes or inferred classes. 80 StringMap<unsigned> SchedClassIdxMap; 81 82 // SchedClass indices 1 up to and including NumItineraryClasses identify 83 // itinerary classes that are explicitly used for this target's instruction 84 // definitions. NoItinerary always has index 0 regardless of whether it is 85 // explicitly referenced. 86 // 87 // Any inferred SchedClass have a index greater than NumItineraryClasses. 88 unsigned NumItineraryClasses; 89 90 // List of unique processor models. 91 std::vector<CodeGenProcModel> ProcModels; 92 93 // Map Processor's MachineModel + ProcItin fields to a CodeGenProcModel index. 94 typedef DenseMap<std::pair<Record*, Record*>, unsigned> ProcModelMapTy; 95 ProcModelMapTy ProcModelMap; 96 97 // True if any processors have nonempty itineraries. 98 bool HasProcItineraries; 99 100public: 101 CodeGenSchedModels(RecordKeeper& RK, const CodeGenTarget &TGT); 102 103 // Check if any instructions are assigned to an explicit itinerary class other 104 // than NoItinerary. 105 bool hasItineraryClasses() const { return NumItineraryClasses > 0; } 106 107 // Return the number of itinerary classes in use by this target's instruction 108 // descriptions, not including "NoItinerary". 109 unsigned numItineraryClasses() const { 110 return NumItineraryClasses; 111 } 112 113 // Get a SchedClass from its index. 114 const CodeGenSchedClass &getSchedClass(unsigned Idx) { 115 assert(Idx < SchedClasses.size() && "bad SchedClass index"); 116 return SchedClasses[Idx]; 117 } 118 119 // Get an itinerary class's index. Value indices are '0' for NoItinerary up to 120 // and including numItineraryClasses(). 121 unsigned getItinClassIdx(Record *ItinDef) const { 122 assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass"); 123 unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName()); 124 assert(Idx <= NumItineraryClasses && "bad ItinClass index"); 125 return Idx; 126 } 127 128 bool hasProcessorItineraries() const { 129 return HasProcItineraries; 130 } 131 132 // Get an existing machine model for a processor definition. 133 const CodeGenProcModel &getProcModel(Record *ProcDef) const { 134 unsigned idx = getProcModelIdx(ProcDef); 135 assert(idx < ProcModels.size() && "missing machine model"); 136 return ProcModels[idx]; 137 } 138 139 // Iterate over the unique processor models. 140 typedef std::vector<CodeGenProcModel>::const_iterator ProcIter; 141 ProcIter procModelBegin() const { return ProcModels.begin(); } 142 ProcIter procModelEnd() const { return ProcModels.end(); } 143 144private: 145 // Get a key that can uniquely identify a machine model. 146 ProcModelMapTy::key_type getProcModelKey(Record *ProcDef) const { 147 Record *ModelDef = ProcDef->getValueAsDef("SchedModel"); 148 Record *ItinsDef = ProcDef->getValueAsDef("ProcItin"); 149 return std::make_pair(ModelDef, ItinsDef); 150 } 151 152 // Get the unique index of a machine model. 153 unsigned getProcModelIdx(Record *ProcDef) const { 154 ProcModelMapTy::const_iterator I = 155 ProcModelMap.find(getProcModelKey(ProcDef)); 156 if (I == ProcModelMap.end()) 157 return ProcModels.size(); 158 return I->second; 159 } 160 161 // Initialize a new processor model if it is unique. 162 void addProcModel(Record *ProcDef); 163 164 void CollectSchedClasses(); 165 void CollectProcModels(); 166 void CollectProcItin(CodeGenProcModel &ProcModel, 167 std::vector<Record*> ItinRecords); 168}; 169 170} // namespace llvm 171 172#endif 173