1*9880d681SAndroid Build Coastguard Worker //===- CodeGenSchedule.h - Scheduling Machine Models ------------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file defines structures to encapsulate the machine model as described in 11*9880d681SAndroid Build Coastguard Worker // the target description. 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_UTILS_TABLEGEN_CODEGENSCHEDULE_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_UTILS_TABLEGEN_CODEGENSCHEDULE_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/Record.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/TableGen/SetTheory.h" 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker namespace llvm { 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker class CodeGenTarget; 27*9880d681SAndroid Build Coastguard Worker class CodeGenSchedModels; 28*9880d681SAndroid Build Coastguard Worker class CodeGenInstruction; 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker typedef std::vector<Record*> RecVec; 31*9880d681SAndroid Build Coastguard Worker typedef std::vector<Record*>::const_iterator RecIter; 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker typedef std::vector<unsigned> IdxVec; 34*9880d681SAndroid Build Coastguard Worker typedef std::vector<unsigned>::const_iterator IdxIter; 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker void splitSchedReadWrites(const RecVec &RWDefs, 37*9880d681SAndroid Build Coastguard Worker RecVec &WriteDefs, RecVec &ReadDefs); 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker /// We have two kinds of SchedReadWrites. Explicitly defined and inferred 40*9880d681SAndroid Build Coastguard Worker /// sequences. TheDef is nonnull for explicit SchedWrites, but Sequence may or 41*9880d681SAndroid Build Coastguard Worker /// may not be empty. TheDef is null for inferred sequences, and Sequence must 42*9880d681SAndroid Build Coastguard Worker /// be nonempty. 43*9880d681SAndroid Build Coastguard Worker /// 44*9880d681SAndroid Build Coastguard Worker /// IsVariadic controls whether the variants are expanded into multiple operands 45*9880d681SAndroid Build Coastguard Worker /// or a sequence of writes on one operand. 46*9880d681SAndroid Build Coastguard Worker struct CodeGenSchedRW { 47*9880d681SAndroid Build Coastguard Worker unsigned Index; 48*9880d681SAndroid Build Coastguard Worker std::string Name; 49*9880d681SAndroid Build Coastguard Worker Record *TheDef; 50*9880d681SAndroid Build Coastguard Worker bool IsRead; 51*9880d681SAndroid Build Coastguard Worker bool IsAlias; 52*9880d681SAndroid Build Coastguard Worker bool HasVariants; 53*9880d681SAndroid Build Coastguard Worker bool IsVariadic; 54*9880d681SAndroid Build Coastguard Worker bool IsSequence; 55*9880d681SAndroid Build Coastguard Worker IdxVec Sequence; 56*9880d681SAndroid Build Coastguard Worker RecVec Aliases; 57*9880d681SAndroid Build Coastguard Worker CodeGenSchedRWCodeGenSchedRW58*9880d681SAndroid Build Coastguard Worker CodeGenSchedRW() 59*9880d681SAndroid Build Coastguard Worker : Index(0), TheDef(nullptr), IsRead(false), IsAlias(false), 60*9880d681SAndroid Build Coastguard Worker HasVariants(false), IsVariadic(false), IsSequence(false) {} CodeGenSchedRWCodeGenSchedRW61*9880d681SAndroid Build Coastguard Worker CodeGenSchedRW(unsigned Idx, Record *Def) 62*9880d681SAndroid Build Coastguard Worker : Index(Idx), TheDef(Def), IsAlias(false), IsVariadic(false) { 63*9880d681SAndroid Build Coastguard Worker Name = Def->getName(); 64*9880d681SAndroid Build Coastguard Worker IsRead = Def->isSubClassOf("SchedRead"); 65*9880d681SAndroid Build Coastguard Worker HasVariants = Def->isSubClassOf("SchedVariant"); 66*9880d681SAndroid Build Coastguard Worker if (HasVariants) 67*9880d681SAndroid Build Coastguard Worker IsVariadic = Def->getValueAsBit("Variadic"); 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker // Read records don't currently have sequences, but it can be easily 70*9880d681SAndroid Build Coastguard Worker // added. Note that implicit Reads (from ReadVariant) may have a Sequence 71*9880d681SAndroid Build Coastguard Worker // (but no record). 72*9880d681SAndroid Build Coastguard Worker IsSequence = Def->isSubClassOf("WriteSequence"); 73*9880d681SAndroid Build Coastguard Worker } 74*9880d681SAndroid Build Coastguard Worker CodeGenSchedRWCodeGenSchedRW75*9880d681SAndroid Build Coastguard Worker CodeGenSchedRW(unsigned Idx, bool Read, ArrayRef<unsigned> Seq, 76*9880d681SAndroid Build Coastguard Worker const std::string &Name) 77*9880d681SAndroid Build Coastguard Worker : Index(Idx), Name(Name), TheDef(nullptr), IsRead(Read), IsAlias(false), 78*9880d681SAndroid Build Coastguard Worker HasVariants(false), IsVariadic(false), IsSequence(true), Sequence(Seq) { 79*9880d681SAndroid Build Coastguard Worker assert(Sequence.size() > 1 && "implied sequence needs >1 RWs"); 80*9880d681SAndroid Build Coastguard Worker } 81*9880d681SAndroid Build Coastguard Worker isValidCodeGenSchedRW82*9880d681SAndroid Build Coastguard Worker bool isValid() const { 83*9880d681SAndroid Build Coastguard Worker assert((!HasVariants || TheDef) && "Variant write needs record def"); 84*9880d681SAndroid Build Coastguard Worker assert((!IsVariadic || HasVariants) && "Variadic write needs variants"); 85*9880d681SAndroid Build Coastguard Worker assert((!IsSequence || !HasVariants) && "Sequence can't have variant"); 86*9880d681SAndroid Build Coastguard Worker assert((!IsSequence || !Sequence.empty()) && "Sequence should be nonempty"); 87*9880d681SAndroid Build Coastguard Worker assert((!IsAlias || Aliases.empty()) && "Alias cannot have aliases"); 88*9880d681SAndroid Build Coastguard Worker return TheDef || !Sequence.empty(); 89*9880d681SAndroid Build Coastguard Worker } 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG 92*9880d681SAndroid Build Coastguard Worker void dump() const; 93*9880d681SAndroid Build Coastguard Worker #endif 94*9880d681SAndroid Build Coastguard Worker }; 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker /// Represent a transition between SchedClasses induced by SchedVariant. 97*9880d681SAndroid Build Coastguard Worker struct CodeGenSchedTransition { 98*9880d681SAndroid Build Coastguard Worker unsigned ToClassIdx; 99*9880d681SAndroid Build Coastguard Worker IdxVec ProcIndices; 100*9880d681SAndroid Build Coastguard Worker RecVec PredTerm; 101*9880d681SAndroid Build Coastguard Worker }; 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker /// Scheduling class. 104*9880d681SAndroid Build Coastguard Worker /// 105*9880d681SAndroid Build Coastguard Worker /// Each instruction description will be mapped to a scheduling class. There are 106*9880d681SAndroid Build Coastguard Worker /// four types of classes: 107*9880d681SAndroid Build Coastguard Worker /// 108*9880d681SAndroid Build Coastguard Worker /// 1) An explicitly defined itinerary class with ItinClassDef set. 109*9880d681SAndroid Build Coastguard Worker /// Writes and ReadDefs are empty. ProcIndices contains 0 for any processor. 110*9880d681SAndroid Build Coastguard Worker /// 111*9880d681SAndroid Build Coastguard Worker /// 2) An implied class with a list of SchedWrites and SchedReads that are 112*9880d681SAndroid Build Coastguard Worker /// defined in an instruction definition and which are common across all 113*9880d681SAndroid Build Coastguard Worker /// subtargets. ProcIndices contains 0 for any processor. 114*9880d681SAndroid Build Coastguard Worker /// 115*9880d681SAndroid Build Coastguard Worker /// 3) An implied class with a list of InstRW records that map instructions to 116*9880d681SAndroid Build Coastguard Worker /// SchedWrites and SchedReads per-processor. InstrClassMap should map the same 117*9880d681SAndroid Build Coastguard Worker /// instructions to this class. ProcIndices contains all the processors that 118*9880d681SAndroid Build Coastguard Worker /// provided InstrRW records for this class. ItinClassDef or Writes/Reads may 119*9880d681SAndroid Build Coastguard Worker /// still be defined for processors with no InstRW entry. 120*9880d681SAndroid Build Coastguard Worker /// 121*9880d681SAndroid Build Coastguard Worker /// 4) An inferred class represents a variant of another class that may be 122*9880d681SAndroid Build Coastguard Worker /// resolved at runtime. ProcIndices contains the set of processors that may 123*9880d681SAndroid Build Coastguard Worker /// require the class. ProcIndices are propagated through SchedClasses as 124*9880d681SAndroid Build Coastguard Worker /// variants are expanded. Multiple SchedClasses may be inferred from an 125*9880d681SAndroid Build Coastguard Worker /// itinerary class. Each inherits the processor index from the ItinRW record 126*9880d681SAndroid Build Coastguard Worker /// that mapped the itinerary class to the variant Writes or Reads. 127*9880d681SAndroid Build Coastguard Worker struct CodeGenSchedClass { 128*9880d681SAndroid Build Coastguard Worker unsigned Index; 129*9880d681SAndroid Build Coastguard Worker std::string Name; 130*9880d681SAndroid Build Coastguard Worker Record *ItinClassDef; 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker IdxVec Writes; 133*9880d681SAndroid Build Coastguard Worker IdxVec Reads; 134*9880d681SAndroid Build Coastguard Worker // Sorted list of ProcIdx, where ProcIdx==0 implies any processor. 135*9880d681SAndroid Build Coastguard Worker IdxVec ProcIndices; 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker std::vector<CodeGenSchedTransition> Transitions; 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker // InstRW records associated with this class. These records may refer to an 140*9880d681SAndroid Build Coastguard Worker // Instruction no longer mapped to this class by InstrClassMap. These 141*9880d681SAndroid Build Coastguard Worker // Instructions should be ignored by this class because they have been split 142*9880d681SAndroid Build Coastguard Worker // off to join another inferred class. 143*9880d681SAndroid Build Coastguard Worker RecVec InstRWs; 144*9880d681SAndroid Build Coastguard Worker CodeGenSchedClassCodeGenSchedClass145*9880d681SAndroid Build Coastguard Worker CodeGenSchedClass(): Index(0), ItinClassDef(nullptr) {} 146*9880d681SAndroid Build Coastguard Worker isKeyEqualCodeGenSchedClass147*9880d681SAndroid Build Coastguard Worker bool isKeyEqual(Record *IC, ArrayRef<unsigned> W, ArrayRef<unsigned> R) { 148*9880d681SAndroid Build Coastguard Worker return ItinClassDef == IC && makeArrayRef(Writes) == W && 149*9880d681SAndroid Build Coastguard Worker makeArrayRef(Reads) == R; 150*9880d681SAndroid Build Coastguard Worker } 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker // Is this class generated from a variants if existing classes? Instructions 153*9880d681SAndroid Build Coastguard Worker // are never mapped directly to inferred scheduling classes. isInferredCodeGenSchedClass154*9880d681SAndroid Build Coastguard Worker bool isInferred() const { return !ItinClassDef; } 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG 157*9880d681SAndroid Build Coastguard Worker void dump(const CodeGenSchedModels *SchedModels) const; 158*9880d681SAndroid Build Coastguard Worker #endif 159*9880d681SAndroid Build Coastguard Worker }; 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker // Processor model. 162*9880d681SAndroid Build Coastguard Worker // 163*9880d681SAndroid Build Coastguard Worker // ModelName is a unique name used to name an instantiation of MCSchedModel. 164*9880d681SAndroid Build Coastguard Worker // 165*9880d681SAndroid Build Coastguard Worker // ModelDef is NULL for inferred Models. This happens when a processor defines 166*9880d681SAndroid Build Coastguard Worker // an itinerary but no machine model. If the processor defines neither a machine 167*9880d681SAndroid Build Coastguard Worker // model nor itinerary, then ModelDef remains pointing to NoModel. NoModel has 168*9880d681SAndroid Build Coastguard Worker // the special "NoModel" field set to true. 169*9880d681SAndroid Build Coastguard Worker // 170*9880d681SAndroid Build Coastguard Worker // ItinsDef always points to a valid record definition, but may point to the 171*9880d681SAndroid Build Coastguard Worker // default NoItineraries. NoItineraries has an empty list of InstrItinData 172*9880d681SAndroid Build Coastguard Worker // records. 173*9880d681SAndroid Build Coastguard Worker // 174*9880d681SAndroid Build Coastguard Worker // ItinDefList orders this processor's InstrItinData records by SchedClass idx. 175*9880d681SAndroid Build Coastguard Worker struct CodeGenProcModel { 176*9880d681SAndroid Build Coastguard Worker unsigned Index; 177*9880d681SAndroid Build Coastguard Worker std::string ModelName; 178*9880d681SAndroid Build Coastguard Worker Record *ModelDef; 179*9880d681SAndroid Build Coastguard Worker Record *ItinsDef; 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Worker // Derived members... 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker // Array of InstrItinData records indexed by a CodeGenSchedClass index. 184*9880d681SAndroid Build Coastguard Worker // This list is empty if the Processor has no value for Itineraries. 185*9880d681SAndroid Build Coastguard Worker // Initialized by collectProcItins(). 186*9880d681SAndroid Build Coastguard Worker RecVec ItinDefList; 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker // Map itinerary classes to per-operand resources. 189*9880d681SAndroid Build Coastguard Worker // This list is empty if no ItinRW refers to this Processor. 190*9880d681SAndroid Build Coastguard Worker RecVec ItinRWDefs; 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Worker // List of unsupported feature. 193*9880d681SAndroid Build Coastguard Worker // This list is empty if the Processor has no UnsupportedFeatures. 194*9880d681SAndroid Build Coastguard Worker RecVec UnsupportedFeaturesDefs; 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Worker // All read/write resources associated with this processor. 197*9880d681SAndroid Build Coastguard Worker RecVec WriteResDefs; 198*9880d681SAndroid Build Coastguard Worker RecVec ReadAdvanceDefs; 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker // Per-operand machine model resources associated with this processor. 201*9880d681SAndroid Build Coastguard Worker RecVec ProcResourceDefs; 202*9880d681SAndroid Build Coastguard Worker RecVec ProcResGroupDefs; 203*9880d681SAndroid Build Coastguard Worker CodeGenProcModelCodeGenProcModel204*9880d681SAndroid Build Coastguard Worker CodeGenProcModel(unsigned Idx, const std::string &Name, Record *MDef, 205*9880d681SAndroid Build Coastguard Worker Record *IDef) : 206*9880d681SAndroid Build Coastguard Worker Index(Idx), ModelName(Name), ModelDef(MDef), ItinsDef(IDef) {} 207*9880d681SAndroid Build Coastguard Worker hasItinerariesCodeGenProcModel208*9880d681SAndroid Build Coastguard Worker bool hasItineraries() const { 209*9880d681SAndroid Build Coastguard Worker return !ItinsDef->getValueAsListOfDefs("IID").empty(); 210*9880d681SAndroid Build Coastguard Worker } 211*9880d681SAndroid Build Coastguard Worker hasInstrSchedModelCodeGenProcModel212*9880d681SAndroid Build Coastguard Worker bool hasInstrSchedModel() const { 213*9880d681SAndroid Build Coastguard Worker return !WriteResDefs.empty() || !ItinRWDefs.empty(); 214*9880d681SAndroid Build Coastguard Worker } 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Worker unsigned getProcResourceIdx(Record *PRDef) const; 217*9880d681SAndroid Build Coastguard Worker 218*9880d681SAndroid Build Coastguard Worker bool isUnsupported(const CodeGenInstruction &Inst) const; 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG 221*9880d681SAndroid Build Coastguard Worker void dump() const; 222*9880d681SAndroid Build Coastguard Worker #endif 223*9880d681SAndroid Build Coastguard Worker }; 224*9880d681SAndroid Build Coastguard Worker 225*9880d681SAndroid Build Coastguard Worker /// Top level container for machine model data. 226*9880d681SAndroid Build Coastguard Worker class CodeGenSchedModels { 227*9880d681SAndroid Build Coastguard Worker RecordKeeper &Records; 228*9880d681SAndroid Build Coastguard Worker const CodeGenTarget &Target; 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Worker // Map dag expressions to Instruction lists. 231*9880d681SAndroid Build Coastguard Worker SetTheory Sets; 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Worker // List of unique processor models. 234*9880d681SAndroid Build Coastguard Worker std::vector<CodeGenProcModel> ProcModels; 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Worker // Map Processor's MachineModel or ProcItin to a CodeGenProcModel index. 237*9880d681SAndroid Build Coastguard Worker typedef DenseMap<Record*, unsigned> ProcModelMapTy; 238*9880d681SAndroid Build Coastguard Worker ProcModelMapTy ProcModelMap; 239*9880d681SAndroid Build Coastguard Worker 240*9880d681SAndroid Build Coastguard Worker // Per-operand SchedReadWrite types. 241*9880d681SAndroid Build Coastguard Worker std::vector<CodeGenSchedRW> SchedWrites; 242*9880d681SAndroid Build Coastguard Worker std::vector<CodeGenSchedRW> SchedReads; 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Worker // List of unique SchedClasses. 245*9880d681SAndroid Build Coastguard Worker std::vector<CodeGenSchedClass> SchedClasses; 246*9880d681SAndroid Build Coastguard Worker 247*9880d681SAndroid Build Coastguard Worker // Any inferred SchedClass has an index greater than NumInstrSchedClassses. 248*9880d681SAndroid Build Coastguard Worker unsigned NumInstrSchedClasses; 249*9880d681SAndroid Build Coastguard Worker 250*9880d681SAndroid Build Coastguard Worker RecVec ProcResourceDefs; 251*9880d681SAndroid Build Coastguard Worker RecVec ProcResGroups; 252*9880d681SAndroid Build Coastguard Worker 253*9880d681SAndroid Build Coastguard Worker // Map each instruction to its unique SchedClass index considering the 254*9880d681SAndroid Build Coastguard Worker // combination of it's itinerary class, SchedRW list, and InstRW records. 255*9880d681SAndroid Build Coastguard Worker typedef DenseMap<Record*, unsigned> InstClassMapTy; 256*9880d681SAndroid Build Coastguard Worker InstClassMapTy InstrClassMap; 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Worker public: 259*9880d681SAndroid Build Coastguard Worker CodeGenSchedModels(RecordKeeper& RK, const CodeGenTarget &TGT); 260*9880d681SAndroid Build Coastguard Worker 261*9880d681SAndroid Build Coastguard Worker // iterator access to the scheduling classes. 262*9880d681SAndroid Build Coastguard Worker typedef std::vector<CodeGenSchedClass>::iterator class_iterator; 263*9880d681SAndroid Build Coastguard Worker typedef std::vector<CodeGenSchedClass>::const_iterator const_class_iterator; classes_begin()264*9880d681SAndroid Build Coastguard Worker class_iterator classes_begin() { return SchedClasses.begin(); } classes_begin()265*9880d681SAndroid Build Coastguard Worker const_class_iterator classes_begin() const { return SchedClasses.begin(); } classes_end()266*9880d681SAndroid Build Coastguard Worker class_iterator classes_end() { return SchedClasses.end(); } classes_end()267*9880d681SAndroid Build Coastguard Worker const_class_iterator classes_end() const { return SchedClasses.end(); } classes()268*9880d681SAndroid Build Coastguard Worker iterator_range<class_iterator> classes() { 269*9880d681SAndroid Build Coastguard Worker return make_range(classes_begin(), classes_end()); 270*9880d681SAndroid Build Coastguard Worker } classes()271*9880d681SAndroid Build Coastguard Worker iterator_range<const_class_iterator> classes() const { 272*9880d681SAndroid Build Coastguard Worker return make_range(classes_begin(), classes_end()); 273*9880d681SAndroid Build Coastguard Worker } explicit_classes()274*9880d681SAndroid Build Coastguard Worker iterator_range<class_iterator> explicit_classes() { 275*9880d681SAndroid Build Coastguard Worker return make_range(classes_begin(), classes_begin() + NumInstrSchedClasses); 276*9880d681SAndroid Build Coastguard Worker } explicit_classes()277*9880d681SAndroid Build Coastguard Worker iterator_range<const_class_iterator> explicit_classes() const { 278*9880d681SAndroid Build Coastguard Worker return make_range(classes_begin(), classes_begin() + NumInstrSchedClasses); 279*9880d681SAndroid Build Coastguard Worker } 280*9880d681SAndroid Build Coastguard Worker getModelOrItinDef(Record * ProcDef)281*9880d681SAndroid Build Coastguard Worker Record *getModelOrItinDef(Record *ProcDef) const { 282*9880d681SAndroid Build Coastguard Worker Record *ModelDef = ProcDef->getValueAsDef("SchedModel"); 283*9880d681SAndroid Build Coastguard Worker Record *ItinsDef = ProcDef->getValueAsDef("ProcItin"); 284*9880d681SAndroid Build Coastguard Worker if (!ItinsDef->getValueAsListOfDefs("IID").empty()) { 285*9880d681SAndroid Build Coastguard Worker assert(ModelDef->getValueAsBit("NoModel") 286*9880d681SAndroid Build Coastguard Worker && "Itineraries must be defined within SchedMachineModel"); 287*9880d681SAndroid Build Coastguard Worker return ItinsDef; 288*9880d681SAndroid Build Coastguard Worker } 289*9880d681SAndroid Build Coastguard Worker return ModelDef; 290*9880d681SAndroid Build Coastguard Worker } 291*9880d681SAndroid Build Coastguard Worker getModelForProc(Record * ProcDef)292*9880d681SAndroid Build Coastguard Worker const CodeGenProcModel &getModelForProc(Record *ProcDef) const { 293*9880d681SAndroid Build Coastguard Worker Record *ModelDef = getModelOrItinDef(ProcDef); 294*9880d681SAndroid Build Coastguard Worker ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef); 295*9880d681SAndroid Build Coastguard Worker assert(I != ProcModelMap.end() && "missing machine model"); 296*9880d681SAndroid Build Coastguard Worker return ProcModels[I->second]; 297*9880d681SAndroid Build Coastguard Worker } 298*9880d681SAndroid Build Coastguard Worker getProcModel(Record * ModelDef)299*9880d681SAndroid Build Coastguard Worker CodeGenProcModel &getProcModel(Record *ModelDef) { 300*9880d681SAndroid Build Coastguard Worker ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef); 301*9880d681SAndroid Build Coastguard Worker assert(I != ProcModelMap.end() && "missing machine model"); 302*9880d681SAndroid Build Coastguard Worker return ProcModels[I->second]; 303*9880d681SAndroid Build Coastguard Worker } getProcModel(Record * ModelDef)304*9880d681SAndroid Build Coastguard Worker const CodeGenProcModel &getProcModel(Record *ModelDef) const { 305*9880d681SAndroid Build Coastguard Worker return const_cast<CodeGenSchedModels*>(this)->getProcModel(ModelDef); 306*9880d681SAndroid Build Coastguard Worker } 307*9880d681SAndroid Build Coastguard Worker 308*9880d681SAndroid Build Coastguard Worker // Iterate over the unique processor models. 309*9880d681SAndroid Build Coastguard Worker typedef std::vector<CodeGenProcModel>::const_iterator ProcIter; procModelBegin()310*9880d681SAndroid Build Coastguard Worker ProcIter procModelBegin() const { return ProcModels.begin(); } procModelEnd()311*9880d681SAndroid Build Coastguard Worker ProcIter procModelEnd() const { return ProcModels.end(); } procModels()312*9880d681SAndroid Build Coastguard Worker ArrayRef<CodeGenProcModel> procModels() const { return ProcModels; } 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Worker // Return true if any processors have itineraries. 315*9880d681SAndroid Build Coastguard Worker bool hasItineraries() const; 316*9880d681SAndroid Build Coastguard Worker 317*9880d681SAndroid Build Coastguard Worker // Get a SchedWrite from its index. getSchedWrite(unsigned Idx)318*9880d681SAndroid Build Coastguard Worker const CodeGenSchedRW &getSchedWrite(unsigned Idx) const { 319*9880d681SAndroid Build Coastguard Worker assert(Idx < SchedWrites.size() && "bad SchedWrite index"); 320*9880d681SAndroid Build Coastguard Worker assert(SchedWrites[Idx].isValid() && "invalid SchedWrite"); 321*9880d681SAndroid Build Coastguard Worker return SchedWrites[Idx]; 322*9880d681SAndroid Build Coastguard Worker } 323*9880d681SAndroid Build Coastguard Worker // Get a SchedWrite from its index. getSchedRead(unsigned Idx)324*9880d681SAndroid Build Coastguard Worker const CodeGenSchedRW &getSchedRead(unsigned Idx) const { 325*9880d681SAndroid Build Coastguard Worker assert(Idx < SchedReads.size() && "bad SchedRead index"); 326*9880d681SAndroid Build Coastguard Worker assert(SchedReads[Idx].isValid() && "invalid SchedRead"); 327*9880d681SAndroid Build Coastguard Worker return SchedReads[Idx]; 328*9880d681SAndroid Build Coastguard Worker } 329*9880d681SAndroid Build Coastguard Worker getSchedRW(unsigned Idx,bool IsRead)330*9880d681SAndroid Build Coastguard Worker const CodeGenSchedRW &getSchedRW(unsigned Idx, bool IsRead) const { 331*9880d681SAndroid Build Coastguard Worker return IsRead ? getSchedRead(Idx) : getSchedWrite(Idx); 332*9880d681SAndroid Build Coastguard Worker } getSchedRW(Record * Def)333*9880d681SAndroid Build Coastguard Worker CodeGenSchedRW &getSchedRW(Record *Def) { 334*9880d681SAndroid Build Coastguard Worker bool IsRead = Def->isSubClassOf("SchedRead"); 335*9880d681SAndroid Build Coastguard Worker unsigned Idx = getSchedRWIdx(Def, IsRead); 336*9880d681SAndroid Build Coastguard Worker return const_cast<CodeGenSchedRW&>( 337*9880d681SAndroid Build Coastguard Worker IsRead ? getSchedRead(Idx) : getSchedWrite(Idx)); 338*9880d681SAndroid Build Coastguard Worker } getSchedRW(Record * Def)339*9880d681SAndroid Build Coastguard Worker const CodeGenSchedRW &getSchedRW(Record*Def) const { 340*9880d681SAndroid Build Coastguard Worker return const_cast<CodeGenSchedModels&>(*this).getSchedRW(Def); 341*9880d681SAndroid Build Coastguard Worker } 342*9880d681SAndroid Build Coastguard Worker 343*9880d681SAndroid Build Coastguard Worker unsigned getSchedRWIdx(Record *Def, bool IsRead, unsigned After = 0) const; 344*9880d681SAndroid Build Coastguard Worker 345*9880d681SAndroid Build Coastguard Worker // Return true if the given write record is referenced by a ReadAdvance. 346*9880d681SAndroid Build Coastguard Worker bool hasReadOfWrite(Record *WriteDef) const; 347*9880d681SAndroid Build Coastguard Worker 348*9880d681SAndroid Build Coastguard Worker // Get a SchedClass from its index. getSchedClass(unsigned Idx)349*9880d681SAndroid Build Coastguard Worker CodeGenSchedClass &getSchedClass(unsigned Idx) { 350*9880d681SAndroid Build Coastguard Worker assert(Idx < SchedClasses.size() && "bad SchedClass index"); 351*9880d681SAndroid Build Coastguard Worker return SchedClasses[Idx]; 352*9880d681SAndroid Build Coastguard Worker } getSchedClass(unsigned Idx)353*9880d681SAndroid Build Coastguard Worker const CodeGenSchedClass &getSchedClass(unsigned Idx) const { 354*9880d681SAndroid Build Coastguard Worker assert(Idx < SchedClasses.size() && "bad SchedClass index"); 355*9880d681SAndroid Build Coastguard Worker return SchedClasses[Idx]; 356*9880d681SAndroid Build Coastguard Worker } 357*9880d681SAndroid Build Coastguard Worker 358*9880d681SAndroid Build Coastguard Worker // Get the SchedClass index for an instruction. Instructions with no 359*9880d681SAndroid Build Coastguard Worker // itinerary, no SchedReadWrites, and no InstrReadWrites references return 0 360*9880d681SAndroid Build Coastguard Worker // for NoItinerary. 361*9880d681SAndroid Build Coastguard Worker unsigned getSchedClassIdx(const CodeGenInstruction &Inst) const; 362*9880d681SAndroid Build Coastguard Worker 363*9880d681SAndroid Build Coastguard Worker typedef std::vector<CodeGenSchedClass>::const_iterator SchedClassIter; schedClassBegin()364*9880d681SAndroid Build Coastguard Worker SchedClassIter schedClassBegin() const { return SchedClasses.begin(); } schedClassEnd()365*9880d681SAndroid Build Coastguard Worker SchedClassIter schedClassEnd() const { return SchedClasses.end(); } schedClasses()366*9880d681SAndroid Build Coastguard Worker ArrayRef<CodeGenSchedClass> schedClasses() const { return SchedClasses; } 367*9880d681SAndroid Build Coastguard Worker numInstrSchedClasses()368*9880d681SAndroid Build Coastguard Worker unsigned numInstrSchedClasses() const { return NumInstrSchedClasses; } 369*9880d681SAndroid Build Coastguard Worker 370*9880d681SAndroid Build Coastguard Worker void findRWs(const RecVec &RWDefs, IdxVec &Writes, IdxVec &Reads) const; 371*9880d681SAndroid Build Coastguard Worker void findRWs(const RecVec &RWDefs, IdxVec &RWs, bool IsRead) const; 372*9880d681SAndroid Build Coastguard Worker void expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, bool IsRead) const; 373*9880d681SAndroid Build Coastguard Worker void expandRWSeqForProc(unsigned RWIdx, IdxVec &RWSeq, bool IsRead, 374*9880d681SAndroid Build Coastguard Worker const CodeGenProcModel &ProcModel) const; 375*9880d681SAndroid Build Coastguard Worker 376*9880d681SAndroid Build Coastguard Worker unsigned addSchedClass(Record *ItinDef, ArrayRef<unsigned> OperWrites, 377*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> OperReads, 378*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> ProcIndices); 379*9880d681SAndroid Build Coastguard Worker 380*9880d681SAndroid Build Coastguard Worker unsigned findOrInsertRW(ArrayRef<unsigned> Seq, bool IsRead); 381*9880d681SAndroid Build Coastguard Worker 382*9880d681SAndroid Build Coastguard Worker unsigned findSchedClassIdx(Record *ItinClassDef, ArrayRef<unsigned> Writes, 383*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> Reads) const; 384*9880d681SAndroid Build Coastguard Worker 385*9880d681SAndroid Build Coastguard Worker Record *findProcResUnits(Record *ProcResKind, 386*9880d681SAndroid Build Coastguard Worker const CodeGenProcModel &PM) const; 387*9880d681SAndroid Build Coastguard Worker 388*9880d681SAndroid Build Coastguard Worker private: 389*9880d681SAndroid Build Coastguard Worker void collectProcModels(); 390*9880d681SAndroid Build Coastguard Worker 391*9880d681SAndroid Build Coastguard Worker // Initialize a new processor model if it is unique. 392*9880d681SAndroid Build Coastguard Worker void addProcModel(Record *ProcDef); 393*9880d681SAndroid Build Coastguard Worker 394*9880d681SAndroid Build Coastguard Worker void collectSchedRW(); 395*9880d681SAndroid Build Coastguard Worker 396*9880d681SAndroid Build Coastguard Worker std::string genRWName(ArrayRef<unsigned> Seq, bool IsRead); 397*9880d681SAndroid Build Coastguard Worker unsigned findRWForSequence(ArrayRef<unsigned> Seq, bool IsRead); 398*9880d681SAndroid Build Coastguard Worker 399*9880d681SAndroid Build Coastguard Worker void collectSchedClasses(); 400*9880d681SAndroid Build Coastguard Worker 401*9880d681SAndroid Build Coastguard Worker std::string createSchedClassName(Record *ItinClassDef, 402*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> OperWrites, 403*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> OperReads); 404*9880d681SAndroid Build Coastguard Worker std::string createSchedClassName(const RecVec &InstDefs); 405*9880d681SAndroid Build Coastguard Worker void createInstRWClass(Record *InstRWDef); 406*9880d681SAndroid Build Coastguard Worker 407*9880d681SAndroid Build Coastguard Worker void collectProcItins(); 408*9880d681SAndroid Build Coastguard Worker 409*9880d681SAndroid Build Coastguard Worker void collectProcItinRW(); 410*9880d681SAndroid Build Coastguard Worker 411*9880d681SAndroid Build Coastguard Worker void collectProcUnsupportedFeatures(); 412*9880d681SAndroid Build Coastguard Worker 413*9880d681SAndroid Build Coastguard Worker void inferSchedClasses(); 414*9880d681SAndroid Build Coastguard Worker 415*9880d681SAndroid Build Coastguard Worker void checkCompleteness(); 416*9880d681SAndroid Build Coastguard Worker 417*9880d681SAndroid Build Coastguard Worker void inferFromRW(ArrayRef<unsigned> OperWrites, ArrayRef<unsigned> OperReads, 418*9880d681SAndroid Build Coastguard Worker unsigned FromClassIdx, ArrayRef<unsigned> ProcIndices); 419*9880d681SAndroid Build Coastguard Worker void inferFromItinClass(Record *ItinClassDef, unsigned FromClassIdx); 420*9880d681SAndroid Build Coastguard Worker void inferFromInstRWs(unsigned SCIdx); 421*9880d681SAndroid Build Coastguard Worker 422*9880d681SAndroid Build Coastguard Worker bool hasSuperGroup(RecVec &SubUnits, CodeGenProcModel &PM); 423*9880d681SAndroid Build Coastguard Worker void verifyProcResourceGroups(CodeGenProcModel &PM); 424*9880d681SAndroid Build Coastguard Worker 425*9880d681SAndroid Build Coastguard Worker void collectProcResources(); 426*9880d681SAndroid Build Coastguard Worker 427*9880d681SAndroid Build Coastguard Worker void collectItinProcResources(Record *ItinClassDef); 428*9880d681SAndroid Build Coastguard Worker 429*9880d681SAndroid Build Coastguard Worker void collectRWResources(unsigned RWIdx, bool IsRead, 430*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> ProcIndices); 431*9880d681SAndroid Build Coastguard Worker 432*9880d681SAndroid Build Coastguard Worker void collectRWResources(ArrayRef<unsigned> Writes, ArrayRef<unsigned> Reads, 433*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> ProcIndices); 434*9880d681SAndroid Build Coastguard Worker 435*9880d681SAndroid Build Coastguard Worker void addProcResource(Record *ProcResourceKind, CodeGenProcModel &PM); 436*9880d681SAndroid Build Coastguard Worker 437*9880d681SAndroid Build Coastguard Worker void addWriteRes(Record *ProcWriteResDef, unsigned PIdx); 438*9880d681SAndroid Build Coastguard Worker 439*9880d681SAndroid Build Coastguard Worker void addReadAdvance(Record *ProcReadAdvanceDef, unsigned PIdx); 440*9880d681SAndroid Build Coastguard Worker }; 441*9880d681SAndroid Build Coastguard Worker 442*9880d681SAndroid Build Coastguard Worker } // namespace llvm 443*9880d681SAndroid Build Coastguard Worker 444*9880d681SAndroid Build Coastguard Worker #endif 445