xref: /aosp_15_r20/external/llvm/utils/TableGen/CodeGenSchedule.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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