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