CodeGenSchedule.cpp revision 3cbd1786ac06fe751dc4b5ad55e75115cb1d51ce
12661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick//===- CodeGenSchedule.cpp - Scheduling MachineModels ---------------------===// 22661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// 32661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// The LLVM Compiler Infrastructure 42661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// 52661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// This file is distributed under the University of Illinois Open Source 62661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// License. See LICENSE.TXT for details. 72661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// 82661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick//===----------------------------------------------------------------------===// 92661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// 102661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// This file defines structures to encapsulate the machine model as decribed in 112661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// the target description. 122661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// 132661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick//===----------------------------------------------------------------------===// 142661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 152661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick#define DEBUG_TYPE "subtarget-emitter" 162661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 172661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick#include "CodeGenSchedule.h" 182661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick#include "CodeGenTarget.h" 1948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick#include "llvm/TableGen/Error.h" 202661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick#include "llvm/Support/Debug.h" 212661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 222661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trickusing namespace llvm; 232661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 2448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick#ifndef NDEBUG 2548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickstatic void dumpIdxVec(const IdxVec &V) { 2648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned i = 0, e = V.size(); i < e; ++i) { 2748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << V[i] << ", "; 2848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 2948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickstatic void dumpIdxVec(const SmallVectorImpl<unsigned> &V) { 315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (unsigned i = 0, e = V.size(); i < e; ++i) { 325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << V[i] << ", "; 335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 3548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick#endif 3648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 3748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// CodeGenModels ctor interprets machine model records and populates maps. 382661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew TrickCodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK, 392661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const CodeGenTarget &TGT): 4048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Records(RK), Target(TGT), NumItineraryClasses(0) { 4148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 4248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Instantiate a CodeGenProcModel for each SchedMachineModel with the values 4348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // that are explicitly referenced in tablegen records. Resources associated 4448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // with each processor will be derived later. Populate ProcModelMap with the 4548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // CodeGenProcModel instances. 4648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick collectProcModels(); 4748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 4848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Instantiate a CodeGenSchedRW for each SchedReadWrite record explicitly 4948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // defined, and populate SchedReads and SchedWrites vectors. Implicit 5048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // SchedReadWrites that represent sequences derived from expanded variant will 5148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // be inferred later. 5248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick collectSchedRW(); 5348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 5448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Instantiate a CodeGenSchedClass for each unique SchedRW signature directly 5548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // required by an instruction definition, and populate SchedClassIdxMap. Set 5648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // NumItineraryClasses to the number of explicit itinerary classes referenced 5748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // by instructions. Set NumInstrSchedClasses to the number of itinerary 5848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // classes plus any classes implied by instructions that derive from class 5948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Sched and provide SchedRW list. This does not infer any new classes from 6048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // SchedVariant. 6148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick collectSchedClasses(); 6248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 6348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Find instruction itineraries for each processor. Sort and populate 6448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // CodeGenProcMode::ItinDefList. (Cycle-to-cycle itineraries). This requires 6548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // all itinerary classes to be discovered. 6648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick collectProcItins(); 6748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 6848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Find ItinRW records for each processor and itinerary class. 6948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // (For per-operand resources mapped to itinerary classes). 7048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick collectProcItinRW(); 715e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 725e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Infer new SchedClasses from SchedVariant. 735e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferSchedClasses(); 745e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 755e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(for (unsigned i = 0; i < SchedClasses.size(); ++i) 765e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedClasses[i].dump(this)); 773cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 783cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // Populate each CodeGenProcModel's WriteResDefs, ReadAdvanceDefs, and 793cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // ProcResourceDefs. 803cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick collectProcResources(); 8148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 8248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 8348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// Gather all processor models. 8448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::collectProcModels() { 8548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec ProcRecords = Records.getAllDerivedDefinitions("Processor"); 8648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::sort(ProcRecords.begin(), ProcRecords.end(), LessRecordFieldName()); 8748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 8848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Reserve space because we can. Reallocation would be ok. 8948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModels.reserve(ProcRecords.size()+1); 9048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 9148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Use idx=0 for NoModel/NoItineraries. 9248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *NoModelDef = Records.getDef("NoSchedModel"); 9348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *NoItinsDef = Records.getDef("NoItineraries"); 9448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModels.push_back(CodeGenProcModel(0, "NoSchedModel", 9548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick NoModelDef, NoItinsDef)); 9648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModelMap[NoModelDef] = 0; 9748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 9848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // For each processor, find a unique machine model. 9948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned i = 0, N = ProcRecords.size(); i < N; ++i) 10048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick addProcModel(ProcRecords[i]); 10148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 10248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 10348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// Get a unique processor model based on the defined MachineModel and 10448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// ProcessorItineraries. 10548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::addProcModel(Record *ProcDef) { 10648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ModelKey = getModelOrItinDef(ProcDef); 10748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!ProcModelMap.insert(std::make_pair(ModelKey, ProcModels.size())).second) 10848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return; 10948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 11048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::string Name = ModelKey->getName(); 11148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (ModelKey->isSubClassOf("SchedMachineModel")) { 11248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ItinsDef = ModelKey->getValueAsDef("Itineraries"); 11348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModels.push_back( 11448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick CodeGenProcModel(ProcModels.size(), Name, ModelKey, ItinsDef)); 11548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 11648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else { 11748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // An itinerary is defined without a machine model. Infer a new model. 11848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!ModelKey->getValueAsListOfDefs("IID").empty()) 11948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name = Name + "Model"; 12048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModels.push_back( 12148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick CodeGenProcModel(ProcModels.size(), Name, 12248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcDef->getValueAsDef("SchedModel"), ModelKey)); 12348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 12448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick DEBUG(ProcModels.back().dump()); 12548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 12648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 12748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Recursively find all reachable SchedReadWrite records. 12848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickstatic void scanSchedRW(Record *RWDef, RecVec &RWDefs, 12948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SmallPtrSet<Record*, 16> &RWSet) { 13048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!RWSet.insert(RWDef)) 13148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return; 13248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RWDefs.push_back(RWDef); 13348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Reads don't current have sequence records, but it can be added later. 13448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (RWDef->isSubClassOf("WriteSequence")) { 13548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec Seq = RWDef->getValueAsListOfDefs("Writes"); 13648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter I = Seq.begin(), E = Seq.end(); I != E; ++I) 13748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*I, RWDefs, RWSet); 13848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 13948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else if (RWDef->isSubClassOf("SchedVariant")) { 14048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Visit each variant (guarded by a different predicate). 14148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec Vars = RWDef->getValueAsListOfDefs("Variants"); 14248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter VI = Vars.begin(), VE = Vars.end(); VI != VE; ++VI) { 14348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Visit each RW in the sequence selected by the current variant. 14448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec Selected = (*VI)->getValueAsListOfDefs("Selected"); 14548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter I = Selected.begin(), E = Selected.end(); I != E; ++I) 14648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*I, RWDefs, RWSet); 14748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 14848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 14948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 15048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 15148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Collect and sort all SchedReadWrites reachable via tablegen records. 15248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// More may be inferred later when inferring new SchedClasses from variants. 15348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::collectSchedRW() { 15448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Reserve idx=0 for invalid writes/reads. 15548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedWrites.resize(1); 15648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedReads.resize(1); 1572661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 15848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SmallPtrSet<Record*, 16> RWSet; 1592661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 16048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Find all SchedReadWrites referenced by instruction defs. 16148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec SWDefs, SRDefs; 16248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 16348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick E = Target.inst_end(); I != E; ++I) { 16448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *SchedDef = (*I)->TheDef; 16548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!SchedDef->isSubClassOf("Sched")) 16648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 16748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec RWs = SchedDef->getValueAsListOfDefs("SchedRW"); 16848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RWI = RWs.begin(), RWE = RWs.end(); RWI != RWE; ++RWI) { 16948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if ((*RWI)->isSubClassOf("SchedWrite")) 17048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*RWI, SWDefs, RWSet); 17148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else { 17248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert((*RWI)->isSubClassOf("SchedRead") && "Unknown SchedReadWrite"); 17348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*RWI, SRDefs, RWSet); 17448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 17548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 17648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 17748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Find all ReadWrites referenced by InstRW. 17848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW"); 17948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter OI = InstRWDefs.begin(), OE = InstRWDefs.end(); OI != OE; ++OI) { 18048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // For all OperandReadWrites. 18148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec RWDefs = (*OI)->getValueAsListOfDefs("OperandReadWrites"); 18248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); 18348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RWI != RWE; ++RWI) { 18448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if ((*RWI)->isSubClassOf("SchedWrite")) 18548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*RWI, SWDefs, RWSet); 18648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else { 18748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert((*RWI)->isSubClassOf("SchedRead") && "Unknown SchedReadWrite"); 18848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*RWI, SRDefs, RWSet); 18948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 19048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 19148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 19248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Find all ReadWrites referenced by ItinRW. 19348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW"); 19448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter II = ItinRWDefs.begin(), IE = ItinRWDefs.end(); II != IE; ++II) { 19548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // For all OperandReadWrites. 19648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec RWDefs = (*II)->getValueAsListOfDefs("OperandReadWrites"); 19748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); 19848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RWI != RWE; ++RWI) { 19948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if ((*RWI)->isSubClassOf("SchedWrite")) 20048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*RWI, SWDefs, RWSet); 20148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else { 20248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert((*RWI)->isSubClassOf("SchedRead") && "Unknown SchedReadWrite"); 20348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick scanSchedRW(*RWI, SRDefs, RWSet); 20448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 20548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 20648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 20748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Sort and add the SchedReadWrites directly referenced by instructions or 20848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // itinerary resources. Index reads and writes in separate domains. 20948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::sort(SWDefs.begin(), SWDefs.end(), LessRecord()); 21048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter SWI = SWDefs.begin(), SWE = SWDefs.end(); SWI != SWE; ++SWI) { 21148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(!getSchedRWIdx(*SWI, /*IsRead=*/false) && "duplicate SchedWrite"); 21248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedWrites.push_back(CodeGenSchedRW(*SWI)); 21348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 21448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::sort(SRDefs.begin(), SRDefs.end(), LessRecord()); 21548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter SRI = SRDefs.begin(), SRE = SRDefs.end(); SRI != SRE; ++SRI) { 21648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(!getSchedRWIdx(*SRI, /*IsRead-*/true) && "duplicate SchedWrite"); 21748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedReads.push_back(CodeGenSchedRW(*SRI)); 21848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 21948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Initialize WriteSequence vectors. 22048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (std::vector<CodeGenSchedRW>::iterator WI = SchedWrites.begin(), 22148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick WE = SchedWrites.end(); WI != WE; ++WI) { 22248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!WI->IsSequence) 22348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 22448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs(WI->TheDef->getValueAsListOfDefs("Writes"), WI->Sequence, 22548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick /*IsRead=*/false); 22648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 22748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick DEBUG( 22848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned WIdx = 0, WEnd = SchedWrites.size(); WIdx != WEnd; ++WIdx) { 22948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << WIdx << ": "; 23048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedWrites[WIdx].dump(); 23148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << '\n'; 23248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 23348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned RIdx = 0, REnd = SchedReads.size(); RIdx != REnd; ++RIdx) { 23448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << RIdx << ": "; 23548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedReads[RIdx].dump(); 23648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << '\n'; 23748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 23848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec RWDefs = Records.getAllDerivedDefinitions("SchedReadWrite"); 23948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RI = RWDefs.begin(), RE = RWDefs.end(); 24048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RI != RE; ++RI) { 24148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!getSchedRWIdx(*RI, (*RI)->isSubClassOf("SchedRead"))) { 24248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const std::string &Name = (*RI)->getName(); 24348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (Name != "NoWrite" && Name != "ReadDefault") 24448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "Unused SchedReadWrite " << (*RI)->getName() << '\n'; 24548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 24648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick }); 24748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 24848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 24948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// Compute a SchedWrite name from a sequence of writes. 25048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickstd::string CodeGenSchedModels::genRWName(const IdxVec& Seq, bool IsRead) { 25148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::string Name("("); 25248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter I = Seq.begin(), E = Seq.end(); I != E; ++I) { 25348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (I != Seq.begin()) 25448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += '_'; 25548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += getSchedRW(*I, IsRead).Name; 25648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 25748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += ')'; 25848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return Name; 25948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 26048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 26148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickunsigned CodeGenSchedModels::getSchedRWIdx(Record *Def, bool IsRead, 26248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned After) const { 26348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites; 26448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(After < RWVec.size() && "start position out of bounds"); 26548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (std::vector<CodeGenSchedRW>::const_iterator I = RWVec.begin() + After, 26648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick E = RWVec.end(); I != E; ++I) { 26748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (I->TheDef == Def) 26848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return I - RWVec.begin(); 26948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 27048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return 0; 27148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 27248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 27348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Tricknamespace llvm { 27448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid splitSchedReadWrites(const RecVec &RWDefs, 27548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec &WriteDefs, RecVec &ReadDefs) { 27648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); RWI != RWE; ++RWI) { 27748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if ((*RWI)->isSubClassOf("SchedWrite")) 27848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick WriteDefs.push_back(*RWI); 27948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else { 28048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert((*RWI)->isSubClassOf("SchedRead") && "unknown SchedReadWrite"); 28148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ReadDefs.push_back(*RWI); 28248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 28348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 28448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 28548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} // namespace llvm 28648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 28748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Split the SchedReadWrites defs and call findRWs for each list. 28848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::findRWs(const RecVec &RWDefs, 28948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec &Writes, IdxVec &Reads) const { 29048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec WriteDefs; 29148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec ReadDefs; 29248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick splitSchedReadWrites(RWDefs, WriteDefs, ReadDefs); 29348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs(WriteDefs, Writes, false); 29448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs(ReadDefs, Reads, true); 29548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 29648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 29748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Call getSchedRWIdx for all elements in a sequence of SchedRW defs. 29848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::findRWs(const RecVec &RWDefs, IdxVec &RWs, 29948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick bool IsRead) const { 30048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RI = RWDefs.begin(), RE = RWDefs.end(); RI != RE; ++RI) { 30148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned Idx = getSchedRWIdx(*RI, IsRead); 30248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(Idx && "failed to collect SchedReadWrite"); 30348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RWs.push_back(Idx); 30448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 3052661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick} 3062661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 3075e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, 3085e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool IsRead) const { 3095e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const CodeGenSchedRW &SchedRW = getSchedRW(RWIdx, IsRead); 3105e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (!SchedRW.IsSequence) { 3115e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RWSeq.push_back(RWIdx); 3125e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return; 3135e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 3145e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick int Repeat = 3155e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedRW.TheDef ? SchedRW.TheDef->getValueAsInt("Repeat") : 1; 3165e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (int i = 0; i < Repeat; ++i) { 3175e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter I = SchedRW.Sequence.begin(), E = SchedRW.Sequence.end(); 3185e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I != E; ++I) { 3195e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick expandRWSequence(*I, RWSeq, IsRead); 3205e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 3215e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 3225e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 3235e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 3245e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Find the existing SchedWrite that models this sequence of writes. 3255e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickunsigned CodeGenSchedModels::findRWForSequence(const IdxVec &Seq, 3265e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool IsRead) { 3275e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick std::vector<CodeGenSchedRW> &RWVec = IsRead ? SchedReads : SchedWrites; 3285e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 3295e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (std::vector<CodeGenSchedRW>::iterator I = RWVec.begin(), E = RWVec.end(); 3305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I != E; ++I) { 3315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (I->Sequence == Seq) 3325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return I - RWVec.begin(); 3335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 3345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Index zero reserved for invalid RW. 3355e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return 0; 3365e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 3375e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 3385e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// Add this ReadWrite if it doesn't already exist. 3395e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickunsigned CodeGenSchedModels::findOrInsertRW(ArrayRef<unsigned> Seq, 3405e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool IsRead) { 3415e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick assert(!Seq.empty() && "cannot insert empty sequence"); 3425e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (Seq.size() == 1) 3435e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return Seq.back(); 3445e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 3455e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned Idx = findRWForSequence(Seq, IsRead); 3465e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (Idx) 3475e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return Idx; 3485e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 3495e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick CodeGenSchedRW SchedRW(Seq, genRWName(Seq, IsRead)); 3505e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (IsRead) { 3515e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedReads.push_back(SchedRW); 3525e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return SchedReads.size() - 1; 3535e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 3545e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedWrites.push_back(SchedRW); 3555e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return SchedWrites.size() - 1; 3565e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 3575e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 35848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// Visit all the instruction definitions for this target to gather and 35948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// enumerate the itinerary classes. These are the explicitly specified 36048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// SchedClasses. More SchedClasses may be inferred. 36148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::collectSchedClasses() { 3622661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 36348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // NoItinerary is always the first class at Idx=0 3642661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick SchedClasses.resize(1); 3652661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick SchedClasses.back().Name = "NoItinerary"; 36648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses.back().ProcIndices.push_back(0); 3672661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick SchedClassIdxMap[SchedClasses.back().Name] = 0; 3682661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 3692661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick // Gather and sort all itinerary classes used by instruction descriptions. 37048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec ItinClassList; 3712661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 3722661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick E = Target.inst_end(); I != E; ++I) { 37348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ItinDef = (*I)->TheDef->getValueAsDef("Itinerary"); 3742661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick // Map a new SchedClass with no index. 37548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!SchedClassIdxMap.count(ItinDef->getName())) { 37648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClassIdxMap[ItinDef->getName()] = 0; 37748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ItinClassList.push_back(ItinDef); 3782661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 3792661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 3802661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick // Assign each itinerary class unique number, skipping NoItinerary==0 3812661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick NumItineraryClasses = ItinClassList.size(); 3822661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); 3832661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick for (unsigned i = 0, N = NumItineraryClasses; i < N; i++) { 3842661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick Record *ItinDef = ItinClassList[i]; 3852661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick SchedClassIdxMap[ItinDef->getName()] = SchedClasses.size(); 3862661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick SchedClasses.push_back(CodeGenSchedClass(ItinDef)); 3872661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 38848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Infer classes from SchedReadWrite resources listed for each 38948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // instruction definition that inherits from class Sched. 39048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 39148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick E = Target.inst_end(); I != E; ++I) { 39248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!(*I)->TheDef->isSubClassOf("Sched")) 39348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 39448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec Writes, Reads; 39548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads); 39648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // ProcIdx == 0 indicates the class applies to all processors. 39748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec ProcIndices(1, 0); 39848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick addSchedClass(Writes, Reads, ProcIndices); 39948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 40048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Create classes for InstReadWrite defs. 40148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW"); 40248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::sort(InstRWDefs.begin(), InstRWDefs.end(), LessRecord()); 40348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter OI = InstRWDefs.begin(), OE = InstRWDefs.end(); OI != OE; ++OI) 40448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick createInstRWClass(*OI); 4052661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 40648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick NumInstrSchedClasses = SchedClasses.size(); 40748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 40848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick bool EnableDump = false; 40948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick DEBUG(EnableDump = true); 41048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!EnableDump) 41148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return; 41248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 41348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick E = Target.inst_end(); I != E; ++I) { 41448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *SchedDef = (*I)->TheDef; 41548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::string InstName = (*I)->TheDef->getName(); 41648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (SchedDef->isSubClassOf("Sched")) { 41748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec Writes; 41848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec Reads; 41948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads); 42048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "SchedRW machine model for " << InstName; 42148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) 42248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << " " << SchedWrites[*WI].Name; 42348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI) 42448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << " " << SchedReads[*RI].Name; 42548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << '\n'; 42648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 42748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned SCIdx = InstrClassMap.lookup((*I)->TheDef); 42848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (SCIdx) { 42948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs; 43048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); 43148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RWI != RWE; ++RWI) { 43248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const CodeGenProcModel &ProcModel = 43348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick getProcModel((*RWI)->getValueAsDef("SchedModel")); 43448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "InstrRW on " << ProcModel.ModelName << " for " << InstName; 43548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec Writes; 43648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec Reads; 43748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"), 43848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Writes, Reads); 43948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) 44048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << " " << SchedWrites[*WI].Name; 44148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI) 44248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << " " << SchedReads[*RI].Name; 44348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << '\n'; 44448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 44548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 44648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 44748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!SchedDef->isSubClassOf("Sched") 44848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick && (SchedDef->getValueAsDef("Itinerary")->getName() == "NoItinerary")) { 44948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "No machine model for " << (*I)->TheDef->getName() << '\n'; 45048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 45148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 4522661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick} 4532661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 45448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickunsigned CodeGenSchedModels::getSchedClassIdx( 45548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const RecVec &RWDefs) const { 4562661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 45748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec Writes, Reads; 45848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick findRWs(RWDefs, Writes, Reads); 45948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return findSchedClassIdx(Writes, Reads); 46048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 4612661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 46248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// Find an SchedClass that has been inferred from a per-operand list of 46348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// SchedWrites and SchedReads. 46448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickunsigned CodeGenSchedModels::findSchedClassIdx(const IdxVec &Writes, 46548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const IdxVec &Reads) const { 46648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (SchedClassIter I = schedClassBegin(), E = schedClassEnd(); I != E; ++I) { 46748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Classes with InstRWs may have the same Writes/Reads as a class originally 46848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // produced by a SchedRW definition. We need to be able to recover the 46948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // original class index for processors that don't match any InstRWs. 47048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (I->ItinClassDef || !I->InstRWs.empty()) 47148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 47248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 47348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (I->Writes == Writes && I->Reads == Reads) { 47448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return I - schedClassBegin(); 47548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 47648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 47748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return 0; 4782661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick} 4792661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 48048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Get the SchedClass index for an instruction. 48148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickunsigned CodeGenSchedModels::getSchedClassIdx( 48248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const CodeGenInstruction &Inst) const { 4832661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 48448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned SCIdx = InstrClassMap.lookup(Inst.TheDef); 48548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (SCIdx) 48648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return SCIdx; 4872661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 48848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // If this opcode isn't mapped by the subtarget fallback to the instruction 48948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // definition's SchedRW or ItinDef values. 49048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (Inst.TheDef->isSubClassOf("Sched")) { 49148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec RWs = Inst.TheDef->getValueAsListOfDefs("SchedRW"); 49248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return getSchedClassIdx(RWs); 49348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 49448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ItinDef = Inst.TheDef->getValueAsDef("Itinerary"); 49548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass"); 49648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName()); 49748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(Idx <= NumItineraryClasses && "bad ItinClass index"); 49848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return Idx; 49948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 5002661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 50148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickstd::string CodeGenSchedModels::createSchedClassName( 50248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const IdxVec &OperWrites, const IdxVec &OperReads) { 50348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 50448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::string Name; 50548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter WI = OperWrites.begin(), WE = OperWrites.end(); WI != WE; ++WI) { 50648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (WI != OperWrites.begin()) 50748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += '_'; 50848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += SchedWrites[*WI].Name; 5092661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 51048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (IdxIter RI = OperReads.begin(), RE = OperReads.end(); RI != RE; ++RI) { 51148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += '_'; 51248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += SchedReads[*RI].Name; 5132661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 51448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return Name; 51548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 5162661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 51748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickstd::string CodeGenSchedModels::createSchedClassName(const RecVec &InstDefs) { 5182661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 51948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::string Name; 52048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter I = InstDefs.begin(), E = InstDefs.end(); I != E; ++I) { 52148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (I != InstDefs.begin()) 52248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += '_'; 52348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Name += (*I)->getName(); 52448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 52548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return Name; 52648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 52748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 52848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// Add an inferred sched class from a per-operand list of SchedWrites and 52948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// SchedReads. ProcIndices contains the set of IDs of processors that may 53048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick/// utilize this class. 53148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickunsigned CodeGenSchedModels::addSchedClass(const IdxVec &OperWrites, 53248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const IdxVec &OperReads, 53348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick const IdxVec &ProcIndices) 53448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick{ 53548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(!ProcIndices.empty() && "expect at least one ProcIdx"); 53648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 53748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned Idx = findSchedClassIdx(OperWrites, OperReads); 53848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (Idx) { 53948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick IdxVec PI; 54048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::set_union(SchedClasses[Idx].ProcIndices.begin(), 54148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses[Idx].ProcIndices.end(), 54248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcIndices.begin(), ProcIndices.end(), 54348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::back_inserter(PI)); 54448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses[Idx].ProcIndices.swap(PI); 54548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return Idx; 54648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 54748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Idx = SchedClasses.size(); 54848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses.resize(Idx+1); 54948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick CodeGenSchedClass &SC = SchedClasses.back(); 55048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.Name = createSchedClassName(OperWrites, OperReads); 55148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.Writes = OperWrites; 55248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.Reads = OperReads; 55348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.ProcIndices = ProcIndices; 5542661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 55548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick return Idx; 55648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 55748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 55848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Create classes for each set of opcodes that are in the same InstReadWrite 55948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// definition across all processors. 56048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::createInstRWClass(Record *InstRWDef) { 56148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // ClassInstrs will hold an entry for each subset of Instrs in InstRWDef that 56248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // intersects with an existing class via a previous InstRWDef. Instrs that do 56348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // not intersect with an existing class refer back to their former class as 56448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // determined from ItinDef or SchedRW. 56548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SmallVector<std::pair<unsigned, SmallVector<Record *, 8> >, 4> ClassInstrs; 56648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Sort Instrs into sets. 56748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec InstDefs = InstRWDef->getValueAsListOfDefs("Instrs"); 56848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::sort(InstDefs.begin(), InstDefs.end(), LessRecord()); 56948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter I = InstDefs.begin(), E = InstDefs.end(); I != E; ++I) { 57048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned SCIdx = 0; 57148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick InstClassMapTy::const_iterator Pos = InstrClassMap.find(*I); 57248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (Pos != InstrClassMap.end()) 57348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SCIdx = Pos->second; 57448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick else { 57548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // This instruction has not been mapped yet. Get the original class. All 57648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // instructions in the same InstrRW class must be from the same original 57748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // class because that is the fall-back class for other processors. 57848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ItinDef = (*I)->getValueAsDef("Itinerary"); 57948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SCIdx = SchedClassIdxMap.lookup(ItinDef->getName()); 58048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!SCIdx && (*I)->isSubClassOf("Sched")) 58148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SCIdx = getSchedClassIdx((*I)->getValueAsListOfDefs("SchedRW")); 58248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 58348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned CIdx = 0, CEnd = ClassInstrs.size(); 58448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (; CIdx != CEnd; ++CIdx) { 58548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (ClassInstrs[CIdx].first == SCIdx) 58648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick break; 58748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 58848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (CIdx == CEnd) { 58948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ClassInstrs.resize(CEnd + 1); 59048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ClassInstrs[CIdx].first = SCIdx; 59148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 59248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ClassInstrs[CIdx].second.push_back(*I); 59348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 59448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // For each set of Instrs, create a new class if necessary, and map or remap 59548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // the Instrs to it. 59648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned CIdx = 0, CEnd = ClassInstrs.size(); 59748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (; CIdx != CEnd; ++CIdx) { 59848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned OldSCIdx = ClassInstrs[CIdx].first; 59948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ArrayRef<Record*> InstDefs = ClassInstrs[CIdx].second; 60048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // If the all instrs in the current class are accounted for, then leave 60148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // them mapped to their old class. 60248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (SchedClasses[OldSCIdx].InstRWs.size() == InstDefs.size()) { 60348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(SchedClasses[OldSCIdx].ProcIndices[0] == 0 && 60448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick "expected a generic SchedClass"); 60548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 60648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 60748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned SCIdx = SchedClasses.size(); 60848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses.resize(SCIdx+1); 60948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick CodeGenSchedClass &SC = SchedClasses.back(); 61048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.Name = createSchedClassName(InstDefs); 61148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Preserve ItinDef and Writes/Reads for processors without an InstRW entry. 61248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.ItinClassDef = SchedClasses[OldSCIdx].ItinClassDef; 61348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.Writes = SchedClasses[OldSCIdx].Writes; 61448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.Reads = SchedClasses[OldSCIdx].Reads; 61548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.ProcIndices.push_back(0); 61648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Map each Instr to this new class. 61748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Note that InstDefs may be a smaller list than InstRWDef's "Instrs". 61848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (ArrayRef<Record*>::const_iterator 61948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick II = InstDefs.begin(), IE = InstDefs.end(); II != IE; ++II) { 62048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned OldSCIdx = InstrClassMap[*II]; 62148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (OldSCIdx) { 62248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.InstRWs.insert(SC.InstRWs.end(), 62348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses[OldSCIdx].InstRWs.begin(), 62448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedClasses[OldSCIdx].InstRWs.end()); 62548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 62648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick InstrClassMap[*II] = SCIdx; 62748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 62848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SC.InstRWs.push_back(InstRWDef); 62948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 6302661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick} 6312661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 6322661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick// Gather the processor itineraries. 63348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::collectProcItins() { 63448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (std::vector<CodeGenProcModel>::iterator PI = ProcModels.begin(), 63548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick PE = ProcModels.end(); PI != PE; ++PI) { 63648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick CodeGenProcModel &ProcModel = *PI; 63748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec ItinRecords = ProcModel.ItinsDef->getValueAsListOfDefs("IID"); 63848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Skip empty itinerary. 63948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (ItinRecords.empty()) 64048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 6412661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 64248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModel.ItinDefList.resize(NumItineraryClasses+1); 6432661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 64448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Insert each itinerary data record in the correct position within 64548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // the processor model's ItinDefList. 64648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned i = 0, N = ItinRecords.size(); i < N; i++) { 64748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ItinData = ItinRecords[i]; 64848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ItinDef = ItinData->getValueAsDef("TheClass"); 64948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!SchedClassIdxMap.count(ItinDef->getName())) { 65048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick DEBUG(dbgs() << ProcModel.ItinsDef->getName() 65148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick << " has unused itinerary class " << ItinDef->getName() << '\n'); 65248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick continue; 65348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 65448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass"); 65548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName()); 65648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(Idx <= NumItineraryClasses && "bad ItinClass index"); 65748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModel.ItinDefList[Idx] = ItinData; 65848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 65948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick // Check for missing itinerary entries. 66048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick assert(!ProcModel.ItinDefList[0] && "NoItinerary class can't have rec"); 66148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick DEBUG( 66248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned i = 1, N = ProcModel.ItinDefList.size(); i < N; ++i) { 66348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!ProcModel.ItinDefList[i]) 66448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << ProcModel.ItinsDef->getName() 66548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick << " missing itinerary for class " 66648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick << SchedClasses[i].Name << '\n'; 66748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick }); 66848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 66948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 6702661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 67148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick// Gather the read/write types for each itinerary class. 67248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedModels::collectProcItinRW() { 67348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick RecVec ItinRWDefs = Records.getAllDerivedDefinitions("ItinRW"); 67448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick std::sort(ItinRWDefs.begin(), ItinRWDefs.end(), LessRecord()); 67548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (RecIter II = ItinRWDefs.begin(), IE = ItinRWDefs.end(); II != IE; ++II) { 67648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (!(*II)->getValueInit("SchedModel")->isComplete()) 67748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick throw TGError((*II)->getLoc(), "SchedModel is undefined"); 67848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick Record *ModelDef = (*II)->getValueAsDef("SchedModel"); 67948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef); 68048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (I == ProcModelMap.end()) { 68148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick throw TGError((*II)->getLoc(), "Undefined SchedMachineModel " 68248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick + ModelDef->getName()); 6832661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 68448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick ProcModels[I->second].ItinRWDefs.push_back(*II); 6852661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 68648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 68748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 6885e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// Infer new classes from existing classes. In the process, this may create new 6895e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// SchedWrites from sequences of existing SchedWrites. 6905e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid CodeGenSchedModels::inferSchedClasses() { 6915e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Visit all existing classes and newly created classes. 6925e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (unsigned Idx = 0; Idx != SchedClasses.size(); ++Idx) { 6935e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (SchedClasses[Idx].ItinClassDef) 6945e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferFromItinClass(SchedClasses[Idx].ItinClassDef, Idx); 6955e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else if (!SchedClasses[Idx].InstRWs.empty()) 6965e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferFromInstRWs(Idx); 6975e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else { 6985e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferFromRW(SchedClasses[Idx].Writes, SchedClasses[Idx].Reads, 6995e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Idx, SchedClasses[Idx].ProcIndices); 7005e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 7015e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick assert(SchedClasses.size() < (NumInstrSchedClasses*6) && 7025e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick "too many SchedVariants"); 7035e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 7045e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 7055e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7065e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// Infer classes from per-processor itinerary resources. 7075e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef, 7085e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned FromClassIdx) { 7095e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) { 7105e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const CodeGenProcModel &PM = ProcModels[PIdx]; 7115e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // For all ItinRW entries. 7125e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool HasMatch = false; 7135e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end(); 7145e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick II != IE; ++II) { 7155e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses"); 7165e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (!std::count(Matched.begin(), Matched.end(), ItinClassDef)) 7175e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick continue; 7185e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (HasMatch) 7195e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick throw TGError((*II)->getLoc(), "Duplicate itinerary class " 7205e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick + ItinClassDef->getName() 7215e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick + " in ItinResources for " + PM.ModelName); 7225e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick HasMatch = true; 7235e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec Writes, Reads; 7245e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads); 7255e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec ProcIndices(1, PIdx); 7265e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferFromRW(Writes, Reads, FromClassIdx, ProcIndices); 7275e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 7285e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 7295e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 7305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// Infer classes from per-processor InstReadWrite definitions. 7325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) { 7335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs; 7345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); RWI != RWE; ++RWI) { 7355e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecVec Instrs = (*RWI)->getValueAsListOfDefs("Instrs"); 7365e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecIter II = Instrs.begin(), IE = Instrs.end(); 7375e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (; II != IE; ++II) { 7385e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (InstrClassMap[*II] == SCIdx) 7395e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick break; 7405e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 7415e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // If this class no longer has any instructions mapped to it, it has become 7425e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // irrelevant. 7435e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (II == IE) 7445e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick continue; 7455e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec Writes, Reads; 7465e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads); 7475e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned PIdx = getProcModel((*RWI)->getValueAsDef("SchedModel")).Index; 7485e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec ProcIndices(1, PIdx); 7495e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferFromRW(Writes, Reads, SCIdx, ProcIndices); 7505e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 7515e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 7525e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7535e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Tricknamespace { 7545e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Associate a predicate with the SchedReadWrite that it guards. 7555e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// RWIdx is the index of the read/write variant. 7565e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickstruct PredCheck { 7575e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool IsRead; 7585e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned RWIdx; 7595e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Record *Predicate; 7605e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7615e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PredCheck(bool r, unsigned w, Record *p): IsRead(r), RWIdx(w), Predicate(p) {} 7625e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick}; 7635e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7645e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// A Predicate transition is a list of RW sequences guarded by a PredTerm. 7655e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickstruct PredTransition { 7665e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // A predicate term is a conjunction of PredChecks. 7675e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVector<PredCheck, 4> PredTerm; 7685e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVector<SmallVector<unsigned,4>, 16> WriteSequences; 7695e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVector<SmallVector<unsigned,4>, 16> ReadSequences; 7705e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick}; 7715e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7725e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Encapsulate a set of partially constructed transitions. 7735e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// The results are built by repeated calls to substituteVariants. 7745e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickclass PredTransitions { 7755e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick CodeGenSchedModels &SchedModels; 7765e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7775e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickpublic: 7785e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick std::vector<PredTransition> TransVec; 7795e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7805e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PredTransitions(CodeGenSchedModels &sm): SchedModels(sm) {} 7815e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7825e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick void substituteVariantOperand(const SmallVectorImpl<unsigned> &RWSeq, 7835e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool IsRead, unsigned StartIdx); 7845e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7855e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick void substituteVariants(const PredTransition &Trans); 7865e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7875e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick#ifndef NDEBUG 7885e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick void dump() const; 7895e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick#endif 7905e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7915e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickprivate: 7925e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool mutuallyExclusive(Record *PredDef, ArrayRef<PredCheck> Term); 7935e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick void pushVariant(unsigned SchedRW, Record *Variant, PredTransition &Trans, 7945e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick bool IsRead); 7955e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick}; 7965e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} // anonymous 7975e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 7985e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Return true if this predicate is mutually exclusive with a PredTerm. This 7995e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// degenerates into checking if the predicate is mutually exclusive with any 8005e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// predicate in the Term's conjunction. 8015e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// 8025e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// All predicates associated with a given SchedRW are considered mutually 8035e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// exclusive. This should work even if the conditions expressed by the 8045e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// predicates are not exclusive because the predicates for a given SchedWrite 8055e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// are always checked in the order they are defined in the .td file. Later 8065e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// conditions implicitly negate any prior condition. 8075e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickbool PredTransitions::mutuallyExclusive(Record *PredDef, 8085e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick ArrayRef<PredCheck> Term) { 8095e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8105e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (ArrayRef<PredCheck>::iterator I = Term.begin(), E = Term.end(); 8115e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I != E; ++I) { 8125e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (I->Predicate == PredDef) 8135e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return false; 8145e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8155e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(I->RWIdx, I->IsRead); 8165e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick assert(SchedRW.HasVariants && "PredCheck must refer to a SchedVariant"); 8175e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants"); 8185e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (RecIter VI = Variants.begin(), VE = Variants.end(); VI != VE; ++VI) { 8195e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if ((*VI)->getValueAsDef("Predicate") == PredDef) 8205e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return true; 8215e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8225e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8235e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return false; 8245e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 8255e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8265e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Push the Reads/Writes selected by this variant onto the given PredTransition. 8275e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid PredTransitions::pushVariant(unsigned RWIdx, Record *Variant, 8285e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PredTransition &Trans, bool IsRead) { 8295e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Trans.PredTerm.push_back( 8305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PredCheck(IsRead, RWIdx, Variant->getValueAsDef("Predicate"))); 8315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecVec SelectedDefs = Variant->getValueAsListOfDefs("Selected"); 8325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec SelectedRWs; 8335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead); 8345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8355e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(RWIdx, IsRead); 8365e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8375e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVectorImpl<SmallVector<unsigned,4> > &RWSequences = IsRead 8385e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick ? Trans.ReadSequences : Trans.WriteSequences; 8395e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (SchedRW.IsVariadic) { 8405e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned OperIdx = RWSequences.size()-1; 8415e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Make N-1 copies of this transition's last sequence. 8425e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (unsigned i = 1, e = SelectedRWs.size(); i != e; ++i) { 8435e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RWSequences.push_back(RWSequences[OperIdx]); 8445e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8455e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Push each of the N elements of the SelectedRWs onto a copy of the last 8465e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // sequence (split the current operand into N operands). 8475e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Note that write sequences should be expanded within this loop--the entire 8485e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // sequence belongs to a single operand. 8495e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end(); 8505e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RWI != RWE; ++RWI, ++OperIdx) { 8515e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec ExpandedRWs; 8525e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (IsRead) 8535e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick ExpandedRWs.push_back(*RWI); 8545e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else 8555e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead); 8565e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RWSequences[OperIdx].insert(RWSequences[OperIdx].end(), 8575e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick ExpandedRWs.begin(), ExpandedRWs.end()); 8585e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8595e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick assert(OperIdx == RWSequences.size() && "missed a sequence"); 8605e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8615e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else { 8625e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Push this transition's expanded sequence onto this transition's last 8635e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // sequence (add to the current operand's sequence). 8645e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVectorImpl<unsigned> &Seq = RWSequences.back(); 8655e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec ExpandedRWs; 8665e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end(); 8675e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RWI != RWE; ++RWI) { 8685e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (IsRead) 8695e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick ExpandedRWs.push_back(*RWI); 8705e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else 8715e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead); 8725e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8735e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Seq.insert(Seq.end(), ExpandedRWs.begin(), ExpandedRWs.end()); 8745e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 8755e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 8765e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8775e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// RWSeq is a sequence of all Reads or all Writes for the next read or write 8785e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// operand. StartIdx is an index into TransVec where partial results 8795e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// starts. RWSeq must be applied to all tranistions between StartIdx and the end 8805e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// of TransVec. 8815e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid PredTransitions::substituteVariantOperand( 8825e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) { 8835e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 8845e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Visit each original RW within the current sequence. 8855e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<unsigned>::const_iterator 8865e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RWI = RWSeq.begin(), RWE = RWSeq.end(); RWI != RWE; ++RWI) { 8875e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(*RWI, IsRead); 8885e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Push this RW on all partial PredTransitions or distribute variants. 8895e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // New PredTransitions may be pushed within this loop which should not be 8905e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // revisited (TransEnd must be loop invariant). 8915e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (unsigned TransIdx = StartIdx, TransEnd = TransVec.size(); 8925e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransIdx != TransEnd; ++TransIdx) { 8935e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // In the common case, push RW onto the current operand's sequence. 8945e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (!SchedRW.HasVariants) { 8955e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (IsRead) 8965e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec[TransIdx].ReadSequences.back().push_back(*RWI); 8975e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else 8985e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec[TransIdx].WriteSequences.back().push_back(*RWI); 8995e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick continue; 9005e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9015e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Distribute this partial PredTransition across intersecting variants. 9025e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecVec Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants"); 9035e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick std::vector<std::pair<Record*,unsigned> > IntersectingVariants; 9045e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (RecIter VI = Variants.begin(), VE = Variants.end(); VI != VE; ++VI) { 9055e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Record *PredDef = (*VI)->getValueAsDef("Predicate"); 9065e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm)) 9075e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick continue; 9085e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (IntersectingVariants.empty()) 9095e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // The first variant builds on the existing transition. 9105e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IntersectingVariants.push_back(std::make_pair(*VI, TransIdx)); 9115e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick else { 9125e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Push another copy of the current transition for more variants. 9135e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IntersectingVariants.push_back( 9145e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick std::make_pair(*VI, TransVec.size())); 9155e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec.push_back(TransVec[TransIdx]); 9165e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9175e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9185e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Now expand each variant on top of its copy of the transition. 9195e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (std::vector<std::pair<Record*, unsigned> >::const_iterator 9205e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IVI = IntersectingVariants.begin(), 9215e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IVE = IntersectingVariants.end(); 9225e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IVI != IVE; ++IVI) 9235e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick pushVariant(*RWI, IVI->first, TransVec[IVI->second], IsRead); 9245e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9255e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9265e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 9275e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 9285e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// For each variant of a Read/Write in Trans, substitute the sequence of 9295e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Read/Writes guarded by the variant. This is exponential in the number of 9305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// variant Read/Writes, but in practice detection of mutually exclusive 9315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// predicates should result in linear growth in the total number variants. 9325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// 9335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// This is one step in a breadth-first search of nested variants. 9345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid PredTransitions::substituteVariants(const PredTransition &Trans) { 9355e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Build up a set of partial results starting at the back of 9365e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // PredTransitions. Remember the first new transition. 9375e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned StartIdx = TransVec.size(); 9385e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec.resize(TransVec.size() + 1); 9395e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec.back().PredTerm = Trans.PredTerm; 9405e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 9415e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Visit each original write sequence. 9425e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 9435e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI = Trans.WriteSequences.begin(), WSE = Trans.WriteSequences.end(); 9445e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI != WSE; ++WSI) { 9455e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Push a new (empty) write sequence onto all partial Transitions. 9465e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (std::vector<PredTransition>::iterator I = 9475e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) { 9485e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I->WriteSequences.resize(I->WriteSequences.size() + 1); 9495e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9505e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx); 9515e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9525e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Visit each original read sequence. 9535e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 9545e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RSI = Trans.ReadSequences.begin(), RSE = Trans.ReadSequences.end(); 9555e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RSI != RSE; ++RSI) { 9565e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Push a new (empty) read sequence onto all partial Transitions. 9575e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (std::vector<PredTransition>::iterator I = 9585e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) { 9595e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I->ReadSequences.resize(I->ReadSequences.size() + 1); 9605e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9615e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx); 9625e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9635e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 9645e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 9655e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickstatic bool hasVariant(ArrayRef<PredTransition> Transitions, 9665e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick CodeGenSchedModels &SchedModels) { 9675e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (ArrayRef<PredTransition>::iterator 9685e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PTI = Transitions.begin(), PTE = Transitions.end(); 9695e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PTI != PTE; ++PTI) { 9705e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 9715e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end(); 9725e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI != WSE; ++WSI) { 9735e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<unsigned>::const_iterator 9745e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) { 9755e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (SchedModels.getSchedWrite(*WI).HasVariants) 9765e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return true; 9775e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9785e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9795e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 9805e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end(); 9815e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RSI != RSE; ++RSI) { 9825e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<unsigned>::const_iterator 9835e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RI = RSI->begin(), RE = RSI->end(); RI != RE; ++RI) { 9845e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (SchedModels.getSchedRead(*RI).HasVariants) 9855e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return true; 9865e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9875e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9885e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 9895e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return false; 9905e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 9915e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 9925e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// Create a new SchedClass for each variant found by inferFromRW. Pass 9935e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick// ProcIndices by copy to avoid referencing anything from SchedClasses. 9945e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickstatic void inferFromTransitions(ArrayRef<PredTransition> LastTransitions, 9955e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned FromClassIdx, IdxVec ProcIndices, 9965e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick CodeGenSchedModels &SchedModels) { 9975e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // For each PredTransition, create a new CodeGenSchedTransition, which usually 9985e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // requires creating a new SchedClass. 9995e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (ArrayRef<PredTransition>::iterator 10005e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I = LastTransitions.begin(), E = LastTransitions.end(); I != E; ++I) { 10015e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec OperWritesVariant; 10025e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 10035e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI = I->WriteSequences.begin(), WSE = I->WriteSequences.end(); 10045e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI != WSE; ++WSI) { 10055e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Create a new write representing the expanded sequence. 10065e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick OperWritesVariant.push_back( 10075e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.findOrInsertRW(*WSI, /*IsRead=*/false)); 10085e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10095e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec OperReadsVariant; 10105e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 10115e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RSI = I->ReadSequences.begin(), RSE = I->ReadSequences.end(); 10125e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RSI != RSE; ++RSI) { 10135e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Create a new write representing the expanded sequence. 10145e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick OperReadsVariant.push_back( 10155e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.findOrInsertRW(*RSI, /*IsRead=*/true)); 10165e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10175e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick CodeGenSchedTransition SCTrans; 10185e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SCTrans.ToClassIdx = 10195e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.addSchedClass(OperWritesVariant, OperReadsVariant, 10205e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick ProcIndices); 10215e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SCTrans.ProcIndices = ProcIndices; 10225e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // The final PredTerm is unique set of predicates guarding the transition. 10235e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecVec Preds; 10245e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<PredCheck>::const_iterator 10255e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PI = I->PredTerm.begin(), PE = I->PredTerm.end(); PI != PE; ++PI) { 10265e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Preds.push_back(PI->Predicate); 10275e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10285e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick RecIter PredsEnd = std::unique(Preds.begin(), Preds.end()); 10295e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Preds.resize(PredsEnd - Preds.begin()); 10305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SCTrans.PredTerm = Preds; 10315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SchedModels.getSchedClass(FromClassIdx).Transitions.push_back(SCTrans); 10325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 10345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 10355e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// Find each variant write that OperWrites or OperaReads refers to and create a 10365e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick/// new SchedClass for each variant. 10375e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites, 10385e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const IdxVec &OperReads, 10395e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned FromClassIdx, 10405e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick const IdxVec &ProcIndices) { 10415e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(dbgs() << "INFERRW Writes: "); 10425e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 10435e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Create a seed transition with an empty PredTerm and the expanded sequences 10445e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // of SchedWrites for the current SchedClass. 10455e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick std::vector<PredTransition> LastTransitions; 10465e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick LastTransitions.resize(1); 10475e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter I = OperWrites.begin(), E = OperWrites.end(); I != E; ++I) { 10485e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec WriteSeq; 10495e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick expandRWSequence(*I, WriteSeq, /*IsRead=*/false); 10505e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned Idx = LastTransitions[0].WriteSequences.size(); 10515e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick LastTransitions[0].WriteSequences.resize(Idx + 1); 10525e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVectorImpl<unsigned> &Seq = LastTransitions[0].WriteSequences[Idx]; 10535e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter WI = WriteSeq.begin(), WE = WriteSeq.end(); WI != WE; ++WI) 10545e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Seq.push_back(*WI); 10555e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") "); 10565e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10575e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(dbgs() << " Reads: "); 10585e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter I = OperReads.begin(), E = OperReads.end(); I != E; ++I) { 10595e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick IdxVec ReadSeq; 10605e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick expandRWSequence(*I, ReadSeq, /*IsRead=*/true); 10615e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick unsigned Idx = LastTransitions[0].ReadSequences.size(); 10625e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick LastTransitions[0].ReadSequences.resize(Idx + 1); 10635e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick SmallVectorImpl<unsigned> &Seq = LastTransitions[0].ReadSequences[Idx]; 10645e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (IdxIter RI = ReadSeq.begin(), RE = ReadSeq.end(); RI != RE; ++RI) 10655e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Seq.push_back(*RI); 10665e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(dbgs() << "("; dumpIdxVec(Seq); dbgs() << ") "); 10675e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10685e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(dbgs() << '\n'); 10695e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 10705e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Collect all PredTransitions for individual operands. 10715e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // Iterate until no variant writes remain. 10725e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick while (hasVariant(LastTransitions, *this)) { 10735e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PredTransitions Transitions(*this); 10745e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (std::vector<PredTransition>::const_iterator 10755e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I = LastTransitions.begin(), E = LastTransitions.end(); 10765e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick I != E; ++I) { 10775e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick Transitions.substituteVariants(*I); 10785e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10795e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick DEBUG(Transitions.dump()); 10805e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick LastTransitions.swap(Transitions.TransVec); 10815e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 10825e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // If the first transition has no variants, nothing to do. 10835e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (LastTransitions[0].PredTerm.empty()) 10845e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick return; 10855e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 10865e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // WARNING: We are about to mutate the SchedClasses vector. Do not refer to 10875e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick // OperWrites, OperReads, or ProcIndices after calling inferFromTransitions. 10885e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick inferFromTransitions(LastTransitions, FromClassIdx, ProcIndices, *this); 10895e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 10905e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 10913cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Collect and sort WriteRes, ReadAdvance, and ProcResources. 10923cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trickvoid CodeGenSchedModels::collectProcResources() { 10933cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // Add any subtarget-specific SchedReadWrites that are directly associated 10943cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // with processor resources. Refer to the parent SchedClass's ProcIndices to 10953cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // determine which processors they apply to. 10963cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (SchedClassIter SCI = schedClassBegin(), SCE = schedClassEnd(); 10973cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick SCI != SCE; ++SCI) { 10983cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (SCI->ItinClassDef) 10993cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick collectItinProcResources(SCI->ItinClassDef); 11003cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick else 11013cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick collectRWResources(SCI->Writes, SCI->Reads, SCI->ProcIndices); 11023cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11033cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // Add resources separately defined by each subtarget. 11043cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec WRDefs = Records.getAllDerivedDefinitions("WriteRes"); 11053cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter WRI = WRDefs.begin(), WRE = WRDefs.end(); WRI != WRE; ++WRI) { 11063cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick Record *ModelDef = (*WRI)->getValueAsDef("SchedModel"); 11073cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick addWriteRes(*WRI, getProcModel(ModelDef).Index); 11083cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11093cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec RADefs = Records.getAllDerivedDefinitions("ReadAdvance"); 11103cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter RAI = RADefs.begin(), RAE = RADefs.end(); RAI != RAE; ++RAI) { 11113cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick Record *ModelDef = (*RAI)->getValueAsDef("SchedModel"); 11123cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick addReadAdvance(*RAI, getProcModel(ModelDef).Index); 11133cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11143cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // Finalize each ProcModel by sorting the record arrays. 11153cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) { 11163cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick CodeGenProcModel &PM = ProcModels[PIdx]; 11173cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick std::sort(PM.WriteResDefs.begin(), PM.WriteResDefs.end(), 11183cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick LessRecord()); 11193cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick std::sort(PM.ReadAdvanceDefs.begin(), PM.ReadAdvanceDefs.end(), 11203cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick LessRecord()); 11213cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick std::sort(PM.ProcResourceDefs.begin(), PM.ProcResourceDefs.end(), 11223cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick LessRecord()); 11233cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick DEBUG( 11243cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick PM.dump(); 11253cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << "WriteResDefs: "; 11263cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter RI = PM.WriteResDefs.begin(), 11273cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RE = PM.WriteResDefs.end(); RI != RE; ++RI) { 11283cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if ((*RI)->isSubClassOf("WriteRes")) 11293cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << (*RI)->getValueAsDef("WriteType")->getName() << " "; 11303cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick else 11313cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << (*RI)->getName() << " "; 11323cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11333cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << "\nReadAdvanceDefs: "; 11343cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter RI = PM.ReadAdvanceDefs.begin(), 11353cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RE = PM.ReadAdvanceDefs.end(); RI != RE; ++RI) { 11363cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if ((*RI)->isSubClassOf("ReadAdvance")) 11373cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << (*RI)->getValueAsDef("ReadType")->getName() << " "; 11383cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick else 11393cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << (*RI)->getName() << " "; 11403cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11413cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << "\nProcResourceDefs: "; 11423cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter RI = PM.ProcResourceDefs.begin(), 11433cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RE = PM.ProcResourceDefs.end(); RI != RE; ++RI) { 11443cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << (*RI)->getName() << " "; 11453cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11463cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick dbgs() << '\n'); 11473cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11483cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 11493cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 11503cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Collect itinerary class resources for each processor. 11513cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trickvoid CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) { 11523cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) { 11533cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick const CodeGenProcModel &PM = ProcModels[PIdx]; 11543cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // For all ItinRW entries. 11553cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick bool HasMatch = false; 11563cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter II = PM.ItinRWDefs.begin(), IE = PM.ItinRWDefs.end(); 11573cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick II != IE; ++II) { 11583cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses"); 11593cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (!std::count(Matched.begin(), Matched.end(), ItinClassDef)) 11603cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick continue; 11613cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (HasMatch) 11623cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick throw TGError((*II)->getLoc(), "Duplicate itinerary class " 11633cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick + ItinClassDef->getName() 11643cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick + " in ItinResources for " + PM.ModelName); 11653cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick HasMatch = true; 11663cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick IdxVec Writes, Reads; 11673cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), Writes, Reads); 11683cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick IdxVec ProcIndices(1, PIdx); 11693cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick collectRWResources(Writes, Reads, ProcIndices); 11703cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11713cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11723cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 11733cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 11743cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 11753cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Collect resources for a set of read/write types and processor indices. 11763cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trickvoid CodeGenSchedModels::collectRWResources(const IdxVec &Writes, 11773cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick const IdxVec &Reads, 11783cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick const IdxVec &ProcIndices) { 11793cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 11803cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) { 11813cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick const CodeGenSchedRW &SchedRW = getSchedRW(*WI, /*IsRead=*/false); 11823cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (SchedRW.TheDef && SchedRW.TheDef->isSubClassOf("SchedWriteRes")) { 11833cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end(); 11843cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick PI != PE; ++PI) { 11853cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick addWriteRes(SchedRW.TheDef, *PI); 11863cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11873cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11883cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11893cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI) { 11903cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick const CodeGenSchedRW &SchedRW = getSchedRW(*RI, /*IsRead=*/true); 11913cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (SchedRW.TheDef && SchedRW.TheDef->isSubClassOf("SchedReadAdvance")) { 11923cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end(); 11933cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick PI != PE; ++PI) { 11943cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick addReadAdvance(SchedRW.TheDef, *PI); 11953cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11963cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11973cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 11983cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 11993cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12003cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Find the processor's resource units for this kind of resource. 12013cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew TrickRecord *CodeGenSchedModels::findProcResUnits(Record *ProcResKind, 12023cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick const CodeGenProcModel &PM) const { 12033cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (ProcResKind->isSubClassOf("ProcResourceUnits")) 12043cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick return ProcResKind; 12053cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12063cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick Record *ProcUnitDef = 0; 12073cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec ProcResourceDefs = 12083cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick Records.getAllDerivedDefinitions("ProcResourceUnits"); 12093cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12103cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter RI = ProcResourceDefs.begin(), RE = ProcResourceDefs.end(); 12113cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RI != RE; ++RI) { 12123cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12133cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if ((*RI)->getValueAsDef("Kind") == ProcResKind 12143cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick && (*RI)->getValueAsDef("SchedModel") == PM.ModelDef) { 12153cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (ProcUnitDef) { 12163cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick throw TGError((*RI)->getLoc(), 12173cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick "Multiple ProcessorResourceUnits associated with " 12183cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick + ProcResKind->getName()); 12193cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 12203cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick ProcUnitDef = *RI; 12213cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 12223cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 12233cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (!ProcUnitDef) { 12243cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick throw TGError(ProcResKind->getLoc(), 12253cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick "No ProcessorResources associated with " 12263cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick + ProcResKind->getName()); 12273cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 12283cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick return ProcUnitDef; 12293cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 12303cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12313cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Iteratively add a resource and its super resources. 12323cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trickvoid CodeGenSchedModels::addProcResource(Record *ProcResKind, 12333cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick CodeGenProcModel &PM) { 12343cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (;;) { 12353cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick Record *ProcResUnits = findProcResUnits(ProcResKind, PM); 12363cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12373cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // See if this ProcResource is already associated with this processor. 12383cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecIter I = std::find(PM.ProcResourceDefs.begin(), 12393cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick PM.ProcResourceDefs.end(), ProcResUnits); 12403cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (I != PM.ProcResourceDefs.end()) 12413cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick return; 12423cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12433cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick PM.ProcResourceDefs.push_back(ProcResUnits); 12443cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (!ProcResUnits->getValueInit("Super")->isComplete()) 12453cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick return; 12463cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12473cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick ProcResKind = ProcResUnits->getValueAsDef("Super"); 12483cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 12493cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 12503cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12513cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Add resources for a SchedWrite to this processor if they don't exist. 12523cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trickvoid CodeGenSchedModels::addWriteRes(Record *ProcWriteResDef, unsigned PIdx) { 12533cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec &WRDefs = ProcModels[PIdx].WriteResDefs; 12543cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecIter WRI = std::find(WRDefs.begin(), WRDefs.end(), ProcWriteResDef); 12553cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (WRI != WRDefs.end()) 12563cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick return; 12573cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick WRDefs.push_back(ProcWriteResDef); 12583cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12593cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick // Visit ProcResourceKinds referenced by the newly discovered WriteRes. 12603cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec ProcResDefs = ProcWriteResDef->getValueAsListOfDefs("ProcResources"); 12613cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick for (RecIter WritePRI = ProcResDefs.begin(), WritePRE = ProcResDefs.end(); 12623cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick WritePRI != WritePRE; ++WritePRI) { 12633cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick addProcResource(*WritePRI, ProcModels[PIdx]); 12643cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick } 12653cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 12663cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12673cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick// Add resources for a ReadAdvance to this processor if they don't exist. 12683cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trickvoid CodeGenSchedModels::addReadAdvance(Record *ProcReadAdvanceDef, 12693cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick unsigned PIdx) { 12703cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecVec &RADefs = ProcModels[PIdx].ReadAdvanceDefs; 12713cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RecIter I = std::find(RADefs.begin(), RADefs.end(), ProcReadAdvanceDef); 12723cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick if (I != RADefs.end()) 12733cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick return; 12743cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick RADefs.push_back(ProcReadAdvanceDef); 12753cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick} 12763cbd1786ac06fe751dc4b5ad55e75115cb1d51ceAndrew Trick 12772661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick#ifndef NDEBUG 127848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenProcModel::dump() const { 127948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << Index << ": " << ModelName << " " 128048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick << (ModelDef ? ModelDef->getName() : "inferred") << " " 128148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick << (ItinsDef ? ItinsDef->getName() : "no itinerary") << '\n'; 128248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 128348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 128448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedRW::dump() const { 128548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << Name << (IsVariadic ? " (V) " : " "); 128648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (IsSequence) { 128748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "("; 128848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dumpIdxVec(Sequence); 128948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << ")"; 12902661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick } 12912661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick} 129248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick 129348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trickvoid CodeGenSchedClass::dump(const CodeGenSchedModels* SchedModels) const { 129448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "SCHEDCLASS " << Name << '\n' 129548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick << " Writes: "; 129648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned i = 0, N = Writes.size(); i < N; ++i) { 129748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedModels->getSchedWrite(Writes[i]).dump(); 129848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (i < N-1) { 129948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << '\n'; 130048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs().indent(10); 130148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 130248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 130348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "\n Reads: "; 130448605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick for (unsigned i = 0, N = Reads.size(); i < N; ++i) { 130548605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick SchedModels->getSchedRead(Reads[i]).dump(); 130648605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick if (i < N-1) { 130748605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << '\n'; 130848605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs().indent(10); 130948605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 131048605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick } 131148605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick dbgs() << "\n ProcIdx: "; dumpIdxVec(ProcIndices); dbgs() << '\n'; 131248605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick} 13135e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick 13145e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trickvoid PredTransitions::dump() const { 13155e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << "Expanded Variants:\n"; 13165e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (std::vector<PredTransition>::const_iterator 13175e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick TI = TransVec.begin(), TE = TransVec.end(); TI != TE; ++TI) { 13185e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << "{"; 13195e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<PredCheck>::const_iterator 13205e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PCI = TI->PredTerm.begin(), PCE = TI->PredTerm.end(); 13215e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick PCI != PCE; ++PCI) { 13225e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (PCI != TI->PredTerm.begin()) 13235e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << ", "; 13245e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << SchedModels.getSchedRW(PCI->RWIdx, PCI->IsRead).Name 13255e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick << ":" << PCI->Predicate->getName(); 13265e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 13275e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << "},\n => {"; 13285e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator 13295e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI = TI->WriteSequences.begin(), WSE = TI->WriteSequences.end(); 13305e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WSI != WSE; ++WSI) { 13315e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << "("; 13325e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick for (SmallVectorImpl<unsigned>::const_iterator 13335e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) { 13345e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick if (WI != WSI->begin()) 13355e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << ", "; 13365e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << SchedModels.getSchedWrite(*WI).Name; 13375e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 13385e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << "),"; 13395e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 13405e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick dbgs() << "}\n"; 13415e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick } 13425e613c260bb3044eb059dea74cd6bccfa9b85bddAndrew Trick} 134348605c340614fc1fb2ae1d975fc565a4188182e0Andrew Trick#endif // NDEBUG 1344