X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FSubtargetEmitter.cpp;h=b9f9d060394066abe55b08533218cb7660cf447e;hb=d92ff21d6f526cadea7d6db21f493ba5c85e1411;hp=ac81ceffee078ad6eda988de37748fbc2a2e6147;hpb=1754aca83af1658c832706889c0e2933f8dfa8ee;p=oota-llvm.git diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index ac81ceffee0..b9f9d060394 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -447,17 +447,15 @@ EmitStageAndOperandCycleData(raw_ostream &OS, // If this processor defines no itineraries, then leave the itinerary list // empty. std::vector &ItinList = ProcItinLists.back(); - if (ProcModel.ItinDefList.empty()) + if (!ProcModel.hasItineraries()) continue; - // Reserve index==0 for NoItinerary. - ItinList.resize(SchedModels.numItineraryClasses()+1); - const std::string &Name = ProcModel.ItinsDef->getName(); - // For each itinerary data - for (unsigned SchedClassIdx = 0, - SchedClassEnd = ProcModel.ItinDefList.size(); + ItinList.resize(SchedModels.numInstrSchedClasses()); + assert(ProcModel.ItinDefList.size() == ItinList.size() && "bad Itins"); + + for (unsigned SchedClassIdx = 0, SchedClassEnd = ItinList.size(); SchedClassIdx < SchedClassEnd; ++SchedClassIdx) { // Next itinerary data @@ -636,16 +634,11 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel, Record *SuperDef = 0; unsigned SuperIdx = 0; unsigned NumUnits = 0; - bool IsBuffered = true; + int BufferSize = PRDef->getValueAsInt("BufferSize"); if (PRDef->isSubClassOf("ProcResGroup")) { RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources"); for (RecIter RUI = ResUnits.begin(), RUE = ResUnits.end(); RUI != RUE; ++RUI) { - if (!NumUnits) - IsBuffered = (*RUI)->getValueAsBit("Buffered"); - else if(IsBuffered != (*RUI)->getValueAsBit("Buffered")) - PrintFatalError(PRDef->getLoc(), - "Mixing buffered and unbuffered resources."); NumUnits += (*RUI)->getValueAsInt("NumUnits"); } } @@ -656,6 +649,7 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel, PRDef->getValueAsDef("Super"), ProcModel); SuperIdx = ProcModel.getProcResourceIdx(SuperDef); } + NumUnits = PRDef->getValueAsInt("NumUnits"); } // Emit the ProcResourceDesc if (i+1 == e) @@ -664,7 +658,7 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel, if (PRDef->getName().size() < 15) OS.indent(15 - PRDef->getName().size()); OS << NumUnits << ", " << SuperIdx << ", " - << IsBuffered << "}" << Sep << " // #" << i+1; + << BufferSize << "}" << Sep << " // #" << i+1; if (SuperDef) OS << ", Super=" << SuperDef->getName(); OS << "\n"; @@ -782,41 +776,46 @@ Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead, } // Expand an explicit list of processor resources into a full list of implied -// resource groups that cover them. -// -// FIXME: Effectively consider a super-resource a group that include all of its -// subresources to allow mixing and matching super-resources and groups. -// -// FIXME: Warn if two overlapping groups don't have a common supergroup. +// resource groups and super resources that cover them. void SubtargetEmitter::ExpandProcResources(RecVec &PRVec, std::vector &Cycles, - const CodeGenProcModel &ProcModel) { + const CodeGenProcModel &PM) { // Default to 1 resource cycle. Cycles.resize(PRVec.size(), 1); for (unsigned i = 0, e = PRVec.size(); i != e; ++i) { + Record *PRDef = PRVec[i]; RecVec SubResources; - if (PRVec[i]->isSubClassOf("ProcResGroup")) { - SubResources = PRVec[i]->getValueAsListOfDefs("Resources"); - std::sort(SubResources.begin(), SubResources.end(), LessRecord()); - } + if (PRDef->isSubClassOf("ProcResGroup")) + SubResources = PRDef->getValueAsListOfDefs("Resources"); else { - SubResources.push_back(PRVec[i]); + SubResources.push_back(PRDef); + PRDef = SchedModels.findProcResUnits(PRVec[i], PM); + for (Record *SubDef = PRDef; + SubDef->getValueInit("Super")->isComplete();) { + if (SubDef->isSubClassOf("ProcResGroup")) { + // Disallow this for simplicitly. + PrintFatalError(SubDef->getLoc(), "Processor resource group " + " cannot be a super resources."); + } + Record *SuperDef = + SchedModels.findProcResUnits(SubDef->getValueAsDef("Super"), PM); + PRVec.push_back(SuperDef); + Cycles.push_back(Cycles[i]); + SubDef = SuperDef; + } } - for (RecIter PRI = ProcModel.ProcResourceDefs.begin(), - PRE = ProcModel.ProcResourceDefs.end(); + for (RecIter PRI = PM.ProcResourceDefs.begin(), + PRE = PM.ProcResourceDefs.end(); PRI != PRE; ++PRI) { - if (*PRI == PRVec[i] || !(*PRI)->isSubClassOf("ProcResGroup")) + if (*PRI == PRDef || !(*PRI)->isSubClassOf("ProcResGroup")) continue; RecVec SuperResources = (*PRI)->getValueAsListOfDefs("Resources"); - std::sort(SuperResources.begin(), SuperResources.end(), LessRecord()); RecIter SubI = SubResources.begin(), SubE = SubResources.end(); - RecIter SuperI = SuperResources.begin(), SuperE = SuperResources.end(); - for ( ; SubI != SubE && SuperI != SuperE; ++SuperI) { - if (*SubI < *SuperI) + for( ; SubI != SubE; ++SubI) { + if (std::find(SuperResources.begin(), SuperResources.end(), *SubI) + == SuperResources.end()) { break; - else if (*SuperI < *SubI) - continue; - ++SubI; + } } if (SubI == SubE) { PRVec.push_back(*PRI); @@ -850,7 +849,22 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, SCDesc.ReadAdvanceIdx = 0; // A Variant SchedClass has no resources of its own. - if (!SCI->Transitions.empty()) { + bool HasVariants = false; + for (std::vector::const_iterator + TI = SCI->Transitions.begin(), TE = SCI->Transitions.end(); + TI != TE; ++TI) { + if (TI->ProcIndices[0] == 0) { + HasVariants = true; + break; + } + IdxIter PIPos = std::find(TI->ProcIndices.begin(), + TI->ProcIndices.end(), ProcModel.Index); + if (PIPos != TI->ProcIndices.end()) { + HasVariants = true; + break; + } + } + if (HasVariants) { SCDesc.NumMicroOps = MCSchedClassDesc::VariantNumMicroOps; continue; } @@ -867,27 +881,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, } IdxVec Writes = SCI->Writes; IdxVec Reads = SCI->Reads; - if (SCI->ItinClassDef) { - assert(SCI->InstRWs.empty() && "ItinClass should not have InstRWs"); - // Check this processor's itinerary class resources. - for (RecIter II = ProcModel.ItinRWDefs.begin(), - IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) { - RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses"); - if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef) - != Matched.end()) { - SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), - Writes, Reads); - break; - } - } - if (Writes.empty()) { - DEBUG(dbgs() << ProcModel.ItinsDef->getName() - << " does not have resources for itinerary class " - << SCI->ItinClassDef->getName() << '\n'); - } - } - else if (!SCI->InstRWs.empty()) { - // This class may have a default ReadWrite list which can be overriden by + if (!SCI->InstRWs.empty()) { + // This class has a default ReadWrite list which can be overriden by // InstRW definitions. Record *RWDef = 0; for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end(); @@ -905,6 +900,23 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, Writes, Reads); } } + if (Writes.empty()) { + // Check this processor's itinerary class resources. + for (RecIter II = ProcModel.ItinRWDefs.begin(), + IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) { + RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses"); + if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef) + != Matched.end()) { + SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), + Writes, Reads); + break; + } + } + if (Writes.empty()) { + DEBUG(dbgs() << ProcModel.ModelName + << " does not have resources for class " << SCI->Name << '\n'); + } + } // Sum resources across all operand writes. std::vector WriteProcResources; std::vector WriteLatencies; @@ -922,7 +934,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel, WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name); // If this Write is not referenced by a ReadAdvance, don't distinguish it // from other WriteLatency entries. - if (!SchedModels.hasReadOfWrite(SchedModels.getSchedWrite(WriteID).TheDef)) { + if (!SchedModels.hasReadOfWrite( + SchedModels.getSchedWrite(WriteID).TheDef)) { WriteID = 0; } WLEntry.WriteResourceID = WriteID; @@ -1138,7 +1151,7 @@ void SubtargetEmitter::EmitSchedClassTables(SchedClassTables &SchedTables, // The first class is always invalid. We no way to distinguish it except by // name and position. - assert(SchedModels.getSchedClass(0).Name == "NoItinerary" + assert(SchedModels.getSchedClass(0).Name == "NoInstrModel" && "invalid class not first"); OS << " {DBGFIELD(\"InvalidSchedClass\") " << MCSchedClassDesc::InvalidNumMicroOps @@ -1181,11 +1194,15 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) { OS << "\n"; OS << "static const llvm::MCSchedModel " << PI->ModelName << "(\n"; EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ','); - EmitProcessorProp(OS, PI->ModelDef, "MinLatency", ','); + EmitProcessorProp(OS, PI->ModelDef, "MicroOpBufferSize", ','); EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ','); EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ','); - EmitProcessorProp(OS, PI->ModelDef, "ILPWindow", ','); EmitProcessorProp(OS, PI->ModelDef, "MispredictPenalty", ','); + + OS << " " << (bool)(PI->ModelDef ? + PI->ModelDef->getValueAsBit("CompleteModel") : 0) + << ", // " << "CompleteModel\n"; + OS << " " << PI->Index << ", // Processor ID\n"; if (PI->hasInstrSchedModel()) OS << " " << PI->ModelName << "ProcResources" << ",\n" @@ -1195,7 +1212,7 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) { - SchedModels.schedClassBegin()) << ",\n"; else OS << " 0, 0, 0, 0, // No instruction-level machine model.\n"; - if (SchedModels.hasItineraryClasses()) + if (SchedModels.hasItineraries()) OS << " " << PI->ItinsDef->getName() << ");\n"; else OS << " 0); // No Itinerary\n"; @@ -1252,7 +1269,7 @@ void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) { << "#define DBGFIELD(x)\n" << "#endif\n"; - if (SchedModels.hasItineraryClasses()) { + if (SchedModels.hasItineraries()) { std::vector > ProcItinLists; // Emit the stage data EmitStageAndOperandCycleData(OS, ProcItinLists); @@ -1293,7 +1310,7 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName, SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) { if (SCI->Transitions.empty()) continue; - VariantClasses.push_back(SCI - SchedModels.schedClassBegin()); + VariantClasses.push_back(SCI->Index); } if (!VariantClasses.empty()) { OS << " switch (SchedClass) {\n"; @@ -1321,11 +1338,11 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName, for (std::vector::const_iterator TI = SC.Transitions.begin(), TE = SC.Transitions.end(); TI != TE; ++TI) { - OS << " if ("; if (*PI != 0 && !std::count(TI->ProcIndices.begin(), TI->ProcIndices.end(), *PI)) { continue; } + OS << " if ("; for (RecIter RI = TI->PredTerm.begin(), RE = TI->PredTerm.end(); RI != RE; ++RI) { if (RI != TI->PredTerm.begin()) @@ -1340,13 +1357,8 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName, if (*PI == 0) break; } - unsigned SCIdx = 0; - if (SC.ItinClassDef) - SCIdx = SchedModels.getSchedClassIdxForItin(SC.ItinClassDef); - else - SCIdx = SchedModels.findSchedClassIdx(SC.Writes, SC.Reads); - if (SCIdx != *VCI) - OS << " return " << SCIdx << ";\n"; + if (SC.isInferred()) + OS << " return " << SC.Index << ";\n"; OS << " break;\n"; } OS << " };\n"; @@ -1452,7 +1464,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { << Target << "WriteProcResTable, " << Target << "WriteLatencyTable, " << Target << "ReadAdvanceTable, "; - if (SchedModels.hasItineraryClasses()) { + if (SchedModels.hasItineraries()) { OS << '\n'; OS.indent(22); OS << Target << "Stages, " << Target << "OperandCycles, " @@ -1509,7 +1521,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "extern const llvm::MCReadAdvanceEntry " << Target << "ReadAdvanceTable[];\n"; - if (SchedModels.hasItineraryClasses()) { + if (SchedModels.hasItineraries()) { OS << "extern const llvm::InstrStage " << Target << "Stages[];\n"; OS << "extern const unsigned " << Target << "OperandCycles[];\n"; OS << "extern const unsigned " << Target << "ForwardingPaths[];\n"; @@ -1533,7 +1545,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { << Target << "WriteLatencyTable, " << Target << "ReadAdvanceTable, "; OS << '\n'; OS.indent(22); - if (SchedModels.hasItineraryClasses()) { + if (SchedModels.hasItineraries()) { OS << Target << "Stages, " << Target << "OperandCycles, " << Target << "ForwardingPaths, ";