1 //===- CodeGenSchedule.cpp - Scheduling MachineModels ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines structures to encapsulate the machine model as described in
11 // the target description.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "CodeGenSchedule.h"
16 #include "CodeGenInstruction.h"
17 #include "CodeGenTarget.h"
18 #include "llvm/ADT/MapVector.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/SmallSet.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/Regex.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/TableGen/Error.h"
28 #include <algorithm>
29 #include <iterator>
30 #include <utility>
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "subtarget-emitter"
35 
36 #ifndef NDEBUG
37 static void dumpIdxVec(ArrayRef<unsigned> V) {
38   for (unsigned Idx : V)
39     dbgs() << Idx << ", ";
40 }
41 #endif
42 
43 namespace {
44 
45 // (instrs a, b, ...) Evaluate and union all arguments. Identical to AddOp.
46 struct InstrsOp : public SetTheory::Operator {
47   void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
48              ArrayRef<SMLoc> Loc) override {
49     ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc);
50   }
51 };
52 
53 // (instregex "OpcPat",...) Find all instructions matching an opcode pattern.
54 struct InstRegexOp : public SetTheory::Operator {
55   const CodeGenTarget &Target;
56   InstRegexOp(const CodeGenTarget &t): Target(t) {}
57 
58   /// Remove any text inside of parentheses from S.
59   static std::string removeParens(llvm::StringRef S) {
60     std::string Result;
61     unsigned Paren = 0;
62     // NB: We don't care about escaped parens here.
63     for (char C : S) {
64       switch (C) {
65       case '(':
66         ++Paren;
67         break;
68       case ')':
69         --Paren;
70         break;
71       default:
72         if (Paren == 0)
73           Result += C;
74       }
75     }
76     return Result;
77   }
78 
79   void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
80              ArrayRef<SMLoc> Loc) override {
81     for (Init *Arg : make_range(Expr->arg_begin(), Expr->arg_end())) {
82       StringInit *SI = dyn_cast<StringInit>(Arg);
83       if (!SI)
84         PrintFatalError(Loc, "instregex requires pattern string: " +
85                                  Expr->getAsString());
86       StringRef Original = SI->getValue();
87 
88       // Extract a prefix that we can binary search on.
89       static const char RegexMetachars[] = "()^$|*+?.[]\\{}";
90       auto FirstMeta = Original.find_first_of(RegexMetachars);
91 
92       // Look for top-level | or ?. We cannot optimize them to binary search.
93       if (removeParens(Original).find_first_of("|?") != std::string::npos)
94         FirstMeta = 0;
95 
96       Optional<Regex> Regexpr = None;
97       StringRef Prefix = Original.substr(0, FirstMeta);
98       StringRef PatStr = Original.substr(FirstMeta);
99       if (!PatStr.empty()) {
100         // For the rest use a python-style prefix match.
101         std::string pat = PatStr;
102         if (pat[0] != '^') {
103           pat.insert(0, "^(");
104           pat.insert(pat.end(), ')');
105         }
106         Regexpr = Regex(pat);
107       }
108 
109       int NumMatches = 0;
110 
111       unsigned NumGeneric = Target.getNumFixedInstructions();
112       ArrayRef<const CodeGenInstruction *> Generics =
113           Target.getInstructionsByEnumValue().slice(0, NumGeneric + 1);
114 
115       // The generic opcodes are unsorted, handle them manually.
116       for (auto *Inst : Generics) {
117         StringRef InstName = Inst->TheDef->getName();
118         if (InstName.startswith(Prefix) &&
119             (!Regexpr || Regexpr->match(InstName.substr(Prefix.size())))) {
120           Elts.insert(Inst->TheDef);
121           NumMatches++;
122         }
123       }
124 
125       ArrayRef<const CodeGenInstruction *> Instructions =
126           Target.getInstructionsByEnumValue().slice(NumGeneric + 1);
127 
128       // Target instructions are sorted. Find the range that starts with our
129       // prefix.
130       struct Comp {
131         bool operator()(const CodeGenInstruction *LHS, StringRef RHS) {
132           return LHS->TheDef->getName() < RHS;
133         }
134         bool operator()(StringRef LHS, const CodeGenInstruction *RHS) {
135           return LHS < RHS->TheDef->getName() &&
136                  !RHS->TheDef->getName().startswith(LHS);
137         }
138       };
139       auto Range = std::equal_range(Instructions.begin(), Instructions.end(),
140                                     Prefix, Comp());
141 
142       // For this range we know that it starts with the prefix. Check if there's
143       // a regex that needs to be checked.
144       for (auto *Inst : make_range(Range)) {
145         StringRef InstName = Inst->TheDef->getName();
146         if (!Regexpr || Regexpr->match(InstName.substr(Prefix.size()))) {
147           Elts.insert(Inst->TheDef);
148           NumMatches++;
149         }
150       }
151 
152       if (0 == NumMatches)
153         PrintFatalError(Loc, "instregex has no matches: " + Original);
154     }
155   }
156 };
157 
158 } // end anonymous namespace
159 
160 /// CodeGenModels ctor interprets machine model records and populates maps.
161 CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
162                                        const CodeGenTarget &TGT):
163   Records(RK), Target(TGT) {
164 
165   Sets.addFieldExpander("InstRW", "Instrs");
166 
167   // Allow Set evaluation to recognize the dags used in InstRW records:
168   // (instrs Op1, Op1...)
169   Sets.addOperator("instrs", llvm::make_unique<InstrsOp>());
170   Sets.addOperator("instregex", llvm::make_unique<InstRegexOp>(Target));
171 
172   // Instantiate a CodeGenProcModel for each SchedMachineModel with the values
173   // that are explicitly referenced in tablegen records. Resources associated
174   // with each processor will be derived later. Populate ProcModelMap with the
175   // CodeGenProcModel instances.
176   collectProcModels();
177 
178   // Instantiate a CodeGenSchedRW for each SchedReadWrite record explicitly
179   // defined, and populate SchedReads and SchedWrites vectors. Implicit
180   // SchedReadWrites that represent sequences derived from expanded variant will
181   // be inferred later.
182   collectSchedRW();
183 
184   // Instantiate a CodeGenSchedClass for each unique SchedRW signature directly
185   // required by an instruction definition, and populate SchedClassIdxMap. Set
186   // NumItineraryClasses to the number of explicit itinerary classes referenced
187   // by instructions. Set NumInstrSchedClasses to the number of itinerary
188   // classes plus any classes implied by instructions that derive from class
189   // Sched and provide SchedRW list. This does not infer any new classes from
190   // SchedVariant.
191   collectSchedClasses();
192 
193   // Find instruction itineraries for each processor. Sort and populate
194   // CodeGenProcModel::ItinDefList. (Cycle-to-cycle itineraries). This requires
195   // all itinerary classes to be discovered.
196   collectProcItins();
197 
198   // Find ItinRW records for each processor and itinerary class.
199   // (For per-operand resources mapped to itinerary classes).
200   collectProcItinRW();
201 
202   // Find UnsupportedFeatures records for each processor.
203   // (For per-operand resources mapped to itinerary classes).
204   collectProcUnsupportedFeatures();
205 
206   // Infer new SchedClasses from SchedVariant.
207   inferSchedClasses();
208 
209   // Populate each CodeGenProcModel's WriteResDefs, ReadAdvanceDefs, and
210   // ProcResourceDefs.
211   DEBUG(dbgs() << "\n+++ RESOURCE DEFINITIONS (collectProcResources) +++\n");
212   collectProcResources();
213 
214   // Collect optional processor description.
215   collectOptionalProcessorInfo();
216 
217   checkCompleteness();
218 }
219 
220 void CodeGenSchedModels::collectRetireControlUnits() {
221   RecVec Units = Records.getAllDerivedDefinitions("RetireControlUnit");
222 
223   for (Record *RCU : Units) {
224     CodeGenProcModel &PM = getProcModel(RCU->getValueAsDef("SchedModel"));
225     if (PM.RetireControlUnit) {
226       PrintError(RCU->getLoc(),
227                  "Expected a single RetireControlUnit definition");
228       PrintNote(PM.RetireControlUnit->getLoc(),
229                 "Previous definition of RetireControlUnit was here");
230     }
231     PM.RetireControlUnit = RCU;
232   }
233 }
234 
235 /// Collect optional processor information.
236 void CodeGenSchedModels::collectOptionalProcessorInfo() {
237   // Find register file definitions for each processor.
238   collectRegisterFiles();
239 
240   // Collect processor RetireControlUnit descriptors if available.
241   collectRetireControlUnits();
242 
243   // Find pfm counter definitions for each processor.
244   collectPfmCounters();
245 
246   checkCompleteness();
247 }
248 
249 /// Gather all processor models.
250 void CodeGenSchedModels::collectProcModels() {
251   RecVec ProcRecords = Records.getAllDerivedDefinitions("Processor");
252   llvm::sort(ProcRecords.begin(), ProcRecords.end(), LessRecordFieldName());
253 
254   // Reserve space because we can. Reallocation would be ok.
255   ProcModels.reserve(ProcRecords.size()+1);
256 
257   // Use idx=0 for NoModel/NoItineraries.
258   Record *NoModelDef = Records.getDef("NoSchedModel");
259   Record *NoItinsDef = Records.getDef("NoItineraries");
260   ProcModels.emplace_back(0, "NoSchedModel", NoModelDef, NoItinsDef);
261   ProcModelMap[NoModelDef] = 0;
262 
263   // For each processor, find a unique machine model.
264   DEBUG(dbgs() << "+++ PROCESSOR MODELs (addProcModel) +++\n");
265   for (Record *ProcRecord : ProcRecords)
266     addProcModel(ProcRecord);
267 }
268 
269 /// Get a unique processor model based on the defined MachineModel and
270 /// ProcessorItineraries.
271 void CodeGenSchedModels::addProcModel(Record *ProcDef) {
272   Record *ModelKey = getModelOrItinDef(ProcDef);
273   if (!ProcModelMap.insert(std::make_pair(ModelKey, ProcModels.size())).second)
274     return;
275 
276   std::string Name = ModelKey->getName();
277   if (ModelKey->isSubClassOf("SchedMachineModel")) {
278     Record *ItinsDef = ModelKey->getValueAsDef("Itineraries");
279     ProcModels.emplace_back(ProcModels.size(), Name, ModelKey, ItinsDef);
280   }
281   else {
282     // An itinerary is defined without a machine model. Infer a new model.
283     if (!ModelKey->getValueAsListOfDefs("IID").empty())
284       Name = Name + "Model";
285     ProcModels.emplace_back(ProcModels.size(), Name,
286                             ProcDef->getValueAsDef("SchedModel"), ModelKey);
287   }
288   DEBUG(ProcModels.back().dump());
289 }
290 
291 // Recursively find all reachable SchedReadWrite records.
292 static void scanSchedRW(Record *RWDef, RecVec &RWDefs,
293                         SmallPtrSet<Record*, 16> &RWSet) {
294   if (!RWSet.insert(RWDef).second)
295     return;
296   RWDefs.push_back(RWDef);
297   // Reads don't currently have sequence records, but it can be added later.
298   if (RWDef->isSubClassOf("WriteSequence")) {
299     RecVec Seq = RWDef->getValueAsListOfDefs("Writes");
300     for (Record *WSRec : Seq)
301       scanSchedRW(WSRec, RWDefs, RWSet);
302   }
303   else if (RWDef->isSubClassOf("SchedVariant")) {
304     // Visit each variant (guarded by a different predicate).
305     RecVec Vars = RWDef->getValueAsListOfDefs("Variants");
306     for (Record *Variant : Vars) {
307       // Visit each RW in the sequence selected by the current variant.
308       RecVec Selected = Variant->getValueAsListOfDefs("Selected");
309       for (Record *SelDef : Selected)
310         scanSchedRW(SelDef, RWDefs, RWSet);
311     }
312   }
313 }
314 
315 // Collect and sort all SchedReadWrites reachable via tablegen records.
316 // More may be inferred later when inferring new SchedClasses from variants.
317 void CodeGenSchedModels::collectSchedRW() {
318   // Reserve idx=0 for invalid writes/reads.
319   SchedWrites.resize(1);
320   SchedReads.resize(1);
321 
322   SmallPtrSet<Record*, 16> RWSet;
323 
324   // Find all SchedReadWrites referenced by instruction defs.
325   RecVec SWDefs, SRDefs;
326   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
327     Record *SchedDef = Inst->TheDef;
328     if (SchedDef->isValueUnset("SchedRW"))
329       continue;
330     RecVec RWs = SchedDef->getValueAsListOfDefs("SchedRW");
331     for (Record *RW : RWs) {
332       if (RW->isSubClassOf("SchedWrite"))
333         scanSchedRW(RW, SWDefs, RWSet);
334       else {
335         assert(RW->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
336         scanSchedRW(RW, SRDefs, RWSet);
337       }
338     }
339   }
340   // Find all ReadWrites referenced by InstRW.
341   RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
342   for (Record *InstRWDef : InstRWDefs) {
343     // For all OperandReadWrites.
344     RecVec RWDefs = InstRWDef->getValueAsListOfDefs("OperandReadWrites");
345     for (Record *RWDef : RWDefs) {
346       if (RWDef->isSubClassOf("SchedWrite"))
347         scanSchedRW(RWDef, SWDefs, RWSet);
348       else {
349         assert(RWDef->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
350         scanSchedRW(RWDef, SRDefs, RWSet);
351       }
352     }
353   }
354   // Find all ReadWrites referenced by ItinRW.
355   RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW");
356   for (Record *ItinRWDef : ItinRWDefs) {
357     // For all OperandReadWrites.
358     RecVec RWDefs = ItinRWDef->getValueAsListOfDefs("OperandReadWrites");
359     for (Record *RWDef : RWDefs) {
360       if (RWDef->isSubClassOf("SchedWrite"))
361         scanSchedRW(RWDef, SWDefs, RWSet);
362       else {
363         assert(RWDef->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
364         scanSchedRW(RWDef, SRDefs, RWSet);
365       }
366     }
367   }
368   // Find all ReadWrites referenced by SchedAlias. AliasDefs needs to be sorted
369   // for the loop below that initializes Alias vectors.
370   RecVec AliasDefs = Records.getAllDerivedDefinitions("SchedAlias");
371   llvm::sort(AliasDefs.begin(), AliasDefs.end(), LessRecord());
372   for (Record *ADef : AliasDefs) {
373     Record *MatchDef = ADef->getValueAsDef("MatchRW");
374     Record *AliasDef = ADef->getValueAsDef("AliasRW");
375     if (MatchDef->isSubClassOf("SchedWrite")) {
376       if (!AliasDef->isSubClassOf("SchedWrite"))
377         PrintFatalError(ADef->getLoc(), "SchedWrite Alias must be SchedWrite");
378       scanSchedRW(AliasDef, SWDefs, RWSet);
379     }
380     else {
381       assert(MatchDef->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
382       if (!AliasDef->isSubClassOf("SchedRead"))
383         PrintFatalError(ADef->getLoc(), "SchedRead Alias must be SchedRead");
384       scanSchedRW(AliasDef, SRDefs, RWSet);
385     }
386   }
387   // Sort and add the SchedReadWrites directly referenced by instructions or
388   // itinerary resources. Index reads and writes in separate domains.
389   llvm::sort(SWDefs.begin(), SWDefs.end(), LessRecord());
390   for (Record *SWDef : SWDefs) {
391     assert(!getSchedRWIdx(SWDef, /*IsRead=*/false) && "duplicate SchedWrite");
392     SchedWrites.emplace_back(SchedWrites.size(), SWDef);
393   }
394   llvm::sort(SRDefs.begin(), SRDefs.end(), LessRecord());
395   for (Record *SRDef : SRDefs) {
396     assert(!getSchedRWIdx(SRDef, /*IsRead-*/true) && "duplicate SchedWrite");
397     SchedReads.emplace_back(SchedReads.size(), SRDef);
398   }
399   // Initialize WriteSequence vectors.
400   for (CodeGenSchedRW &CGRW : SchedWrites) {
401     if (!CGRW.IsSequence)
402       continue;
403     findRWs(CGRW.TheDef->getValueAsListOfDefs("Writes"), CGRW.Sequence,
404             /*IsRead=*/false);
405   }
406   // Initialize Aliases vectors.
407   for (Record *ADef : AliasDefs) {
408     Record *AliasDef = ADef->getValueAsDef("AliasRW");
409     getSchedRW(AliasDef).IsAlias = true;
410     Record *MatchDef = ADef->getValueAsDef("MatchRW");
411     CodeGenSchedRW &RW = getSchedRW(MatchDef);
412     if (RW.IsAlias)
413       PrintFatalError(ADef->getLoc(), "Cannot Alias an Alias");
414     RW.Aliases.push_back(ADef);
415   }
416   DEBUG(
417     dbgs() << "\n+++ SCHED READS and WRITES (collectSchedRW) +++\n";
418     for (unsigned WIdx = 0, WEnd = SchedWrites.size(); WIdx != WEnd; ++WIdx) {
419       dbgs() << WIdx << ": ";
420       SchedWrites[WIdx].dump();
421       dbgs() << '\n';
422     }
423     for (unsigned RIdx = 0, REnd = SchedReads.size(); RIdx != REnd; ++RIdx) {
424       dbgs() << RIdx << ": ";
425       SchedReads[RIdx].dump();
426       dbgs() << '\n';
427     }
428     RecVec RWDefs = Records.getAllDerivedDefinitions("SchedReadWrite");
429     for (Record *RWDef : RWDefs) {
430       if (!getSchedRWIdx(RWDef, RWDef->isSubClassOf("SchedRead"))) {
431         StringRef Name = RWDef->getName();
432         if (Name != "NoWrite" && Name != "ReadDefault")
433           dbgs() << "Unused SchedReadWrite " << Name << '\n';
434       }
435     });
436 }
437 
438 /// Compute a SchedWrite name from a sequence of writes.
439 std::string CodeGenSchedModels::genRWName(ArrayRef<unsigned> Seq, bool IsRead) {
440   std::string Name("(");
441   for (auto I = Seq.begin(), E = Seq.end(); I != E; ++I) {
442     if (I != Seq.begin())
443       Name += '_';
444     Name += getSchedRW(*I, IsRead).Name;
445   }
446   Name += ')';
447   return Name;
448 }
449 
450 unsigned CodeGenSchedModels::getSchedRWIdx(const Record *Def,
451                                            bool IsRead) const {
452   const std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites;
453   const auto I = find_if(
454       RWVec, [Def](const CodeGenSchedRW &RW) { return RW.TheDef == Def; });
455   return I == RWVec.end() ? 0 : std::distance(RWVec.begin(), I);
456 }
457 
458 bool CodeGenSchedModels::hasReadOfWrite(Record *WriteDef) const {
459   for (const CodeGenSchedRW &Read : SchedReads) {
460     Record *ReadDef = Read.TheDef;
461     if (!ReadDef || !ReadDef->isSubClassOf("ProcReadAdvance"))
462       continue;
463 
464     RecVec ValidWrites = ReadDef->getValueAsListOfDefs("ValidWrites");
465     if (is_contained(ValidWrites, WriteDef)) {
466       return true;
467     }
468   }
469   return false;
470 }
471 
472 static void splitSchedReadWrites(const RecVec &RWDefs,
473                                  RecVec &WriteDefs, RecVec &ReadDefs) {
474   for (Record *RWDef : RWDefs) {
475     if (RWDef->isSubClassOf("SchedWrite"))
476       WriteDefs.push_back(RWDef);
477     else {
478       assert(RWDef->isSubClassOf("SchedRead") && "unknown SchedReadWrite");
479       ReadDefs.push_back(RWDef);
480     }
481   }
482 }
483 
484 // Split the SchedReadWrites defs and call findRWs for each list.
485 void CodeGenSchedModels::findRWs(const RecVec &RWDefs,
486                                  IdxVec &Writes, IdxVec &Reads) const {
487   RecVec WriteDefs;
488   RecVec ReadDefs;
489   splitSchedReadWrites(RWDefs, WriteDefs, ReadDefs);
490   findRWs(WriteDefs, Writes, false);
491   findRWs(ReadDefs, Reads, true);
492 }
493 
494 // Call getSchedRWIdx for all elements in a sequence of SchedRW defs.
495 void CodeGenSchedModels::findRWs(const RecVec &RWDefs, IdxVec &RWs,
496                                  bool IsRead) const {
497   for (Record *RWDef : RWDefs) {
498     unsigned Idx = getSchedRWIdx(RWDef, IsRead);
499     assert(Idx && "failed to collect SchedReadWrite");
500     RWs.push_back(Idx);
501   }
502 }
503 
504 void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq,
505                                           bool IsRead) const {
506   const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead);
507   if (!SchedRW.IsSequence) {
508     RWSeq.push_back(RWIdx);
509     return;
510   }
511   int Repeat =
512     SchedRW.TheDef ? SchedRW.TheDef->getValueAsInt("Repeat") : 1;
513   for (int i = 0; i < Repeat; ++i) {
514     for (unsigned I : SchedRW.Sequence) {
515       expandRWSequence(I, RWSeq, IsRead);
516     }
517   }
518 }
519 
520 // Expand a SchedWrite as a sequence following any aliases that coincide with
521 // the given processor model.
522 void CodeGenSchedModels::expandRWSeqForProc(
523   unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
524   const CodeGenProcModel &ProcModel) const {
525 
526   const CodeGenSchedRW &SchedWrite = getSchedRW(RWIdx, IsRead);
527   Record *AliasDef = nullptr;
528   for (const Record *Rec : SchedWrite.Aliases) {
529     const CodeGenSchedRW &AliasRW = getSchedRW(Rec->getValueAsDef("AliasRW"));
530     if (Rec->getValueInit("SchedModel")->isComplete()) {
531       Record *ModelDef = Rec->getValueAsDef("SchedModel");
532       if (&getProcModel(ModelDef) != &ProcModel)
533         continue;
534     }
535     if (AliasDef)
536       PrintFatalError(AliasRW.TheDef->getLoc(), "Multiple aliases "
537                       "defined for processor " + ProcModel.ModelName +
538                       " Ensure only one SchedAlias exists per RW.");
539     AliasDef = AliasRW.TheDef;
540   }
541   if (AliasDef) {
542     expandRWSeqForProc(getSchedRWIdx(AliasDef, IsRead),
543                        RWSeq, IsRead,ProcModel);
544     return;
545   }
546   if (!SchedWrite.IsSequence) {
547     RWSeq.push_back(RWIdx);
548     return;
549   }
550   int Repeat =
551     SchedWrite.TheDef ? SchedWrite.TheDef->getValueAsInt("Repeat") : 1;
552   for (int I = 0, E = Repeat; I < E; ++I) {
553     for (unsigned Idx : SchedWrite.Sequence) {
554       expandRWSeqForProc(Idx, RWSeq, IsRead, ProcModel);
555     }
556   }
557 }
558 
559 // Find the existing SchedWrite that models this sequence of writes.
560 unsigned CodeGenSchedModels::findRWForSequence(ArrayRef<unsigned> Seq,
561                                                bool IsRead) {
562   std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites;
563 
564   auto I = find_if(RWVec, [Seq](CodeGenSchedRW &RW) {
565     return makeArrayRef(RW.Sequence) == Seq;
566   });
567   // Index zero reserved for invalid RW.
568   return I == RWVec.end() ? 0 : std::distance(RWVec.begin(), I);
569 }
570 
571 /// Add this ReadWrite if it doesn't already exist.
572 unsigned CodeGenSchedModels::findOrInsertRW(ArrayRef<unsigned> Seq,
573                                             bool IsRead) {
574   assert(!Seq.empty() && "cannot insert empty sequence");
575   if (Seq.size() == 1)
576     return Seq.back();
577 
578   unsigned Idx = findRWForSequence(Seq, IsRead);
579   if (Idx)
580     return Idx;
581 
582   std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites;
583   unsigned RWIdx = RWVec.size();
584   CodeGenSchedRW SchedRW(RWIdx, IsRead, Seq, genRWName(Seq, IsRead));
585   RWVec.push_back(SchedRW);
586   return RWIdx;
587 }
588 
589 /// Visit all the instruction definitions for this target to gather and
590 /// enumerate the itinerary classes. These are the explicitly specified
591 /// SchedClasses. More SchedClasses may be inferred.
592 void CodeGenSchedModels::collectSchedClasses() {
593 
594   // NoItinerary is always the first class at Idx=0
595   assert(SchedClasses.empty() && "Expected empty sched class");
596   SchedClasses.emplace_back(0, "NoInstrModel",
597                             Records.getDef("NoItinerary"));
598   SchedClasses.back().ProcIndices.push_back(0);
599 
600   // Create a SchedClass for each unique combination of itinerary class and
601   // SchedRW list.
602   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
603     Record *ItinDef = Inst->TheDef->getValueAsDef("Itinerary");
604     IdxVec Writes, Reads;
605     if (!Inst->TheDef->isValueUnset("SchedRW"))
606       findRWs(Inst->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads);
607 
608     // ProcIdx == 0 indicates the class applies to all processors.
609     unsigned SCIdx = addSchedClass(ItinDef, Writes, Reads, /*ProcIndices*/{0});
610     InstrClassMap[Inst->TheDef] = SCIdx;
611   }
612   // Create classes for InstRW defs.
613   RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
614   llvm::sort(InstRWDefs.begin(), InstRWDefs.end(), LessRecord());
615   DEBUG(dbgs() << "\n+++ SCHED CLASSES (createInstRWClass) +++\n");
616   for (Record *RWDef : InstRWDefs)
617     createInstRWClass(RWDef);
618 
619   NumInstrSchedClasses = SchedClasses.size();
620 
621   bool EnableDump = false;
622   DEBUG(EnableDump = true);
623   if (!EnableDump)
624     return;
625 
626   DEBUG(
627       dbgs()
628       << "\n+++ ITINERARIES and/or MACHINE MODELS (collectSchedClasses) +++\n");
629   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
630     StringRef InstName = Inst->TheDef->getName();
631     unsigned SCIdx = getSchedClassIdx(*Inst);
632     if (!SCIdx) {
633       DEBUG({
634         if (!Inst->hasNoSchedulingInfo)
635           dbgs() << "No machine model for " << Inst->TheDef->getName() << '\n';
636       });
637       continue;
638     }
639     CodeGenSchedClass &SC = getSchedClass(SCIdx);
640     if (SC.ProcIndices[0] != 0)
641       PrintFatalError(Inst->TheDef->getLoc(), "Instruction's sched class "
642                       "must not be subtarget specific.");
643 
644     IdxVec ProcIndices;
645     if (SC.ItinClassDef->getName() != "NoItinerary") {
646       ProcIndices.push_back(0);
647       dbgs() << "Itinerary for " << InstName << ": "
648              << SC.ItinClassDef->getName() << '\n';
649     }
650     if (!SC.Writes.empty()) {
651       ProcIndices.push_back(0);
652       DEBUG({
653         dbgs() << "SchedRW machine model for " << InstName;
654         for (IdxIter WI = SC.Writes.begin(), WE = SC.Writes.end(); WI != WE;
655              ++WI)
656           dbgs() << " " << SchedWrites[*WI].Name;
657         for (IdxIter RI = SC.Reads.begin(), RE = SC.Reads.end(); RI != RE; ++RI)
658           dbgs() << " " << SchedReads[*RI].Name;
659         dbgs() << '\n';
660       });
661     }
662     const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
663     for (Record *RWDef : RWDefs) {
664       const CodeGenProcModel &ProcModel =
665           getProcModel(RWDef->getValueAsDef("SchedModel"));
666       ProcIndices.push_back(ProcModel.Index);
667       DEBUG(dbgs() << "InstRW on " << ProcModel.ModelName << " for " << InstName);
668       IdxVec Writes;
669       IdxVec Reads;
670       findRWs(RWDef->getValueAsListOfDefs("OperandReadWrites"),
671               Writes, Reads);
672       DEBUG({
673         for (unsigned WIdx : Writes)
674           dbgs() << " " << SchedWrites[WIdx].Name;
675         for (unsigned RIdx : Reads)
676           dbgs() << " " << SchedReads[RIdx].Name;
677         dbgs() << '\n';
678       });
679     }
680     // If ProcIndices contains zero, the class applies to all processors.
681     DEBUG({
682       if (!std::count(ProcIndices.begin(), ProcIndices.end(), 0)) {
683         for (const CodeGenProcModel &PM : ProcModels) {
684           if (!std::count(ProcIndices.begin(), ProcIndices.end(), PM.Index))
685             dbgs() << "No machine model for " << Inst->TheDef->getName()
686                    << " on processor " << PM.ModelName << '\n';
687         }
688       }
689     });
690   }
691 }
692 
693 // Get the SchedClass index for an instruction.
694 unsigned
695 CodeGenSchedModels::getSchedClassIdx(const CodeGenInstruction &Inst) const {
696   return InstrClassMap.lookup(Inst.TheDef);
697 }
698 
699 std::string
700 CodeGenSchedModels::createSchedClassName(Record *ItinClassDef,
701                                          ArrayRef<unsigned> OperWrites,
702                                          ArrayRef<unsigned> OperReads) {
703 
704   std::string Name;
705   if (ItinClassDef && ItinClassDef->getName() != "NoItinerary")
706     Name = ItinClassDef->getName();
707   for (unsigned Idx : OperWrites) {
708     if (!Name.empty())
709       Name += '_';
710     Name += SchedWrites[Idx].Name;
711   }
712   for (unsigned Idx : OperReads) {
713     Name += '_';
714     Name += SchedReads[Idx].Name;
715   }
716   return Name;
717 }
718 
719 std::string CodeGenSchedModels::createSchedClassName(const RecVec &InstDefs) {
720 
721   std::string Name;
722   for (RecIter I = InstDefs.begin(), E = InstDefs.end(); I != E; ++I) {
723     if (I != InstDefs.begin())
724       Name += '_';
725     Name += (*I)->getName();
726   }
727   return Name;
728 }
729 
730 /// Add an inferred sched class from an itinerary class and per-operand list of
731 /// SchedWrites and SchedReads. ProcIndices contains the set of IDs of
732 /// processors that may utilize this class.
733 unsigned CodeGenSchedModels::addSchedClass(Record *ItinClassDef,
734                                            ArrayRef<unsigned> OperWrites,
735                                            ArrayRef<unsigned> OperReads,
736                                            ArrayRef<unsigned> ProcIndices) {
737   assert(!ProcIndices.empty() && "expect at least one ProcIdx");
738 
739   auto IsKeyEqual = [=](const CodeGenSchedClass &SC) {
740                      return SC.isKeyEqual(ItinClassDef, OperWrites, OperReads);
741                    };
742 
743   auto I = find_if(make_range(schedClassBegin(), schedClassEnd()), IsKeyEqual);
744   unsigned Idx = I == schedClassEnd() ? 0 : std::distance(schedClassBegin(), I);
745   if (Idx || SchedClasses[0].isKeyEqual(ItinClassDef, OperWrites, OperReads)) {
746     IdxVec PI;
747     std::set_union(SchedClasses[Idx].ProcIndices.begin(),
748                    SchedClasses[Idx].ProcIndices.end(),
749                    ProcIndices.begin(), ProcIndices.end(),
750                    std::back_inserter(PI));
751     SchedClasses[Idx].ProcIndices = std::move(PI);
752     return Idx;
753   }
754   Idx = SchedClasses.size();
755   SchedClasses.emplace_back(Idx,
756                             createSchedClassName(ItinClassDef, OperWrites,
757                                                  OperReads),
758                             ItinClassDef);
759   CodeGenSchedClass &SC = SchedClasses.back();
760   SC.Writes = OperWrites;
761   SC.Reads = OperReads;
762   SC.ProcIndices = ProcIndices;
763 
764   return Idx;
765 }
766 
767 // Create classes for each set of opcodes that are in the same InstReadWrite
768 // definition across all processors.
769 void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
770   // ClassInstrs will hold an entry for each subset of Instrs in InstRWDef that
771   // intersects with an existing class via a previous InstRWDef. Instrs that do
772   // not intersect with an existing class refer back to their former class as
773   // determined from ItinDef or SchedRW.
774   SmallMapVector<unsigned, SmallVector<Record *, 8>, 4> ClassInstrs;
775   // Sort Instrs into sets.
776   const RecVec *InstDefs = Sets.expand(InstRWDef);
777   if (InstDefs->empty())
778     PrintFatalError(InstRWDef->getLoc(), "No matching instruction opcodes");
779 
780   for (Record *InstDef : *InstDefs) {
781     InstClassMapTy::const_iterator Pos = InstrClassMap.find(InstDef);
782     if (Pos == InstrClassMap.end())
783       PrintFatalError(InstDef->getLoc(), "No sched class for instruction.");
784     unsigned SCIdx = Pos->second;
785     ClassInstrs[SCIdx].push_back(InstDef);
786   }
787   // For each set of Instrs, create a new class if necessary, and map or remap
788   // the Instrs to it.
789   for (auto &Entry : ClassInstrs) {
790     unsigned OldSCIdx = Entry.first;
791     ArrayRef<Record*> InstDefs = Entry.second;
792     // If the all instrs in the current class are accounted for, then leave
793     // them mapped to their old class.
794     if (OldSCIdx) {
795       const RecVec &RWDefs = SchedClasses[OldSCIdx].InstRWs;
796       if (!RWDefs.empty()) {
797         const RecVec *OrigInstDefs = Sets.expand(RWDefs[0]);
798         unsigned OrigNumInstrs =
799           count_if(*OrigInstDefs, [&](Record *OIDef) {
800                      return InstrClassMap[OIDef] == OldSCIdx;
801                    });
802         if (OrigNumInstrs == InstDefs.size()) {
803           assert(SchedClasses[OldSCIdx].ProcIndices[0] == 0 &&
804                  "expected a generic SchedClass");
805           Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
806           // Make sure we didn't already have a InstRW containing this
807           // instruction on this model.
808           for (Record *RWD : RWDefs) {
809             if (RWD->getValueAsDef("SchedModel") == RWModelDef &&
810                 RWModelDef->getValueAsBit("FullInstRWOverlapCheck")) {
811               for (Record *Inst : InstDefs) {
812                 PrintFatalError(InstRWDef->getLoc(), "Overlapping InstRW def " +
813                             Inst->getName() + " also matches " +
814                             RWD->getValue("Instrs")->getValue()->getAsString());
815               }
816             }
817           }
818           DEBUG(dbgs() << "InstRW: Reuse SC " << OldSCIdx << ":"
819                 << SchedClasses[OldSCIdx].Name << " on "
820                 << RWModelDef->getName() << "\n");
821           SchedClasses[OldSCIdx].InstRWs.push_back(InstRWDef);
822           continue;
823         }
824       }
825     }
826     unsigned SCIdx = SchedClasses.size();
827     SchedClasses.emplace_back(SCIdx, createSchedClassName(InstDefs), nullptr);
828     CodeGenSchedClass &SC = SchedClasses.back();
829     DEBUG(dbgs() << "InstRW: New SC " << SCIdx << ":" << SC.Name << " on "
830           << InstRWDef->getValueAsDef("SchedModel")->getName() << "\n");
831 
832     // Preserve ItinDef and Writes/Reads for processors without an InstRW entry.
833     SC.ItinClassDef = SchedClasses[OldSCIdx].ItinClassDef;
834     SC.Writes = SchedClasses[OldSCIdx].Writes;
835     SC.Reads = SchedClasses[OldSCIdx].Reads;
836     SC.ProcIndices.push_back(0);
837     // If we had an old class, copy it's InstRWs to this new class.
838     if (OldSCIdx) {
839       Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
840       for (Record *OldRWDef : SchedClasses[OldSCIdx].InstRWs) {
841         if (OldRWDef->getValueAsDef("SchedModel") == RWModelDef) {
842           for (Record *InstDef : InstDefs) {
843             PrintFatalError(OldRWDef->getLoc(), "Overlapping InstRW def " +
844                        InstDef->getName() + " also matches " +
845                        OldRWDef->getValue("Instrs")->getValue()->getAsString());
846           }
847         }
848         assert(OldRWDef != InstRWDef &&
849                "SchedClass has duplicate InstRW def");
850         SC.InstRWs.push_back(OldRWDef);
851       }
852     }
853     // Map each Instr to this new class.
854     for (Record *InstDef : InstDefs)
855       InstrClassMap[InstDef] = SCIdx;
856     SC.InstRWs.push_back(InstRWDef);
857   }
858 }
859 
860 // True if collectProcItins found anything.
861 bool CodeGenSchedModels::hasItineraries() const {
862   for (const CodeGenProcModel &PM : make_range(procModelBegin(),procModelEnd()))
863     if (PM.hasItineraries())
864       return true;
865   return false;
866 }
867 
868 // Gather the processor itineraries.
869 void CodeGenSchedModels::collectProcItins() {
870   DEBUG(dbgs() << "\n+++ PROBLEM ITINERARIES (collectProcItins) +++\n");
871   for (CodeGenProcModel &ProcModel : ProcModels) {
872     if (!ProcModel.hasItineraries())
873       continue;
874 
875     RecVec ItinRecords = ProcModel.ItinsDef->getValueAsListOfDefs("IID");
876     assert(!ItinRecords.empty() && "ProcModel.hasItineraries is incorrect");
877 
878     // Populate ItinDefList with Itinerary records.
879     ProcModel.ItinDefList.resize(NumInstrSchedClasses);
880 
881     // Insert each itinerary data record in the correct position within
882     // the processor model's ItinDefList.
883     for (Record *ItinData : ItinRecords) {
884       const Record *ItinDef = ItinData->getValueAsDef("TheClass");
885       bool FoundClass = false;
886 
887       for (const CodeGenSchedClass &SC :
888            make_range(schedClassBegin(), schedClassEnd())) {
889         // Multiple SchedClasses may share an itinerary. Update all of them.
890         if (SC.ItinClassDef == ItinDef) {
891           ProcModel.ItinDefList[SC.Index] = ItinData;
892           FoundClass = true;
893         }
894       }
895       if (!FoundClass) {
896         DEBUG(dbgs() << ProcModel.ItinsDef->getName()
897               << " missing class for itinerary " << ItinDef->getName() << '\n');
898       }
899     }
900     // Check for missing itinerary entries.
901     assert(!ProcModel.ItinDefList[0] && "NoItinerary class can't have rec");
902     DEBUG(
903       for (unsigned i = 1, N = ProcModel.ItinDefList.size(); i < N; ++i) {
904         if (!ProcModel.ItinDefList[i])
905           dbgs() << ProcModel.ItinsDef->getName()
906                  << " missing itinerary for class "
907                  << SchedClasses[i].Name << '\n';
908       });
909   }
910 }
911 
912 // Gather the read/write types for each itinerary class.
913 void CodeGenSchedModels::collectProcItinRW() {
914   RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW");
915   llvm::sort(ItinRWDefs.begin(), ItinRWDefs.end(), LessRecord());
916   for (Record *RWDef  : ItinRWDefs) {
917     if (!RWDef->getValueInit("SchedModel")->isComplete())
918       PrintFatalError(RWDef->getLoc(), "SchedModel is undefined");
919     Record *ModelDef = RWDef->getValueAsDef("SchedModel");
920     ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef);
921     if (I == ProcModelMap.end()) {
922       PrintFatalError(RWDef->getLoc(), "Undefined SchedMachineModel "
923                     + ModelDef->getName());
924     }
925     ProcModels[I->second].ItinRWDefs.push_back(RWDef);
926   }
927 }
928 
929 // Gather the unsupported features for processor models.
930 void CodeGenSchedModels::collectProcUnsupportedFeatures() {
931   for (CodeGenProcModel &ProcModel : ProcModels) {
932     for (Record *Pred : ProcModel.ModelDef->getValueAsListOfDefs("UnsupportedFeatures")) {
933        ProcModel.UnsupportedFeaturesDefs.push_back(Pred);
934     }
935   }
936 }
937 
938 /// Infer new classes from existing classes. In the process, this may create new
939 /// SchedWrites from sequences of existing SchedWrites.
940 void CodeGenSchedModels::inferSchedClasses() {
941   DEBUG(dbgs() << "\n+++ INFERRING SCHED CLASSES (inferSchedClasses) +++\n");
942   DEBUG(dbgs() << NumInstrSchedClasses << " instr sched classes.\n");
943 
944   // Visit all existing classes and newly created classes.
945   for (unsigned Idx = 0; Idx != SchedClasses.size(); ++Idx) {
946     assert(SchedClasses[Idx].Index == Idx && "bad SCIdx");
947 
948     if (SchedClasses[Idx].ItinClassDef)
949       inferFromItinClass(SchedClasses[Idx].ItinClassDef, Idx);
950     if (!SchedClasses[Idx].InstRWs.empty())
951       inferFromInstRWs(Idx);
952     if (!SchedClasses[Idx].Writes.empty()) {
953       inferFromRW(SchedClasses[Idx].Writes, SchedClasses[Idx].Reads,
954                   Idx, SchedClasses[Idx].ProcIndices);
955     }
956     assert(SchedClasses.size() < (NumInstrSchedClasses*6) &&
957            "too many SchedVariants");
958   }
959 }
960 
961 /// Infer classes from per-processor itinerary resources.
962 void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef,
963                                             unsigned FromClassIdx) {
964   for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
965     const CodeGenProcModel &PM = ProcModels[PIdx];
966     // For all ItinRW entries.
967     bool HasMatch = false;
968     for (const Record *Rec : PM.ItinRWDefs) {
969       RecVec Matched = Rec->getValueAsListOfDefs("MatchedItinClasses");
970       if (!std::count(Matched.begin(), Matched.end(), ItinClassDef))
971         continue;
972       if (HasMatch)
973         PrintFatalError(Rec->getLoc(), "Duplicate itinerary class "
974                       + ItinClassDef->getName()
975                       + " in ItinResources for " + PM.ModelName);
976       HasMatch = true;
977       IdxVec Writes, Reads;
978       findRWs(Rec->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
979       inferFromRW(Writes, Reads, FromClassIdx, PIdx);
980     }
981   }
982 }
983 
984 /// Infer classes from per-processor InstReadWrite definitions.
985 void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) {
986   for (unsigned I = 0, E = SchedClasses[SCIdx].InstRWs.size(); I != E; ++I) {
987     assert(SchedClasses[SCIdx].InstRWs.size() == E && "InstrRWs was mutated!");
988     Record *Rec = SchedClasses[SCIdx].InstRWs[I];
989     const RecVec *InstDefs = Sets.expand(Rec);
990     RecIter II = InstDefs->begin(), IE = InstDefs->end();
991     for (; II != IE; ++II) {
992       if (InstrClassMap[*II] == SCIdx)
993         break;
994     }
995     // If this class no longer has any instructions mapped to it, it has become
996     // irrelevant.
997     if (II == IE)
998       continue;
999     IdxVec Writes, Reads;
1000     findRWs(Rec->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
1001     unsigned PIdx = getProcModel(Rec->getValueAsDef("SchedModel")).Index;
1002     inferFromRW(Writes, Reads, SCIdx, PIdx); // May mutate SchedClasses.
1003   }
1004 }
1005 
1006 namespace {
1007 
1008 // Helper for substituteVariantOperand.
1009 struct TransVariant {
1010   Record *VarOrSeqDef;  // Variant or sequence.
1011   unsigned RWIdx;       // Index of this variant or sequence's matched type.
1012   unsigned ProcIdx;     // Processor model index or zero for any.
1013   unsigned TransVecIdx; // Index into PredTransitions::TransVec.
1014 
1015   TransVariant(Record *def, unsigned rwi, unsigned pi, unsigned ti):
1016     VarOrSeqDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {}
1017 };
1018 
1019 // Associate a predicate with the SchedReadWrite that it guards.
1020 // RWIdx is the index of the read/write variant.
1021 struct PredCheck {
1022   bool IsRead;
1023   unsigned RWIdx;
1024   Record *Predicate;
1025 
1026   PredCheck(bool r, unsigned w, Record *p): IsRead(r), RWIdx(w), Predicate(p) {}
1027 };
1028 
1029 // A Predicate transition is a list of RW sequences guarded by a PredTerm.
1030 struct PredTransition {
1031   // A predicate term is a conjunction of PredChecks.
1032   SmallVector<PredCheck, 4> PredTerm;
1033   SmallVector<SmallVector<unsigned,4>, 16> WriteSequences;
1034   SmallVector<SmallVector<unsigned,4>, 16> ReadSequences;
1035   SmallVector<unsigned, 4> ProcIndices;
1036 };
1037 
1038 // Encapsulate a set of partially constructed transitions.
1039 // The results are built by repeated calls to substituteVariants.
1040 class PredTransitions {
1041   CodeGenSchedModels &SchedModels;
1042 
1043 public:
1044   std::vector<PredTransition> TransVec;
1045 
1046   PredTransitions(CodeGenSchedModels &sm): SchedModels(sm) {}
1047 
1048   void substituteVariantOperand(const SmallVectorImpl<unsigned> &RWSeq,
1049                                 bool IsRead, unsigned StartIdx);
1050 
1051   void substituteVariants(const PredTransition &Trans);
1052 
1053 #ifndef NDEBUG
1054   void dump() const;
1055 #endif
1056 
1057 private:
1058   bool mutuallyExclusive(Record *PredDef, ArrayRef<PredCheck> Term);
1059   void getIntersectingVariants(
1060     const CodeGenSchedRW &SchedRW, unsigned TransIdx,
1061     std::vector<TransVariant> &IntersectingVariants);
1062   void pushVariant(const TransVariant &VInfo, bool IsRead);
1063 };
1064 
1065 } // end anonymous namespace
1066 
1067 // Return true if this predicate is mutually exclusive with a PredTerm. This
1068 // degenerates into checking if the predicate is mutually exclusive with any
1069 // predicate in the Term's conjunction.
1070 //
1071 // All predicates associated with a given SchedRW are considered mutually
1072 // exclusive. This should work even if the conditions expressed by the
1073 // predicates are not exclusive because the predicates for a given SchedWrite
1074 // are always checked in the order they are defined in the .td file. Later
1075 // conditions implicitly negate any prior condition.
1076 bool PredTransitions::mutuallyExclusive(Record *PredDef,
1077                                         ArrayRef<PredCheck> Term) {
1078   for (const PredCheck &PC: Term) {
1079     if (PC.Predicate == PredDef)
1080       return false;
1081 
1082     const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(PC.RWIdx, PC.IsRead);
1083     assert(SchedRW.HasVariants && "PredCheck must refer to a SchedVariant");
1084     RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants");
1085     if (any_of(Variants, [PredDef](const Record *R) {
1086           return R->getValueAsDef("Predicate") == PredDef;
1087         }))
1088       return true;
1089   }
1090   return false;
1091 }
1092 
1093 static bool hasAliasedVariants(const CodeGenSchedRW &RW,
1094                                CodeGenSchedModels &SchedModels) {
1095   if (RW.HasVariants)
1096     return true;
1097 
1098   for (Record *Alias : RW.Aliases) {
1099     const CodeGenSchedRW &AliasRW =
1100       SchedModels.getSchedRW(Alias->getValueAsDef("AliasRW"));
1101     if (AliasRW.HasVariants)
1102       return true;
1103     if (AliasRW.IsSequence) {
1104       IdxVec ExpandedRWs;
1105       SchedModels.expandRWSequence(AliasRW.Index, ExpandedRWs, AliasRW.IsRead);
1106       for (unsigned SI : ExpandedRWs) {
1107         if (hasAliasedVariants(SchedModels.getSchedRW(SI, AliasRW.IsRead),
1108                                SchedModels))
1109           return true;
1110       }
1111     }
1112   }
1113   return false;
1114 }
1115 
1116 static bool hasVariant(ArrayRef<PredTransition> Transitions,
1117                        CodeGenSchedModels &SchedModels) {
1118   for (const PredTransition &PTI : Transitions) {
1119     for (const SmallVectorImpl<unsigned> &WSI : PTI.WriteSequences)
1120       for (unsigned WI : WSI)
1121         if (hasAliasedVariants(SchedModels.getSchedWrite(WI), SchedModels))
1122           return true;
1123 
1124     for (const SmallVectorImpl<unsigned> &RSI : PTI.ReadSequences)
1125       for (unsigned RI : RSI)
1126         if (hasAliasedVariants(SchedModels.getSchedRead(RI), SchedModels))
1127           return true;
1128   }
1129   return false;
1130 }
1131 
1132 // Populate IntersectingVariants with any variants or aliased sequences of the
1133 // given SchedRW whose processor indices and predicates are not mutually
1134 // exclusive with the given transition.
1135 void PredTransitions::getIntersectingVariants(
1136   const CodeGenSchedRW &SchedRW, unsigned TransIdx,
1137   std::vector<TransVariant> &IntersectingVariants) {
1138 
1139   bool GenericRW = false;
1140 
1141   std::vector<TransVariant> Variants;
1142   if (SchedRW.HasVariants) {
1143     unsigned VarProcIdx = 0;
1144     if (SchedRW.TheDef->getValueInit("SchedModel")->isComplete()) {
1145       Record *ModelDef = SchedRW.TheDef->getValueAsDef("SchedModel");
1146       VarProcIdx = SchedModels.getProcModel(ModelDef).Index;
1147     }
1148     // Push each variant. Assign TransVecIdx later.
1149     const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants");
1150     for (Record *VarDef : VarDefs)
1151       Variants.emplace_back(VarDef, SchedRW.Index, VarProcIdx, 0);
1152     if (VarProcIdx == 0)
1153       GenericRW = true;
1154   }
1155   for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
1156        AI != AE; ++AI) {
1157     // If either the SchedAlias itself or the SchedReadWrite that it aliases
1158     // to is defined within a processor model, constrain all variants to
1159     // that processor.
1160     unsigned AliasProcIdx = 0;
1161     if ((*AI)->getValueInit("SchedModel")->isComplete()) {
1162       Record *ModelDef = (*AI)->getValueAsDef("SchedModel");
1163       AliasProcIdx = SchedModels.getProcModel(ModelDef).Index;
1164     }
1165     const CodeGenSchedRW &AliasRW =
1166       SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
1167 
1168     if (AliasRW.HasVariants) {
1169       const RecVec VarDefs = AliasRW.TheDef->getValueAsListOfDefs("Variants");
1170       for (Record *VD : VarDefs)
1171         Variants.emplace_back(VD, AliasRW.Index, AliasProcIdx, 0);
1172     }
1173     if (AliasRW.IsSequence)
1174       Variants.emplace_back(AliasRW.TheDef, SchedRW.Index, AliasProcIdx, 0);
1175     if (AliasProcIdx == 0)
1176       GenericRW = true;
1177   }
1178   for (TransVariant &Variant : Variants) {
1179     // Don't expand variants if the processor models don't intersect.
1180     // A zero processor index means any processor.
1181     SmallVectorImpl<unsigned> &ProcIndices = TransVec[TransIdx].ProcIndices;
1182     if (ProcIndices[0] && Variant.ProcIdx) {
1183       unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(),
1184                                 Variant.ProcIdx);
1185       if (!Cnt)
1186         continue;
1187       if (Cnt > 1) {
1188         const CodeGenProcModel &PM =
1189           *(SchedModels.procModelBegin() + Variant.ProcIdx);
1190         PrintFatalError(Variant.VarOrSeqDef->getLoc(),
1191                         "Multiple variants defined for processor " +
1192                         PM.ModelName +
1193                         " Ensure only one SchedAlias exists per RW.");
1194       }
1195     }
1196     if (Variant.VarOrSeqDef->isSubClassOf("SchedVar")) {
1197       Record *PredDef = Variant.VarOrSeqDef->getValueAsDef("Predicate");
1198       if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm))
1199         continue;
1200     }
1201     if (IntersectingVariants.empty()) {
1202       // The first variant builds on the existing transition.
1203       Variant.TransVecIdx = TransIdx;
1204       IntersectingVariants.push_back(Variant);
1205     }
1206     else {
1207       // Push another copy of the current transition for more variants.
1208       Variant.TransVecIdx = TransVec.size();
1209       IntersectingVariants.push_back(Variant);
1210       TransVec.push_back(TransVec[TransIdx]);
1211     }
1212   }
1213   if (GenericRW && IntersectingVariants.empty()) {
1214     PrintFatalError(SchedRW.TheDef->getLoc(), "No variant of this type has "
1215                     "a matching predicate on any processor");
1216   }
1217 }
1218 
1219 // Push the Reads/Writes selected by this variant onto the PredTransition
1220 // specified by VInfo.
1221 void PredTransitions::
1222 pushVariant(const TransVariant &VInfo, bool IsRead) {
1223   PredTransition &Trans = TransVec[VInfo.TransVecIdx];
1224 
1225   // If this operand transition is reached through a processor-specific alias,
1226   // then the whole transition is specific to this processor.
1227   if (VInfo.ProcIdx != 0)
1228     Trans.ProcIndices.assign(1, VInfo.ProcIdx);
1229 
1230   IdxVec SelectedRWs;
1231   if (VInfo.VarOrSeqDef->isSubClassOf("SchedVar")) {
1232     Record *PredDef = VInfo.VarOrSeqDef->getValueAsDef("Predicate");
1233     Trans.PredTerm.emplace_back(IsRead, VInfo.RWIdx,PredDef);
1234     RecVec SelectedDefs = VInfo.VarOrSeqDef->getValueAsListOfDefs("Selected");
1235     SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead);
1236   }
1237   else {
1238     assert(VInfo.VarOrSeqDef->isSubClassOf("WriteSequence") &&
1239            "variant must be a SchedVariant or aliased WriteSequence");
1240     SelectedRWs.push_back(SchedModels.getSchedRWIdx(VInfo.VarOrSeqDef, IsRead));
1241   }
1242 
1243   const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(VInfo.RWIdx, IsRead);
1244 
1245   SmallVectorImpl<SmallVector<unsigned,4>> &RWSequences = IsRead
1246     ? Trans.ReadSequences : Trans.WriteSequences;
1247   if (SchedRW.IsVariadic) {
1248     unsigned OperIdx = RWSequences.size()-1;
1249     // Make N-1 copies of this transition's last sequence.
1250     RWSequences.insert(RWSequences.end(), SelectedRWs.size() - 1,
1251                        RWSequences[OperIdx]);
1252     // Push each of the N elements of the SelectedRWs onto a copy of the last
1253     // sequence (split the current operand into N operands).
1254     // Note that write sequences should be expanded within this loop--the entire
1255     // sequence belongs to a single operand.
1256     for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
1257          RWI != RWE; ++RWI, ++OperIdx) {
1258       IdxVec ExpandedRWs;
1259       if (IsRead)
1260         ExpandedRWs.push_back(*RWI);
1261       else
1262         SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
1263       RWSequences[OperIdx].insert(RWSequences[OperIdx].end(),
1264                                   ExpandedRWs.begin(), ExpandedRWs.end());
1265     }
1266     assert(OperIdx == RWSequences.size() && "missed a sequence");
1267   }
1268   else {
1269     // Push this transition's expanded sequence onto this transition's last
1270     // sequence (add to the current operand's sequence).
1271     SmallVectorImpl<unsigned> &Seq = RWSequences.back();
1272     IdxVec ExpandedRWs;
1273     for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
1274          RWI != RWE; ++RWI) {
1275       if (IsRead)
1276         ExpandedRWs.push_back(*RWI);
1277       else
1278         SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
1279     }
1280     Seq.insert(Seq.end(), ExpandedRWs.begin(), ExpandedRWs.end());
1281   }
1282 }
1283 
1284 // RWSeq is a sequence of all Reads or all Writes for the next read or write
1285 // operand. StartIdx is an index into TransVec where partial results
1286 // starts. RWSeq must be applied to all transitions between StartIdx and the end
1287 // of TransVec.
1288 void PredTransitions::substituteVariantOperand(
1289   const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) {
1290 
1291   // Visit each original RW within the current sequence.
1292   for (SmallVectorImpl<unsigned>::const_iterator
1293          RWI = RWSeq.begin(), RWE = RWSeq.end(); RWI != RWE; ++RWI) {
1294     const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(*RWI, IsRead);
1295     // Push this RW on all partial PredTransitions or distribute variants.
1296     // New PredTransitions may be pushed within this loop which should not be
1297     // revisited (TransEnd must be loop invariant).
1298     for (unsigned TransIdx = StartIdx, TransEnd = TransVec.size();
1299          TransIdx != TransEnd; ++TransIdx) {
1300       // In the common case, push RW onto the current operand's sequence.
1301       if (!hasAliasedVariants(SchedRW, SchedModels)) {
1302         if (IsRead)
1303           TransVec[TransIdx].ReadSequences.back().push_back(*RWI);
1304         else
1305           TransVec[TransIdx].WriteSequences.back().push_back(*RWI);
1306         continue;
1307       }
1308       // Distribute this partial PredTransition across intersecting variants.
1309       // This will push a copies of TransVec[TransIdx] on the back of TransVec.
1310       std::vector<TransVariant> IntersectingVariants;
1311       getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants);
1312       // Now expand each variant on top of its copy of the transition.
1313       for (std::vector<TransVariant>::const_iterator
1314              IVI = IntersectingVariants.begin(),
1315              IVE = IntersectingVariants.end();
1316            IVI != IVE; ++IVI) {
1317         pushVariant(*IVI, IsRead);
1318       }
1319     }
1320   }
1321 }
1322 
1323 // For each variant of a Read/Write in Trans, substitute the sequence of
1324 // Read/Writes guarded by the variant. This is exponential in the number of
1325 // variant Read/Writes, but in practice detection of mutually exclusive
1326 // predicates should result in linear growth in the total number variants.
1327 //
1328 // This is one step in a breadth-first search of nested variants.
1329 void PredTransitions::substituteVariants(const PredTransition &Trans) {
1330   // Build up a set of partial results starting at the back of
1331   // PredTransitions. Remember the first new transition.
1332   unsigned StartIdx = TransVec.size();
1333   TransVec.emplace_back();
1334   TransVec.back().PredTerm = Trans.PredTerm;
1335   TransVec.back().ProcIndices = Trans.ProcIndices;
1336 
1337   // Visit each original write sequence.
1338   for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
1339          WSI = Trans.WriteSequences.begin(), WSE = Trans.WriteSequences.end();
1340        WSI != WSE; ++WSI) {
1341     // Push a new (empty) write sequence onto all partial Transitions.
1342     for (std::vector<PredTransition>::iterator I =
1343            TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
1344       I->WriteSequences.emplace_back();
1345     }
1346     substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx);
1347   }
1348   // Visit each original read sequence.
1349   for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
1350          RSI = Trans.ReadSequences.begin(), RSE = Trans.ReadSequences.end();
1351        RSI != RSE; ++RSI) {
1352     // Push a new (empty) read sequence onto all partial Transitions.
1353     for (std::vector<PredTransition>::iterator I =
1354            TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
1355       I->ReadSequences.emplace_back();
1356     }
1357     substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx);
1358   }
1359 }
1360 
1361 // Create a new SchedClass for each variant found by inferFromRW. Pass
1362 static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
1363                                  unsigned FromClassIdx,
1364                                  CodeGenSchedModels &SchedModels) {
1365   // For each PredTransition, create a new CodeGenSchedTransition, which usually
1366   // requires creating a new SchedClass.
1367   for (ArrayRef<PredTransition>::iterator
1368          I = LastTransitions.begin(), E = LastTransitions.end(); I != E; ++I) {
1369     IdxVec OperWritesVariant;
1370     transform(I->WriteSequences, std::back_inserter(OperWritesVariant),
1371               [&SchedModels](ArrayRef<unsigned> WS) {
1372                 return SchedModels.findOrInsertRW(WS, /*IsRead=*/false);
1373               });
1374     IdxVec OperReadsVariant;
1375     transform(I->ReadSequences, std::back_inserter(OperReadsVariant),
1376               [&SchedModels](ArrayRef<unsigned> RS) {
1377                 return SchedModels.findOrInsertRW(RS, /*IsRead=*/true);
1378               });
1379     CodeGenSchedTransition SCTrans;
1380     SCTrans.ToClassIdx =
1381       SchedModels.addSchedClass(/*ItinClassDef=*/nullptr, OperWritesVariant,
1382                                 OperReadsVariant, I->ProcIndices);
1383     SCTrans.ProcIndices.assign(I->ProcIndices.begin(), I->ProcIndices.end());
1384     // The final PredTerm is unique set of predicates guarding the transition.
1385     RecVec Preds;
1386     transform(I->PredTerm, std::back_inserter(Preds),
1387               [](const PredCheck &P) {
1388                 return P.Predicate;
1389               });
1390     Preds.erase(std::unique(Preds.begin(), Preds.end()), Preds.end());
1391     SCTrans.PredTerm = std::move(Preds);
1392     SchedModels.getSchedClass(FromClassIdx)
1393         .Transitions.push_back(std::move(SCTrans));
1394   }
1395 }
1396 
1397 // Create new SchedClasses for the given ReadWrite list. If any of the
1398 // ReadWrites refers to a SchedVariant, create a new SchedClass for each variant
1399 // of the ReadWrite list, following Aliases if necessary.
1400 void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
1401                                      ArrayRef<unsigned> OperReads,
1402                                      unsigned FromClassIdx,
1403                                      ArrayRef<unsigned> ProcIndices) {
1404   DEBUG(dbgs() << "INFER RW proc("; dumpIdxVec(ProcIndices); dbgs() << ") ");
1405 
1406   // Create a seed transition with an empty PredTerm and the expanded sequences
1407   // of SchedWrites for the current SchedClass.
1408   std::vector<PredTransition> LastTransitions;
1409   LastTransitions.emplace_back();
1410   LastTransitions.back().ProcIndices.append(ProcIndices.begin(),
1411                                             ProcIndices.end());
1412 
1413   for (unsigned WriteIdx : OperWrites) {
1414     IdxVec WriteSeq;
1415     expandRWSequence(WriteIdx, WriteSeq, /*IsRead=*/false);
1416     LastTransitions[0].WriteSequences.emplace_back();
1417     SmallVectorImpl<unsigned> &Seq = LastTransitions[0].WriteSequences.back();
1418     Seq.append(WriteSeq.begin(), WriteSeq.end());
1419     DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
1420   }
1421   DEBUG(dbgs() << " Reads: ");
1422   for (unsigned ReadIdx : OperReads) {
1423     IdxVec ReadSeq;
1424     expandRWSequence(ReadIdx, ReadSeq, /*IsRead=*/true);
1425     LastTransitions[0].ReadSequences.emplace_back();
1426     SmallVectorImpl<unsigned> &Seq = LastTransitions[0].ReadSequences.back();
1427     Seq.append(ReadSeq.begin(), ReadSeq.end());
1428     DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
1429   }
1430   DEBUG(dbgs() << '\n');
1431 
1432   // Collect all PredTransitions for individual operands.
1433   // Iterate until no variant writes remain.
1434   while (hasVariant(LastTransitions, *this)) {
1435     PredTransitions Transitions(*this);
1436     for (const PredTransition &Trans : LastTransitions)
1437       Transitions.substituteVariants(Trans);
1438     DEBUG(Transitions.dump());
1439     LastTransitions.swap(Transitions.TransVec);
1440   }
1441   // If the first transition has no variants, nothing to do.
1442   if (LastTransitions[0].PredTerm.empty())
1443     return;
1444 
1445   // WARNING: We are about to mutate the SchedClasses vector. Do not refer to
1446   // OperWrites, OperReads, or ProcIndices after calling inferFromTransitions.
1447   inferFromTransitions(LastTransitions, FromClassIdx, *this);
1448 }
1449 
1450 // Check if any processor resource group contains all resource records in
1451 // SubUnits.
1452 bool CodeGenSchedModels::hasSuperGroup(RecVec &SubUnits, CodeGenProcModel &PM) {
1453   for (unsigned i = 0, e = PM.ProcResourceDefs.size(); i < e; ++i) {
1454     if (!PM.ProcResourceDefs[i]->isSubClassOf("ProcResGroup"))
1455       continue;
1456     RecVec SuperUnits =
1457       PM.ProcResourceDefs[i]->getValueAsListOfDefs("Resources");
1458     RecIter RI = SubUnits.begin(), RE = SubUnits.end();
1459     for ( ; RI != RE; ++RI) {
1460       if (!is_contained(SuperUnits, *RI)) {
1461         break;
1462       }
1463     }
1464     if (RI == RE)
1465       return true;
1466   }
1467   return false;
1468 }
1469 
1470 // Verify that overlapping groups have a common supergroup.
1471 void CodeGenSchedModels::verifyProcResourceGroups(CodeGenProcModel &PM) {
1472   for (unsigned i = 0, e = PM.ProcResourceDefs.size(); i < e; ++i) {
1473     if (!PM.ProcResourceDefs[i]->isSubClassOf("ProcResGroup"))
1474       continue;
1475     RecVec CheckUnits =
1476       PM.ProcResourceDefs[i]->getValueAsListOfDefs("Resources");
1477     for (unsigned j = i+1; j < e; ++j) {
1478       if (!PM.ProcResourceDefs[j]->isSubClassOf("ProcResGroup"))
1479         continue;
1480       RecVec OtherUnits =
1481         PM.ProcResourceDefs[j]->getValueAsListOfDefs("Resources");
1482       if (std::find_first_of(CheckUnits.begin(), CheckUnits.end(),
1483                              OtherUnits.begin(), OtherUnits.end())
1484           != CheckUnits.end()) {
1485         // CheckUnits and OtherUnits overlap
1486         OtherUnits.insert(OtherUnits.end(), CheckUnits.begin(),
1487                           CheckUnits.end());
1488         if (!hasSuperGroup(OtherUnits, PM)) {
1489           PrintFatalError((PM.ProcResourceDefs[i])->getLoc(),
1490                           "proc resource group overlaps with "
1491                           + PM.ProcResourceDefs[j]->getName()
1492                           + " but no supergroup contains both.");
1493         }
1494       }
1495     }
1496   }
1497 }
1498 
1499 // Collect all the RegisterFile definitions available in this target.
1500 void CodeGenSchedModels::collectRegisterFiles() {
1501   RecVec RegisterFileDefs = Records.getAllDerivedDefinitions("RegisterFile");
1502 
1503   // RegisterFiles is the vector of CodeGenRegisterFile.
1504   for (Record *RF : RegisterFileDefs) {
1505     // For each register file definition, construct a CodeGenRegisterFile object
1506     // and add it to the appropriate scheduling model.
1507     CodeGenProcModel &PM = getProcModel(RF->getValueAsDef("SchedModel"));
1508     PM.RegisterFiles.emplace_back(CodeGenRegisterFile(RF->getName(),RF));
1509     CodeGenRegisterFile &CGRF = PM.RegisterFiles.back();
1510 
1511     // Now set the number of physical registers as well as the cost of registers
1512     // in each register class.
1513     CGRF.NumPhysRegs = RF->getValueAsInt("NumPhysRegs");
1514     RecVec RegisterClasses = RF->getValueAsListOfDefs("RegClasses");
1515     std::vector<int64_t> RegisterCosts = RF->getValueAsListOfInts("RegCosts");
1516     for (unsigned I = 0, E = RegisterClasses.size(); I < E; ++I) {
1517       int Cost = RegisterCosts.size() > I ? RegisterCosts[I] : 1;
1518       CGRF.Costs.emplace_back(RegisterClasses[I], Cost);
1519     }
1520   }
1521 }
1522 
1523 // Collect all the RegisterFile definitions available in this target.
1524 void CodeGenSchedModels::collectPfmCounters() {
1525   for (Record *Def : Records.getAllDerivedDefinitions("PfmIssueCounter")) {
1526     CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
1527     PM.PfmIssueCounterDefs.emplace_back(Def);
1528   }
1529   for (Record *Def : Records.getAllDerivedDefinitions("PfmCycleCounter")) {
1530     CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
1531     if (PM.PfmCycleCounterDef) {
1532       PrintFatalError(Def->getLoc(),
1533                       "multiple cycle counters for " +
1534                           Def->getValueAsDef("SchedModel")->getName());
1535     }
1536     PM.PfmCycleCounterDef = Def;
1537   }
1538 }
1539 
1540 // Collect and sort WriteRes, ReadAdvance, and ProcResources.
1541 void CodeGenSchedModels::collectProcResources() {
1542   ProcResourceDefs = Records.getAllDerivedDefinitions("ProcResourceUnits");
1543   ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
1544 
1545   // Add any subtarget-specific SchedReadWrites that are directly associated
1546   // with processor resources. Refer to the parent SchedClass's ProcIndices to
1547   // determine which processors they apply to.
1548   for (const CodeGenSchedClass &SC :
1549        make_range(schedClassBegin(), schedClassEnd())) {
1550     if (SC.ItinClassDef) {
1551       collectItinProcResources(SC.ItinClassDef);
1552       continue;
1553     }
1554 
1555     // This class may have a default ReadWrite list which can be overriden by
1556     // InstRW definitions.
1557     for (Record *RW : SC.InstRWs) {
1558       Record *RWModelDef = RW->getValueAsDef("SchedModel");
1559       unsigned PIdx = getProcModel(RWModelDef).Index;
1560       IdxVec Writes, Reads;
1561       findRWs(RW->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
1562       collectRWResources(Writes, Reads, PIdx);
1563     }
1564 
1565     collectRWResources(SC.Writes, SC.Reads, SC.ProcIndices);
1566   }
1567   // Add resources separately defined by each subtarget.
1568   RecVec WRDefs = Records.getAllDerivedDefinitions("WriteRes");
1569   for (Record *WR : WRDefs) {
1570     Record *ModelDef = WR->getValueAsDef("SchedModel");
1571     addWriteRes(WR, getProcModel(ModelDef).Index);
1572   }
1573   RecVec SWRDefs = Records.getAllDerivedDefinitions("SchedWriteRes");
1574   for (Record *SWR : SWRDefs) {
1575     Record *ModelDef = SWR->getValueAsDef("SchedModel");
1576     addWriteRes(SWR, getProcModel(ModelDef).Index);
1577   }
1578   RecVec RADefs = Records.getAllDerivedDefinitions("ReadAdvance");
1579   for (Record *RA : RADefs) {
1580     Record *ModelDef = RA->getValueAsDef("SchedModel");
1581     addReadAdvance(RA, getProcModel(ModelDef).Index);
1582   }
1583   RecVec SRADefs = Records.getAllDerivedDefinitions("SchedReadAdvance");
1584   for (Record *SRA : SRADefs) {
1585     if (SRA->getValueInit("SchedModel")->isComplete()) {
1586       Record *ModelDef = SRA->getValueAsDef("SchedModel");
1587       addReadAdvance(SRA, getProcModel(ModelDef).Index);
1588     }
1589   }
1590   // Add ProcResGroups that are defined within this processor model, which may
1591   // not be directly referenced but may directly specify a buffer size.
1592   RecVec ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
1593   for (Record *PRG : ProcResGroups) {
1594     if (!PRG->getValueInit("SchedModel")->isComplete())
1595       continue;
1596     CodeGenProcModel &PM = getProcModel(PRG->getValueAsDef("SchedModel"));
1597     if (!is_contained(PM.ProcResourceDefs, PRG))
1598       PM.ProcResourceDefs.push_back(PRG);
1599   }
1600   // Add ProcResourceUnits unconditionally.
1601   for (Record *PRU : Records.getAllDerivedDefinitions("ProcResourceUnits")) {
1602     if (!PRU->getValueInit("SchedModel")->isComplete())
1603       continue;
1604     CodeGenProcModel &PM = getProcModel(PRU->getValueAsDef("SchedModel"));
1605     if (!is_contained(PM.ProcResourceDefs, PRU))
1606       PM.ProcResourceDefs.push_back(PRU);
1607   }
1608   // Finalize each ProcModel by sorting the record arrays.
1609   for (CodeGenProcModel &PM : ProcModels) {
1610     llvm::sort(PM.WriteResDefs.begin(), PM.WriteResDefs.end(),
1611                LessRecord());
1612     llvm::sort(PM.ReadAdvanceDefs.begin(), PM.ReadAdvanceDefs.end(),
1613                LessRecord());
1614     llvm::sort(PM.ProcResourceDefs.begin(), PM.ProcResourceDefs.end(),
1615                LessRecord());
1616     DEBUG(
1617       PM.dump();
1618       dbgs() << "WriteResDefs: ";
1619       for (RecIter RI = PM.WriteResDefs.begin(),
1620              RE = PM.WriteResDefs.end(); RI != RE; ++RI) {
1621         if ((*RI)->isSubClassOf("WriteRes"))
1622           dbgs() << (*RI)->getValueAsDef("WriteType")->getName() << " ";
1623         else
1624           dbgs() << (*RI)->getName() << " ";
1625       }
1626       dbgs() << "\nReadAdvanceDefs: ";
1627       for (RecIter RI = PM.ReadAdvanceDefs.begin(),
1628              RE = PM.ReadAdvanceDefs.end(); RI != RE; ++RI) {
1629         if ((*RI)->isSubClassOf("ReadAdvance"))
1630           dbgs() << (*RI)->getValueAsDef("ReadType")->getName() << " ";
1631         else
1632           dbgs() << (*RI)->getName() << " ";
1633       }
1634       dbgs() << "\nProcResourceDefs: ";
1635       for (RecIter RI = PM.ProcResourceDefs.begin(),
1636              RE = PM.ProcResourceDefs.end(); RI != RE; ++RI) {
1637         dbgs() << (*RI)->getName() << " ";
1638       }
1639       dbgs() << '\n');
1640     verifyProcResourceGroups(PM);
1641   }
1642 
1643   ProcResourceDefs.clear();
1644   ProcResGroups.clear();
1645 }
1646 
1647 void CodeGenSchedModels::checkCompleteness() {
1648   bool Complete = true;
1649   bool HadCompleteModel = false;
1650   for (const CodeGenProcModel &ProcModel : procModels()) {
1651     const bool HasItineraries = ProcModel.hasItineraries();
1652     if (!ProcModel.ModelDef->getValueAsBit("CompleteModel"))
1653       continue;
1654     for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
1655       if (Inst->hasNoSchedulingInfo)
1656         continue;
1657       if (ProcModel.isUnsupported(*Inst))
1658         continue;
1659       unsigned SCIdx = getSchedClassIdx(*Inst);
1660       if (!SCIdx) {
1661         if (Inst->TheDef->isValueUnset("SchedRW") && !HadCompleteModel) {
1662           PrintError("No schedule information for instruction '"
1663                      + Inst->TheDef->getName() + "'");
1664           Complete = false;
1665         }
1666         continue;
1667       }
1668 
1669       const CodeGenSchedClass &SC = getSchedClass(SCIdx);
1670       if (!SC.Writes.empty())
1671         continue;
1672       if (HasItineraries && SC.ItinClassDef != nullptr &&
1673           SC.ItinClassDef->getName() != "NoItinerary")
1674         continue;
1675 
1676       const RecVec &InstRWs = SC.InstRWs;
1677       auto I = find_if(InstRWs, [&ProcModel](const Record *R) {
1678         return R->getValueAsDef("SchedModel") == ProcModel.ModelDef;
1679       });
1680       if (I == InstRWs.end()) {
1681         PrintError("'" + ProcModel.ModelName + "' lacks information for '" +
1682                    Inst->TheDef->getName() + "'");
1683         Complete = false;
1684       }
1685     }
1686     HadCompleteModel = true;
1687   }
1688   if (!Complete) {
1689     errs() << "\n\nIncomplete schedule models found.\n"
1690       << "- Consider setting 'CompleteModel = 0' while developing new models.\n"
1691       << "- Pseudo instructions can be marked with 'hasNoSchedulingInfo = 1'.\n"
1692       << "- Instructions should usually have Sched<[...]> as a superclass, "
1693          "you may temporarily use an empty list.\n"
1694       << "- Instructions related to unsupported features can be excluded with "
1695          "list<Predicate> UnsupportedFeatures = [HasA,..,HasY]; in the "
1696          "processor model.\n\n";
1697     PrintFatalError("Incomplete schedule model");
1698   }
1699 }
1700 
1701 // Collect itinerary class resources for each processor.
1702 void CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) {
1703   for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
1704     const CodeGenProcModel &PM = ProcModels[PIdx];
1705     // For all ItinRW entries.
1706     bool HasMatch = false;
1707     for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end();
1708          II != IE; ++II) {
1709       RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
1710       if (!std::count(Matched.begin(), Matched.end(), ItinClassDef))
1711         continue;
1712       if (HasMatch)
1713         PrintFatalError((*II)->getLoc(), "Duplicate itinerary class "
1714                         + ItinClassDef->getName()
1715                         + " in ItinResources for " + PM.ModelName);
1716       HasMatch = true;
1717       IdxVec Writes, Reads;
1718       findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
1719       collectRWResources(Writes, Reads, PIdx);
1720     }
1721   }
1722 }
1723 
1724 void CodeGenSchedModels::collectRWResources(unsigned RWIdx, bool IsRead,
1725                                             ArrayRef<unsigned> ProcIndices) {
1726   const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead);
1727   if (SchedRW.TheDef) {
1728     if (!IsRead && SchedRW.TheDef->isSubClassOf("SchedWriteRes")) {
1729       for (unsigned Idx : ProcIndices)
1730         addWriteRes(SchedRW.TheDef, Idx);
1731     }
1732     else if (IsRead && SchedRW.TheDef->isSubClassOf("SchedReadAdvance")) {
1733       for (unsigned Idx : ProcIndices)
1734         addReadAdvance(SchedRW.TheDef, Idx);
1735     }
1736   }
1737   for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
1738        AI != AE; ++AI) {
1739     IdxVec AliasProcIndices;
1740     if ((*AI)->getValueInit("SchedModel")->isComplete()) {
1741       AliasProcIndices.push_back(
1742         getProcModel((*AI)->getValueAsDef("SchedModel")).Index);
1743     }
1744     else
1745       AliasProcIndices = ProcIndices;
1746     const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW"));
1747     assert(AliasRW.IsRead == IsRead && "cannot alias reads to writes");
1748 
1749     IdxVec ExpandedRWs;
1750     expandRWSequence(AliasRW.Index, ExpandedRWs, IsRead);
1751     for (IdxIter SI = ExpandedRWs.begin(), SE = ExpandedRWs.end();
1752          SI != SE; ++SI) {
1753       collectRWResources(*SI, IsRead, AliasProcIndices);
1754     }
1755   }
1756 }
1757 
1758 // Collect resources for a set of read/write types and processor indices.
1759 void CodeGenSchedModels::collectRWResources(ArrayRef<unsigned> Writes,
1760                                             ArrayRef<unsigned> Reads,
1761                                             ArrayRef<unsigned> ProcIndices) {
1762   for (unsigned Idx : Writes)
1763     collectRWResources(Idx, /*IsRead=*/false, ProcIndices);
1764 
1765   for (unsigned Idx : Reads)
1766     collectRWResources(Idx, /*IsRead=*/true, ProcIndices);
1767 }
1768 
1769 // Find the processor's resource units for this kind of resource.
1770 Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
1771                                              const CodeGenProcModel &PM,
1772                                              ArrayRef<SMLoc> Loc) const {
1773   if (ProcResKind->isSubClassOf("ProcResourceUnits"))
1774     return ProcResKind;
1775 
1776   Record *ProcUnitDef = nullptr;
1777   assert(!ProcResourceDefs.empty());
1778   assert(!ProcResGroups.empty());
1779 
1780   for (Record *ProcResDef : ProcResourceDefs) {
1781     if (ProcResDef->getValueAsDef("Kind") == ProcResKind
1782         && ProcResDef->getValueAsDef("SchedModel") == PM.ModelDef) {
1783       if (ProcUnitDef) {
1784         PrintFatalError(Loc,
1785                         "Multiple ProcessorResourceUnits associated with "
1786                         + ProcResKind->getName());
1787       }
1788       ProcUnitDef = ProcResDef;
1789     }
1790   }
1791   for (Record *ProcResGroup : ProcResGroups) {
1792     if (ProcResGroup == ProcResKind
1793         && ProcResGroup->getValueAsDef("SchedModel") == PM.ModelDef) {
1794       if (ProcUnitDef) {
1795         PrintFatalError(Loc,
1796                         "Multiple ProcessorResourceUnits associated with "
1797                         + ProcResKind->getName());
1798       }
1799       ProcUnitDef = ProcResGroup;
1800     }
1801   }
1802   if (!ProcUnitDef) {
1803     PrintFatalError(Loc,
1804                     "No ProcessorResources associated with "
1805                     + ProcResKind->getName());
1806   }
1807   return ProcUnitDef;
1808 }
1809 
1810 // Iteratively add a resource and its super resources.
1811 void CodeGenSchedModels::addProcResource(Record *ProcResKind,
1812                                          CodeGenProcModel &PM,
1813                                          ArrayRef<SMLoc> Loc) {
1814   while (true) {
1815     Record *ProcResUnits = findProcResUnits(ProcResKind, PM, Loc);
1816 
1817     // See if this ProcResource is already associated with this processor.
1818     if (is_contained(PM.ProcResourceDefs, ProcResUnits))
1819       return;
1820 
1821     PM.ProcResourceDefs.push_back(ProcResUnits);
1822     if (ProcResUnits->isSubClassOf("ProcResGroup"))
1823       return;
1824 
1825     if (!ProcResUnits->getValueInit("Super")->isComplete())
1826       return;
1827 
1828     ProcResKind = ProcResUnits->getValueAsDef("Super");
1829   }
1830 }
1831 
1832 // Add resources for a SchedWrite to this processor if they don't exist.
1833 void CodeGenSchedModels::addWriteRes(Record *ProcWriteResDef, unsigned PIdx) {
1834   assert(PIdx && "don't add resources to an invalid Processor model");
1835 
1836   RecVec &WRDefs = ProcModels[PIdx].WriteResDefs;
1837   if (is_contained(WRDefs, ProcWriteResDef))
1838     return;
1839   WRDefs.push_back(ProcWriteResDef);
1840 
1841   // Visit ProcResourceKinds referenced by the newly discovered WriteRes.
1842   RecVec ProcResDefs = ProcWriteResDef->getValueAsListOfDefs("ProcResources");
1843   for (RecIter WritePRI = ProcResDefs.begin(), WritePRE = ProcResDefs.end();
1844        WritePRI != WritePRE; ++WritePRI) {
1845     addProcResource(*WritePRI, ProcModels[PIdx], ProcWriteResDef->getLoc());
1846   }
1847 }
1848 
1849 // Add resources for a ReadAdvance to this processor if they don't exist.
1850 void CodeGenSchedModels::addReadAdvance(Record *ProcReadAdvanceDef,
1851                                         unsigned PIdx) {
1852   RecVec &RADefs = ProcModels[PIdx].ReadAdvanceDefs;
1853   if (is_contained(RADefs, ProcReadAdvanceDef))
1854     return;
1855   RADefs.push_back(ProcReadAdvanceDef);
1856 }
1857 
1858 unsigned CodeGenProcModel::getProcResourceIdx(Record *PRDef) const {
1859   RecIter PRPos = find(ProcResourceDefs, PRDef);
1860   if (PRPos == ProcResourceDefs.end())
1861     PrintFatalError(PRDef->getLoc(), "ProcResource def is not included in "
1862                     "the ProcResources list for " + ModelName);
1863   // Idx=0 is reserved for invalid.
1864   return 1 + (PRPos - ProcResourceDefs.begin());
1865 }
1866 
1867 bool CodeGenProcModel::isUnsupported(const CodeGenInstruction &Inst) const {
1868   for (const Record *TheDef : UnsupportedFeaturesDefs) {
1869     for (const Record *PredDef : Inst.TheDef->getValueAsListOfDefs("Predicates")) {
1870       if (TheDef->getName() == PredDef->getName())
1871         return true;
1872     }
1873   }
1874   return false;
1875 }
1876 
1877 #ifndef NDEBUG
1878 void CodeGenProcModel::dump() const {
1879   dbgs() << Index << ": " << ModelName << " "
1880          << (ModelDef ? ModelDef->getName() : "inferred") << " "
1881          << (ItinsDef ? ItinsDef->getName() : "no itinerary") << '\n';
1882 }
1883 
1884 void CodeGenSchedRW::dump() const {
1885   dbgs() << Name << (IsVariadic ? " (V) " : " ");
1886   if (IsSequence) {
1887     dbgs() << "(";
1888     dumpIdxVec(Sequence);
1889     dbgs() << ")";
1890   }
1891 }
1892 
1893 void CodeGenSchedClass::dump(const CodeGenSchedModels* SchedModels) const {
1894   dbgs() << "SCHEDCLASS " << Index << ":" << Name << '\n'
1895          << "  Writes: ";
1896   for (unsigned i = 0, N = Writes.size(); i < N; ++i) {
1897     SchedModels->getSchedWrite(Writes[i]).dump();
1898     if (i < N-1) {
1899       dbgs() << '\n';
1900       dbgs().indent(10);
1901     }
1902   }
1903   dbgs() << "\n  Reads: ";
1904   for (unsigned i = 0, N = Reads.size(); i < N; ++i) {
1905     SchedModels->getSchedRead(Reads[i]).dump();
1906     if (i < N-1) {
1907       dbgs() << '\n';
1908       dbgs().indent(10);
1909     }
1910   }
1911   dbgs() << "\n  ProcIdx: "; dumpIdxVec(ProcIndices); dbgs() << '\n';
1912   if (!Transitions.empty()) {
1913     dbgs() << "\n Transitions for Proc ";
1914     for (const CodeGenSchedTransition &Transition : Transitions) {
1915       dumpIdxVec(Transition.ProcIndices);
1916     }
1917   }
1918 }
1919 
1920 void PredTransitions::dump() const {
1921   dbgs() << "Expanded Variants:\n";
1922   for (std::vector<PredTransition>::const_iterator
1923          TI = TransVec.begin(), TE = TransVec.end(); TI != TE; ++TI) {
1924     dbgs() << "{";
1925     for (SmallVectorImpl<PredCheck>::const_iterator
1926            PCI = TI->PredTerm.begin(), PCE = TI->PredTerm.end();
1927          PCI != PCE; ++PCI) {
1928       if (PCI != TI->PredTerm.begin())
1929         dbgs() << ", ";
1930       dbgs() << SchedModels.getSchedRW(PCI->RWIdx, PCI->IsRead).Name
1931              << ":" << PCI->Predicate->getName();
1932     }
1933     dbgs() << "},\n  => {";
1934     for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
1935            WSI = TI->WriteSequences.begin(), WSE = TI->WriteSequences.end();
1936          WSI != WSE; ++WSI) {
1937       dbgs() << "(";
1938       for (SmallVectorImpl<unsigned>::const_iterator
1939              WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
1940         if (WI != WSI->begin())
1941           dbgs() << ", ";
1942         dbgs() << SchedModels.getSchedWrite(*WI).Name;
1943       }
1944       dbgs() << "),";
1945     }
1946     dbgs() << "}\n";
1947   }
1948 }
1949 #endif // NDEBUG
1950