SubtargetEmitter.cpp revision 98eb98b0f2e6573f5aee67ce3e75624392d637b7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tablegen backend emits subtarget enumerations. 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CodeGenTarget.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CodeGenSchedule.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/ADT/StringExtras.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/MC/MCInstrItineraries.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Debug.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/TableGen/Record.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/TableGen/TableGenBackend.h" 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <algorithm> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing namespace llvm; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SubtargetEmitter { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordKeeper &Records; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenSchedModels &SchedModels; 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string Target; 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned FeatureKeyValues(raw_ostream &OS); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned CPUKeyValues(raw_ostream &OS); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FormItineraryStageString(const std::string &Names, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *ItinData, std::string &ItinString, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned &NStages); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned &NOperandCycles); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FormItineraryBypassString(const std::string &Names, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *ItinData, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string &ItinString, unsigned NOperandCycles); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitStageAndOperandCycleData(raw_ostream &OS, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::vector<InstrItinerary> > 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ProcItinLists); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitItineraries(raw_ostream &OS, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::vector<InstrItinerary> > 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ProcItinLists); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitProcessorProp(raw_ostream &OS, const Record *R, const char *Name, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char Separator); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitProcessorModels(raw_ostream &OS); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitProcessorLookup(raw_ostream &OS); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EmitSchedModel(raw_ostream &OS); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned NumProcs); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT): 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void run(raw_ostream &o); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // End anonymous namespace 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enumeration - Emit the specified class as an enumeration. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SubtargetEmitter::Enumeration(raw_ostream &OS, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *ClassName, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool isBits) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get all records of class and sort 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(DefList.begin(), DefList.end(), LessRecord()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned N = DefList.size(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N == 0) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N > 64) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errs() << "Too many (> 64) subtarget features!\n"; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(1); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "namespace " << Target << " {\n"; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For bit flag enumerations with more than 32 items, emit constants. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit an enum for everything else. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isBits && N > 32) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each record 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < N; i++) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next record 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *Def = DefList[i]; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get and emit name and expression (1 << i) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << " const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n"; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open enumeration 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "enum {\n"; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each record 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < N;) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next record 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *Def = DefList[i]; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get and emit name 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << " " << Def->getName(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If bit flags then emit expression (1 << i) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isBits) OS << " = " << " 1ULL << " << i; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Depending on 'if more in the list' emit comma 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++i < N) OS << ","; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << "\n"; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close enumeration 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "};\n"; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << "}\n"; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// FeatureKeyValues - Emit data of all the subtarget features. Used by the 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// command line. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Gather and sort all the features 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<Record*> FeatureList = 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Records.getAllDerivedDefinitions("SubtargetFeature"); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FeatureList.empty()) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName()); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Begin feature table 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << "// Sorted (by key) array of values for CPU features.\n" 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "extern const llvm::SubtargetFeatureKV " << Target 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "FeatureKV[] = {\n"; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For each feature 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned NumFeatures = 0; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Next feature 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Record *Feature = FeatureList[i]; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string &Name = Feature->getName(); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string &CommandLineName = Feature->getValueAsString("Name"); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string &Desc = Feature->getValueAsString("Desc"); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (CommandLineName.empty()) continue; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in } 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << " { " 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "\"" << CommandLineName << "\", " 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "\"" << Desc << "\", " 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << Target << "::" << Name << ", "; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<Record*> &ImpliesList = 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Feature->getValueAsListOfDefs("Implies"); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ImpliesList.empty()) { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << "0ULL"; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned j = 0, M = ImpliesList.size(); j < M;) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << Target << "::" << ImpliesList[j]->getName(); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (++j < M) OS << " | "; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << " }"; 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ++NumFeatures; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Depending on 'if more in the list' emit comma 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((i + 1) < N) OS << ","; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "\n"; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // End feature table 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "};\n"; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NumFeatures; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CPUKeyValues - Emit data of all the subtarget processors. Used by command 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// line. 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gather and sort processor information 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Record*> ProcessorList = 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Records.getAllDerivedDefinitions("Processor"); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begin processor table 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "// Sorted (by key) array of values for CPU subtype.\n" 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "extern const llvm::SubtargetFeatureKV " << Target 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "SubTypeKV[] = {\n"; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // For each processor 2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (unsigned i = 0, N = ProcessorList.size(); i < N;) { 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Next processor 2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Record *Processor = ProcessorList[i]; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string &Name = Processor->getValueAsString("Name"); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<Record*> &FeatureList = 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Processor->getValueAsListOfDefs("Features"); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit as { "cpu", "description", f1 | f2 | ... fn }, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << " { " 2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "\"" << Name << "\", " 2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "\"Select the " << Name << " processor\", "; 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FeatureList.empty()) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "0ULL"; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned j = 0, M = FeatureList.size(); j < M;) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << Target << "::" << FeatureList[j]->getName(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++j < M) OS << " | "; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The "0" is for the "implies" section of this data structure. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << ", 0ULL }"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Depending on 'if more in the list' emit comma 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++i < N) OS << ","; 2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "\n"; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // End processor table 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "};\n"; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProcessorList.size(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FormItineraryStageString - Compose a string containing the stage 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data initialization for the specified itinerary. N is the number 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of stages. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SubtargetEmitter::FormItineraryStageString(const std::string &Name, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *ItinData, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string &ItinString, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned &NStages) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get states list 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<Record*> &StageList = 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ItinData->getValueAsListOfDefs("Stages"); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For each stage 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned N = NStages = StageList.size(); 2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (unsigned i = 0; i < N;) { 2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Next stage 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Record *Stage = StageList[i]; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Cycles = Stage->getValueAsInt("Cycles"); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinString += " { " + itostr(Cycles) + ", "; 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get unit list 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units"); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each unit 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned j = 0, M = UnitList.size(); j < M;) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add name and bitwise or 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinString += Name + "FU::" + UnitList[j]->getName(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++j < M) ItinString += " | "; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int TimeInc = Stage->getValueAsInt("TimeInc"); 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ItinString += ", " + itostr(TimeInc); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Kind = Stage->getValueAsInt("Kind"); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close off stage 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinString += " }"; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++i < N) ItinString += ", "; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// FormItineraryOperandCycleString - Compose a string containing the 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operand cycle initialization for the specified itinerary. N is the 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number of operands that has cycles specified. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData, 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string &ItinString, unsigned &NOperandCycles) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get operand cycle list 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<int64_t> &OperandCycleList = 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinData->getValueAsListOfInts("OperandCycles"); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each operand cycle 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned N = NOperandCycles = OperandCycleList.size(); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < N;) { 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Next operand cycle 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int OCycle = OperandCycleList[i]; 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ItinString += " " + itostr(OCycle); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++i < N) ItinString += ", "; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SubtargetEmitter::FormItineraryBypassString(const std::string &Name, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *ItinData, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string &ItinString, 31468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) unsigned NOperandCycles) { 31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::vector<Record*> &BypassList = 31668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ItinData->getValueAsListOfDefs("Bypasses"); 31768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) unsigned N = BypassList.size(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned i = 0; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < N;) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinString += Name + "Bypass::" + BypassList[i]->getName(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++i < NOperandCycles) ItinString += ", "; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (; i < NOperandCycles;) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ItinString += " 0"; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++i < NOperandCycles) ItinString += ", "; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EmitStageAndOperandCycleData - Generate unique itinerary stages and operand 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cycle tables. Create a list of InstrItinerary objects (ProcItinLists) indexed 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by CodeGenSchedClass::Index. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SubtargetEmitter:: 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EmitStageAndOperandCycleData(raw_ostream &OS, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::vector<InstrItinerary> > 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ProcItinLists) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Multiple processor models may share an itinerary record. Emit it once. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SmallPtrSet<Record*, 8> ItinsDefSet; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit functional units for all the itineraries. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PE = SchedModels.procModelEnd(); PI != PE; ++PI) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ItinsDefSet.insert(PI->ItinsDef)) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Record*> FUs = PI->ItinsDef->getValueAsListOfDefs("FU"); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FUs.empty()) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string &Name = PI->ItinsDef->getName(); 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "\n// Functional units for \"" << Name << "\"\n" 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "namespace " << Name << "FU {\n"; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << " const unsigned " << FUs[j]->getName() 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " = 1 << " << j << ";\n"; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "}\n"; 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<Record*> BPs = PI->ItinsDef->getValueAsListOfDefs("BP"); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BPs.size()) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\"\n" << "namespace " << Name << "Bypass {\n"; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << " const unsigned NoBypass = 0;\n"; 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j) 37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OS << " const unsigned " << BPs[j]->getName() 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " = 1 << " << j << ";\n"; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OS << "}\n"; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begin stages table 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string StageTable = "\nextern const llvm::InstrStage " + Target + 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Stages[] = {\n"; 38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n"; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begin operand cycle table 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string OperandCycleTable = "extern const unsigned " + Target + 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "OperandCycles[] = {\n"; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OperandCycleTable += " 0, // No itinerary\n"; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begin pipeline bypass table 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string BypassTable = "extern const unsigned " + Target + 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ForwardingPaths[] = {\n"; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BypassTable += " 0, // No itinerary\n"; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each Itinerary across all processors, add a unique entry to the stages, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operand cycles, and pipepine bypess tables. Then add the new Itinerary 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object with computed offsets to the ProcItinLists result. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned StageCount = 1, OperandCycleCount = 1; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, unsigned> ItinStageMap, ItinOperandMap; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PE = SchedModels.procModelEnd(); PI != PE; ++PI) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CodeGenProcModel &ProcModel = *PI; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add process itinerary to the list. 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcItinLists.resize(ProcItinLists.size()+1); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this processor defines no itineraries, then leave the itinerary list 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // empty. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<InstrItinerary> &ItinList = ProcItinLists.back(); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ProcModel.ItinDefList.empty()) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reserve index==0 for NoItinerary. 4111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ItinList.resize(SchedModels.numItineraryClasses()+1); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string &Name = ProcModel.ItinsDef->getName(); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For each itinerary data 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned SchedClassIdx = 0, 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SchedClassEnd = ProcModel.ItinDefList.size(); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SchedClassIdx < SchedClassEnd; ++SchedClassIdx) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Next itinerary data 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Record *ItinData = ProcModel.ItinDefList[SchedClassIdx]; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get string and stage count 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string ItinStageString; 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned NStages = 0; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ItinData) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FormItineraryStageString(Name, ItinData, ItinStageString, NStages); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get string and operand cycle count 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string ItinOperandCycleString; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned NOperandCycles = 0; 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string ItinBypassString; 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ItinData) { 4341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOperandCycles); 4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FormItineraryBypassString(Name, ItinData, ItinBypassString, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOperandCycles); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check to see if stage already exists and create if it doesn't 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned FindStage = 0; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NStages > 0) { 4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FindStage = ItinStageMap[ItinStageString]; 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (FindStage == 0) { 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StageTable += ItinStageString + ", // " + itostr(StageCount); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NStages > 1) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StageTable += "-" + itostr(StageCount + NStages - 1); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StageTable += "\n"; 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record Itin class number. 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ItinStageMap[ItinStageString] = FindStage = StageCount; 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StageCount += NStages; 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check to see if operand cycle already exists and create if it doesn't 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned FindOperandCycle = 0; 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NOperandCycles > 0) { 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string ItinOperandString = ItinOperandCycleString+ItinBypassString; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindOperandCycle = ItinOperandMap[ItinOperandString]; 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FindOperandCycle == 0) { 46368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Emit as cycle, // index 46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OperandCycleTable += ItinOperandCycleString + ", // "; 46568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string OperandIdxComment = itostr(OperandCycleCount); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (NOperandCycles > 1) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OperandIdxComment += "-" 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) + itostr(OperandCycleCount + NOperandCycles - 1); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OperandCycleTable += OperandIdxComment + "\n"; 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Record Itin class number. 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ItinOperandMap[ItinOperandCycleString] = 47268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FindOperandCycle = OperandCycleCount; 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Emit as bypass, // index 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n"; 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OperandCycleCount += NOperandCycles; 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set up itinerary as location and location + stage count 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int NumUOps = ItinData ? ItinData->getValueAsInt("NumMicroOps") : 0; 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindOperandCycle, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindOperandCycle + NOperandCycles}; 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Inject - empty slots will be 0, 0 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ItinList[SchedClassIdx] = Intinerary; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Closing stage 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End stages\n"; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StageTable += "};\n"; 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Closing operand cycles 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OperandCycleTable += " 0 // End operand cycles\n"; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OperandCycleTable += "};\n"; 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BypassTable += " 0 // End bypass tables\n"; 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BypassTable += "};\n"; 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Emit tables. 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OS << StageTable; 5031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << OperandCycleTable; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << BypassTable; 5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EmitProcessorData - Generate data for processor itineraries that were 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// computed during EmitStageAndOperandCycleData(). ProcItinLists lists all 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Itineraries for each processor. The Itinerary lists are indexed on 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CodeGenSchedClass::Index. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SubtargetEmitter:: 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EmitItineraries(raw_ostream &OS, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::vector<InstrItinerary> > &ProcItinLists) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Multiple processor models may share an itinerary record. Emit it once. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SmallPtrSet<Record*, 8> ItinsDefSet; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each processor's machine model 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::vector<InstrItinerary> >::iterator 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcItinListsIter = ProcItinLists.begin(); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PE = SchedModels.procModelEnd(); PI != PE; ++PI) { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Record *ItinsDef = PI->ItinsDef; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ItinsDefSet.insert(ItinsDef)) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Get processor itinerary name 5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::string &Name = ItinsDef->getName(); 5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Get the itinerary list for the processor. 5341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) assert(ProcItinListsIter != ProcItinLists.end() && "bad iterator"); 5351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::vector<InstrItinerary> &ItinList = *ProcItinListsIter++; 5361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "\n"; 5381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "static const llvm::InstrItinerary "; 5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ItinList.empty()) { 5401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << '*' << Name << " = 0;\n"; 5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) continue; 5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Begin processor itinerary table 5451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << Name << "[] = {\n"; 5461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // For each itinerary class in CodeGenSchedClass::Index order. 5481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (unsigned j = 0, M = ItinList.size(); j < M; ++j) { 5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) InstrItinerary &Intinerary = ItinList[j]; 5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Emit Itinerary in the form of 5521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // { firstStage, lastStage, firstCycle, lastCycle } // index 5531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << " { " << 5541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Intinerary.NumMicroOps << ", " << 5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Intinerary.FirstStage << ", " << 5561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Intinerary.LastStage << ", " << 5571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Intinerary.FirstOperandCycle << ", " << 5581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Intinerary.LastOperandCycle << " }" << 5591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ", // " << j << " " << SchedModels.getSchedClass(j).Name << "\n"; 5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // End processor itinerary table 5621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << " { 0, ~0U, ~0U, ~0U, ~0U } // end marker\n"; 5631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "};\n"; 5641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Emit either the value defined in the TableGen Record, or the default 5681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// value defined in the C++ header. The Record is null if the processor does not 5691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// define a model. 5701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SubtargetEmitter::EmitProcessorProp(raw_ostream &OS, const Record *R, 5711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const char *Name, char Separator) { 5721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << " "; 5731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int V = R ? R->getValueAsInt(Name) : -1; 5741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (V >= 0) 5751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << V << Separator << " // " << Name; 5761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 5771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "MCSchedModel::Default" << Name << Separator; 5781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << '\n'; 5791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) { 5821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // For each processor model. 5831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), 5841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PE = SchedModels.procModelEnd(); PI != PE; ++PI) { 5851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Skip default 5861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Begin processor itinerary properties 5871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "\n"; 5881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "static const llvm::MCSchedModel " << PI->ModelName << "(\n"; 5891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ','); 5901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EmitProcessorProp(OS, PI->ModelDef, "MinLatency", ','); 5911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ','); 5921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ','); 5931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EmitProcessorProp(OS, PI->ModelDef, "MispredictPenalty", ','); 5941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (SchedModels.hasItineraryClasses()) 5951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << " " << PI->ItinsDef->getName(); 5961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 5971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << " 0"; 5981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << ");\n"; 5991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 6001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 6011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// EmitProcessorLookup - generate cpu name to itinerary lookup table. 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) { 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Gather and sort processor information 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<Record*> ProcessorList = 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Records.getAllDerivedDefinitions("Processor"); 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Begin processor table 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OS << "\n"; 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OS << "// Sorted (by key) array of itineraries for CPU subtype.\n" 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "extern const llvm::SubtargetInfoKV " 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << Target << "ProcSchedKV[] = {\n"; 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // For each processor 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned i = 0, N = ProcessorList.size(); i < N;) { 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Next processor 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Record *Processor = ProcessorList[i]; 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string &Name = Processor->getValueAsString("Name"); 623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string &ProcModelName = 624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SchedModels.getProcModel(Processor).ModelName; 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Emit as { "cpu", procinit }, 627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OS << " { " 628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "\"" << Name << "\", " 629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << "(const void *)&" << ProcModelName; 630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OS << " }"; 632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Depending on ''if more in the list'' emit comma 634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (++i < N) OS << ","; 635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OS << "\n"; 637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // End processor table 640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OS << "};\n"; 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// EmitSchedModel - Emits all scheduling model tables, folding common patterns. 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) { 647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (SchedModels.hasItineraryClasses()) { 648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<std::vector<InstrItinerary> > ProcItinLists; 649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Emit the stage data 650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EmitStageAndOperandCycleData(OS, ProcItinLists); 651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EmitItineraries(OS, ProcItinLists); 652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Emit the processor machine model 654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EmitProcessorModels(OS); 655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Emit the processor lookup data 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EmitProcessorLookup(OS); 657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ParseFeaturesFunction - Produces a subtarget specific function for parsing 661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the subtarget features string. 662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS, 664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned NumFeatures, 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned NumProcs) { 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<Record*> Features = 6671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Records.getAllDerivedDefinitions("SubtargetFeature"); 6681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::sort(Features.begin(), Features.end(), LessRecord()); 6691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 6701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 6711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "// subtarget options.\n" 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "void llvm::"; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << Target; 674 OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n" 675 << " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n" 676 << " DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n"; 677 678 if (Features.empty()) { 679 OS << "}\n"; 680 return; 681 } 682 683 OS << " uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n"; 684 685 for (unsigned i = 0; i < Features.size(); i++) { 686 // Next record 687 Record *R = Features[i]; 688 const std::string &Instance = R->getName(); 689 const std::string &Value = R->getValueAsString("Value"); 690 const std::string &Attribute = R->getValueAsString("Attribute"); 691 692 if (Value=="true" || Value=="false") 693 OS << " if ((Bits & " << Target << "::" 694 << Instance << ") != 0) " 695 << Attribute << " = " << Value << ";\n"; 696 else 697 OS << " if ((Bits & " << Target << "::" 698 << Instance << ") != 0 && " 699 << Attribute << " < " << Value << ") " 700 << Attribute << " = " << Value << ";\n"; 701 } 702 703 OS << "}\n"; 704} 705 706// 707// SubtargetEmitter::run - Main subtarget enumeration emitter. 708// 709void SubtargetEmitter::run(raw_ostream &OS) { 710 emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); 711 712 OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; 713 OS << "#undef GET_SUBTARGETINFO_ENUM\n"; 714 715 OS << "namespace llvm {\n"; 716 Enumeration(OS, "SubtargetFeature", true); 717 OS << "} // End llvm namespace \n"; 718 OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; 719 720 OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; 721 OS << "#undef GET_SUBTARGETINFO_MC_DESC\n"; 722 723 OS << "namespace llvm {\n"; 724#if 0 725 OS << "namespace {\n"; 726#endif 727 unsigned NumFeatures = FeatureKeyValues(OS); 728 OS << "\n"; 729 unsigned NumProcs = CPUKeyValues(OS); 730 OS << "\n"; 731 EmitSchedModel(OS); 732 OS << "\n"; 733#if 0 734 OS << "}\n"; 735#endif 736 737 // MCInstrInfo initialization routine. 738 OS << "static inline void Init" << Target 739 << "MCSubtargetInfo(MCSubtargetInfo *II, " 740 << "StringRef TT, StringRef CPU, StringRef FS) {\n"; 741 OS << " II->InitMCSubtargetInfo(TT, CPU, FS, "; 742 if (NumFeatures) 743 OS << Target << "FeatureKV, "; 744 else 745 OS << "0, "; 746 if (NumProcs) 747 OS << Target << "SubTypeKV, "; 748 else 749 OS << "0, "; 750 if (SchedModels.hasItineraryClasses()) { 751 OS << Target << "ProcSchedKV, " 752 << Target << "Stages, " 753 << Target << "OperandCycles, " 754 << Target << "ForwardingPaths, "; 755 } else 756 OS << "0, 0, 0, 0, "; 757 OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; 758 759 OS << "} // End llvm namespace \n"; 760 761 OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; 762 763 OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; 764 OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n"; 765 766 OS << "#include \"llvm/Support/Debug.h\"\n"; 767 OS << "#include \"llvm/Support/raw_ostream.h\"\n"; 768 ParseFeaturesFunction(OS, NumFeatures, NumProcs); 769 770 OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; 771 772 // Create a TargetSubtargetInfo subclass to hide the MC layer initialization. 773 OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n"; 774 OS << "#undef GET_SUBTARGETINFO_HEADER\n"; 775 776 std::string ClassName = Target + "GenSubtargetInfo"; 777 OS << "namespace llvm {\n"; 778 OS << "class DFAPacketizer;\n"; 779 OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" 780 << " explicit " << ClassName << "(StringRef TT, StringRef CPU, " 781 << "StringRef FS);\n" 782 << "public:\n" 783 << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" 784 << " const;\n" 785 << "};\n"; 786 OS << "} // End llvm namespace \n"; 787 788 OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; 789 790 OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; 791 OS << "#undef GET_SUBTARGETINFO_CTOR\n"; 792 793 OS << "namespace llvm {\n"; 794 OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n"; 795 OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n"; 796 if (SchedModels.hasItineraryClasses()) { 797 OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcSchedKV[];\n"; 798 OS << "extern const llvm::InstrStage " << Target << "Stages[];\n"; 799 OS << "extern const unsigned " << Target << "OperandCycles[];\n"; 800 OS << "extern const unsigned " << Target << "ForwardingPaths[];\n"; 801 } 802 803 OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, " 804 << "StringRef FS)\n" 805 << " : TargetSubtargetInfo() {\n" 806 << " InitMCSubtargetInfo(TT, CPU, FS, "; 807 if (NumFeatures) 808 OS << Target << "FeatureKV, "; 809 else 810 OS << "0, "; 811 if (NumProcs) 812 OS << Target << "SubTypeKV, "; 813 else 814 OS << "0, "; 815 if (SchedModels.hasItineraryClasses()) { 816 OS << Target << "ProcSchedKV, " 817 << Target << "Stages, " 818 << Target << "OperandCycles, " 819 << Target << "ForwardingPaths, "; 820 } else 821 OS << "0, 0, 0, 0, "; 822 OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; 823 OS << "} // End llvm namespace \n"; 824 825 OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; 826} 827 828namespace llvm { 829 830void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) { 831 CodeGenTarget CGTarget(RK); 832 SubtargetEmitter(RK, CGTarget).run(OS); 833} 834 835} // End llvm namespace 836