From c74ad502cecf221e2cbfed86f79a93155247760a Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Thu, 5 Apr 2018 15:41:41 +0000 Subject: [MC][Tablegen] Allow models to describe the retire control unit for llvm-mca. This patch adds the ability to describe properties of the hardware retire control unit. Tablegen class RetireControlUnit has been added for this purpose (see TargetSchedule.td). A RetireControlUnit specifies the size of the reorder buffer, as well as the maximum number of opcodes that can be retired every cycle. A zero (or negative) value for the reorder buffer size means: "the size is unknown". If the size is unknown, then llvm-mca defaults it to the value of field SchedMachineModel::MicroOpBufferSize. A zero or negative number of opcodes retired per cycle means: "there is no restriction on the number of instructions that can be retired every cycle". Models can optionally specify an instance of RetireControlUnit. There can only be up-to one RetireControlUnit definition per scheduling model. Information related to the RCU (RetireControlUnit) is stored in (two new fields of) MCExtraProcessorInfo. llvm-mca loads that information when it initializes the DispatchUnit / RetireControlUnit (see Dispatch.h/Dispatch.cpp). This patch fixes PR36661. Differential Revision: https://reviews.llvm.org/D45259 llvm-svn: 329304 --- llvm/utils/TableGen/CodeGenSchedule.cpp | 26 +++++++++++++++++++++++++- llvm/utils/TableGen/CodeGenSchedule.h | 12 ++++++++++-- llvm/utils/TableGen/SubtargetEmitter.cpp | 17 +++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) (limited to 'llvm/utils/TableGen') diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp index cc28cdfe8f1..0c79da9f779 100644 --- a/llvm/utils/TableGen/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/CodeGenSchedule.cpp @@ -211,10 +211,34 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK, DEBUG(dbgs() << "\n+++ RESOURCE DEFINITIONS (collectProcResources) +++\n"); collectProcResources(); + // Collect optional processor description. + collectOptionalProcessorInfo(); + + checkCompleteness(); +} + +void CodeGenSchedModels::collectRetireControlUnits() { + RecVec Units = Records.getAllDerivedDefinitions("RetireControlUnit"); + + for (Record *RCU : Units) { + CodeGenProcModel &PM = getProcModel(RCU->getValueAsDef("SchedModel")); + if (PM.RetireControlUnit) { + PrintError(RCU->getLoc(), + "Expected a single RetireControlUnit definition"); + PrintNote(PM.RetireControlUnit->getLoc(), + "Previous definition of RetireControlUnit was here"); + } + PM.RetireControlUnit = RCU; + } +} + +/// Collect optional processor information. +void CodeGenSchedModels::collectOptionalProcessorInfo() { // Find register file definitions for each processor. collectRegisterFiles(); - checkCompleteness(); + // Collect processor RetireControlUnit descriptors if available. + collectRetireControlUnits(); } /// Gather all processor models. diff --git a/llvm/utils/TableGen/CodeGenSchedule.h b/llvm/utils/TableGen/CodeGenSchedule.h index 388249622b1..8379a929ee7 100644 --- a/llvm/utils/TableGen/CodeGenSchedule.h +++ b/llvm/utils/TableGen/CodeGenSchedule.h @@ -235,9 +235,13 @@ struct CodeGenProcModel { // List of Register Files. std::vector RegisterFiles; + // Optional Retire Control Unit definition. + Record *RetireControlUnit; + CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef, Record *IDef) : - Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef) {} + Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef), + RetireControlUnit(nullptr) {} bool hasItineraries() const { return !ItinsDef->getValueAsListOfDefs("IID").empty(); @@ -248,7 +252,7 @@ struct CodeGenProcModel { } bool hasExtraProcessorInfo() const { - return !RegisterFiles.empty(); + return RetireControlUnit || !RegisterFiles.empty(); } unsigned getProcResourceIdx(Record *PRDef) const; @@ -436,8 +440,12 @@ private: void collectSchedClasses(); + void collectRetireControlUnits(); + void collectRegisterFiles(); + void collectOptionalProcessorInfo(); + std::string createSchedClassName(Record *ItinClassDef, ArrayRef OperWrites, ArrayRef OperReads); diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 1af8181cbf3..3ded329c34e 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -608,6 +608,20 @@ void SubtargetEmitter::EmitProcessorResourceSubUnits( OS << "};\n"; } +static void EmitRetireControlUnitInfo(const CodeGenProcModel &ProcModel, + raw_ostream &OS) { + long ReorderBufferSize = 0, MaxRetirePerCycle = 0; + if (Record *RCU = ProcModel.RetireControlUnit) { + ReorderBufferSize = + std::max(ReorderBufferSize, RCU->getValueAsInt("ReorderBufferSize")); + MaxRetirePerCycle = + std::max(MaxRetirePerCycle, RCU->getValueAsInt("MaxRetirePerCycle")); + } + + OS << ReorderBufferSize << ", // ReorderBufferSize\n "; + OS << MaxRetirePerCycle << ", // MaxRetirePerCycle\n "; +} + static void EmitRegisterFileInfo(const CodeGenProcModel &ProcModel, unsigned NumRegisterFiles, unsigned NumCostEntries, raw_ostream &OS) { @@ -683,6 +697,9 @@ void SubtargetEmitter::EmitExtraProcessorInfo(const CodeGenProcModel &ProcModel, OS << "\nstatic const llvm::MCExtraProcessorInfo " << ProcModel.ModelName << "ExtraInfo = {\n "; + // Add information related to the retire control unit. + EmitRetireControlUnitInfo(ProcModel, OS); + // Add information related to the register files (i.e. where to find register // file descriptors and register costs). EmitRegisterFileInfo(ProcModel, ProcModel.RegisterFiles.size(), -- cgit v1.2.3