xref: /llvm-project/llvm/utils/TableGen/Common/CodeGenSchedule.h (revision e19261faf5c771bd7951b987abe8de698469e9f1)
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