diff options
Diffstat (limited to 'contrib/llvm/utils/TableGen/SubtargetEmitter.cpp')
-rw-r--r-- | contrib/llvm/utils/TableGen/SubtargetEmitter.cpp | 106 |
1 files changed, 82 insertions, 24 deletions
diff --git a/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp b/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp index b04eaf8..e35bdca 100644 --- a/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -172,13 +172,10 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) { // CollectAllItinClasses - Gathers and enumerates all the itinerary classes. // Returns itinerary class count. // -unsigned SubtargetEmitter::CollectAllItinClasses(raw_ostream &OS, - std::map<std::string, unsigned> &ItinClassesMap) { - // Gather and sort all itinerary classes - std::vector<Record*> ItinClassList = - Records.getAllDerivedDefinitions("InstrItinClass"); - std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); - +unsigned SubtargetEmitter:: +CollectAllItinClasses(raw_ostream &OS, + std::map<std::string, unsigned> &ItinClassesMap, + std::vector<Record*> &ItinClassList) { // For each itinerary class unsigned N = ItinClassList.size(); for (unsigned i = 0; i < N; i++) { @@ -265,13 +262,32 @@ void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData, } } +void SubtargetEmitter::FormItineraryBypassString(const std::string &Name, + Record *ItinData, + std::string &ItinString, + unsigned NOperandCycles) { + const std::vector<Record*> &BypassList = + ItinData->getValueAsListOfDefs("Bypasses"); + unsigned N = BypassList.size(); + unsigned i = 0; + for (; i < N;) { + ItinString += Name + "Bypass::" + BypassList[i]->getName(); + if (++i < NOperandCycles) ItinString += ", "; + } + for (; i < NOperandCycles;) { + ItinString += " 0"; + if (++i < NOperandCycles) 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::map<std::string, unsigned> &ItinClassesMap, + std::vector<Record*> &ItinClassList, std::vector<std::vector<InstrItinerary> > &ProcList) { // Gather processor iteraries std::vector<Record*> ProcItinList = @@ -298,6 +314,19 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, << " = 1 << " << j << ";\n"; OS << "}\n"; + + std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP"); + if (BPs.size()) { + OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name + << "\"\n" << "namespace " << Name << "Bypass {\n"; + + OS << " const unsigned NoBypass = 0;\n"; + for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j) + OS << " const unsigned " << BPs[j]->getName() + << " = 1 << " << j << ";\n"; + + OS << "}\n"; + } } // Begin stages table @@ -307,10 +336,14 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, // Begin operand cycle table std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; OperandCycleTable += " 0, // No itinerary\n"; + + // Begin pipeline bypass table + std::string BypassTable = "static const unsigned ForwardingPathes[] = {\n"; + BypassTable += " 0, // No itinerary\n"; unsigned StageCount = 1, OperandCycleCount = 1; unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; - std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap; + std::map<std::string, unsigned> ItinStageMap, ItinOperandMap; for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { // Next record Record *Proc = ProcItinList[i]; @@ -344,6 +377,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, NOperandCycles); + std::string ItinBypassString; + FormItineraryBypassString(Name, ItinData, ItinBypassString, + NOperandCycles); + // Check to see if stage already exists and create if it doesn't unsigned FindStage = 0; if (NStages > 0) { @@ -361,27 +398,35 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, // Check to see if operand cycle already exists and create if it doesn't unsigned FindOperandCycle = 0; if (NOperandCycles > 0) { - FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString]; + std::string ItinOperandString = ItinOperandCycleString+ItinBypassString; + FindOperandCycle = ItinOperandMap[ItinOperandString]; if (FindOperandCycle == 0) { // Emit as cycle, // index OperandCycleTable += ItinOperandCycleString + ", // " + itostr(ItinOperandCycleEnum) + "\n"; // Record Itin class number. - ItinOperandCycleMap[ItinOperandCycleString] = + ItinOperandMap[ItinOperandCycleString] = FindOperandCycle = OperandCycleCount; + + // Emit as bypass, // index + BypassTable += ItinBypassString + ", // " + + itostr(ItinOperandCycleEnum) + "\n"; + OperandCycleCount += NOperandCycles; ItinOperandCycleEnum++; } } - // Set up itinerary as location and location + stage count - InstrItinerary Intinerary = { FindStage, FindStage + NStages, - FindOperandCycle, FindOperandCycle + NOperandCycles}; - // Locate where to inject into processor itinerary table const std::string &Name = ItinData->getValueAsDef("TheClass")->getName(); unsigned Find = ItinClassesMap[Name]; + // Set up itinerary as location and location + stage count + unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps"); + InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages, + FindOperandCycle, + FindOperandCycle + NOperandCycles}; + // Inject - empty slots will be 0, 0 ItinList[Find] = Intinerary; } @@ -389,7 +434,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, // Add process itinerary to list ProcList.push_back(ItinList); } - + // Closing stage StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n"; StageTable += "};\n"; @@ -398,9 +443,13 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, OperandCycleTable += " 0 // End itinerary\n"; OperandCycleTable += "};\n"; + BypassTable += " 0 // End itinerary\n"; + BypassTable += "};\n"; + // Emit tables. OS << StageTable; OS << OperandCycleTable; + OS << BypassTable; // Emit size of tables OS<<"\nenum {\n"; @@ -443,9 +492,11 @@ void SubtargetEmitter::EmitProcessorData(raw_ostream &OS, // Emit in the form of // { firstStage, lastStage, firstCycle, lastCycle } // index if (Intinerary.FirstStage == 0) { - OS << " { 0, 0, 0, 0 }"; + OS << " { 1, 0, 0, 0, 0 }"; } else { - OS << " { " << Intinerary.FirstStage << ", " << + OS << " { " << + Intinerary.NumMicroOps << ", " << + Intinerary.FirstStage << ", " << Intinerary.LastStage << ", " << Intinerary.FirstOperandCycle << ", " << Intinerary.LastOperandCycle << " }"; @@ -455,7 +506,7 @@ void SubtargetEmitter::EmitProcessorData(raw_ostream &OS, } // End processor itinerary table - OS << " { ~0U, ~0U, ~0U, ~0U } // end marker\n"; + OS << " { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n"; OS << "};\n"; } } @@ -511,16 +562,22 @@ void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) { // void SubtargetEmitter::EmitData(raw_ostream &OS) { std::map<std::string, unsigned> ItinClassesMap; - std::vector<std::vector<InstrItinerary> > ProcList; + // Gather and sort all itinerary classes + std::vector<Record*> ItinClassList = + Records.getAllDerivedDefinitions("InstrItinClass"); + std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); // Enumerate all the itinerary classes - unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap); + unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap, + ItinClassList); // Make sure the rest is worth the effort HasItineraries = NItinClasses != 1; // Ignore NoItinerary. if (HasItineraries) { + std::vector<std::vector<InstrItinerary> > ProcList; // Emit the stage data - EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList); + EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, + ItinClassList, ProcList); // Emit the processor itinerary data EmitProcessorData(OS, ProcList); // Emit the processor lookup data @@ -569,7 +626,8 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { OS << "\n" << " InstrItinerary *Itinerary = (InstrItinerary *)" << "Features.getInfo(ProcItinKV, ProcItinKVSize);\n" - << " InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n"; + << " InstrItins = InstrItineraryData(Stages, OperandCycles, " + << "ForwardingPathes, Itinerary);\n"; } OS << " return Features.getCPU();\n" @@ -580,7 +638,7 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { // SubtargetEmitter::run - Main subtarget enumeration emitter. // void SubtargetEmitter::run(raw_ostream &OS) { - Target = CodeGenTarget().getName(); + Target = CodeGenTarget(Records).getName(); EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); |