diff options
Diffstat (limited to 'utils/TableGen/SubtargetEmitter.cpp')
-rw-r--r-- | utils/TableGen/SubtargetEmitter.cpp | 141 |
1 files changed, 102 insertions, 39 deletions
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 4a0bacd19c..9760b171dd 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -199,12 +199,13 @@ unsigned SubtargetEmitter::CollectAllItinClasses(raw_ostream &OS, } // -// FormItineraryString - Compose a string containing the data initialization -// for the specified itinerary. N is the number of stages. +// FormItineraryStageString - Compose a string containing the stage +// data initialization for the specified itinerary. N is the number +// of stages. // -void SubtargetEmitter::FormItineraryString(Record *ItinData, - std::string &ItinString, - unsigned &NStages) { +void SubtargetEmitter::FormItineraryStageString(Record *ItinData, + std::string &ItinString, + unsigned &NStages) { // Get states list const std::vector<Record*> &StageList = ItinData->getValueAsListOfDefs("Stages"); @@ -239,10 +240,32 @@ void SubtargetEmitter::FormItineraryString(Record *ItinData, } // -// EmitStageData - Generate unique itinerary stages. Record itineraries for -// processors. +// FormItineraryOperandCycleString - Compose a string containing the +// operand cycle initialization for the specified itinerary. N is the +// number of operands that has cycles specified. // -void SubtargetEmitter::EmitStageData(raw_ostream &OS, +void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData, + std::string &ItinString, unsigned &NOperandCycles) { + // Get operand cycle list + const std::vector<int64_t> &OperandCycleList = + ItinData->getValueAsListOfInts("OperandCycles"); + + // For each operand cycle + unsigned N = NOperandCycles = OperandCycleList.size(); + for (unsigned i = 0; i < N;) { + // Next operand cycle + const int OCycle = OperandCycleList[i]; + + ItinString += " " + itostr(OCycle); + if (++i < N) ItinString += ", "; + } +} + +// +// EmitStageAndOperandCycleData - Generate unique itinerary stages and +// operand cycle tables. Record itineraries for processors. +// +void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses, std::map<std::string, unsigned> &ItinClassesMap, std::vector<std::vector<InstrItinerary> > &ProcList) { @@ -254,12 +277,16 @@ void SubtargetEmitter::EmitStageData(raw_ostream &OS, if (ProcItinList.size() < 2) return; // Begin stages table - OS << "static const llvm::InstrStage Stages[] = {\n" - " { 0, 0, 0 }, // No itinerary\n"; + std::string StageTable = "static const llvm::InstrStage Stages[] = {\n"; + StageTable += " { 0, 0, 0 }, // No itinerary\n"; - unsigned StageCount = 1; - unsigned ItinEnum = 1; - std::map<std::string, unsigned> ItinMap; + // Begin operand cycle table + std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; + OperandCycleTable += " 0, // No itinerary\n"; + + unsigned StageCount = 1, OperandCycleCount = 1; + unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; + std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap; for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { // Next record Record *Proc = ProcItinList[i]; @@ -283,29 +310,53 @@ void SubtargetEmitter::EmitStageData(raw_ostream &OS, Record *ItinData = ItinDataList[j]; // Get string and stage count - std::string ItinString; + std::string ItinStageString; unsigned NStages; - FormItineraryString(ItinData, ItinString, NStages); - - // Check to see if it already exists - unsigned Find = ItinMap[ItinString]; + FormItineraryStageString(ItinData, ItinStageString, NStages); + + // Get string and operand cycle count + std::string ItinOperandCycleString; + unsigned NOperandCycles; + FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, + NOperandCycles); + + // Check to see if stage already exists and create if it doesn't + unsigned FindStage = 0; + if (NStages > 0) { + FindStage = ItinStageMap[ItinStageString]; + if (FindStage == 0) { + // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index + StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n"; + // Record Itin class number. + ItinStageMap[ItinStageString] = FindStage = StageCount; + StageCount += NStages; + ItinStageEnum++; + } + } - // If new itinerary - if (Find == 0) { - // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index - OS << ItinString << ", // " << ItinEnum << "\n"; - // Record Itin class number. - ItinMap[ItinString] = Find = StageCount; - StageCount += NStages; - ItinEnum++; + // Check to see if operand cycle already exists and create if it doesn't + unsigned FindOperandCycle = 0; + if (NOperandCycles > 0) { + FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString]; + if (FindOperandCycle == 0) { + // Emit as cycle, // index + OperandCycleTable += ItinOperandCycleString + ", // " + + itostr(ItinOperandCycleEnum) + "\n"; + // Record Itin class number. + ItinOperandCycleMap[ItinOperandCycleString] = + FindOperandCycle = OperandCycleCount; + OperandCycleCount += NOperandCycles; + ItinOperandCycleEnum++; + } } // Set up itinerary as location and location + stage count - InstrItinerary Intinerary = { Find, Find + NStages }; + InstrItinerary Intinerary = { FindStage, FindStage + NStages, + FindOperandCycle, FindOperandCycle + NOperandCycles}; // Locate where to inject into processor itinerary table const std::string &Name = ItinData->getValueAsDef("TheClass")->getName(); - Find = ItinClassesMap[Name]; + unsigned Find = ItinClassesMap[Name]; // Inject - empty slots will be 0, 0 ItinList[Find] = Intinerary; @@ -316,13 +367,21 @@ void SubtargetEmitter::EmitStageData(raw_ostream &OS, } // Closing stage - OS << " { 0, 0, 0 } // End itinerary\n"; - // End stages table - OS << "};\n"; + StageTable += " { 0, 0, 0 } // End itinerary\n"; + StageTable += "};\n"; + + // Closing operand cycles + OperandCycleTable += " 0 // End itinerary\n"; + OperandCycleTable += "};\n"; + + // Emit tables. + OS << StageTable; + OS << OperandCycleTable; - // Emit size of table + // Emit size of tables OS<<"\nenum {\n"; - OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n"; + OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n"; + OS<<" OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n"; OS<<"};\n"; } @@ -357,11 +416,15 @@ void SubtargetEmitter::EmitProcessorData(raw_ostream &OS, for (unsigned j = 0, M = ItinList.size(); j < M;) { InstrItinerary &Intinerary = ItinList[j]; - // Emit in the form of { first, last } // index - if (Intinerary.First == 0) { - OS << " { 0, 0 }"; + // Emit in the form of + // { firstStage, lastStage, firstCycle, lastCycle } // index + if (Intinerary.FirstStage == 0) { + OS << " { 0, 0, 0, 0 }"; } else { - OS << " { " << Intinerary.First << ", " << Intinerary.Last << " }"; + OS << " { " << Intinerary.FirstStage << ", " << + Intinerary.LastStage << ", " << + Intinerary.FirstOperandCycle << ", " << + Intinerary.LastOperandCycle << " }"; } // If more in list add comma @@ -435,7 +498,7 @@ void SubtargetEmitter::EmitData(raw_ostream &OS) { if (HasItineraries) { // Emit the stage data - EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList); + EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList); // Emit the processor itinerary data EmitProcessorData(OS, ProcList); // Emit the processor lookup data @@ -482,7 +545,7 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { OS << "\n" << " InstrItinerary *Itinerary = (InstrItinerary *)" << "Features.getInfo(ProcItinKV, ProcItinKVSize);\n" - << " InstrItins = InstrItineraryData(Stages, Itinerary);\n"; + << " InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n"; } OS << " return Features.getCPU();\n" |