//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "subtarget-emitter"
-
#include "CodeGenTarget.h"
#include "CodeGenSchedule.h"
#include "llvm/ADT/STLExtras.h"
#include <vector>
using namespace llvm;
+#define DEBUG_TYPE "subtarget-emitter"
+
namespace {
class SubtargetEmitter {
// Each processor has a SchedClassDesc table with an entry for each SchedClass.
OS << "\n";
OS << "static const llvm::InstrItinerary ";
if (ItinList.empty()) {
- OS << '*' << Name << " = 0;\n";
+ OS << '*' << Name << " = nullptr;\n";
continue;
}
for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e; ++i) {
Record *PRDef = ProcModel.ProcResourceDefs[i];
- Record *SuperDef = 0;
+ Record *SuperDef = nullptr;
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");
}
}
SuperIdx = ProcModel.getProcResourceIdx(SuperDef);
}
NumUnits = PRDef->getValueAsInt("NumUnits");
- IsBuffered = PRDef->getValueAsBit("Buffered");
}
// Emit the ProcResourceDesc
if (i+1 == e)
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";
if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes"))
return SchedWrite.TheDef;
- Record *AliasDef = 0;
+ Record *AliasDef = nullptr;
for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end();
AI != AE; ++AI) {
const CodeGenSchedRW &AliasRW =
return AliasDef;
// Check this processor's list of write resources.
- Record *ResDef = 0;
+ Record *ResDef = nullptr;
for (RecIter WRI = ProcModel.WriteResDefs.begin(),
WRE = ProcModel.WriteResDefs.end(); WRI != WRE; ++WRI) {
if (!(*WRI)->isSubClassOf("WriteRes"))
return SchedRead.TheDef;
// Check this processor's list of aliases for SchedRead.
- Record *AliasDef = 0;
+ Record *AliasDef = nullptr;
for (RecIter AI = SchedRead.Aliases.begin(), AE = SchedRead.Aliases.end();
AI != AE; ++AI) {
const CodeGenSchedRW &AliasRW =
return AliasDef;
// Check this processor's ReadAdvanceList.
- Record *ResDef = 0;
+ Record *ResDef = nullptr;
for (RecIter RAI = ProcModel.ReadAdvanceDefs.begin(),
RAE = ProcModel.ReadAdvanceDefs.end(); RAI != RAE; ++RAI) {
if (!(*RAI)->isSubClassOf("ReadAdvance"))
}
// 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<int64_t> &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");
- }
+ 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");
RecIter SubI = SubResources.begin(), SubE = SubResources.end();
if (!SCI->InstRWs.empty()) {
// This class has a default ReadWrite list which can be overriden by
// InstRW definitions.
- Record *RWDef = 0;
+ Record *RWDef = nullptr;
for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end();
RWI != RWE; ++RWI) {
Record *RWModelDef = (*RWI)->getValueAsDef("SchedModel");
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, "LoopMicroOpBufferSize", ',');
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("PostRAScheduler") : 0)
+ << ", // " << "PostRAScheduler\n";
+
+ 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"
for (std::vector<CodeGenSchedTransition>::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())
if (NumFeatures)
OS << Target << "FeatureKV, ";
else
- OS << "0, ";
+ OS << "None, ";
if (NumProcs)
OS << Target << "SubTypeKV, ";
else
- OS << "0, ";
+ OS << "None, ";
OS << '\n'; OS.indent(22);
OS << Target << "ProcSchedKV, "
<< Target << "WriteProcResTable, "
OS << '\n'; OS.indent(22);
OS << Target << "Stages, "
<< Target << "OperandCycles, "
- << Target << "ForwardingPaths, ";
+ << Target << "ForwardingPaths";
} else
- OS << "0, 0, 0, ";
- OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
+ OS << "0, 0, 0";
+ OS << ");\n}\n\n";
OS << "} // End llvm namespace \n";
OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
OS << "#include \"llvm/Support/Debug.h\"\n";
- OS << "#include \"llvm/Support/raw_ostream.h\"\n";
ParseFeaturesFunction(OS, NumFeatures, NumProcs);
OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
<< "StringRef FS);\n"
<< "public:\n"
<< " unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *DefMI,"
- << " const TargetSchedModel *SchedModel) const;\n"
+ << " const TargetSchedModel *SchedModel) const override;\n"
<< " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
<< " const;\n"
<< "};\n";
<< " : TargetSubtargetInfo() {\n"
<< " InitMCSubtargetInfo(TT, CPU, FS, ";
if (NumFeatures)
- OS << Target << "FeatureKV, ";
+ OS << "makeArrayRef(" << Target << "FeatureKV, " << NumFeatures << "), ";
else
- OS << "0, ";
+ OS << "None, ";
if (NumProcs)
- OS << Target << "SubTypeKV, ";
+ OS << "makeArrayRef(" << Target << "SubTypeKV, " << NumProcs << "), ";
else
- OS << "0, ";
+ OS << "None, ";
OS << '\n'; OS.indent(22);
OS << Target << "ProcSchedKV, "
<< Target << "WriteProcResTable, "
if (SchedModels.hasItineraries()) {
OS << Target << "Stages, "
<< Target << "OperandCycles, "
- << Target << "ForwardingPaths, ";
+ << Target << "ForwardingPaths";
} else
- OS << "0, 0, 0, ";
- OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
+ OS << "0, 0, 0";
+ OS << ");\n}\n\n";
EmitSchedModelHelpers(ClassName, OS);