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 decribed in
11 // the target description.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #define DEBUG_TYPE "subtarget-emitter"
16 
17 #include "CodeGenSchedule.h"
18 #include "CodeGenTarget.h"
19 #include "llvm/TableGen/Error.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Regex.h"
22 #include "llvm/ADT/STLExtras.h"
23 
24 using namespace llvm;
25 
26 #ifndef NDEBUG
27 static void dumpIdxVec(const IdxVec &V) {
28   for (unsigned i = 0, e = V.size(); i < e; ++i) {
29     dbgs() << V[i] << ", ";
30   }
31 }
32 static void dumpIdxVec(const SmallVectorImpl<unsigned> &V) {
33   for (unsigned i = 0, e = V.size(); i < e; ++i) {
34     dbgs() << V[i] << ", ";
35   }
36 }
37 #endif
38 
39 // (instrs a, b, ...) Evaluate and union all arguments. Identical to AddOp.
40 struct InstrsOp : public SetTheory::Operator {
41   void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts) {
42     ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts);
43   }
44 };
45 
46 // (instregex "OpcPat",...) Find all instructions matching an opcode pattern.
47 //
48 // TODO: Since this is a prefix match, perform a binary search over the
49 // instruction names using lower_bound. Note that the predefined instrs must be
50 // scanned linearly first. However, this is only safe if the regex pattern has
51 // no top-level bars. The DAG already has a list of patterns, so there's no
52 // reason to use top-level bars, but we need a way to verify they don't exist
53 // before implementing the optimization.
54 struct InstRegexOp : public SetTheory::Operator {
55   const CodeGenTarget &Target;
56   InstRegexOp(const CodeGenTarget &t): Target(t) {}
57 
58   void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts) {
59     SmallVector<Regex*, 4> RegexList;
60     for (DagInit::const_arg_iterator
61            AI = Expr->arg_begin(), AE = Expr->arg_end(); AI != AE; ++AI) {
62       StringInit *SI = dyn_cast<StringInit>(*AI);
63       if (!SI)
64         throw "instregex requires pattern string: " + Expr->getAsString();
65       std::string pat = SI->getValue();
66       // Implement a python-style prefix match.
67       if (pat[0] != '^') {
68         pat.insert(0, "^(");
69         pat.insert(pat.end(), ')');
70       }
71       RegexList.push_back(new Regex(pat));
72     }
73     for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
74            E = Target.inst_end(); I != E; ++I) {
75       for (SmallVectorImpl<Regex*>::iterator
76              RI = RegexList.begin(), RE = RegexList.end(); RI != RE; ++RI) {
77         if ((*RI)->match((*I)->TheDef->getName()))
78           Elts.insert((*I)->TheDef);
79       }
80     }
81     DeleteContainerPointers(RegexList);
82   }
83 };
84 
85 /// CodeGenModels ctor interprets machine model records and populates maps.
86 CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
87                                        const CodeGenTarget &TGT):
88   Records(RK), Target(TGT), NumItineraryClasses(0) {
89 
90   Sets.addFieldExpander("InstRW", "Instrs");
91 
92   // Allow Set evaluation to recognize the dags used in InstRW records:
93   // (instrs Op1, Op1...)
94   Sets.addOperator("instrs", new InstrsOp);
95   Sets.addOperator("instregex", new InstRegexOp(Target));
96 
97   // Instantiate a CodeGenProcModel for each SchedMachineModel with the values
98   // that are explicitly referenced in tablegen records. Resources associated
99   // with each processor will be derived later. Populate ProcModelMap with the
100   // CodeGenProcModel instances.
101   collectProcModels();
102 
103   // Instantiate a CodeGenSchedRW for each SchedReadWrite record explicitly
104   // defined, and populate SchedReads and SchedWrites vectors. Implicit
105   // SchedReadWrites that represent sequences derived from expanded variant will
106   // be inferred later.
107   collectSchedRW();
108 
109   // Instantiate a CodeGenSchedClass for each unique SchedRW signature directly
110   // required by an instruction definition, and populate SchedClassIdxMap. Set
111   // NumItineraryClasses to the number of explicit itinerary classes referenced
112   // by instructions. Set NumInstrSchedClasses to the number of itinerary
113   // classes plus any classes implied by instructions that derive from class
114   // Sched and provide SchedRW list. This does not infer any new classes from
115   // SchedVariant.
116   collectSchedClasses();
117 
118   // Find instruction itineraries for each processor. Sort and populate
119   // CodeGenProcModel::ItinDefList. (Cycle-to-cycle itineraries). This requires
120   // all itinerary classes to be discovered.
121   collectProcItins();
122 
123   // Find ItinRW records for each processor and itinerary class.
124   // (For per-operand resources mapped to itinerary classes).
125   collectProcItinRW();
126 
127   // Infer new SchedClasses from SchedVariant.
128   inferSchedClasses();
129 
130   // Populate each CodeGenProcModel's WriteResDefs, ReadAdvanceDefs, and
131   // ProcResourceDefs.
132   collectProcResources();
133 }
134 
135 /// Gather all processor models.
136 void CodeGenSchedModels::collectProcModels() {
137   RecVec ProcRecords = Records.getAllDerivedDefinitions("Processor");
138   std::sort(ProcRecords.begin(), ProcRecords.end(), LessRecordFieldName());
139 
140   // Reserve space because we can. Reallocation would be ok.
141   ProcModels.reserve(ProcRecords.size()+1);
142 
143   // Use idx=0 for NoModel/NoItineraries.
144   Record *NoModelDef = Records.getDef("NoSchedModel");
145   Record *NoItinsDef = Records.getDef("NoItineraries");
146   ProcModels.push_back(CodeGenProcModel(0, "NoSchedModel",
147                                         NoModelDef, NoItinsDef));
148   ProcModelMap[NoModelDef] = 0;
149 
150   // For each processor, find a unique machine model.
151   for (unsigned i = 0, N = ProcRecords.size(); i < N; ++i)
152     addProcModel(ProcRecords[i]);
153 }
154 
155 /// Get a unique processor model based on the defined MachineModel and
156 /// ProcessorItineraries.
157 void CodeGenSchedModels::addProcModel(Record *ProcDef) {
158   Record *ModelKey = getModelOrItinDef(ProcDef);
159   if (!ProcModelMap.insert(std::make_pair(ModelKey, ProcModels.size())).second)
160     return;
161 
162   std::string Name = ModelKey->getName();
163   if (ModelKey->isSubClassOf("SchedMachineModel")) {
164     Record *ItinsDef = ModelKey->getValueAsDef("Itineraries");
165     ProcModels.push_back(
166       CodeGenProcModel(ProcModels.size(), Name, ModelKey, ItinsDef));
167   }
168   else {
169     // An itinerary is defined without a machine model. Infer a new model.
170     if (!ModelKey->getValueAsListOfDefs("IID").empty())
171       Name = Name + "Model";
172     ProcModels.push_back(
173       CodeGenProcModel(ProcModels.size(), Name,
174                        ProcDef->getValueAsDef("SchedModel"), ModelKey));
175   }
176   DEBUG(ProcModels.back().dump());
177 }
178 
179 // Recursively find all reachable SchedReadWrite records.
180 static void scanSchedRW(Record *RWDef, RecVec &RWDefs,
181                         SmallPtrSet<Record*, 16> &RWSet) {
182   if (!RWSet.insert(RWDef))
183     return;
184   RWDefs.push_back(RWDef);
185   // Reads don't current have sequence records, but it can be added later.
186   if (RWDef->isSubClassOf("WriteSequence")) {
187     RecVec Seq = RWDef->getValueAsListOfDefs("Writes");
188     for (RecIter I = Seq.begin(), E = Seq.end(); I != E; ++I)
189       scanSchedRW(*I, RWDefs, RWSet);
190   }
191   else if (RWDef->isSubClassOf("SchedVariant")) {
192     // Visit each variant (guarded by a different predicate).
193     RecVec Vars = RWDef->getValueAsListOfDefs("Variants");
194     for (RecIter VI = Vars.begin(), VE = Vars.end(); VI != VE; ++VI) {
195       // Visit each RW in the sequence selected by the current variant.
196       RecVec Selected = (*VI)->getValueAsListOfDefs("Selected");
197       for (RecIter I = Selected.begin(), E = Selected.end(); I != E; ++I)
198         scanSchedRW(*I, RWDefs, RWSet);
199     }
200   }
201 }
202 
203 // Collect and sort all SchedReadWrites reachable via tablegen records.
204 // More may be inferred later when inferring new SchedClasses from variants.
205 void CodeGenSchedModels::collectSchedRW() {
206   // Reserve idx=0 for invalid writes/reads.
207   SchedWrites.resize(1);
208   SchedReads.resize(1);
209 
210   SmallPtrSet<Record*, 16> RWSet;
211 
212   // Find all SchedReadWrites referenced by instruction defs.
213   RecVec SWDefs, SRDefs;
214   for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
215          E = Target.inst_end(); I != E; ++I) {
216     Record *SchedDef = (*I)->TheDef;
217     if (!SchedDef->isSubClassOf("Sched"))
218       continue;
219     RecVec RWs = SchedDef->getValueAsListOfDefs("SchedRW");
220     for (RecIter RWI = RWs.begin(), RWE = RWs.end(); RWI != RWE; ++RWI) {
221       if ((*RWI)->isSubClassOf("SchedWrite"))
222         scanSchedRW(*RWI, SWDefs, RWSet);
223       else {
224         assert((*RWI)->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
225         scanSchedRW(*RWI, SRDefs, RWSet);
226       }
227     }
228   }
229   // Find all ReadWrites referenced by InstRW.
230   RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
231   for (RecIter OI = InstRWDefs.begin(), OE = InstRWDefs.end(); OI != OE; ++OI) {
232     // For all OperandReadWrites.
233     RecVec RWDefs = (*OI)->getValueAsListOfDefs("OperandReadWrites");
234     for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end();
235          RWI != RWE; ++RWI) {
236       if ((*RWI)->isSubClassOf("SchedWrite"))
237         scanSchedRW(*RWI, SWDefs, RWSet);
238       else {
239         assert((*RWI)->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
240         scanSchedRW(*RWI, SRDefs, RWSet);
241       }
242     }
243   }
244   // Find all ReadWrites referenced by ItinRW.
245   RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW");
246   for (RecIter II = ItinRWDefs.begin(), IE = ItinRWDefs.end(); II != IE; ++II) {
247     // For all OperandReadWrites.
248     RecVec RWDefs = (*II)->getValueAsListOfDefs("OperandReadWrites");
249     for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end();
250          RWI != RWE; ++RWI) {
251       if ((*RWI)->isSubClassOf("SchedWrite"))
252         scanSchedRW(*RWI, SWDefs, RWSet);
253       else {
254         assert((*RWI)->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
255         scanSchedRW(*RWI, SRDefs, RWSet);
256       }
257     }
258   }
259   // Find all ReadWrites referenced by SchedAlias. AliasDefs needs to be sorted
260   // for the loop below that initializes Alias vectors.
261   RecVec AliasDefs = Records.getAllDerivedDefinitions("SchedAlias");
262   std::sort(AliasDefs.begin(), AliasDefs.end(), LessRecord());
263   for (RecIter AI = AliasDefs.begin(), AE = AliasDefs.end(); AI != AE; ++AI) {
264     Record *MatchDef = (*AI)->getValueAsDef("MatchRW");
265     Record *AliasDef = (*AI)->getValueAsDef("AliasRW");
266     if (MatchDef->isSubClassOf("SchedWrite")) {
267       if (!AliasDef->isSubClassOf("SchedWrite"))
268         throw TGError((*AI)->getLoc(), "SchedWrite Alias must be SchedWrite");
269       scanSchedRW(AliasDef, SWDefs, RWSet);
270     }
271     else {
272       assert(MatchDef->isSubClassOf("SchedRead") && "Unknown SchedReadWrite");
273       if (!AliasDef->isSubClassOf("SchedRead"))
274         throw TGError((*AI)->getLoc(), "SchedRead Alias must be SchedRead");
275       scanSchedRW(AliasDef, SRDefs, RWSet);
276     }
277   }
278   // Sort and add the SchedReadWrites directly referenced by instructions or
279   // itinerary resources. Index reads and writes in separate domains.
280   std::sort(SWDefs.begin(), SWDefs.end(), LessRecord());
281   for (RecIter SWI = SWDefs.begin(), SWE = SWDefs.end(); SWI != SWE; ++SWI) {
282     assert(!getSchedRWIdx(*SWI, /*IsRead=*/false) && "duplicate SchedWrite");
283     SchedWrites.push_back(CodeGenSchedRW(SchedWrites.size(), *SWI));
284   }
285   std::sort(SRDefs.begin(), SRDefs.end(), LessRecord());
286   for (RecIter SRI = SRDefs.begin(), SRE = SRDefs.end(); SRI != SRE; ++SRI) {
287     assert(!getSchedRWIdx(*SRI, /*IsRead-*/true) && "duplicate SchedWrite");
288     SchedReads.push_back(CodeGenSchedRW(SchedReads.size(), *SRI));
289   }
290   // Initialize WriteSequence vectors.
291   for (std::vector<CodeGenSchedRW>::iterator WI = SchedWrites.begin(),
292          WE = SchedWrites.end(); WI != WE; ++WI) {
293     if (!WI->IsSequence)
294       continue;
295     findRWs(WI->TheDef->getValueAsListOfDefs("Writes"), WI->Sequence,
296             /*IsRead=*/false);
297   }
298   // Initialize Aliases vectors.
299   for (RecIter AI = AliasDefs.begin(), AE = AliasDefs.end(); AI != AE; ++AI) {
300     Record *AliasDef = (*AI)->getValueAsDef("AliasRW");
301     getSchedRW(AliasDef).IsAlias = true;
302     Record *MatchDef = (*AI)->getValueAsDef("MatchRW");
303     CodeGenSchedRW &RW = getSchedRW(MatchDef);
304     if (RW.IsAlias)
305       throw TGError((*AI)->getLoc(), "Cannot Alias an Alias");
306     RW.Aliases.push_back(*AI);
307   }
308   DEBUG(
309     for (unsigned WIdx = 0, WEnd = SchedWrites.size(); WIdx != WEnd; ++WIdx) {
310       dbgs() << WIdx << ": ";
311       SchedWrites[WIdx].dump();
312       dbgs() << '\n';
313     }
314     for (unsigned RIdx = 0, REnd = SchedReads.size(); RIdx != REnd; ++RIdx) {
315       dbgs() << RIdx << ": ";
316       SchedReads[RIdx].dump();
317       dbgs() << '\n';
318     }
319     RecVec RWDefs = Records.getAllDerivedDefinitions("SchedReadWrite");
320     for (RecIter RI = RWDefs.begin(), RE = RWDefs.end();
321          RI != RE; ++RI) {
322       if (!getSchedRWIdx(*RI, (*RI)->isSubClassOf("SchedRead"))) {
323         const std::string &Name = (*RI)->getName();
324         if (Name != "NoWrite" && Name != "ReadDefault")
325           dbgs() << "Unused SchedReadWrite " << (*RI)->getName() << '\n';
326       }
327     });
328 }
329 
330 /// Compute a SchedWrite name from a sequence of writes.
331 std::string CodeGenSchedModels::genRWName(const IdxVec& Seq, bool IsRead) {
332   std::string Name("(");
333   for (IdxIter I = Seq.begin(), E = Seq.end(); I != E; ++I) {
334     if (I != Seq.begin())
335       Name += '_';
336     Name += getSchedRW(*I, IsRead).Name;
337   }
338   Name += ')';
339   return Name;
340 }
341 
342 unsigned CodeGenSchedModels::getSchedRWIdx(Record *Def, bool IsRead,
343                                            unsigned After) const {
344   const std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites;
345   assert(After < RWVec.size() && "start position out of bounds");
346   for (std::vector<CodeGenSchedRW>::const_iterator I = RWVec.begin() + After,
347          E = RWVec.end(); I != E; ++I) {
348     if (I->TheDef == Def)
349       return I - RWVec.begin();
350   }
351   return 0;
352 }
353 
354 bool CodeGenSchedModels::hasReadOfWrite(Record *WriteDef) const {
355   for (unsigned i = 0, e = SchedReads.size(); i < e; ++i) {
356     Record *ReadDef = SchedReads[i].TheDef;
357     if (!ReadDef || !ReadDef->isSubClassOf("ProcReadAdvance"))
358       continue;
359 
360     RecVec ValidWrites = ReadDef->getValueAsListOfDefs("ValidWrites");
361     if (std::find(ValidWrites.begin(), ValidWrites.end(), WriteDef)
362         != ValidWrites.end()) {
363       return true;
364     }
365   }
366   return false;
367 }
368 
369 namespace llvm {
370 void splitSchedReadWrites(const RecVec &RWDefs,
371                           RecVec &WriteDefs, RecVec &ReadDefs) {
372   for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); RWI != RWE; ++RWI) {
373     if ((*RWI)->isSubClassOf("SchedWrite"))
374       WriteDefs.push_back(*RWI);
375     else {
376       assert((*RWI)->isSubClassOf("SchedRead") && "unknown SchedReadWrite");
377       ReadDefs.push_back(*RWI);
378     }
379   }
380 }
381 } // namespace llvm
382 
383 // Split the SchedReadWrites defs and call findRWs for each list.
384 void CodeGenSchedModels::findRWs(const RecVec &RWDefs,
385                                  IdxVec &Writes, IdxVec &Reads) const {
386     RecVec WriteDefs;
387     RecVec ReadDefs;
388     splitSchedReadWrites(RWDefs, WriteDefs, ReadDefs);
389     findRWs(WriteDefs, Writes, false);
390     findRWs(ReadDefs, Reads, true);
391 }
392 
393 // Call getSchedRWIdx for all elements in a sequence of SchedRW defs.
394 void CodeGenSchedModels::findRWs(const RecVec &RWDefs, IdxVec &RWs,
395                                  bool IsRead) const {
396   for (RecIter RI = RWDefs.begin(), RE = RWDefs.end(); RI != RE; ++RI) {
397     unsigned Idx = getSchedRWIdx(*RI, IsRead);
398     assert(Idx && "failed to collect SchedReadWrite");
399     RWs.push_back(Idx);
400   }
401 }
402 
403 void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq,
404                                           bool IsRead) const {
405   const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead);
406   if (!SchedRW.IsSequence) {
407     RWSeq.push_back(RWIdx);
408     return;
409   }
410   int Repeat =
411     SchedRW.TheDef ? SchedRW.TheDef->getValueAsInt("Repeat") : 1;
412   for (int i = 0; i < Repeat; ++i) {
413     for (IdxIter I = SchedRW.Sequence.begin(), E = SchedRW.Sequence.end();
414          I != E; ++I) {
415       expandRWSequence(*I, RWSeq, IsRead);
416     }
417   }
418 }
419 
420 // Expand a SchedWrite as a sequence following any aliases that coincide with
421 // the given processor model.
422 void CodeGenSchedModels::expandRWSeqForProc(
423   unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
424   const CodeGenProcModel &ProcModel) const {
425 
426   const CodeGenSchedRW &SchedWrite = getSchedRW(RWIdx, IsRead);
427   Record *AliasDef = 0;
428   for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end();
429        AI != AE; ++AI) {
430     const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW"));
431     if ((*AI)->getValueInit("SchedModel")->isComplete()) {
432       Record *ModelDef = (*AI)->getValueAsDef("SchedModel");
433       if (&getProcModel(ModelDef) != &ProcModel)
434         continue;
435     }
436     if (AliasDef)
437       throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases "
438                     "defined for processor " + ProcModel.ModelName +
439                     " Ensure only one SchedAlias exists per RW.");
440     AliasDef = AliasRW.TheDef;
441   }
442   if (AliasDef) {
443     expandRWSeqForProc(getSchedRWIdx(AliasDef, IsRead),
444                        RWSeq, IsRead,ProcModel);
445     return;
446   }
447   if (!SchedWrite.IsSequence) {
448     RWSeq.push_back(RWIdx);
449     return;
450   }
451   int Repeat =
452     SchedWrite.TheDef ? SchedWrite.TheDef->getValueAsInt("Repeat") : 1;
453   for (int i = 0; i < Repeat; ++i) {
454     for (IdxIter I = SchedWrite.Sequence.begin(), E = SchedWrite.Sequence.end();
455          I != E; ++I) {
456       expandRWSeqForProc(*I, RWSeq, IsRead, ProcModel);
457     }
458   }
459 }
460 
461 // Find the existing SchedWrite that models this sequence of writes.
462 unsigned CodeGenSchedModels::findRWForSequence(const IdxVec &Seq,
463                                                bool IsRead) {
464   std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites;
465 
466   for (std::vector<CodeGenSchedRW>::iterator I = RWVec.begin(), E = RWVec.end();
467        I != E; ++I) {
468     if (I->Sequence == Seq)
469       return I - RWVec.begin();
470   }
471   // Index zero reserved for invalid RW.
472   return 0;
473 }
474 
475 /// Add this ReadWrite if it doesn't already exist.
476 unsigned CodeGenSchedModels::findOrInsertRW(ArrayRef<unsigned> Seq,
477                                             bool IsRead) {
478   assert(!Seq.empty() && "cannot insert empty sequence");
479   if (Seq.size() == 1)
480     return Seq.back();
481 
482   unsigned Idx = findRWForSequence(Seq, IsRead);
483   if (Idx)
484     return Idx;
485 
486   unsigned RWIdx = IsRead ? SchedReads.size() : SchedWrites.size();
487   CodeGenSchedRW SchedRW(RWIdx, IsRead, Seq, genRWName(Seq, IsRead));
488   if (IsRead)
489     SchedReads.push_back(SchedRW);
490   else
491     SchedWrites.push_back(SchedRW);
492   return RWIdx;
493 }
494 
495 /// Visit all the instruction definitions for this target to gather and
496 /// enumerate the itinerary classes. These are the explicitly specified
497 /// SchedClasses. More SchedClasses may be inferred.
498 void CodeGenSchedModels::collectSchedClasses() {
499 
500   // NoItinerary is always the first class at Idx=0
501   SchedClasses.resize(1);
502   SchedClasses.back().Name = "NoItinerary";
503   SchedClasses.back().ProcIndices.push_back(0);
504   SchedClassIdxMap[SchedClasses.back().Name] = 0;
505 
506   // Gather and sort all itinerary classes used by instruction descriptions.
507   RecVec ItinClassList;
508   for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
509          E = Target.inst_end(); I != E; ++I) {
510     Record *ItinDef = (*I)->TheDef->getValueAsDef("Itinerary");
511     // Map a new SchedClass with no index.
512     if (!SchedClassIdxMap.count(ItinDef->getName())) {
513       SchedClassIdxMap[ItinDef->getName()] = 0;
514       ItinClassList.push_back(ItinDef);
515     }
516   }
517   // Assign each itinerary class unique number, skipping NoItinerary==0
518   NumItineraryClasses = ItinClassList.size();
519   std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
520   for (unsigned i = 0, N = NumItineraryClasses; i < N; i++) {
521     Record *ItinDef = ItinClassList[i];
522     SchedClassIdxMap[ItinDef->getName()] = SchedClasses.size();
523     SchedClasses.push_back(CodeGenSchedClass(ItinDef));
524   }
525   // Infer classes from SchedReadWrite resources listed for each
526   // instruction definition that inherits from class Sched.
527   for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
528          E = Target.inst_end(); I != E; ++I) {
529     if (!(*I)->TheDef->isSubClassOf("Sched"))
530       continue;
531     IdxVec Writes, Reads;
532     findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads);
533     // ProcIdx == 0 indicates the class applies to all processors.
534     IdxVec ProcIndices(1, 0);
535     addSchedClass(Writes, Reads, ProcIndices);
536   }
537   // Create classes for InstRW defs.
538   RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
539   std::sort(InstRWDefs.begin(), InstRWDefs.end(), LessRecord());
540   for (RecIter OI = InstRWDefs.begin(), OE = InstRWDefs.end(); OI != OE; ++OI)
541     createInstRWClass(*OI);
542 
543   NumInstrSchedClasses = SchedClasses.size();
544 
545   bool EnableDump = false;
546   DEBUG(EnableDump = true);
547   if (!EnableDump)
548     return;
549   for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
550          E = Target.inst_end(); I != E; ++I) {
551     Record *SchedDef = (*I)->TheDef;
552     std::string InstName = (*I)->TheDef->getName();
553     if (SchedDef->isSubClassOf("Sched")) {
554       IdxVec Writes;
555       IdxVec Reads;
556       findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads);
557       dbgs() << "SchedRW machine model for " << InstName;
558       for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI)
559         dbgs() << " " << SchedWrites[*WI].Name;
560       for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI)
561         dbgs() << " " << SchedReads[*RI].Name;
562       dbgs() << '\n';
563     }
564     unsigned SCIdx = InstrClassMap.lookup((*I)->TheDef);
565     if (SCIdx) {
566       const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
567       for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end();
568            RWI != RWE; ++RWI) {
569         const CodeGenProcModel &ProcModel =
570           getProcModel((*RWI)->getValueAsDef("SchedModel"));
571         dbgs() << "InstRW on " << ProcModel.ModelName << " for " << InstName;
572         IdxVec Writes;
573         IdxVec Reads;
574         findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"),
575                 Writes, Reads);
576         for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI)
577           dbgs() << " " << SchedWrites[*WI].Name;
578         for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI)
579           dbgs() << " " << SchedReads[*RI].Name;
580         dbgs() << '\n';
581       }
582       continue;
583     }
584     if (!SchedDef->isSubClassOf("Sched")
585         && (SchedDef->getValueAsDef("Itinerary")->getName() == "NoItinerary")) {
586       dbgs() << "No machine model for " << (*I)->TheDef->getName() << '\n';
587     }
588   }
589 }
590 
591 unsigned CodeGenSchedModels::getSchedClassIdx(
592   const RecVec &RWDefs) const {
593 
594   IdxVec Writes, Reads;
595   findRWs(RWDefs, Writes, Reads);
596   return findSchedClassIdx(Writes, Reads);
597 }
598 
599 /// Find an SchedClass that has been inferred from a per-operand list of
600 /// SchedWrites and SchedReads.
601 unsigned CodeGenSchedModels::findSchedClassIdx(const IdxVec &Writes,
602                                                const IdxVec &Reads) const {
603   for (SchedClassIter I = schedClassBegin(), E = schedClassEnd(); I != E; ++I) {
604     // Classes with InstRWs may have the same Writes/Reads as a class originally
605     // produced by a SchedRW definition. We need to be able to recover the
606     // original class index for processors that don't match any InstRWs.
607     if (I->ItinClassDef || !I->InstRWs.empty())
608       continue;
609 
610     if (I->Writes == Writes && I->Reads == Reads) {
611       return I - schedClassBegin();
612     }
613   }
614   return 0;
615 }
616 
617 // Get the SchedClass index for an instruction.
618 unsigned CodeGenSchedModels::getSchedClassIdx(
619   const CodeGenInstruction &Inst) const {
620 
621   unsigned SCIdx = InstrClassMap.lookup(Inst.TheDef);
622   if (SCIdx)
623     return SCIdx;
624 
625   // If this opcode isn't mapped by the subtarget fallback to the instruction
626   // definition's SchedRW or ItinDef values.
627   if (Inst.TheDef->isSubClassOf("Sched")) {
628     RecVec RWs = Inst.TheDef->getValueAsListOfDefs("SchedRW");
629     return getSchedClassIdx(RWs);
630   }
631   Record *ItinDef = Inst.TheDef->getValueAsDef("Itinerary");
632   assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass");
633   unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName());
634   assert(Idx <= NumItineraryClasses && "bad ItinClass index");
635   return Idx;
636 }
637 
638 std::string CodeGenSchedModels::createSchedClassName(
639   const IdxVec &OperWrites, const IdxVec &OperReads) {
640 
641   std::string Name;
642   for (IdxIter WI = OperWrites.begin(), WE = OperWrites.end(); WI != WE; ++WI) {
643     if (WI != OperWrites.begin())
644       Name += '_';
645     Name += SchedWrites[*WI].Name;
646   }
647   for (IdxIter RI = OperReads.begin(), RE = OperReads.end(); RI != RE; ++RI) {
648     Name += '_';
649     Name += SchedReads[*RI].Name;
650   }
651   return Name;
652 }
653 
654 std::string CodeGenSchedModels::createSchedClassName(const RecVec &InstDefs) {
655 
656   std::string Name;
657   for (RecIter I = InstDefs.begin(), E = InstDefs.end(); I != E; ++I) {
658     if (I != InstDefs.begin())
659       Name += '_';
660     Name += (*I)->getName();
661   }
662   return Name;
663 }
664 
665 /// Add an inferred sched class from a per-operand list of SchedWrites and
666 /// SchedReads. ProcIndices contains the set of IDs of processors that may
667 /// utilize this class.
668 unsigned CodeGenSchedModels::addSchedClass(const IdxVec &OperWrites,
669                                            const IdxVec &OperReads,
670                                            const IdxVec &ProcIndices)
671 {
672   assert(!ProcIndices.empty() && "expect at least one ProcIdx");
673 
674   unsigned Idx = findSchedClassIdx(OperWrites, OperReads);
675   if (Idx) {
676     IdxVec PI;
677     std::set_union(SchedClasses[Idx].ProcIndices.begin(),
678                    SchedClasses[Idx].ProcIndices.end(),
679                    ProcIndices.begin(), ProcIndices.end(),
680                    std::back_inserter(PI));
681     SchedClasses[Idx].ProcIndices.swap(PI);
682     return Idx;
683   }
684   Idx = SchedClasses.size();
685   SchedClasses.resize(Idx+1);
686   CodeGenSchedClass &SC = SchedClasses.back();
687   SC.Name = createSchedClassName(OperWrites, OperReads);
688   SC.Writes = OperWrites;
689   SC.Reads = OperReads;
690   SC.ProcIndices = ProcIndices;
691 
692   return Idx;
693 }
694 
695 // Create classes for each set of opcodes that are in the same InstReadWrite
696 // definition across all processors.
697 void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
698   // ClassInstrs will hold an entry for each subset of Instrs in InstRWDef that
699   // intersects with an existing class via a previous InstRWDef. Instrs that do
700   // not intersect with an existing class refer back to their former class as
701   // determined from ItinDef or SchedRW.
702   SmallVector<std::pair<unsigned, SmallVector<Record *, 8> >, 4> ClassInstrs;
703   // Sort Instrs into sets.
704   const RecVec *InstDefs = Sets.expand(InstRWDef);
705   if (InstDefs->empty())
706     throw TGError(InstRWDef->getLoc(), "No matching instruction opcodes");
707 
708   for (RecIter I = InstDefs->begin(), E = InstDefs->end(); I != E; ++I) {
709     unsigned SCIdx = 0;
710     InstClassMapTy::const_iterator Pos = InstrClassMap.find(*I);
711     if (Pos != InstrClassMap.end())
712       SCIdx = Pos->second;
713     else {
714       // This instruction has not been mapped yet. Get the original class. All
715       // instructions in the same InstrRW class must be from the same original
716       // class because that is the fall-back class for other processors.
717       Record *ItinDef = (*I)->getValueAsDef("Itinerary");
718       SCIdx = SchedClassIdxMap.lookup(ItinDef->getName());
719       if (!SCIdx && (*I)->isSubClassOf("Sched"))
720         SCIdx = getSchedClassIdx((*I)->getValueAsListOfDefs("SchedRW"));
721     }
722     unsigned CIdx = 0, CEnd = ClassInstrs.size();
723     for (; CIdx != CEnd; ++CIdx) {
724       if (ClassInstrs[CIdx].first == SCIdx)
725         break;
726     }
727     if (CIdx == CEnd) {
728       ClassInstrs.resize(CEnd + 1);
729       ClassInstrs[CIdx].first = SCIdx;
730     }
731     ClassInstrs[CIdx].second.push_back(*I);
732   }
733   // For each set of Instrs, create a new class if necessary, and map or remap
734   // the Instrs to it.
735   unsigned CIdx = 0, CEnd = ClassInstrs.size();
736   for (; CIdx != CEnd; ++CIdx) {
737     unsigned OldSCIdx = ClassInstrs[CIdx].first;
738     ArrayRef<Record*> InstDefs = ClassInstrs[CIdx].second;
739     // If the all instrs in the current class are accounted for, then leave
740     // them mapped to their old class.
741     if (SchedClasses[OldSCIdx].InstRWs.size() == InstDefs.size()) {
742       assert(SchedClasses[OldSCIdx].ProcIndices[0] == 0 &&
743              "expected a generic SchedClass");
744       continue;
745     }
746     unsigned SCIdx = SchedClasses.size();
747     SchedClasses.resize(SCIdx+1);
748     CodeGenSchedClass &SC = SchedClasses.back();
749     SC.Name = createSchedClassName(InstDefs);
750     // Preserve ItinDef and Writes/Reads for processors without an InstRW entry.
751     SC.ItinClassDef = SchedClasses[OldSCIdx].ItinClassDef;
752     SC.Writes = SchedClasses[OldSCIdx].Writes;
753     SC.Reads = SchedClasses[OldSCIdx].Reads;
754     SC.ProcIndices.push_back(0);
755     // Map each Instr to this new class.
756     // Note that InstDefs may be a smaller list than InstRWDef's "Instrs".
757     Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
758     SmallSet<unsigned, 4> RemappedClassIDs;
759     for (ArrayRef<Record*>::const_iterator
760            II = InstDefs.begin(), IE = InstDefs.end(); II != IE; ++II) {
761       unsigned OldSCIdx = InstrClassMap[*II];
762       if (OldSCIdx && RemappedClassIDs.insert(OldSCIdx)) {
763         for (RecIter RI = SchedClasses[OldSCIdx].InstRWs.begin(),
764                RE = SchedClasses[OldSCIdx].InstRWs.end(); RI != RE; ++RI) {
765           if ((*RI)->getValueAsDef("SchedModel") == RWModelDef) {
766             throw TGError(InstRWDef->getLoc(), "Overlapping InstRW def " +
767                           (*II)->getName() + " also matches " +
768                           (*RI)->getValue("Instrs")->getValue()->getAsString());
769           }
770           assert(*RI != InstRWDef && "SchedClass has duplicate InstRW def");
771           SC.InstRWs.push_back(*RI);
772         }
773       }
774       InstrClassMap[*II] = SCIdx;
775     }
776     SC.InstRWs.push_back(InstRWDef);
777   }
778 }
779 
780 // Gather the processor itineraries.
781 void CodeGenSchedModels::collectProcItins() {
782   for (std::vector<CodeGenProcModel>::iterator PI = ProcModels.begin(),
783          PE = ProcModels.end(); PI != PE; ++PI) {
784     CodeGenProcModel &ProcModel = *PI;
785     RecVec ItinRecords = ProcModel.ItinsDef->getValueAsListOfDefs("IID");
786     // Skip empty itinerary.
787     if (ItinRecords.empty())
788       continue;
789 
790     ProcModel.ItinDefList.resize(NumItineraryClasses+1);
791 
792     // Insert each itinerary data record in the correct position within
793     // the processor model's ItinDefList.
794     for (unsigned i = 0, N = ItinRecords.size(); i < N; i++) {
795       Record *ItinData = ItinRecords[i];
796       Record *ItinDef = ItinData->getValueAsDef("TheClass");
797       if (!SchedClassIdxMap.count(ItinDef->getName())) {
798         DEBUG(dbgs() << ProcModel.ItinsDef->getName()
799               << " has unused itinerary class " << ItinDef->getName() << '\n');
800         continue;
801       }
802       assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass");
803       unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName());
804       assert(Idx <= NumItineraryClasses && "bad ItinClass index");
805       ProcModel.ItinDefList[Idx] = ItinData;
806     }
807     // Check for missing itinerary entries.
808     assert(!ProcModel.ItinDefList[0] && "NoItinerary class can't have rec");
809     DEBUG(
810       for (unsigned i = 1, N = ProcModel.ItinDefList.size(); i < N; ++i) {
811         if (!ProcModel.ItinDefList[i])
812           dbgs() << ProcModel.ItinsDef->getName()
813                  << " missing itinerary for class "
814                  << SchedClasses[i].Name << '\n';
815       });
816   }
817 }
818 
819 // Gather the read/write types for each itinerary class.
820 void CodeGenSchedModels::collectProcItinRW() {
821   RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW");
822   std::sort(ItinRWDefs.begin(), ItinRWDefs.end(), LessRecord());
823   for (RecIter II = ItinRWDefs.begin(), IE = ItinRWDefs.end(); II != IE; ++II) {
824     if (!(*II)->getValueInit("SchedModel")->isComplete())
825       throw TGError((*II)->getLoc(), "SchedModel is undefined");
826     Record *ModelDef = (*II)->getValueAsDef("SchedModel");
827     ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef);
828     if (I == ProcModelMap.end()) {
829       throw TGError((*II)->getLoc(), "Undefined SchedMachineModel "
830                     + ModelDef->getName());
831     }
832     ProcModels[I->second].ItinRWDefs.push_back(*II);
833   }
834 }
835 
836 /// Infer new classes from existing classes. In the process, this may create new
837 /// SchedWrites from sequences of existing SchedWrites.
838 void CodeGenSchedModels::inferSchedClasses() {
839   // Visit all existing classes and newly created classes.
840   for (unsigned Idx = 0; Idx != SchedClasses.size(); ++Idx) {
841     if (SchedClasses[Idx].ItinClassDef)
842       inferFromItinClass(SchedClasses[Idx].ItinClassDef, Idx);
843     else if (!SchedClasses[Idx].InstRWs.empty())
844       inferFromInstRWs(Idx);
845     else {
846       inferFromRW(SchedClasses[Idx].Writes, SchedClasses[Idx].Reads,
847                   Idx, SchedClasses[Idx].ProcIndices);
848     }
849     assert(SchedClasses.size() < (NumInstrSchedClasses*6) &&
850            "too many SchedVariants");
851   }
852 }
853 
854 /// Infer classes from per-processor itinerary resources.
855 void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef,
856                                             unsigned FromClassIdx) {
857   for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
858     const CodeGenProcModel &PM = ProcModels[PIdx];
859     // For all ItinRW entries.
860     bool HasMatch = false;
861     for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end();
862          II != IE; ++II) {
863       RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
864       if (!std::count(Matched.begin(), Matched.end(), ItinClassDef))
865         continue;
866       if (HasMatch)
867         throw TGError((*II)->getLoc(), "Duplicate itinerary class "
868                       + ItinClassDef->getName()
869                       + " in ItinResources for " + PM.ModelName);
870       HasMatch = true;
871       IdxVec Writes, Reads;
872       findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
873       IdxVec ProcIndices(1, PIdx);
874       inferFromRW(Writes, Reads, FromClassIdx, ProcIndices);
875     }
876   }
877 }
878 
879 /// Infer classes from per-processor InstReadWrite definitions.
880 void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) {
881   const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
882   for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); RWI != RWE; ++RWI) {
883     const RecVec *InstDefs = Sets.expand(*RWI);
884     RecIter II = InstDefs->begin(), IE = InstDefs->end();
885     for (; II != IE; ++II) {
886       if (InstrClassMap[*II] == SCIdx)
887         break;
888     }
889     // If this class no longer has any instructions mapped to it, it has become
890     // irrelevant.
891     if (II == IE)
892       continue;
893     IdxVec Writes, Reads;
894     findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
895     unsigned PIdx = getProcModel((*RWI)->getValueAsDef("SchedModel")).Index;
896     IdxVec ProcIndices(1, PIdx);
897     inferFromRW(Writes, Reads, SCIdx, ProcIndices);
898   }
899 }
900 
901 namespace {
902 // Helper for substituteVariantOperand.
903 struct TransVariant {
904   Record *VarOrSeqDef;  // Variant or sequence.
905   unsigned RWIdx;       // Index of this variant or sequence's matched type.
906   unsigned ProcIdx;     // Processor model index or zero for any.
907   unsigned TransVecIdx; // Index into PredTransitions::TransVec.
908 
909   TransVariant(Record *def, unsigned rwi, unsigned pi, unsigned ti):
910     VarOrSeqDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {}
911 };
912 
913 // Associate a predicate with the SchedReadWrite that it guards.
914 // RWIdx is the index of the read/write variant.
915 struct PredCheck {
916   bool IsRead;
917   unsigned RWIdx;
918   Record *Predicate;
919 
920   PredCheck(bool r, unsigned w, Record *p): IsRead(r), RWIdx(w), Predicate(p) {}
921 };
922 
923 // A Predicate transition is a list of RW sequences guarded by a PredTerm.
924 struct PredTransition {
925   // A predicate term is a conjunction of PredChecks.
926   SmallVector<PredCheck, 4> PredTerm;
927   SmallVector<SmallVector<unsigned,4>, 16> WriteSequences;
928   SmallVector<SmallVector<unsigned,4>, 16> ReadSequences;
929   SmallVector<unsigned, 4> ProcIndices;
930 };
931 
932 // Encapsulate a set of partially constructed transitions.
933 // The results are built by repeated calls to substituteVariants.
934 class PredTransitions {
935   CodeGenSchedModels &SchedModels;
936 
937 public:
938   std::vector<PredTransition> TransVec;
939 
940   PredTransitions(CodeGenSchedModels &sm): SchedModels(sm) {}
941 
942   void substituteVariantOperand(const SmallVectorImpl<unsigned> &RWSeq,
943                                 bool IsRead, unsigned StartIdx);
944 
945   void substituteVariants(const PredTransition &Trans);
946 
947 #ifndef NDEBUG
948   void dump() const;
949 #endif
950 
951 private:
952   bool mutuallyExclusive(Record *PredDef, ArrayRef<PredCheck> Term);
953   void getIntersectingVariants(
954     const CodeGenSchedRW &SchedRW, unsigned TransIdx,
955     std::vector<TransVariant> &IntersectingVariants);
956   void pushVariant(const TransVariant &VInfo, bool IsRead);
957 };
958 } // anonymous
959 
960 // Return true if this predicate is mutually exclusive with a PredTerm. This
961 // degenerates into checking if the predicate is mutually exclusive with any
962 // predicate in the Term's conjunction.
963 //
964 // All predicates associated with a given SchedRW are considered mutually
965 // exclusive. This should work even if the conditions expressed by the
966 // predicates are not exclusive because the predicates for a given SchedWrite
967 // are always checked in the order they are defined in the .td file. Later
968 // conditions implicitly negate any prior condition.
969 bool PredTransitions::mutuallyExclusive(Record *PredDef,
970                                         ArrayRef<PredCheck> Term) {
971 
972   for (ArrayRef<PredCheck>::iterator I = Term.begin(), E = Term.end();
973        I != E; ++I) {
974     if (I->Predicate == PredDef)
975       return false;
976 
977     const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(I->RWIdx, I->IsRead);
978     assert(SchedRW.HasVariants && "PredCheck must refer to a SchedVariant");
979     RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants");
980     for (RecIter VI = Variants.begin(), VE = Variants.end(); VI != VE; ++VI) {
981       if ((*VI)->getValueAsDef("Predicate") == PredDef)
982         return true;
983     }
984   }
985   return false;
986 }
987 
988 static bool hasAliasedVariants(const CodeGenSchedRW &RW,
989                                CodeGenSchedModels &SchedModels) {
990   if (RW.HasVariants)
991     return true;
992 
993   for (RecIter I = RW.Aliases.begin(), E = RW.Aliases.end(); I != E; ++I) {
994     const CodeGenSchedRW &AliasRW =
995       SchedModels.getSchedRW((*I)->getValueAsDef("AliasRW"));
996     if (AliasRW.HasVariants)
997       return true;
998     if (AliasRW.IsSequence) {
999       IdxVec ExpandedRWs;
1000       SchedModels.expandRWSequence(AliasRW.Index, ExpandedRWs, AliasRW.IsRead);
1001       for (IdxIter SI = ExpandedRWs.begin(), SE = ExpandedRWs.end();
1002            SI != SE; ++SI) {
1003         if (hasAliasedVariants(SchedModels.getSchedRW(*SI, AliasRW.IsRead),
1004                                SchedModels)) {
1005           return true;
1006         }
1007       }
1008     }
1009   }
1010   return false;
1011 }
1012 
1013 static bool hasVariant(ArrayRef<PredTransition> Transitions,
1014                        CodeGenSchedModels &SchedModels) {
1015   for (ArrayRef<PredTransition>::iterator
1016          PTI = Transitions.begin(), PTE = Transitions.end();
1017        PTI != PTE; ++PTI) {
1018     for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1019            WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end();
1020          WSI != WSE; ++WSI) {
1021       for (SmallVectorImpl<unsigned>::const_iterator
1022              WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
1023         if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels))
1024           return true;
1025       }
1026     }
1027     for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1028            RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end();
1029          RSI != RSE; ++RSI) {
1030       for (SmallVectorImpl<unsigned>::const_iterator
1031              RI = RSI->begin(), RE = RSI->end(); RI != RE; ++RI) {
1032         if (hasAliasedVariants(SchedModels.getSchedRead(*RI), SchedModels))
1033           return true;
1034       }
1035     }
1036   }
1037   return false;
1038 }
1039 
1040 // Populate IntersectingVariants with any variants or aliased sequences of the
1041 // given SchedRW whose processor indices and predicates are not mutually
1042 // exclusive with the given transition,
1043 void PredTransitions::getIntersectingVariants(
1044   const CodeGenSchedRW &SchedRW, unsigned TransIdx,
1045   std::vector<TransVariant> &IntersectingVariants) {
1046 
1047   std::vector<TransVariant> Variants;
1048   if (SchedRW.HasVariants) {
1049     unsigned VarProcIdx = 0;
1050     if (SchedRW.TheDef->getValueInit("SchedModel")->isComplete()) {
1051       Record *ModelDef = SchedRW.TheDef->getValueAsDef("SchedModel");
1052       VarProcIdx = SchedModels.getProcModel(ModelDef).Index;
1053     }
1054     // Push each variant. Assign TransVecIdx later.
1055     const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants");
1056     for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI)
1057       Variants.push_back(TransVariant(*RI, SchedRW.Index, VarProcIdx, 0));
1058   }
1059   for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
1060        AI != AE; ++AI) {
1061     // If either the SchedAlias itself or the SchedReadWrite that it aliases
1062     // to is defined within a processor model, constrain all variants to
1063     // that processor.
1064     unsigned AliasProcIdx = 0;
1065     if ((*AI)->getValueInit("SchedModel")->isComplete()) {
1066       Record *ModelDef = (*AI)->getValueAsDef("SchedModel");
1067       AliasProcIdx = SchedModels.getProcModel(ModelDef).Index;
1068     }
1069     const CodeGenSchedRW &AliasRW =
1070       SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
1071 
1072     if (AliasRW.HasVariants) {
1073       const RecVec VarDefs = AliasRW.TheDef->getValueAsListOfDefs("Variants");
1074       for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI)
1075         Variants.push_back(TransVariant(*RI, AliasRW.Index, AliasProcIdx, 0));
1076     }
1077     if (AliasRW.IsSequence) {
1078       Variants.push_back(
1079         TransVariant(AliasRW.TheDef, SchedRW.Index, AliasProcIdx, 0));
1080     }
1081   }
1082   for (unsigned VIdx = 0, VEnd = Variants.size(); VIdx != VEnd; ++VIdx) {
1083     TransVariant &Variant = Variants[VIdx];
1084     // Don't expand variants if the processor models don't intersect.
1085     // A zero processor index means any processor.
1086     SmallVector<unsigned, 4> &ProcIndices = TransVec[TransIdx].ProcIndices;
1087     if (ProcIndices[0] && Variants[VIdx].ProcIdx) {
1088       unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(),
1089                                 Variant.ProcIdx);
1090       if (!Cnt)
1091         continue;
1092       if (Cnt > 1) {
1093         const CodeGenProcModel &PM =
1094           *(SchedModels.procModelBegin() + Variant.ProcIdx);
1095         throw TGError(Variant.VarOrSeqDef->getLoc(),
1096                       "Multiple variants defined for processor " + PM.ModelName +
1097                       " Ensure only one SchedAlias exists per RW.");
1098       }
1099     }
1100     if (Variant.VarOrSeqDef->isSubClassOf("SchedVar")) {
1101       Record *PredDef = Variant.VarOrSeqDef->getValueAsDef("Predicate");
1102       if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm))
1103         continue;
1104     }
1105     if (IntersectingVariants.empty()) {
1106       // The first variant builds on the existing transition.
1107       Variant.TransVecIdx = TransIdx;
1108       IntersectingVariants.push_back(Variant);
1109     }
1110     else {
1111       // Push another copy of the current transition for more variants.
1112       Variant.TransVecIdx = TransVec.size();
1113       IntersectingVariants.push_back(Variant);
1114       TransVec.push_back(TransVec[TransIdx]);
1115     }
1116   }
1117 }
1118 
1119 // Push the Reads/Writes selected by this variant onto the PredTransition
1120 // specified by VInfo.
1121 void PredTransitions::
1122 pushVariant(const TransVariant &VInfo, bool IsRead) {
1123 
1124   PredTransition &Trans = TransVec[VInfo.TransVecIdx];
1125 
1126   // If this operand transition is reached through a processor-specific alias,
1127   // then the whole transition is specific to this processor.
1128   if (VInfo.ProcIdx != 0)
1129     Trans.ProcIndices.assign(1, VInfo.ProcIdx);
1130 
1131   IdxVec SelectedRWs;
1132   if (VInfo.VarOrSeqDef->isSubClassOf("SchedVar")) {
1133     Record *PredDef = VInfo.VarOrSeqDef->getValueAsDef("Predicate");
1134     Trans.PredTerm.push_back(PredCheck(IsRead, VInfo.RWIdx,PredDef));
1135     RecVec SelectedDefs = VInfo.VarOrSeqDef->getValueAsListOfDefs("Selected");
1136     SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead);
1137   }
1138   else {
1139     assert(VInfo.VarOrSeqDef->isSubClassOf("WriteSequence") &&
1140            "variant must be a SchedVariant or aliased WriteSequence");
1141     SelectedRWs.push_back(SchedModels.getSchedRWIdx(VInfo.VarOrSeqDef, IsRead));
1142   }
1143 
1144   const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(VInfo.RWIdx, IsRead);
1145 
1146   SmallVectorImpl<SmallVector<unsigned,4> > &RWSequences = IsRead
1147     ? Trans.ReadSequences : Trans.WriteSequences;
1148   if (SchedRW.IsVariadic) {
1149     unsigned OperIdx = RWSequences.size()-1;
1150     // Make N-1 copies of this transition's last sequence.
1151     for (unsigned i = 1, e = SelectedRWs.size(); i != e; ++i) {
1152       RWSequences.push_back(RWSequences[OperIdx]);
1153     }
1154     // Push each of the N elements of the SelectedRWs onto a copy of the last
1155     // sequence (split the current operand into N operands).
1156     // Note that write sequences should be expanded within this loop--the entire
1157     // sequence belongs to a single operand.
1158     for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
1159          RWI != RWE; ++RWI, ++OperIdx) {
1160       IdxVec ExpandedRWs;
1161       if (IsRead)
1162         ExpandedRWs.push_back(*RWI);
1163       else
1164         SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
1165       RWSequences[OperIdx].insert(RWSequences[OperIdx].end(),
1166                                   ExpandedRWs.begin(), ExpandedRWs.end());
1167     }
1168     assert(OperIdx == RWSequences.size() && "missed a sequence");
1169   }
1170   else {
1171     // Push this transition's expanded sequence onto this transition's last
1172     // sequence (add to the current operand's sequence).
1173     SmallVectorImpl<unsigned> &Seq = RWSequences.back();
1174     IdxVec ExpandedRWs;
1175     for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
1176          RWI != RWE; ++RWI) {
1177       if (IsRead)
1178         ExpandedRWs.push_back(*RWI);
1179       else
1180         SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
1181     }
1182     Seq.insert(Seq.end(), ExpandedRWs.begin(), ExpandedRWs.end());
1183   }
1184 }
1185 
1186 // RWSeq is a sequence of all Reads or all Writes for the next read or write
1187 // operand. StartIdx is an index into TransVec where partial results
1188 // starts. RWSeq must be applied to all transitions between StartIdx and the end
1189 // of TransVec.
1190 void PredTransitions::substituteVariantOperand(
1191   const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) {
1192 
1193   // Visit each original RW within the current sequence.
1194   for (SmallVectorImpl<unsigned>::const_iterator
1195          RWI = RWSeq.begin(), RWE = RWSeq.end(); RWI != RWE; ++RWI) {
1196     const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(*RWI, IsRead);
1197     // Push this RW on all partial PredTransitions or distribute variants.
1198     // New PredTransitions may be pushed within this loop which should not be
1199     // revisited (TransEnd must be loop invariant).
1200     for (unsigned TransIdx = StartIdx, TransEnd = TransVec.size();
1201          TransIdx != TransEnd; ++TransIdx) {
1202       // In the common case, push RW onto the current operand's sequence.
1203       if (!hasAliasedVariants(SchedRW, SchedModels)) {
1204         if (IsRead)
1205           TransVec[TransIdx].ReadSequences.back().push_back(*RWI);
1206         else
1207           TransVec[TransIdx].WriteSequences.back().push_back(*RWI);
1208         continue;
1209       }
1210       // Distribute this partial PredTransition across intersecting variants.
1211       // This will push a copies of TransVec[TransIdx] on the back of TransVec.
1212       std::vector<TransVariant> IntersectingVariants;
1213       getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants);
1214       if (IntersectingVariants.empty())
1215         throw TGError(SchedRW.TheDef->getLoc(), "No variant of this type has a "
1216                       "matching predicate on any processor ");
1217       // Now expand each variant on top of its copy of the transition.
1218       for (std::vector<TransVariant>::const_iterator
1219              IVI = IntersectingVariants.begin(),
1220              IVE = IntersectingVariants.end();
1221            IVI != IVE; ++IVI) {
1222         pushVariant(*IVI, IsRead);
1223       }
1224     }
1225   }
1226 }
1227 
1228 // For each variant of a Read/Write in Trans, substitute the sequence of
1229 // Read/Writes guarded by the variant. This is exponential in the number of
1230 // variant Read/Writes, but in practice detection of mutually exclusive
1231 // predicates should result in linear growth in the total number variants.
1232 //
1233 // This is one step in a breadth-first search of nested variants.
1234 void PredTransitions::substituteVariants(const PredTransition &Trans) {
1235   // Build up a set of partial results starting at the back of
1236   // PredTransitions. Remember the first new transition.
1237   unsigned StartIdx = TransVec.size();
1238   TransVec.resize(TransVec.size() + 1);
1239   TransVec.back().PredTerm = Trans.PredTerm;
1240   TransVec.back().ProcIndices = Trans.ProcIndices;
1241 
1242   // Visit each original write sequence.
1243   for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1244          WSI = Trans.WriteSequences.begin(), WSE = Trans.WriteSequences.end();
1245        WSI != WSE; ++WSI) {
1246     // Push a new (empty) write sequence onto all partial Transitions.
1247     for (std::vector<PredTransition>::iterator I =
1248            TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
1249       I->WriteSequences.resize(I->WriteSequences.size() + 1);
1250     }
1251     substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx);
1252   }
1253   // Visit each original read sequence.
1254   for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1255          RSI = Trans.ReadSequences.begin(), RSE = Trans.ReadSequences.end();
1256        RSI != RSE; ++RSI) {
1257     // Push a new (empty) read sequence onto all partial Transitions.
1258     for (std::vector<PredTransition>::iterator I =
1259            TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
1260       I->ReadSequences.resize(I->ReadSequences.size() + 1);
1261     }
1262     substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx);
1263   }
1264 }
1265 
1266 // Create a new SchedClass for each variant found by inferFromRW. Pass
1267 static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
1268                                  unsigned FromClassIdx,
1269                                  CodeGenSchedModels &SchedModels) {
1270   // For each PredTransition, create a new CodeGenSchedTransition, which usually
1271   // requires creating a new SchedClass.
1272   for (ArrayRef<PredTransition>::iterator
1273          I = LastTransitions.begin(), E = LastTransitions.end(); I != E; ++I) {
1274     IdxVec OperWritesVariant;
1275     for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1276            WSI = I->WriteSequences.begin(), WSE = I->WriteSequences.end();
1277          WSI != WSE; ++WSI) {
1278       // Create a new write representing the expanded sequence.
1279       OperWritesVariant.push_back(
1280         SchedModels.findOrInsertRW(*WSI, /*IsRead=*/false));
1281     }
1282     IdxVec OperReadsVariant;
1283     for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1284            RSI = I->ReadSequences.begin(), RSE = I->ReadSequences.end();
1285          RSI != RSE; ++RSI) {
1286       // Create a new read representing the expanded sequence.
1287       OperReadsVariant.push_back(
1288         SchedModels.findOrInsertRW(*RSI, /*IsRead=*/true));
1289     }
1290     IdxVec ProcIndices(I->ProcIndices.begin(), I->ProcIndices.end());
1291     CodeGenSchedTransition SCTrans;
1292     SCTrans.ToClassIdx =
1293       SchedModels.addSchedClass(OperWritesVariant, OperReadsVariant,
1294                                 ProcIndices);
1295     SCTrans.ProcIndices = ProcIndices;
1296     // The final PredTerm is unique set of predicates guarding the transition.
1297     RecVec Preds;
1298     for (SmallVectorImpl<PredCheck>::const_iterator
1299            PI = I->PredTerm.begin(), PE = I->PredTerm.end(); PI != PE; ++PI) {
1300       Preds.push_back(PI->Predicate);
1301     }
1302     RecIter PredsEnd = std::unique(Preds.begin(), Preds.end());
1303     Preds.resize(PredsEnd - Preds.begin());
1304     SCTrans.PredTerm = Preds;
1305     SchedModels.getSchedClass(FromClassIdx).Transitions.push_back(SCTrans);
1306   }
1307 }
1308 
1309 // Create new SchedClasses for the given ReadWrite list. If any of the
1310 // ReadWrites refers to a SchedVariant, create a new SchedClass for each variant
1311 // of the ReadWrite list, following Aliases if necessary.
1312 void CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites,
1313                                      const IdxVec &OperReads,
1314                                      unsigned FromClassIdx,
1315                                      const IdxVec &ProcIndices) {
1316   DEBUG(dbgs() << "INFER RW: ");
1317 
1318   // Create a seed transition with an empty PredTerm and the expanded sequences
1319   // of SchedWrites for the current SchedClass.
1320   std::vector<PredTransition> LastTransitions;
1321   LastTransitions.resize(1);
1322   LastTransitions.back().ProcIndices.append(ProcIndices.begin(),
1323                                             ProcIndices.end());
1324 
1325   for (IdxIter I = OperWrites.begin(), E = OperWrites.end(); I != E; ++I) {
1326     IdxVec WriteSeq;
1327     expandRWSequence(*I, WriteSeq, /*IsRead=*/false);
1328     unsigned Idx = LastTransitions[0].WriteSequences.size();
1329     LastTransitions[0].WriteSequences.resize(Idx + 1);
1330     SmallVectorImpl<unsigned> &Seq = LastTransitions[0].WriteSequences[Idx];
1331     for (IdxIter WI = WriteSeq.begin(), WE = WriteSeq.end(); WI != WE; ++WI)
1332       Seq.push_back(*WI);
1333     DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
1334   }
1335   DEBUG(dbgs() << " Reads: ");
1336   for (IdxIter I = OperReads.begin(), E = OperReads.end(); I != E; ++I) {
1337     IdxVec ReadSeq;
1338     expandRWSequence(*I, ReadSeq, /*IsRead=*/true);
1339     unsigned Idx = LastTransitions[0].ReadSequences.size();
1340     LastTransitions[0].ReadSequences.resize(Idx + 1);
1341     SmallVectorImpl<unsigned> &Seq = LastTransitions[0].ReadSequences[Idx];
1342     for (IdxIter RI = ReadSeq.begin(), RE = ReadSeq.end(); RI != RE; ++RI)
1343       Seq.push_back(*RI);
1344     DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") ");
1345   }
1346   DEBUG(dbgs() << '\n');
1347 
1348   // Collect all PredTransitions for individual operands.
1349   // Iterate until no variant writes remain.
1350   while (hasVariant(LastTransitions, *this)) {
1351     PredTransitions Transitions(*this);
1352     for (std::vector<PredTransition>::const_iterator
1353            I = LastTransitions.begin(), E = LastTransitions.end();
1354          I != E; ++I) {
1355       Transitions.substituteVariants(*I);
1356     }
1357     DEBUG(Transitions.dump());
1358     LastTransitions.swap(Transitions.TransVec);
1359   }
1360   // If the first transition has no variants, nothing to do.
1361   if (LastTransitions[0].PredTerm.empty())
1362     return;
1363 
1364   // WARNING: We are about to mutate the SchedClasses vector. Do not refer to
1365   // OperWrites, OperReads, or ProcIndices after calling inferFromTransitions.
1366   inferFromTransitions(LastTransitions, FromClassIdx, *this);
1367 }
1368 
1369 // Collect and sort WriteRes, ReadAdvance, and ProcResources.
1370 void CodeGenSchedModels::collectProcResources() {
1371   // Add any subtarget-specific SchedReadWrites that are directly associated
1372   // with processor resources. Refer to the parent SchedClass's ProcIndices to
1373   // determine which processors they apply to.
1374   for (SchedClassIter SCI = schedClassBegin(), SCE = schedClassEnd();
1375        SCI != SCE; ++SCI) {
1376     if (SCI->ItinClassDef)
1377       collectItinProcResources(SCI->ItinClassDef);
1378     else
1379       collectRWResources(SCI->Writes, SCI->Reads, SCI->ProcIndices);
1380   }
1381   // Add resources separately defined by each subtarget.
1382   RecVec WRDefs = Records.getAllDerivedDefinitions("WriteRes");
1383   for (RecIter WRI = WRDefs.begin(), WRE = WRDefs.end(); WRI != WRE; ++WRI) {
1384     Record *ModelDef = (*WRI)->getValueAsDef("SchedModel");
1385     addWriteRes(*WRI, getProcModel(ModelDef).Index);
1386   }
1387   RecVec RADefs = Records.getAllDerivedDefinitions("ReadAdvance");
1388   for (RecIter RAI = RADefs.begin(), RAE = RADefs.end(); RAI != RAE; ++RAI) {
1389     Record *ModelDef = (*RAI)->getValueAsDef("SchedModel");
1390     addReadAdvance(*RAI, getProcModel(ModelDef).Index);
1391   }
1392   // Finalize each ProcModel by sorting the record arrays.
1393   for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
1394     CodeGenProcModel &PM = ProcModels[PIdx];
1395     std::sort(PM.WriteResDefs.begin(), PM.WriteResDefs.end(),
1396               LessRecord());
1397     std::sort(PM.ReadAdvanceDefs.begin(), PM.ReadAdvanceDefs.end(),
1398               LessRecord());
1399     std::sort(PM.ProcResourceDefs.begin(), PM.ProcResourceDefs.end(),
1400               LessRecord());
1401     DEBUG(
1402       PM.dump();
1403       dbgs() << "WriteResDefs: ";
1404       for (RecIter RI = PM.WriteResDefs.begin(),
1405              RE = PM.WriteResDefs.end(); RI != RE; ++RI) {
1406         if ((*RI)->isSubClassOf("WriteRes"))
1407           dbgs() << (*RI)->getValueAsDef("WriteType")->getName() << " ";
1408         else
1409           dbgs() << (*RI)->getName() << " ";
1410       }
1411       dbgs() << "\nReadAdvanceDefs: ";
1412       for (RecIter RI = PM.ReadAdvanceDefs.begin(),
1413              RE = PM.ReadAdvanceDefs.end(); RI != RE; ++RI) {
1414         if ((*RI)->isSubClassOf("ReadAdvance"))
1415           dbgs() << (*RI)->getValueAsDef("ReadType")->getName() << " ";
1416         else
1417           dbgs() << (*RI)->getName() << " ";
1418       }
1419       dbgs() << "\nProcResourceDefs: ";
1420       for (RecIter RI = PM.ProcResourceDefs.begin(),
1421              RE = PM.ProcResourceDefs.end(); RI != RE; ++RI) {
1422         dbgs() << (*RI)->getName() << " ";
1423       }
1424       dbgs() << '\n');
1425   }
1426 }
1427 
1428 // Collect itinerary class resources for each processor.
1429 void CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) {
1430   for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
1431     const CodeGenProcModel &PM = ProcModels[PIdx];
1432     // For all ItinRW entries.
1433     bool HasMatch = false;
1434     for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end();
1435          II != IE; ++II) {
1436       RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
1437       if (!std::count(Matched.begin(), Matched.end(), ItinClassDef))
1438         continue;
1439       if (HasMatch)
1440         throw TGError((*II)->getLoc(), "Duplicate itinerary class "
1441                       + ItinClassDef->getName()
1442                       + " in ItinResources for " + PM.ModelName);
1443       HasMatch = true;
1444       IdxVec Writes, Reads;
1445       findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads);
1446       IdxVec ProcIndices(1, PIdx);
1447       collectRWResources(Writes, Reads, ProcIndices);
1448     }
1449   }
1450 }
1451 
1452 void CodeGenSchedModels::collectRWResources(unsigned RWIdx, bool IsRead,
1453                                             const IdxVec &ProcIndices) {
1454   const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead);
1455   if (SchedRW.TheDef) {
1456     if (!IsRead && SchedRW.TheDef->isSubClassOf("SchedWriteRes")) {
1457       for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end();
1458            PI != PE; ++PI) {
1459         addWriteRes(SchedRW.TheDef, *PI);
1460       }
1461     }
1462     else if (IsRead && SchedRW.TheDef->isSubClassOf("SchedReadAdvance")) {
1463       for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end();
1464            PI != PE; ++PI) {
1465         addReadAdvance(SchedRW.TheDef, *PI);
1466       }
1467     }
1468   }
1469   for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
1470        AI != AE; ++AI) {
1471     IdxVec AliasProcIndices;
1472     if ((*AI)->getValueInit("SchedModel")->isComplete()) {
1473       AliasProcIndices.push_back(
1474         getProcModel((*AI)->getValueAsDef("SchedModel")).Index);
1475     }
1476     else
1477       AliasProcIndices = ProcIndices;
1478     const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW"));
1479     assert(AliasRW.IsRead == IsRead && "cannot alias reads to writes");
1480 
1481     IdxVec ExpandedRWs;
1482     expandRWSequence(AliasRW.Index, ExpandedRWs, IsRead);
1483     for (IdxIter SI = ExpandedRWs.begin(), SE = ExpandedRWs.end();
1484          SI != SE; ++SI) {
1485       collectRWResources(*SI, IsRead, AliasProcIndices);
1486     }
1487   }
1488 }
1489 
1490 // Collect resources for a set of read/write types and processor indices.
1491 void CodeGenSchedModels::collectRWResources(const IdxVec &Writes,
1492                                             const IdxVec &Reads,
1493                                             const IdxVec &ProcIndices) {
1494 
1495   for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI)
1496     collectRWResources(*WI, /*IsRead=*/false, ProcIndices);
1497 
1498   for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI)
1499     collectRWResources(*RI, /*IsRead=*/true, ProcIndices);
1500 }
1501 
1502 
1503 // Find the processor's resource units for this kind of resource.
1504 Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
1505                                              const CodeGenProcModel &PM) const {
1506   if (ProcResKind->isSubClassOf("ProcResourceUnits"))
1507     return ProcResKind;
1508 
1509   Record *ProcUnitDef = 0;
1510   RecVec ProcResourceDefs =
1511     Records.getAllDerivedDefinitions("ProcResourceUnits");
1512 
1513   for (RecIter RI = ProcResourceDefs.begin(), RE = ProcResourceDefs.end();
1514        RI != RE; ++RI) {
1515 
1516     if ((*RI)->getValueAsDef("Kind") == ProcResKind
1517         && (*RI)->getValueAsDef("SchedModel") == PM.ModelDef) {
1518       if (ProcUnitDef) {
1519         throw TGError((*RI)->getLoc(),
1520                       "Multiple ProcessorResourceUnits associated with "
1521                       + ProcResKind->getName());
1522       }
1523       ProcUnitDef = *RI;
1524     }
1525   }
1526   if (!ProcUnitDef) {
1527     throw TGError(ProcResKind->getLoc(),
1528                   "No ProcessorResources associated with "
1529                   + ProcResKind->getName());
1530   }
1531   return ProcUnitDef;
1532 }
1533 
1534 // Iteratively add a resource and its super resources.
1535 void CodeGenSchedModels::addProcResource(Record *ProcResKind,
1536                                          CodeGenProcModel &PM) {
1537   for (;;) {
1538     Record *ProcResUnits = findProcResUnits(ProcResKind, PM);
1539 
1540     // See if this ProcResource is already associated with this processor.
1541     RecIter I = std::find(PM.ProcResourceDefs.begin(),
1542                           PM.ProcResourceDefs.end(), ProcResUnits);
1543     if (I != PM.ProcResourceDefs.end())
1544       return;
1545 
1546     PM.ProcResourceDefs.push_back(ProcResUnits);
1547     if (!ProcResUnits->getValueInit("Super")->isComplete())
1548       return;
1549 
1550     ProcResKind = ProcResUnits->getValueAsDef("Super");
1551   }
1552 }
1553 
1554 // Add resources for a SchedWrite to this processor if they don't exist.
1555 void CodeGenSchedModels::addWriteRes(Record *ProcWriteResDef, unsigned PIdx) {
1556   assert(PIdx && "don't add resources to an invalid Processor model");
1557 
1558   RecVec &WRDefs = ProcModels[PIdx].WriteResDefs;
1559   RecIter WRI = std::find(WRDefs.begin(), WRDefs.end(), ProcWriteResDef);
1560   if (WRI != WRDefs.end())
1561     return;
1562   WRDefs.push_back(ProcWriteResDef);
1563 
1564   // Visit ProcResourceKinds referenced by the newly discovered WriteRes.
1565   RecVec ProcResDefs = ProcWriteResDef->getValueAsListOfDefs("ProcResources");
1566   for (RecIter WritePRI = ProcResDefs.begin(), WritePRE = ProcResDefs.end();
1567        WritePRI != WritePRE; ++WritePRI) {
1568     addProcResource(*WritePRI, ProcModels[PIdx]);
1569   }
1570 }
1571 
1572 // Add resources for a ReadAdvance to this processor if they don't exist.
1573 void CodeGenSchedModels::addReadAdvance(Record *ProcReadAdvanceDef,
1574                                         unsigned PIdx) {
1575   RecVec &RADefs = ProcModels[PIdx].ReadAdvanceDefs;
1576   RecIter I = std::find(RADefs.begin(), RADefs.end(), ProcReadAdvanceDef);
1577   if (I != RADefs.end())
1578     return;
1579   RADefs.push_back(ProcReadAdvanceDef);
1580 }
1581 
1582 unsigned CodeGenProcModel::getProcResourceIdx(Record *PRDef) const {
1583   RecIter PRPos = std::find(ProcResourceDefs.begin(), ProcResourceDefs.end(),
1584                             PRDef);
1585   if (PRPos == ProcResourceDefs.end())
1586     throw TGError(PRDef->getLoc(), "ProcResource def is not included in "
1587                   "the ProcResources list for " + ModelName);
1588   // Idx=0 is reserved for invalid.
1589   return 1 + PRPos - ProcResourceDefs.begin();
1590 }
1591 
1592 #ifndef NDEBUG
1593 void CodeGenProcModel::dump() const {
1594   dbgs() << Index << ": " << ModelName << " "
1595          << (ModelDef ? ModelDef->getName() : "inferred") << " "
1596          << (ItinsDef ? ItinsDef->getName() : "no itinerary") << '\n';
1597 }
1598 
1599 void CodeGenSchedRW::dump() const {
1600   dbgs() << Name << (IsVariadic ? " (V) " : " ");
1601   if (IsSequence) {
1602     dbgs() << "(";
1603     dumpIdxVec(Sequence);
1604     dbgs() << ")";
1605   }
1606 }
1607 
1608 void CodeGenSchedClass::dump(const CodeGenSchedModels* SchedModels) const {
1609   dbgs() << "SCHEDCLASS " << Name << '\n'
1610          << "  Writes: ";
1611   for (unsigned i = 0, N = Writes.size(); i < N; ++i) {
1612     SchedModels->getSchedWrite(Writes[i]).dump();
1613     if (i < N-1) {
1614       dbgs() << '\n';
1615       dbgs().indent(10);
1616     }
1617   }
1618   dbgs() << "\n  Reads: ";
1619   for (unsigned i = 0, N = Reads.size(); i < N; ++i) {
1620     SchedModels->getSchedRead(Reads[i]).dump();
1621     if (i < N-1) {
1622       dbgs() << '\n';
1623       dbgs().indent(10);
1624     }
1625   }
1626   dbgs() << "\n  ProcIdx: "; dumpIdxVec(ProcIndices); dbgs() << '\n';
1627 }
1628 
1629 void PredTransitions::dump() const {
1630   dbgs() << "Expanded Variants:\n";
1631   for (std::vector<PredTransition>::const_iterator
1632          TI = TransVec.begin(), TE = TransVec.end(); TI != TE; ++TI) {
1633     dbgs() << "{";
1634     for (SmallVectorImpl<PredCheck>::const_iterator
1635            PCI = TI->PredTerm.begin(), PCE = TI->PredTerm.end();
1636          PCI != PCE; ++PCI) {
1637       if (PCI != TI->PredTerm.begin())
1638         dbgs() << ", ";
1639       dbgs() << SchedModels.getSchedRW(PCI->RWIdx, PCI->IsRead).Name
1640              << ":" << PCI->Predicate->getName();
1641     }
1642     dbgs() << "},\n  => {";
1643     for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
1644            WSI = TI->WriteSequences.begin(), WSE = TI->WriteSequences.end();
1645          WSI != WSE; ++WSI) {
1646       dbgs() << "(";
1647       for (SmallVectorImpl<unsigned>::const_iterator
1648              WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
1649         if (WI != WSI->begin())
1650           dbgs() << ", ";
1651         dbgs() << SchedModels.getSchedWrite(*WI).Name;
1652       }
1653       dbgs() << "),";
1654     }
1655     dbgs() << "}\n";
1656   }
1657 }
1658 #endif // NDEBUG
1659