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