16ac3f739SEugene Zelenko //===- DFAPacketizerEmitter.cpp - Packetization DFA for a VLIW machine ----===// 208ebdc1eSAnshuman Dasgupta // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 608ebdc1eSAnshuman Dasgupta // 708ebdc1eSAnshuman Dasgupta //===----------------------------------------------------------------------===// 808ebdc1eSAnshuman Dasgupta // 908ebdc1eSAnshuman Dasgupta // This class parses the Schedule.td file and produces an API that can be used 1008ebdc1eSAnshuman Dasgupta // to reason about whether an instruction can be added to a packet on a VLIW 1108ebdc1eSAnshuman Dasgupta // architecture. The class internally generates a deterministic finite 1208ebdc1eSAnshuman Dasgupta // automaton (DFA) that models all possible mappings of machine instructions 1308ebdc1eSAnshuman Dasgupta // to functional units as instructions are added to a packet. 1408ebdc1eSAnshuman Dasgupta // 1508ebdc1eSAnshuman Dasgupta //===----------------------------------------------------------------------===// 1608ebdc1eSAnshuman Dasgupta 17b4655729SKrzysztof Parzyszek #define DEBUG_TYPE "dfa-emitter" 18b4655729SKrzysztof Parzyszek 1939525a67Sjmolloy #include "CodeGenSchedule.h" 2008ebdc1eSAnshuman Dasgupta #include "CodeGenTarget.h" 2112092a96SJames Molloy #include "DFAEmitter.h" 22e6aed139SJakob Stoklund Olesen #include "llvm/ADT/DenseSet.h" 23a3fe70d2SEugene Zelenko #include "llvm/ADT/SmallVector.h" 24b4655729SKrzysztof Parzyszek #include "llvm/ADT/StringExtras.h" 25b4655729SKrzysztof Parzyszek #include "llvm/Support/Debug.h" 26a3fe70d2SEugene Zelenko #include "llvm/Support/raw_ostream.h" 2739525a67Sjmolloy #include "llvm/TableGen/Record.h" 2839525a67Sjmolloy #include "llvm/TableGen/TableGenBackend.h" 29a3fe70d2SEugene Zelenko #include <cassert> 30a3fe70d2SEugene Zelenko #include <cstdint> 31e6aed139SJakob Stoklund Olesen #include <map> 32a3fe70d2SEugene Zelenko #include <set> 33e6aed139SJakob Stoklund Olesen #include <string> 346ccd6732SJames Molloy #include <unordered_map> 35a3fe70d2SEugene Zelenko #include <vector> 366ac3f739SEugene Zelenko 3708ebdc1eSAnshuman Dasgupta using namespace llvm; 3808ebdc1eSAnshuman Dasgupta 3939525a67Sjmolloy // We use a uint64_t to represent a resource bitmask. 4039525a67Sjmolloy #define DFA_MAX_RESOURCES 64 416753f333SKrzysztof Parzyszek 426753f333SKrzysztof Parzyszek namespace { 4339525a67Sjmolloy using ResourceVector = SmallVector<uint64_t, 4>; 44a3fe70d2SEugene Zelenko 4539525a67Sjmolloy struct ScheduleClass { 4639525a67Sjmolloy /// The parent itinerary index (processor model ID). 4739525a67Sjmolloy unsigned ItineraryID; 486753f333SKrzysztof Parzyszek 4939525a67Sjmolloy /// Index within this itinerary of the schedule class. 5039525a67Sjmolloy unsigned Idx; 51a3fe70d2SEugene Zelenko 5239525a67Sjmolloy /// The index within the uniqued set of required resources of Resources. 5339525a67Sjmolloy unsigned ResourcesIdx; 546ac3f739SEugene Zelenko 5539525a67Sjmolloy /// Conjunctive list of resource requirements: 5639525a67Sjmolloy /// {a|b, b|c} => (a OR b) AND (b or c). 5739525a67Sjmolloy /// Resources are unique across all itineraries. 5839525a67Sjmolloy ResourceVector Resources; 5939525a67Sjmolloy }; 606753f333SKrzysztof Parzyszek 6139525a67Sjmolloy // Generates and prints out the DFA for resource tracking. 62e6aed139SJakob Stoklund Olesen class DFAPacketizerEmitter { 63e6aed139SJakob Stoklund Olesen private: 64e6aed139SJakob Stoklund Olesen std::string TargetName; 65e6aed139SJakob Stoklund Olesen RecordKeeper &Records; 66e6aed139SJakob Stoklund Olesen 6739525a67Sjmolloy UniqueVector<ResourceVector> UniqueResources; 6839525a67Sjmolloy std::vector<ScheduleClass> ScheduleClasses; 6939525a67Sjmolloy std::map<std::string, uint64_t> FUNameToBitsMap; 7039525a67Sjmolloy std::map<unsigned, uint64_t> ComboBitToBitsMap; 7139525a67Sjmolloy 72e6aed139SJakob Stoklund Olesen public: 73e6aed139SJakob Stoklund Olesen DFAPacketizerEmitter(RecordKeeper &R); 74e6aed139SJakob Stoklund Olesen 7539525a67Sjmolloy // Construct a map of function unit names to bits. 7639525a67Sjmolloy int collectAllFuncUnits( 7739525a67Sjmolloy ArrayRef<const CodeGenProcModel *> ProcModels); 78b4655729SKrzysztof Parzyszek 7939525a67Sjmolloy // Construct a map from a combo function unit bit to the bits of all included 8039525a67Sjmolloy // functional units. 8139525a67Sjmolloy int collectAllComboFuncs(ArrayRef<Record *> ComboFuncList); 82b4655729SKrzysztof Parzyszek 8339525a67Sjmolloy ResourceVector getResourcesForItinerary(Record *Itinerary); 8439525a67Sjmolloy void createScheduleClasses(unsigned ItineraryIdx, const RecVec &Itineraries); 85e6aed139SJakob Stoklund Olesen 866ccd6732SJames Molloy // Emit code for a subset of itineraries. 876ccd6732SJames Molloy void emitForItineraries(raw_ostream &OS, 8839525a67Sjmolloy std::vector<const CodeGenProcModel *> &ProcItinList, 896ccd6732SJames Molloy std::string DFAName); 906ccd6732SJames Molloy 91e6aed139SJakob Stoklund Olesen void run(raw_ostream &OS); 92e6aed139SJakob Stoklund Olesen }; 936ac3f739SEugene Zelenko } // end anonymous namespace 9408ebdc1eSAnshuman Dasgupta 9539525a67Sjmolloy DFAPacketizerEmitter::DFAPacketizerEmitter(RecordKeeper &R) 96adcd0268SBenjamin Kramer : TargetName(std::string(CodeGenTarget(R).getName())), Records(R) {} 97b4655729SKrzysztof Parzyszek 98b4655729SKrzysztof Parzyszek int DFAPacketizerEmitter::collectAllFuncUnits( 9939525a67Sjmolloy ArrayRef<const CodeGenProcModel *> ProcModels) { 100d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "-------------------------------------------------------" 101d34e60caSNicola Zaghen "----------------------\n"); 102d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "collectAllFuncUnits"); 10339525a67Sjmolloy LLVM_DEBUG(dbgs() << " (" << ProcModels.size() << " itineraries)\n"); 10439525a67Sjmolloy 10539525a67Sjmolloy std::set<Record *> ProcItinList; 10639525a67Sjmolloy for (const CodeGenProcModel *Model : ProcModels) 10739525a67Sjmolloy ProcItinList.insert(Model->ItinsDef); 10808ebdc1eSAnshuman Dasgupta 109b4655729SKrzysztof Parzyszek int totalFUs = 0; 11008ebdc1eSAnshuman Dasgupta // Parse functional units for all the itineraries. 11139525a67Sjmolloy for (Record *Proc : ProcItinList) { 11208ebdc1eSAnshuman Dasgupta std::vector<Record *> FUs = Proc->getValueAsListOfDefs("FU"); 11308ebdc1eSAnshuman Dasgupta 11439525a67Sjmolloy LLVM_DEBUG(dbgs() << " FU:" 11539525a67Sjmolloy << " (" << FUs.size() << " FUs) " << Proc->getName()); 116b4655729SKrzysztof Parzyszek 1179aa6137dSSebastian Pop // Convert macros to bits for each stage. 118b4655729SKrzysztof Parzyszek unsigned numFUs = FUs.size(); 119b4655729SKrzysztof Parzyszek for (unsigned j = 0; j < numFUs; ++j) { 120b4655729SKrzysztof Parzyszek assert((j < DFA_MAX_RESOURCES) && 121b4655729SKrzysztof Parzyszek "Exceeded maximum number of representable resources"); 12239525a67Sjmolloy uint64_t FuncResources = 1ULL << j; 123adcd0268SBenjamin Kramer FUNameToBitsMap[std::string(FUs[j]->getName())] = FuncResources; 124d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " " << FUs[j]->getName() << ":0x" 1253a13ed60SBenjamin Kramer << Twine::utohexstr(FuncResources)); 12608ebdc1eSAnshuman Dasgupta } 127b4655729SKrzysztof Parzyszek totalFUs += numFUs; 128d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\n"); 129b4655729SKrzysztof Parzyszek } 130b4655729SKrzysztof Parzyszek return totalFUs; 131b4655729SKrzysztof Parzyszek } 132b4655729SKrzysztof Parzyszek 13339525a67Sjmolloy int DFAPacketizerEmitter::collectAllComboFuncs(ArrayRef<Record *> ComboFuncList) { 134d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "-------------------------------------------------------" 135d34e60caSNicola Zaghen "----------------------\n"); 136d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "collectAllComboFuncs"); 137d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " (" << ComboFuncList.size() << " sets)\n"); 138b4655729SKrzysztof Parzyszek 139b4655729SKrzysztof Parzyszek int numCombos = 0; 140b4655729SKrzysztof Parzyszek for (unsigned i = 0, N = ComboFuncList.size(); i < N; ++i) { 141b4655729SKrzysztof Parzyszek Record *Func = ComboFuncList[i]; 142b4655729SKrzysztof Parzyszek std::vector<Record *> FUs = Func->getValueAsListOfDefs("CFD"); 143b4655729SKrzysztof Parzyszek 144d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " CFD:" << i << " (" << FUs.size() << " combo FUs) " 1458dd552dbSKrzysztof Parzyszek << Func->getName() << "\n"); 146b4655729SKrzysztof Parzyszek 147b4655729SKrzysztof Parzyszek // Convert macros to bits for each stage. 148b4655729SKrzysztof Parzyszek for (unsigned j = 0, N = FUs.size(); j < N; ++j) { 149b4655729SKrzysztof Parzyszek assert((j < DFA_MAX_RESOURCES) && 150b4655729SKrzysztof Parzyszek "Exceeded maximum number of DFA resources"); 151b4655729SKrzysztof Parzyszek Record *FuncData = FUs[j]; 152b4655729SKrzysztof Parzyszek Record *ComboFunc = FuncData->getValueAsDef("TheComboFunc"); 153b4655729SKrzysztof Parzyszek const std::vector<Record *> &FuncList = 154b4655729SKrzysztof Parzyszek FuncData->getValueAsListOfDefs("FuncList"); 155adcd0268SBenjamin Kramer const std::string &ComboFuncName = std::string(ComboFunc->getName()); 15639525a67Sjmolloy uint64_t ComboBit = FUNameToBitsMap[ComboFuncName]; 15739525a67Sjmolloy uint64_t ComboResources = ComboBit; 158d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " combo: " << ComboFuncName << ":0x" 1593a13ed60SBenjamin Kramer << Twine::utohexstr(ComboResources) << "\n"); 160*e6cf3d64SCoelacanthus for (auto *K : FuncList) { 161*e6cf3d64SCoelacanthus std::string FuncName = std::string(K->getName()); 16239525a67Sjmolloy uint64_t FuncResources = FUNameToBitsMap[FuncName]; 163d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " " << FuncName << ":0x" 1643a13ed60SBenjamin Kramer << Twine::utohexstr(FuncResources) << "\n"); 165b4655729SKrzysztof Parzyszek ComboResources |= FuncResources; 166b4655729SKrzysztof Parzyszek } 167b4655729SKrzysztof Parzyszek ComboBitToBitsMap[ComboBit] = ComboResources; 168b4655729SKrzysztof Parzyszek numCombos++; 169d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " => combo bits: " << ComboFuncName << ":0x" 1703a13ed60SBenjamin Kramer << Twine::utohexstr(ComboBit) << " = 0x" 1713a13ed60SBenjamin Kramer << Twine::utohexstr(ComboResources) << "\n"); 172b4655729SKrzysztof Parzyszek } 173b4655729SKrzysztof Parzyszek } 174b4655729SKrzysztof Parzyszek return numCombos; 175b4655729SKrzysztof Parzyszek } 176b4655729SKrzysztof Parzyszek 17739525a67Sjmolloy ResourceVector 17839525a67Sjmolloy DFAPacketizerEmitter::getResourcesForItinerary(Record *Itinerary) { 17939525a67Sjmolloy ResourceVector Resources; 18039525a67Sjmolloy assert(Itinerary); 18139525a67Sjmolloy for (Record *StageDef : Itinerary->getValueAsListOfDefs("Stages")) { 18239525a67Sjmolloy uint64_t StageResources = 0; 18339525a67Sjmolloy for (Record *Unit : StageDef->getValueAsListOfDefs("Units")) { 184adcd0268SBenjamin Kramer StageResources |= FUNameToBitsMap[std::string(Unit->getName())]; 18539525a67Sjmolloy } 18639525a67Sjmolloy if (StageResources != 0) 18739525a67Sjmolloy Resources.push_back(StageResources); 18839525a67Sjmolloy } 18939525a67Sjmolloy return Resources; 19008ebdc1eSAnshuman Dasgupta } 19108ebdc1eSAnshuman Dasgupta 19239525a67Sjmolloy void DFAPacketizerEmitter::createScheduleClasses(unsigned ItineraryIdx, 19339525a67Sjmolloy const RecVec &Itineraries) { 19439525a67Sjmolloy unsigned Idx = 0; 19539525a67Sjmolloy for (Record *Itinerary : Itineraries) { 19639525a67Sjmolloy if (!Itinerary) { 19739525a67Sjmolloy ScheduleClasses.push_back({ItineraryIdx, Idx++, 0, ResourceVector{}}); 19839525a67Sjmolloy continue; 19908ebdc1eSAnshuman Dasgupta } 20039525a67Sjmolloy ResourceVector Resources = getResourcesForItinerary(Itinerary); 20139525a67Sjmolloy ScheduleClasses.push_back( 20239525a67Sjmolloy {ItineraryIdx, Idx++, UniqueResources.insert(Resources), Resources}); 20308ebdc1eSAnshuman Dasgupta } 204b4655729SKrzysztof Parzyszek } 20508ebdc1eSAnshuman Dasgupta 20608ebdc1eSAnshuman Dasgupta // 2079aa6137dSSebastian Pop // Run the worklist algorithm to generate the DFA. 20808ebdc1eSAnshuman Dasgupta // 209e6aed139SJakob Stoklund Olesen void DFAPacketizerEmitter::run(raw_ostream &OS) { 2106ccd6732SJames Molloy OS << "\n" 2116ccd6732SJames Molloy << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n"; 2126ccd6732SJames Molloy OS << "namespace llvm {\n"; 2136ccd6732SJames Molloy 21439525a67Sjmolloy CodeGenTarget CGT(Records); 21539525a67Sjmolloy CodeGenSchedModels CGS(Records, CGT); 2166ccd6732SJames Molloy 21739525a67Sjmolloy std::unordered_map<std::string, std::vector<const CodeGenProcModel *>> 21839525a67Sjmolloy ItinsByNamespace; 21939525a67Sjmolloy for (const CodeGenProcModel &ProcModel : CGS.procModels()) { 22039525a67Sjmolloy if (ProcModel.hasItineraries()) { 22139525a67Sjmolloy auto NS = ProcModel.ItinsDef->getValueAsString("PacketizerNamespace"); 222adcd0268SBenjamin Kramer ItinsByNamespace[std::string(NS)].push_back(&ProcModel); 22339525a67Sjmolloy } 22439525a67Sjmolloy } 2256ccd6732SJames Molloy 2266ccd6732SJames Molloy for (auto &KV : ItinsByNamespace) 2276ccd6732SJames Molloy emitForItineraries(OS, KV.second, KV.first); 2286ccd6732SJames Molloy OS << "} // end namespace llvm\n"; 2296ccd6732SJames Molloy } 2306ccd6732SJames Molloy 2316ccd6732SJames Molloy void DFAPacketizerEmitter::emitForItineraries( 23239525a67Sjmolloy raw_ostream &OS, std::vector<const CodeGenProcModel *> &ProcModels, 2336ccd6732SJames Molloy std::string DFAName) { 23439525a67Sjmolloy OS << "} // end namespace llvm\n\n"; 23539525a67Sjmolloy OS << "namespace {\n"; 23639525a67Sjmolloy collectAllFuncUnits(ProcModels); 23739525a67Sjmolloy collectAllComboFuncs(Records.getAllDerivedDefinitions("ComboFuncUnits")); 238b4655729SKrzysztof Parzyszek 239b4655729SKrzysztof Parzyszek // Collect the itineraries. 24039525a67Sjmolloy DenseMap<const CodeGenProcModel *, unsigned> ProcModelStartIdx; 24139525a67Sjmolloy for (const CodeGenProcModel *Model : ProcModels) { 24239525a67Sjmolloy assert(Model->hasItineraries()); 24339525a67Sjmolloy ProcModelStartIdx[Model] = ScheduleClasses.size(); 24439525a67Sjmolloy createScheduleClasses(Model->Index, Model->ItinDefList); 24508ebdc1eSAnshuman Dasgupta } 24608ebdc1eSAnshuman Dasgupta 24739525a67Sjmolloy // Output the mapping from ScheduleClass to ResourcesIdx. 24839525a67Sjmolloy unsigned Idx = 0; 2499e4b761aSBenjamin Kramer OS << "constexpr unsigned " << TargetName << DFAName 2509e4b761aSBenjamin Kramer << "ResourceIndices[] = {"; 25139525a67Sjmolloy for (const ScheduleClass &SC : ScheduleClasses) { 25239525a67Sjmolloy if (Idx++ % 32 == 0) 25339525a67Sjmolloy OS << "\n "; 25439525a67Sjmolloy OS << SC.ResourcesIdx << ", "; 25539525a67Sjmolloy } 25639525a67Sjmolloy OS << "\n};\n\n"; 25739525a67Sjmolloy 25839525a67Sjmolloy // And the mapping from Itinerary index into the previous table. 2599e4b761aSBenjamin Kramer OS << "constexpr unsigned " << TargetName << DFAName 26039525a67Sjmolloy << "ProcResourceIndexStart[] = {\n"; 26139525a67Sjmolloy OS << " 0, // NoSchedModel\n"; 26239525a67Sjmolloy for (const CodeGenProcModel *Model : ProcModels) { 26339525a67Sjmolloy OS << " " << ProcModelStartIdx[Model] << ", // " << Model->ModelName 26439525a67Sjmolloy << "\n"; 26539525a67Sjmolloy } 266d0b8810fSJay Foad OS << " " << ScheduleClasses.size() << "\n};\n\n"; 26739525a67Sjmolloy 26812092a96SJames Molloy // The type of a state in the nondeterministic automaton we're defining. 26939525a67Sjmolloy using NfaStateTy = uint64_t; 27008ebdc1eSAnshuman Dasgupta 27112092a96SJames Molloy // Given a resource state, return all resource states by applying 27212092a96SJames Molloy // InsnClass. 27339525a67Sjmolloy auto applyInsnClass = [&](const ResourceVector &InsnClass, 27439525a67Sjmolloy NfaStateTy State) -> std::deque<NfaStateTy> { 27539525a67Sjmolloy std::deque<NfaStateTy> V(1, State); 27612092a96SJames Molloy // Apply every stage in the class individually. 27739525a67Sjmolloy for (NfaStateTy Stage : InsnClass) { 27812092a96SJames Molloy // Apply this stage to every existing member of V in turn. 27912092a96SJames Molloy size_t Sz = V.size(); 28012092a96SJames Molloy for (unsigned I = 0; I < Sz; ++I) { 28139525a67Sjmolloy NfaStateTy S = V.front(); 28212092a96SJames Molloy V.pop_front(); 28308ebdc1eSAnshuman Dasgupta 28412092a96SJames Molloy // For this stage, state combination, try all possible resources. 28512092a96SJames Molloy for (unsigned J = 0; J < DFA_MAX_RESOURCES; ++J) { 28639525a67Sjmolloy NfaStateTy ResourceMask = 1ULL << J; 28712092a96SJames Molloy if ((ResourceMask & Stage) == 0) 28812092a96SJames Molloy // This resource isn't required by this stage. 289b4655729SKrzysztof Parzyszek continue; 29039525a67Sjmolloy NfaStateTy Combo = ComboBitToBitsMap[ResourceMask]; 29112092a96SJames Molloy if (Combo && ((~S & Combo) != Combo)) 29212092a96SJames Molloy // This combo units bits are not available. 29312092a96SJames Molloy continue; 29439525a67Sjmolloy NfaStateTy ResultingResourceState = S | ResourceMask | Combo; 29512092a96SJames Molloy if (ResultingResourceState == S) 29612092a96SJames Molloy continue; 29712092a96SJames Molloy V.push_back(ResultingResourceState); 298b4655729SKrzysztof Parzyszek } 29908ebdc1eSAnshuman Dasgupta } 30012092a96SJames Molloy } 30112092a96SJames Molloy return V; 30212092a96SJames Molloy }; 30308ebdc1eSAnshuman Dasgupta 30412092a96SJames Molloy // Given a resource state, return a quick (conservative) guess as to whether 30512092a96SJames Molloy // InsnClass can be applied. This is a filter for the more heavyweight 30612092a96SJames Molloy // applyInsnClass. 30739525a67Sjmolloy auto canApplyInsnClass = [](const ResourceVector &InsnClass, 30812092a96SJames Molloy NfaStateTy State) -> bool { 30939525a67Sjmolloy for (NfaStateTy Resources : InsnClass) { 31012092a96SJames Molloy if ((State | Resources) == State) 31112092a96SJames Molloy return false; 31212092a96SJames Molloy } 31312092a96SJames Molloy return true; 31412092a96SJames Molloy }; 31512092a96SJames Molloy 31612092a96SJames Molloy DfaEmitter Emitter; 31712092a96SJames Molloy std::deque<NfaStateTy> Worklist(1, 0); 31812092a96SJames Molloy std::set<NfaStateTy> SeenStates; 31912092a96SJames Molloy SeenStates.insert(Worklist.front()); 32012092a96SJames Molloy while (!Worklist.empty()) { 32112092a96SJames Molloy NfaStateTy State = Worklist.front(); 32212092a96SJames Molloy Worklist.pop_front(); 32339525a67Sjmolloy for (const ResourceVector &Resources : UniqueResources) { 32439525a67Sjmolloy if (!canApplyInsnClass(Resources, State)) 32512092a96SJames Molloy continue; 32639525a67Sjmolloy unsigned ResourcesID = UniqueResources.idFor(Resources); 32739525a67Sjmolloy for (uint64_t NewState : applyInsnClass(Resources, State)) { 32812092a96SJames Molloy if (SeenStates.emplace(NewState).second) 32912092a96SJames Molloy Worklist.emplace_back(NewState); 33039525a67Sjmolloy Emitter.addTransition(State, NewState, ResourcesID); 33108ebdc1eSAnshuman Dasgupta } 33208ebdc1eSAnshuman Dasgupta } 33308ebdc1eSAnshuman Dasgupta } 33408ebdc1eSAnshuman Dasgupta 33512092a96SJames Molloy std::string TargetAndDFAName = TargetName + DFAName; 33612092a96SJames Molloy Emitter.emit(TargetAndDFAName, OS); 33712092a96SJames Molloy OS << "} // end anonymous namespace\n\n"; 3386ccd6732SJames Molloy 3396ccd6732SJames Molloy std::string SubTargetClassName = TargetName + "GenSubtargetInfo"; 3406ccd6732SJames Molloy OS << "namespace llvm {\n"; 3416ccd6732SJames Molloy OS << "DFAPacketizer *" << SubTargetClassName << "::" 3426ccd6732SJames Molloy << "create" << DFAName 3436ccd6732SJames Molloy << "DFAPacketizer(const InstrItineraryData *IID) const {\n" 344d5afdbe5SJames Molloy << " static Automaton<uint64_t> A(ArrayRef<" << TargetAndDFAName 34512092a96SJames Molloy << "Transition>(" << TargetAndDFAName << "Transitions), " 34612092a96SJames Molloy << TargetAndDFAName << "TransitionInfo);\n" 34739525a67Sjmolloy << " unsigned ProcResIdxStart = " << TargetAndDFAName 34839525a67Sjmolloy << "ProcResourceIndexStart[IID->SchedModel.ProcID];\n" 34939525a67Sjmolloy << " unsigned ProcResIdxNum = " << TargetAndDFAName 35039525a67Sjmolloy << "ProcResourceIndexStart[IID->SchedModel.ProcID + 1] - " 35139525a67Sjmolloy "ProcResIdxStart;\n" 35239525a67Sjmolloy << " return new DFAPacketizer(IID, A, {&" << TargetAndDFAName 35339525a67Sjmolloy << "ResourceIndices[ProcResIdxStart], ProcResIdxNum});\n" 35412092a96SJames Molloy << "\n}\n\n"; 35508ebdc1eSAnshuman Dasgupta } 356e6aed139SJakob Stoklund Olesen 357e6aed139SJakob Stoklund Olesen namespace llvm { 358e6aed139SJakob Stoklund Olesen 359e6aed139SJakob Stoklund Olesen void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS) { 360e6aed139SJakob Stoklund Olesen emitSourceFileHeader("Target DFA Packetizer Tables", OS); 361e6aed139SJakob Stoklund Olesen DFAPacketizerEmitter(RK).run(OS); 362e6aed139SJakob Stoklund Olesen } 363e6aed139SJakob Stoklund Olesen 364a3fe70d2SEugene Zelenko } // end namespace llvm 365