1fa3d789dSPierre van Houtryve //===- CodeGenSchedule.h - Scheduling Machine Models ------------*- C++ -*-===// 2fa3d789dSPierre van Houtryve // 3fa3d789dSPierre van Houtryve // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fa3d789dSPierre van Houtryve // See https://llvm.org/LICENSE.txt for license information. 5fa3d789dSPierre van Houtryve // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fa3d789dSPierre van Houtryve // 7fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 8fa3d789dSPierre van Houtryve // 9fa3d789dSPierre van Houtryve // This file defines structures to encapsulate the machine model as described in 10fa3d789dSPierre van Houtryve // the target description. 11fa3d789dSPierre van Houtryve // 12fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 13fa3d789dSPierre van Houtryve 148a61bfcfSRahul Joshi #ifndef LLVM_UTILS_TABLEGEN_COMMON_CODEGENSCHEDULE_H 158a61bfcfSRahul Joshi #define LLVM_UTILS_TABLEGEN_COMMON_CODEGENSCHEDULE_H 16fa3d789dSPierre van Houtryve 17fa3d789dSPierre van Houtryve #include "llvm/ADT/APInt.h" 18fa3d789dSPierre van Houtryve #include "llvm/ADT/ArrayRef.h" 19fa3d789dSPierre van Houtryve #include "llvm/ADT/DenseMap.h" 20fa3d789dSPierre van Houtryve #include "llvm/ADT/DenseSet.h" 21fa3d789dSPierre van Houtryve #include "llvm/ADT/STLExtras.h" 22*e19261faSCraig Topper #include "llvm/ADT/SmallPtrSet.h" 23fa3d789dSPierre van Houtryve #include "llvm/ADT/StringRef.h" 24fa3d789dSPierre van Houtryve #include "llvm/TableGen/Record.h" 25fa3d789dSPierre van Houtryve #include "llvm/TableGen/SetTheory.h" 26fa3d789dSPierre van Houtryve #include <cassert> 27fa3d789dSPierre van Houtryve #include <string> 28fa3d789dSPierre van Houtryve #include <utility> 29fa3d789dSPierre van Houtryve #include <vector> 30fa3d789dSPierre van Houtryve 31fa3d789dSPierre van Houtryve namespace llvm { 32fa3d789dSPierre van Houtryve 33fa3d789dSPierre van Houtryve class CodeGenTarget; 34fa3d789dSPierre van Houtryve class CodeGenSchedModels; 35fa3d789dSPierre van Houtryve class CodeGenInstruction; 36fa3d789dSPierre van Houtryve 3716510149SRahul Joshi using ConstRecVec = std::vector<const Record *>; 3816510149SRahul Joshi using ConstRecIter = ConstRecVec::const_iterator; 39fa3d789dSPierre van Houtryve 40fa3d789dSPierre van Houtryve using IdxVec = std::vector<unsigned>; 4116510149SRahul Joshi using IdxIter = IdxVec::const_iterator; 42fa3d789dSPierre van Houtryve 43fa3d789dSPierre van Houtryve /// We have two kinds of SchedReadWrites. Explicitly defined and inferred 44fa3d789dSPierre van Houtryve /// sequences. TheDef is nonnull for explicit SchedWrites, but Sequence may or 45fa3d789dSPierre van Houtryve /// may not be empty. TheDef is null for inferred sequences, and Sequence must 46fa3d789dSPierre van Houtryve /// be nonempty. 47fa3d789dSPierre van Houtryve /// 48fa3d789dSPierre van Houtryve /// IsVariadic controls whether the variants are expanded into multiple operands 49fa3d789dSPierre van Houtryve /// or a sequence of writes on one operand. 50fa3d789dSPierre van Houtryve struct CodeGenSchedRW { 51fa3d789dSPierre van Houtryve unsigned Index; 52fa3d789dSPierre van Houtryve std::string Name; 533ae71d15SRahul Joshi const Record *TheDef; 54fa3d789dSPierre van Houtryve bool IsRead; 55fa3d789dSPierre van Houtryve bool IsAlias; 56fa3d789dSPierre van Houtryve bool HasVariants; 57fa3d789dSPierre van Houtryve bool IsVariadic; 58fa3d789dSPierre van Houtryve bool IsSequence; 59fa3d789dSPierre van Houtryve IdxVec Sequence; 603ae71d15SRahul Joshi ConstRecVec Aliases; 61fa3d789dSPierre van Houtryve 62fa3d789dSPierre van Houtryve CodeGenSchedRW() 63fa3d789dSPierre van Houtryve : Index(0), TheDef(nullptr), IsRead(false), IsAlias(false), 64fa3d789dSPierre van Houtryve HasVariants(false), IsVariadic(false), IsSequence(false) {} 653ae71d15SRahul Joshi CodeGenSchedRW(unsigned Idx, const Record *Def) 66fa3d789dSPierre van Houtryve : Index(Idx), TheDef(Def), IsAlias(false), IsVariadic(false) { 67fa3d789dSPierre van Houtryve Name = std::string(Def->getName()); 68fa3d789dSPierre van Houtryve IsRead = Def->isSubClassOf("SchedRead"); 69fa3d789dSPierre van Houtryve HasVariants = Def->isSubClassOf("SchedVariant"); 70fa3d789dSPierre van Houtryve if (HasVariants) 71fa3d789dSPierre van Houtryve IsVariadic = Def->getValueAsBit("Variadic"); 72fa3d789dSPierre van Houtryve 73fa3d789dSPierre van Houtryve // Read records don't currently have sequences, but it can be easily 74fa3d789dSPierre van Houtryve // added. Note that implicit Reads (from ReadVariant) may have a Sequence 75fa3d789dSPierre van Houtryve // (but no record). 76fa3d789dSPierre van Houtryve IsSequence = Def->isSubClassOf("WriteSequence"); 77fa3d789dSPierre van Houtryve } 78fa3d789dSPierre van Houtryve 79fa3d789dSPierre van Houtryve CodeGenSchedRW(unsigned Idx, bool Read, ArrayRef<unsigned> Seq, 80fa3d789dSPierre van Houtryve const std::string &Name) 81fa3d789dSPierre van Houtryve : Index(Idx), Name(Name), TheDef(nullptr), IsRead(Read), IsAlias(false), 82fa3d789dSPierre van Houtryve HasVariants(false), IsVariadic(false), IsSequence(true), Sequence(Seq) { 83fa3d789dSPierre van Houtryve assert(Sequence.size() > 1 && "implied sequence needs >1 RWs"); 84fa3d789dSPierre van Houtryve } 85fa3d789dSPierre van Houtryve 86fa3d789dSPierre van Houtryve bool isValid() const { 87fa3d789dSPierre van Houtryve assert((!HasVariants || TheDef) && "Variant write needs record def"); 88fa3d789dSPierre van Houtryve assert((!IsVariadic || HasVariants) && "Variadic write needs variants"); 89fa3d789dSPierre van Houtryve assert((!IsSequence || !HasVariants) && "Sequence can't have variant"); 90fa3d789dSPierre van Houtryve assert((!IsSequence || !Sequence.empty()) && "Sequence should be nonempty"); 91fa3d789dSPierre van Houtryve assert((!IsAlias || Aliases.empty()) && "Alias cannot have aliases"); 92fa3d789dSPierre van Houtryve return TheDef || !Sequence.empty(); 93fa3d789dSPierre van Houtryve } 94fa3d789dSPierre van Houtryve 95fa3d789dSPierre van Houtryve #ifndef NDEBUG 96fa3d789dSPierre van Houtryve void dump() const; 97fa3d789dSPierre van Houtryve #endif 98fa3d789dSPierre van Houtryve }; 99fa3d789dSPierre van Houtryve 100fa3d789dSPierre van Houtryve /// Represent a transition between SchedClasses induced by SchedVariant. 101fa3d789dSPierre van Houtryve struct CodeGenSchedTransition { 102fa3d789dSPierre van Houtryve unsigned ToClassIdx; 103fa3d789dSPierre van Houtryve unsigned ProcIndex; 1043ae71d15SRahul Joshi ConstRecVec PredTerm; 105fa3d789dSPierre van Houtryve }; 106fa3d789dSPierre van Houtryve 107fa3d789dSPierre van Houtryve /// Scheduling class. 108fa3d789dSPierre van Houtryve /// 109fa3d789dSPierre van Houtryve /// Each instruction description will be mapped to a scheduling class. There are 110fa3d789dSPierre van Houtryve /// four types of classes: 111fa3d789dSPierre van Houtryve /// 112fa3d789dSPierre van Houtryve /// 1) An explicitly defined itinerary class with ItinClassDef set. 113fa3d789dSPierre van Houtryve /// Writes and ReadDefs are empty. ProcIndices contains 0 for any processor. 114fa3d789dSPierre van Houtryve /// 115fa3d789dSPierre van Houtryve /// 2) An implied class with a list of SchedWrites and SchedReads that are 116fa3d789dSPierre van Houtryve /// defined in an instruction definition and which are common across all 117fa3d789dSPierre van Houtryve /// subtargets. ProcIndices contains 0 for any processor. 118fa3d789dSPierre van Houtryve /// 119fa3d789dSPierre van Houtryve /// 3) An implied class with a list of InstRW records that map instructions to 120fa3d789dSPierre van Houtryve /// SchedWrites and SchedReads per-processor. InstrClassMap should map the same 121fa3d789dSPierre van Houtryve /// instructions to this class. ProcIndices contains all the processors that 122fa3d789dSPierre van Houtryve /// provided InstrRW records for this class. ItinClassDef or Writes/Reads may 123fa3d789dSPierre van Houtryve /// still be defined for processors with no InstRW entry. 124fa3d789dSPierre van Houtryve /// 125fa3d789dSPierre van Houtryve /// 4) An inferred class represents a variant of another class that may be 126fa3d789dSPierre van Houtryve /// resolved at runtime. ProcIndices contains the set of processors that may 127fa3d789dSPierre van Houtryve /// require the class. ProcIndices are propagated through SchedClasses as 128fa3d789dSPierre van Houtryve /// variants are expanded. Multiple SchedClasses may be inferred from an 129fa3d789dSPierre van Houtryve /// itinerary class. Each inherits the processor index from the ItinRW record 130fa3d789dSPierre van Houtryve /// that mapped the itinerary class to the variant Writes or Reads. 131fa3d789dSPierre van Houtryve struct CodeGenSchedClass { 132fa3d789dSPierre van Houtryve unsigned Index; 133fa3d789dSPierre van Houtryve std::string Name; 134c29dfb33SRahul Joshi const Record *ItinClassDef; 135fa3d789dSPierre van Houtryve 136fa3d789dSPierre van Houtryve IdxVec Writes; 137fa3d789dSPierre van Houtryve IdxVec Reads; 138fa3d789dSPierre van Houtryve // Sorted list of ProcIdx, where ProcIdx==0 implies any processor. 139fa3d789dSPierre van Houtryve IdxVec ProcIndices; 140fa3d789dSPierre van Houtryve 141fa3d789dSPierre van Houtryve std::vector<CodeGenSchedTransition> Transitions; 142fa3d789dSPierre van Houtryve 143fa3d789dSPierre van Houtryve // InstRW records associated with this class. These records may refer to an 144fa3d789dSPierre van Houtryve // Instruction no longer mapped to this class by InstrClassMap. These 145fa3d789dSPierre van Houtryve // Instructions should be ignored by this class because they have been split 146fa3d789dSPierre van Houtryve // off to join another inferred class. 1473ae71d15SRahul Joshi ConstRecVec InstRWs; 148fa3d789dSPierre van Houtryve // InstRWs processor indices. Filled in inferFromInstRWs 149fa3d789dSPierre van Houtryve DenseSet<unsigned> InstRWProcIndices; 150fa3d789dSPierre van Houtryve 151c29dfb33SRahul Joshi CodeGenSchedClass(unsigned Index, std::string Name, 152c29dfb33SRahul Joshi const Record *ItinClassDef) 153fa3d789dSPierre van Houtryve : Index(Index), Name(std::move(Name)), ItinClassDef(ItinClassDef) {} 154fa3d789dSPierre van Houtryve 155c29dfb33SRahul Joshi bool isKeyEqual(const Record *IC, ArrayRef<unsigned> W, 156fa3d789dSPierre van Houtryve ArrayRef<unsigned> R) const { 157fa3d789dSPierre van Houtryve return ItinClassDef == IC && ArrayRef(Writes) == W && ArrayRef(Reads) == R; 158fa3d789dSPierre van Houtryve } 159fa3d789dSPierre van Houtryve 160fa3d789dSPierre van Houtryve // Is this class generated from a variants if existing classes? Instructions 161fa3d789dSPierre van Houtryve // are never mapped directly to inferred scheduling classes. 162fa3d789dSPierre van Houtryve bool isInferred() const { return !ItinClassDef; } 163fa3d789dSPierre van Houtryve 164fa3d789dSPierre van Houtryve #ifndef NDEBUG 165fa3d789dSPierre van Houtryve void dump(const CodeGenSchedModels *SchedModels) const; 166fa3d789dSPierre van Houtryve #endif 167fa3d789dSPierre van Houtryve }; 168fa3d789dSPierre van Houtryve 169fa3d789dSPierre van Houtryve /// Represent the cost of allocating a register of register class RCDef. 170fa3d789dSPierre van Houtryve /// 171fa3d789dSPierre van Houtryve /// The cost of allocating a register is equivalent to the number of physical 172fa3d789dSPierre van Houtryve /// registers used by the register renamer. Register costs are defined at 173fa3d789dSPierre van Houtryve /// register class granularity. 174fa3d789dSPierre van Houtryve struct CodeGenRegisterCost { 175c29dfb33SRahul Joshi const Record *RCDef; 176fa3d789dSPierre van Houtryve unsigned Cost; 177fa3d789dSPierre van Houtryve bool AllowMoveElimination; 178c29dfb33SRahul Joshi CodeGenRegisterCost(const Record *RC, unsigned RegisterCost, 179fa3d789dSPierre van Houtryve bool AllowMoveElim = false) 180fa3d789dSPierre van Houtryve : RCDef(RC), Cost(RegisterCost), AllowMoveElimination(AllowMoveElim) {} 181fa3d789dSPierre van Houtryve CodeGenRegisterCost(const CodeGenRegisterCost &) = default; 182fa3d789dSPierre van Houtryve CodeGenRegisterCost &operator=(const CodeGenRegisterCost &) = delete; 183fa3d789dSPierre van Houtryve }; 184fa3d789dSPierre van Houtryve 185fa3d789dSPierre van Houtryve /// A processor register file. 186fa3d789dSPierre van Houtryve /// 187fa3d789dSPierre van Houtryve /// This class describes a processor register file. Register file information is 188fa3d789dSPierre van Houtryve /// currently consumed by external tools like llvm-mca to predict dispatch 189fa3d789dSPierre van Houtryve /// stalls due to register pressure. 190fa3d789dSPierre van Houtryve struct CodeGenRegisterFile { 191fa3d789dSPierre van Houtryve std::string Name; 1923ae71d15SRahul Joshi const Record *RegisterFileDef; 193fa3d789dSPierre van Houtryve unsigned MaxMovesEliminatedPerCycle; 194fa3d789dSPierre van Houtryve bool AllowZeroMoveEliminationOnly; 195fa3d789dSPierre van Houtryve 196fa3d789dSPierre van Houtryve unsigned NumPhysRegs; 197fa3d789dSPierre van Houtryve std::vector<CodeGenRegisterCost> Costs; 198fa3d789dSPierre van Houtryve 1993ae71d15SRahul Joshi CodeGenRegisterFile(StringRef name, const Record *def, 200fa3d789dSPierre van Houtryve unsigned MaxMoveElimPerCy = 0, 201fa3d789dSPierre van Houtryve bool AllowZeroMoveElimOnly = false) 202fa3d789dSPierre van Houtryve : Name(name), RegisterFileDef(def), 203fa3d789dSPierre van Houtryve MaxMovesEliminatedPerCycle(MaxMoveElimPerCy), 204fa3d789dSPierre van Houtryve AllowZeroMoveEliminationOnly(AllowZeroMoveElimOnly), NumPhysRegs(0) {} 205fa3d789dSPierre van Houtryve 206fa3d789dSPierre van Houtryve bool hasDefaultCosts() const { return Costs.empty(); } 207fa3d789dSPierre van Houtryve }; 208fa3d789dSPierre van Houtryve 209fa3d789dSPierre van Houtryve // Processor model. 210fa3d789dSPierre van Houtryve // 211fa3d789dSPierre van Houtryve // ModelName is a unique name used to name an instantiation of MCSchedModel. 212fa3d789dSPierre van Houtryve // 213fa3d789dSPierre van Houtryve // ModelDef is NULL for inferred Models. This happens when a processor defines 214fa3d789dSPierre van Houtryve // an itinerary but no machine model. If the processor defines neither a machine 215fa3d789dSPierre van Houtryve // model nor itinerary, then ModelDef remains pointing to NoModel. NoModel has 216fa3d789dSPierre van Houtryve // the special "NoModel" field set to true. 217fa3d789dSPierre van Houtryve // 218fa3d789dSPierre van Houtryve // ItinsDef always points to a valid record definition, but may point to the 219fa3d789dSPierre van Houtryve // default NoItineraries. NoItineraries has an empty list of InstrItinData 220fa3d789dSPierre van Houtryve // records. 221fa3d789dSPierre van Houtryve // 222fa3d789dSPierre van Houtryve // ItinDefList orders this processor's InstrItinData records by SchedClass idx. 223fa3d789dSPierre van Houtryve struct CodeGenProcModel { 224fa3d789dSPierre van Houtryve unsigned Index; 225fa3d789dSPierre van Houtryve std::string ModelName; 2263ae71d15SRahul Joshi const Record *ModelDef; 2273ae71d15SRahul Joshi const Record *ItinsDef; 228fa3d789dSPierre van Houtryve 229fa3d789dSPierre van Houtryve // Derived members... 230fa3d789dSPierre van Houtryve 231fa3d789dSPierre van Houtryve // Array of InstrItinData records indexed by a CodeGenSchedClass index. 232fa3d789dSPierre van Houtryve // This list is empty if the Processor has no value for Itineraries. 233fa3d789dSPierre van Houtryve // Initialized by collectProcItins(). 234c29dfb33SRahul Joshi ConstRecVec ItinDefList; 235fa3d789dSPierre van Houtryve 236fa3d789dSPierre van Houtryve // Map itinerary classes to per-operand resources. 237fa3d789dSPierre van Houtryve // This list is empty if no ItinRW refers to this Processor. 2383ae71d15SRahul Joshi ConstRecVec ItinRWDefs; 239fa3d789dSPierre van Houtryve 240fa3d789dSPierre van Houtryve // List of unsupported feature. 241fa3d789dSPierre van Houtryve // This list is empty if the Processor has no UnsupportedFeatures. 242c29dfb33SRahul Joshi ConstRecVec UnsupportedFeaturesDefs; 243fa3d789dSPierre van Houtryve 244fa3d789dSPierre van Houtryve // All read/write resources associated with this processor. 2453ae71d15SRahul Joshi ConstRecVec WriteResDefs; 2463ae71d15SRahul Joshi ConstRecVec ReadAdvanceDefs; 247fa3d789dSPierre van Houtryve 248517334bdSCraig Topper // Map from the WriteType field to the parent WriteRes record. 249517334bdSCraig Topper DenseMap<const Record *, const Record *> WriteResMap; 250517334bdSCraig Topper 251517334bdSCraig Topper // Map from the ReadType field to the parent ReadAdvance record. 252517334bdSCraig Topper DenseMap<const Record *, const Record *> ReadAdvanceMap; 253517334bdSCraig Topper 254*e19261faSCraig Topper // Set of WriteRes that are referenced by a ReadAdvance. 255*e19261faSCraig Topper SmallPtrSet<const Record *, 8> ReadOfWriteSet; 256*e19261faSCraig Topper 257fa3d789dSPierre van Houtryve // Per-operand machine model resources associated with this processor. 2583ae71d15SRahul Joshi ConstRecVec ProcResourceDefs; 259fa3d789dSPierre van Houtryve 260fa3d789dSPierre van Houtryve // List of Register Files. 261fa3d789dSPierre van Houtryve std::vector<CodeGenRegisterFile> RegisterFiles; 262fa3d789dSPierre van Houtryve 263fa3d789dSPierre van Houtryve // Optional Retire Control Unit definition. 2643ae71d15SRahul Joshi const Record *RetireControlUnit; 265fa3d789dSPierre van Houtryve 266fa3d789dSPierre van Houtryve // Load/Store queue descriptors. 2673ae71d15SRahul Joshi const Record *LoadQueue; 2683ae71d15SRahul Joshi const Record *StoreQueue; 269fa3d789dSPierre van Houtryve 2703ae71d15SRahul Joshi CodeGenProcModel(unsigned Idx, std::string Name, const Record *MDef, 2713ae71d15SRahul Joshi const Record *IDef) 272fa3d789dSPierre van Houtryve : Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef), 273fa3d789dSPierre van Houtryve RetireControlUnit(nullptr), LoadQueue(nullptr), StoreQueue(nullptr) {} 274fa3d789dSPierre van Houtryve 275fa3d789dSPierre van Houtryve bool hasItineraries() const { 276fa3d789dSPierre van Houtryve return !ItinsDef->getValueAsListOfDefs("IID").empty(); 277fa3d789dSPierre van Houtryve } 278fa3d789dSPierre van Houtryve 279fa3d789dSPierre van Houtryve bool hasInstrSchedModel() const { 280fa3d789dSPierre van Houtryve return !WriteResDefs.empty() || !ItinRWDefs.empty(); 281fa3d789dSPierre van Houtryve } 282fa3d789dSPierre van Houtryve 283fa3d789dSPierre van Houtryve bool hasExtraProcessorInfo() const { 284fa3d789dSPierre van Houtryve return RetireControlUnit || LoadQueue || StoreQueue || 285fa3d789dSPierre van Houtryve !RegisterFiles.empty(); 286fa3d789dSPierre van Houtryve } 287fa3d789dSPierre van Houtryve 2883ae71d15SRahul Joshi unsigned getProcResourceIdx(const Record *PRDef) const; 289fa3d789dSPierre van Houtryve 290fa3d789dSPierre van Houtryve bool isUnsupported(const CodeGenInstruction &Inst) const; 291fa3d789dSPierre van Houtryve 29267beebfcSMichael Maitland // Return true if the given write record is referenced by a ReadAdvance. 2933ae71d15SRahul Joshi bool hasReadOfWrite(const Record *WriteDef) const; 29467beebfcSMichael Maitland 295fa3d789dSPierre van Houtryve #ifndef NDEBUG 296fa3d789dSPierre van Houtryve void dump() const; 297fa3d789dSPierre van Houtryve #endif 298fa3d789dSPierre van Houtryve }; 299fa3d789dSPierre van Houtryve 300fa3d789dSPierre van Houtryve /// Used to correlate instructions to MCInstPredicates specified by 301fa3d789dSPierre van Houtryve /// InstructionEquivalentClass tablegen definitions. 302fa3d789dSPierre van Houtryve /// 303fa3d789dSPierre van Houtryve /// Example: a XOR of a register with self, is a known zero-idiom for most 304fa3d789dSPierre van Houtryve /// X86 processors. 305fa3d789dSPierre van Houtryve /// 306fa3d789dSPierre van Houtryve /// Each processor can use a (potentially different) InstructionEquivalenceClass 307fa3d789dSPierre van Houtryve /// definition to classify zero-idioms. That means, XORrr is likely to appear 308fa3d789dSPierre van Houtryve /// in more than one equivalence class (where each class definition is 309fa3d789dSPierre van Houtryve /// contributed by a different processor). 310fa3d789dSPierre van Houtryve /// 311fa3d789dSPierre van Houtryve /// There is no guarantee that the same MCInstPredicate will be used to describe 312fa3d789dSPierre van Houtryve /// equivalence classes that identify XORrr as a zero-idiom. 313fa3d789dSPierre van Houtryve /// 314fa3d789dSPierre van Houtryve /// To be more specific, the requirements for being a zero-idiom XORrr may be 315fa3d789dSPierre van Houtryve /// different for different processors. 316fa3d789dSPierre van Houtryve /// 317fa3d789dSPierre van Houtryve /// Class PredicateInfo identifies a subset of processors that specify the same 318fa3d789dSPierre van Houtryve /// requirements (i.e. same MCInstPredicate and OperandMask) for an instruction 319fa3d789dSPierre van Houtryve /// opcode. 320fa3d789dSPierre van Houtryve /// 321fa3d789dSPierre van Houtryve /// Back to the example. Field `ProcModelMask` will have one bit set for every 322fa3d789dSPierre van Houtryve /// processor model that sees XORrr as a zero-idiom, and that specifies the same 323fa3d789dSPierre van Houtryve /// set of constraints. 324fa3d789dSPierre van Houtryve /// 325fa3d789dSPierre van Houtryve /// By construction, there can be multiple instances of PredicateInfo associated 326fa3d789dSPierre van Houtryve /// with a same instruction opcode. For example, different processors may define 327fa3d789dSPierre van Houtryve /// different constraints on the same opcode. 328fa3d789dSPierre van Houtryve /// 329fa3d789dSPierre van Houtryve /// Field OperandMask can be used as an extra constraint. 330fa3d789dSPierre van Houtryve /// It may be used to describe conditions that appy only to a subset of the 331fa3d789dSPierre van Houtryve /// operands of a machine instruction, and the operands subset may not be the 332fa3d789dSPierre van Houtryve /// same for all processor models. 333fa3d789dSPierre van Houtryve struct PredicateInfo { 334fa3d789dSPierre van Houtryve llvm::APInt ProcModelMask; // A set of processor model indices. 335fa3d789dSPierre van Houtryve llvm::APInt OperandMask; // An operand mask. 336fa3d789dSPierre van Houtryve const Record *Predicate; // MCInstrPredicate definition. 337fa3d789dSPierre van Houtryve PredicateInfo(llvm::APInt CpuMask, llvm::APInt Operands, const Record *Pred) 338fa3d789dSPierre van Houtryve : ProcModelMask(CpuMask), OperandMask(Operands), Predicate(Pred) {} 339fa3d789dSPierre van Houtryve 340fa3d789dSPierre van Houtryve bool operator==(const PredicateInfo &Other) const { 341fa3d789dSPierre van Houtryve return ProcModelMask == Other.ProcModelMask && 342fa3d789dSPierre van Houtryve OperandMask == Other.OperandMask && Predicate == Other.Predicate; 343fa3d789dSPierre van Houtryve } 344fa3d789dSPierre van Houtryve }; 345fa3d789dSPierre van Houtryve 346fa3d789dSPierre van Houtryve /// A collection of PredicateInfo objects. 347fa3d789dSPierre van Houtryve /// 348fa3d789dSPierre van Houtryve /// There is at least one OpcodeInfo object for every opcode specified by a 349fa3d789dSPierre van Houtryve /// TIPredicate definition. 350fa3d789dSPierre van Houtryve class OpcodeInfo { 351fa3d789dSPierre van Houtryve std::vector<PredicateInfo> Predicates; 352fa3d789dSPierre van Houtryve 353fa3d789dSPierre van Houtryve OpcodeInfo(const OpcodeInfo &Other) = delete; 354fa3d789dSPierre van Houtryve OpcodeInfo &operator=(const OpcodeInfo &Other) = delete; 355fa3d789dSPierre van Houtryve 356fa3d789dSPierre van Houtryve public: 357fa3d789dSPierre van Houtryve OpcodeInfo() = default; 358fa3d789dSPierre van Houtryve OpcodeInfo &operator=(OpcodeInfo &&Other) = default; 359fa3d789dSPierre van Houtryve OpcodeInfo(OpcodeInfo &&Other) = default; 360fa3d789dSPierre van Houtryve 361fa3d789dSPierre van Houtryve ArrayRef<PredicateInfo> getPredicates() const { return Predicates; } 362fa3d789dSPierre van Houtryve 363fa3d789dSPierre van Houtryve void addPredicateForProcModel(const llvm::APInt &CpuMask, 364fa3d789dSPierre van Houtryve const llvm::APInt &OperandMask, 365fa3d789dSPierre van Houtryve const Record *Predicate); 366fa3d789dSPierre van Houtryve }; 367fa3d789dSPierre van Houtryve 368fa3d789dSPierre van Houtryve /// Used to group together tablegen instruction definitions that are subject 369fa3d789dSPierre van Houtryve /// to a same set of constraints (identified by an instance of OpcodeInfo). 370fa3d789dSPierre van Houtryve class OpcodeGroup { 371fa3d789dSPierre van Houtryve OpcodeInfo Info; 372fa3d789dSPierre van Houtryve std::vector<const Record *> Opcodes; 373fa3d789dSPierre van Houtryve 374fa3d789dSPierre van Houtryve OpcodeGroup(const OpcodeGroup &Other) = delete; 375fa3d789dSPierre van Houtryve OpcodeGroup &operator=(const OpcodeGroup &Other) = delete; 376fa3d789dSPierre van Houtryve 377fa3d789dSPierre van Houtryve public: 378fa3d789dSPierre van Houtryve OpcodeGroup(OpcodeInfo &&OpInfo) : Info(std::move(OpInfo)) {} 379fa3d789dSPierre van Houtryve OpcodeGroup(OpcodeGroup &&Other) = default; 380fa3d789dSPierre van Houtryve 381fa3d789dSPierre van Houtryve void addOpcode(const Record *Opcode) { 382fa3d789dSPierre van Houtryve assert(!llvm::is_contained(Opcodes, Opcode) && "Opcode already in set!"); 383fa3d789dSPierre van Houtryve Opcodes.push_back(Opcode); 384fa3d789dSPierre van Houtryve } 385fa3d789dSPierre van Houtryve 386fa3d789dSPierre van Houtryve ArrayRef<const Record *> getOpcodes() const { return Opcodes; } 387fa3d789dSPierre van Houtryve const OpcodeInfo &getOpcodeInfo() const { return Info; } 388fa3d789dSPierre van Houtryve }; 389fa3d789dSPierre van Houtryve 390fa3d789dSPierre van Houtryve /// An STIPredicateFunction descriptor used by tablegen backends to 391fa3d789dSPierre van Houtryve /// auto-generate the body of a predicate function as a member of tablegen'd 392fa3d789dSPierre van Houtryve /// class XXXGenSubtargetInfo. 393fa3d789dSPierre van Houtryve class STIPredicateFunction { 394fa3d789dSPierre van Houtryve const Record *FunctionDeclaration; 395fa3d789dSPierre van Houtryve 396fa3d789dSPierre van Houtryve std::vector<const Record *> Definitions; 397fa3d789dSPierre van Houtryve std::vector<OpcodeGroup> Groups; 398fa3d789dSPierre van Houtryve 399fa3d789dSPierre van Houtryve STIPredicateFunction(const STIPredicateFunction &Other) = delete; 400fa3d789dSPierre van Houtryve STIPredicateFunction &operator=(const STIPredicateFunction &Other) = delete; 401fa3d789dSPierre van Houtryve 402fa3d789dSPierre van Houtryve public: 403fa3d789dSPierre van Houtryve STIPredicateFunction(const Record *Rec) : FunctionDeclaration(Rec) {} 404fa3d789dSPierre van Houtryve STIPredicateFunction(STIPredicateFunction &&Other) = default; 405fa3d789dSPierre van Houtryve 406fa3d789dSPierre van Houtryve bool isCompatibleWith(const STIPredicateFunction &Other) const { 407fa3d789dSPierre van Houtryve return FunctionDeclaration == Other.FunctionDeclaration; 408fa3d789dSPierre van Houtryve } 409fa3d789dSPierre van Houtryve 410fa3d789dSPierre van Houtryve void addDefinition(const Record *Def) { Definitions.push_back(Def); } 411fa3d789dSPierre van Houtryve void addOpcode(const Record *OpcodeRec, OpcodeInfo &&Info) { 412fa3d789dSPierre van Houtryve if (Groups.empty() || 413fa3d789dSPierre van Houtryve Groups.back().getOpcodeInfo().getPredicates() != Info.getPredicates()) 414fa3d789dSPierre van Houtryve Groups.emplace_back(std::move(Info)); 415fa3d789dSPierre van Houtryve Groups.back().addOpcode(OpcodeRec); 416fa3d789dSPierre van Houtryve } 417fa3d789dSPierre van Houtryve 418fa3d789dSPierre van Houtryve StringRef getName() const { 419fa3d789dSPierre van Houtryve return FunctionDeclaration->getValueAsString("Name"); 420fa3d789dSPierre van Houtryve } 421fa3d789dSPierre van Houtryve const Record *getDefaultReturnPredicate() const { 422fa3d789dSPierre van Houtryve return FunctionDeclaration->getValueAsDef("DefaultReturnValue"); 423fa3d789dSPierre van Houtryve } 424fa3d789dSPierre van Houtryve 425fa3d789dSPierre van Houtryve const Record *getDeclaration() const { return FunctionDeclaration; } 426fa3d789dSPierre van Houtryve ArrayRef<const Record *> getDefinitions() const { return Definitions; } 427fa3d789dSPierre van Houtryve ArrayRef<OpcodeGroup> getGroups() const { return Groups; } 428fa3d789dSPierre van Houtryve }; 429fa3d789dSPierre van Houtryve 430fa3d789dSPierre van Houtryve using ProcModelMapTy = DenseMap<const Record *, unsigned>; 431fa3d789dSPierre van Houtryve 432fa3d789dSPierre van Houtryve /// Top level container for machine model data. 433fa3d789dSPierre van Houtryve class CodeGenSchedModels { 4343ae71d15SRahul Joshi const RecordKeeper &Records; 435fa3d789dSPierre van Houtryve const CodeGenTarget &Target; 436fa3d789dSPierre van Houtryve 437fa3d789dSPierre van Houtryve // Map dag expressions to Instruction lists. 438fa3d789dSPierre van Houtryve SetTheory Sets; 439fa3d789dSPierre van Houtryve 440fa3d789dSPierre van Houtryve // List of unique processor models. 441fa3d789dSPierre van Houtryve std::vector<CodeGenProcModel> ProcModels; 442fa3d789dSPierre van Houtryve 443fa3d789dSPierre van Houtryve // Map Processor's MachineModel or ProcItin to a CodeGenProcModel index. 444fa3d789dSPierre van Houtryve ProcModelMapTy ProcModelMap; 445fa3d789dSPierre van Houtryve 446fa3d789dSPierre van Houtryve // Per-operand SchedReadWrite types. 447fa3d789dSPierre van Houtryve std::vector<CodeGenSchedRW> SchedWrites; 448fa3d789dSPierre van Houtryve std::vector<CodeGenSchedRW> SchedReads; 449fa3d789dSPierre van Houtryve 450fa3d789dSPierre van Houtryve // List of unique SchedClasses. 451fa3d789dSPierre van Houtryve std::vector<CodeGenSchedClass> SchedClasses; 452fa3d789dSPierre van Houtryve 453fa3d789dSPierre van Houtryve // Any inferred SchedClass has an index greater than NumInstrSchedClassses. 454fa3d789dSPierre van Houtryve unsigned NumInstrSchedClasses; 455fa3d789dSPierre van Houtryve 4563ae71d15SRahul Joshi ConstRecVec ProcResourceDefs; 4573ae71d15SRahul Joshi ConstRecVec ProcResGroups; 458fa3d789dSPierre van Houtryve 459fa3d789dSPierre van Houtryve // Map each instruction to its unique SchedClass index considering the 460fa3d789dSPierre van Houtryve // combination of it's itinerary class, SchedRW list, and InstRW records. 46116510149SRahul Joshi using InstClassMapTy = DenseMap<const Record *, unsigned>; 462fa3d789dSPierre van Houtryve InstClassMapTy InstrClassMap; 463fa3d789dSPierre van Houtryve 464fa3d789dSPierre van Houtryve std::vector<STIPredicateFunction> STIPredicates; 465fa3d789dSPierre van Houtryve std::vector<unsigned> getAllProcIndices() const; 466fa3d789dSPierre van Houtryve 467fa3d789dSPierre van Houtryve public: 4683ae71d15SRahul Joshi CodeGenSchedModels(const RecordKeeper &RK, const CodeGenTarget &TGT); 469fa3d789dSPierre van Houtryve 470fa3d789dSPierre van Houtryve // iterator access to the scheduling classes. 471fa3d789dSPierre van Houtryve using class_iterator = std::vector<CodeGenSchedClass>::iterator; 472fa3d789dSPierre van Houtryve using const_class_iterator = std::vector<CodeGenSchedClass>::const_iterator; 473fa3d789dSPierre van Houtryve class_iterator classes_begin() { return SchedClasses.begin(); } 474fa3d789dSPierre van Houtryve const_class_iterator classes_begin() const { return SchedClasses.begin(); } 475fa3d789dSPierre van Houtryve class_iterator classes_end() { return SchedClasses.end(); } 476fa3d789dSPierre van Houtryve const_class_iterator classes_end() const { return SchedClasses.end(); } 477fa3d789dSPierre van Houtryve iterator_range<class_iterator> classes() { 478fa3d789dSPierre van Houtryve return make_range(classes_begin(), classes_end()); 479fa3d789dSPierre van Houtryve } 480fa3d789dSPierre van Houtryve iterator_range<const_class_iterator> classes() const { 481fa3d789dSPierre van Houtryve return make_range(classes_begin(), classes_end()); 482fa3d789dSPierre van Houtryve } 483fa3d789dSPierre van Houtryve iterator_range<class_iterator> explicit_classes() { 484fa3d789dSPierre van Houtryve return make_range(classes_begin(), classes_begin() + NumInstrSchedClasses); 485fa3d789dSPierre van Houtryve } 486fa3d789dSPierre van Houtryve iterator_range<const_class_iterator> explicit_classes() const { 487fa3d789dSPierre van Houtryve return make_range(classes_begin(), classes_begin() + NumInstrSchedClasses); 488fa3d789dSPierre van Houtryve } 489fa3d789dSPierre van Houtryve 4903ae71d15SRahul Joshi const Record *getModelOrItinDef(const Record *ProcDef) const { 4913ae71d15SRahul Joshi const Record *ModelDef = ProcDef->getValueAsDef("SchedModel"); 4923ae71d15SRahul Joshi const Record *ItinsDef = ProcDef->getValueAsDef("ProcItin"); 493fa3d789dSPierre van Houtryve if (!ItinsDef->getValueAsListOfDefs("IID").empty()) { 494fa3d789dSPierre van Houtryve assert(ModelDef->getValueAsBit("NoModel") && 495fa3d789dSPierre van Houtryve "Itineraries must be defined within SchedMachineModel"); 496fa3d789dSPierre van Houtryve return ItinsDef; 497fa3d789dSPierre van Houtryve } 498fa3d789dSPierre van Houtryve return ModelDef; 499fa3d789dSPierre van Houtryve } 500fa3d789dSPierre van Houtryve 5018e00afcfSRahul Joshi const CodeGenProcModel &getModelForProc(const Record *ProcDef) const { 5023ae71d15SRahul Joshi const Record *ModelDef = getModelOrItinDef(ProcDef); 503fa3d789dSPierre van Houtryve ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef); 504fa3d789dSPierre van Houtryve assert(I != ProcModelMap.end() && "missing machine model"); 505fa3d789dSPierre van Houtryve return ProcModels[I->second]; 506fa3d789dSPierre van Houtryve } 507fa3d789dSPierre van Houtryve 5082a4c4b55SCraig Topper const CodeGenProcModel &getProcModel(const Record *ModelDef) const { 509fa3d789dSPierre van Houtryve ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef); 510fa3d789dSPierre van Houtryve assert(I != ProcModelMap.end() && "missing machine model"); 511fa3d789dSPierre van Houtryve return ProcModels[I->second]; 512fa3d789dSPierre van Houtryve } 5132a4c4b55SCraig Topper CodeGenProcModel &getProcModel(const Record *ModelDef) { 5142a4c4b55SCraig Topper return const_cast<CodeGenProcModel &>( 5152a4c4b55SCraig Topper static_cast<const CodeGenSchedModels &>(*this).getProcModel(ModelDef)); 516fa3d789dSPierre van Houtryve } 517fa3d789dSPierre van Houtryve 518fa3d789dSPierre van Houtryve // Iterate over the unique processor models. 519fa3d789dSPierre van Houtryve using ProcIter = std::vector<CodeGenProcModel>::const_iterator; 520fa3d789dSPierre van Houtryve ProcIter procModelBegin() const { return ProcModels.begin(); } 521fa3d789dSPierre van Houtryve ProcIter procModelEnd() const { return ProcModels.end(); } 522fa3d789dSPierre van Houtryve ArrayRef<CodeGenProcModel> procModels() const { return ProcModels; } 523fa3d789dSPierre van Houtryve 524fa3d789dSPierre van Houtryve // Return true if any processors have itineraries. 525fa3d789dSPierre van Houtryve bool hasItineraries() const; 526fa3d789dSPierre van Houtryve 527fa3d789dSPierre van Houtryve // Get a SchedWrite from its index. 528fa3d789dSPierre van Houtryve const CodeGenSchedRW &getSchedWrite(unsigned Idx) const { 529fa3d789dSPierre van Houtryve assert(Idx < SchedWrites.size() && "bad SchedWrite index"); 530fa3d789dSPierre van Houtryve assert(SchedWrites[Idx].isValid() && "invalid SchedWrite"); 531fa3d789dSPierre van Houtryve return SchedWrites[Idx]; 532fa3d789dSPierre van Houtryve } 533fa3d789dSPierre van Houtryve // Get a SchedWrite from its index. 534fa3d789dSPierre van Houtryve const CodeGenSchedRW &getSchedRead(unsigned Idx) const { 535fa3d789dSPierre van Houtryve assert(Idx < SchedReads.size() && "bad SchedRead index"); 536fa3d789dSPierre van Houtryve assert(SchedReads[Idx].isValid() && "invalid SchedRead"); 537fa3d789dSPierre van Houtryve return SchedReads[Idx]; 538fa3d789dSPierre van Houtryve } 539fa3d789dSPierre van Houtryve 540fa3d789dSPierre van Houtryve const CodeGenSchedRW &getSchedRW(unsigned Idx, bool IsRead) const { 541fa3d789dSPierre van Houtryve return IsRead ? getSchedRead(Idx) : getSchedWrite(Idx); 542fa3d789dSPierre van Houtryve } 5432a4c4b55SCraig Topper const CodeGenSchedRW &getSchedRW(const Record *Def) const { 544fa3d789dSPierre van Houtryve bool IsRead = Def->isSubClassOf("SchedRead"); 545fa3d789dSPierre van Houtryve unsigned Idx = getSchedRWIdx(Def, IsRead); 5462a4c4b55SCraig Topper return IsRead ? getSchedRead(Idx) : getSchedWrite(Idx); 547fa3d789dSPierre van Houtryve } 5482a4c4b55SCraig Topper CodeGenSchedRW &getSchedRW(const Record *Def) { 5492a4c4b55SCraig Topper return const_cast<CodeGenSchedRW &>( 5502a4c4b55SCraig Topper static_cast<const CodeGenSchedModels &>(*this).getSchedRW(Def)); 551fa3d789dSPierre van Houtryve } 552fa3d789dSPierre van Houtryve 553fa3d789dSPierre van Houtryve unsigned getSchedRWIdx(const Record *Def, bool IsRead) const; 554fa3d789dSPierre van Houtryve 555fa3d789dSPierre van Houtryve // Get a SchedClass from its index. 556fa3d789dSPierre van Houtryve CodeGenSchedClass &getSchedClass(unsigned Idx) { 557fa3d789dSPierre van Houtryve assert(Idx < SchedClasses.size() && "bad SchedClass index"); 558fa3d789dSPierre van Houtryve return SchedClasses[Idx]; 559fa3d789dSPierre van Houtryve } 560fa3d789dSPierre van Houtryve const CodeGenSchedClass &getSchedClass(unsigned Idx) const { 561fa3d789dSPierre van Houtryve assert(Idx < SchedClasses.size() && "bad SchedClass index"); 562fa3d789dSPierre van Houtryve return SchedClasses[Idx]; 563fa3d789dSPierre van Houtryve } 564fa3d789dSPierre van Houtryve 565fa3d789dSPierre van Houtryve // Get the SchedClass index for an instruction. Instructions with no 566fa3d789dSPierre van Houtryve // itinerary, no SchedReadWrites, and no InstrReadWrites references return 0 567fa3d789dSPierre van Houtryve // for NoItinerary. 568fa3d789dSPierre van Houtryve unsigned getSchedClassIdx(const CodeGenInstruction &Inst) const; 569fa3d789dSPierre van Houtryve 570fa3d789dSPierre van Houtryve using SchedClassIter = std::vector<CodeGenSchedClass>::const_iterator; 571fa3d789dSPierre van Houtryve SchedClassIter schedClassBegin() const { return SchedClasses.begin(); } 572fa3d789dSPierre van Houtryve SchedClassIter schedClassEnd() const { return SchedClasses.end(); } 573fa3d789dSPierre van Houtryve ArrayRef<CodeGenSchedClass> schedClasses() const { return SchedClasses; } 574fa3d789dSPierre van Houtryve 575fa3d789dSPierre van Houtryve unsigned numInstrSchedClasses() const { return NumInstrSchedClasses; } 576fa3d789dSPierre van Houtryve 577c29dfb33SRahul Joshi void findRWs(const ConstRecVec &RWDefs, IdxVec &Writes, IdxVec &Reads) const; 578c29dfb33SRahul Joshi void findRWs(const ConstRecVec &RWDefs, IdxVec &RWs, bool IsRead) const; 579fa3d789dSPierre van Houtryve void expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, bool IsRead) const; 580fa3d789dSPierre van Houtryve void expandRWSeqForProc(unsigned RWIdx, IdxVec &RWSeq, bool IsRead, 581fa3d789dSPierre van Houtryve const CodeGenProcModel &ProcModel) const; 582fa3d789dSPierre van Houtryve 583c29dfb33SRahul Joshi unsigned addSchedClass(const Record *ItinDef, ArrayRef<unsigned> OperWrites, 584fa3d789dSPierre van Houtryve ArrayRef<unsigned> OperReads, 585fa3d789dSPierre van Houtryve ArrayRef<unsigned> ProcIndices); 586fa3d789dSPierre van Houtryve 587fa3d789dSPierre van Houtryve unsigned findOrInsertRW(ArrayRef<unsigned> Seq, bool IsRead); 588fa3d789dSPierre van Houtryve 5893ae71d15SRahul Joshi const Record *findProcResUnits(const Record *ProcResKind, 5903ae71d15SRahul Joshi const CodeGenProcModel &PM, 591fa3d789dSPierre van Houtryve ArrayRef<SMLoc> Loc) const; 592fa3d789dSPierre van Houtryve 593fa3d789dSPierre van Houtryve ArrayRef<STIPredicateFunction> getSTIPredicates() const { 594fa3d789dSPierre van Houtryve return STIPredicates; 595fa3d789dSPierre van Houtryve } 596fa3d789dSPierre van Houtryve 597fa3d789dSPierre van Houtryve private: 598fa3d789dSPierre van Houtryve void collectProcModels(); 599fa3d789dSPierre van Houtryve 600fa3d789dSPierre van Houtryve // Initialize a new processor model if it is unique. 6013ae71d15SRahul Joshi void addProcModel(const Record *ProcDef); 602fa3d789dSPierre van Houtryve 603fa3d789dSPierre van Houtryve void collectSchedRW(); 604fa3d789dSPierre van Houtryve 605fa3d789dSPierre van Houtryve std::string genRWName(ArrayRef<unsigned> Seq, bool IsRead); 606fa3d789dSPierre van Houtryve 607fa3d789dSPierre van Houtryve void collectSchedClasses(); 608fa3d789dSPierre van Houtryve 609fa3d789dSPierre van Houtryve void collectRetireControlUnits(); 610fa3d789dSPierre van Houtryve 611fa3d789dSPierre van Houtryve void collectRegisterFiles(); 612fa3d789dSPierre van Houtryve 613fa3d789dSPierre van Houtryve void collectOptionalProcessorInfo(); 614fa3d789dSPierre van Houtryve 615c29dfb33SRahul Joshi std::string createSchedClassName(const Record *ItinClassDef, 616fa3d789dSPierre van Houtryve ArrayRef<unsigned> OperWrites, 617fa3d789dSPierre van Houtryve ArrayRef<unsigned> OperReads); 61816510149SRahul Joshi std::string createSchedClassName(const ConstRecVec &InstDefs); 6193ae71d15SRahul Joshi void createInstRWClass(const Record *InstRWDef); 620fa3d789dSPierre van Houtryve 621fa3d789dSPierre van Houtryve void collectProcItins(); 622fa3d789dSPierre van Houtryve 623fa3d789dSPierre van Houtryve void collectProcItinRW(); 624fa3d789dSPierre van Houtryve 625fa3d789dSPierre van Houtryve void collectProcUnsupportedFeatures(); 626fa3d789dSPierre van Houtryve 627fa3d789dSPierre van Houtryve void inferSchedClasses(); 628fa3d789dSPierre van Houtryve 629fa3d789dSPierre van Houtryve void checkMCInstPredicates() const; 630fa3d789dSPierre van Houtryve 631fa3d789dSPierre van Houtryve void checkSTIPredicates() const; 632fa3d789dSPierre van Houtryve 633fa3d789dSPierre van Houtryve void collectSTIPredicates(); 634fa3d789dSPierre van Houtryve 635fa3d789dSPierre van Houtryve void collectLoadStoreQueueInfo(); 636fa3d789dSPierre van Houtryve 637fa3d789dSPierre van Houtryve void checkCompleteness(); 638fa3d789dSPierre van Houtryve 639fa3d789dSPierre van Houtryve void inferFromRW(ArrayRef<unsigned> OperWrites, ArrayRef<unsigned> OperReads, 640fa3d789dSPierre van Houtryve unsigned FromClassIdx, ArrayRef<unsigned> ProcIndices); 641c29dfb33SRahul Joshi void inferFromItinClass(const Record *ItinClassDef, unsigned FromClassIdx); 642fa3d789dSPierre van Houtryve void inferFromInstRWs(unsigned SCIdx); 643fa3d789dSPierre van Houtryve 644c3aa86c9SCraig Topper bool hasSuperGroup(const ConstRecVec &SubUnits, const CodeGenProcModel &PM); 645c3aa86c9SCraig Topper void verifyProcResourceGroups(const CodeGenProcModel &PM); 646fa3d789dSPierre van Houtryve 647fa3d789dSPierre van Houtryve void collectProcResources(); 648fa3d789dSPierre van Houtryve 649c29dfb33SRahul Joshi void collectItinProcResources(const Record *ItinClassDef); 650fa3d789dSPierre van Houtryve 651fa3d789dSPierre van Houtryve void collectRWResources(unsigned RWIdx, bool IsRead, 652fa3d789dSPierre van Houtryve ArrayRef<unsigned> ProcIndices); 653fa3d789dSPierre van Houtryve 654fa3d789dSPierre van Houtryve void collectRWResources(ArrayRef<unsigned> Writes, ArrayRef<unsigned> Reads, 655fa3d789dSPierre van Houtryve ArrayRef<unsigned> ProcIndices); 656fa3d789dSPierre van Houtryve 6573ae71d15SRahul Joshi void addProcResource(const Record *ProcResourceKind, CodeGenProcModel &PM, 658fa3d789dSPierre van Houtryve ArrayRef<SMLoc> Loc); 659fa3d789dSPierre van Houtryve 660082b1480SCraig Topper void addWriteRes(const Record *ProcWriteResDef, CodeGenProcModel &PM); 661fa3d789dSPierre van Houtryve 662082b1480SCraig Topper void addReadAdvance(const Record *ProcReadAdvanceDef, CodeGenProcModel &PM); 663fa3d789dSPierre van Houtryve }; 664fa3d789dSPierre van Houtryve 665fa3d789dSPierre van Houtryve } // namespace llvm 666fa3d789dSPierre van Houtryve 6678a61bfcfSRahul Joshi #endif // LLVM_UTILS_TABLEGEN_COMMON_CODEGENSCHEDULE_H 668