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