diff options
author | Andrew Trick <atrick@apple.com> | 2012-07-07 04:00:00 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2012-07-07 04:00:00 +0000 |
commit | 2661b411ccc81b1fe19194d3f43b2630cbef3f28 (patch) | |
tree | 0decaebaee6c3a1a9d42df6b5619de1ffb2fac7d | |
parent | 06495cd7f2a91c4f659eac5e55b1c08b014d0a08 (diff) |
I'm introducing a new machine model to simultaneously allow simple
subtarget CPU descriptions and support new features of
MachineScheduler.
MachineModel has three categories of data:
1) Basic properties for coarse grained instruction cost model.
2) Scheduler Read/Write resources for simple per-opcode and operand cost model (TBD).
3) Instruction itineraties for detailed per-cycle reservation tables.
These will all live side-by-side. Any subtarget can use any
combination of them. Instruction itineraries will not change in the
near term. In the long run, I expect them to only be relevant for
in-order VLIW machines that have complex contraints and require a
precise scheduling/bundling model. Once itineraries are only actively
used by VLIW-ish targets, they could be replaced by something more
appropriate for those targets.
This tablegen backend rewrite sets things up for introducing
MachineModel type #2: per opcode/operand cost model.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159891 91177308-0d34-0410-b5e6-96231b3b80d8
27 files changed, 904 insertions, 502 deletions
diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h index d8587068ae..65d1559ac6 100644 --- a/include/llvm/MC/MCInstrItineraries.h +++ b/include/llvm/MC/MCInstrItineraries.h @@ -16,6 +16,7 @@ #ifndef LLVM_MC_MCINSTRITINERARIES_H #define LLVM_MC_MCINSTRITINERARIES_H +#include "llvm/MC/MCSchedule.h" #include <algorithm> namespace llvm { @@ -104,81 +105,12 @@ struct InstrItinerary { //===----------------------------------------------------------------------===// -/// Instruction itinerary properties - These properties provide general -/// information about the microarchitecture to the scheduler. -/// -struct InstrItineraryProps { - // IssueWidth is the maximum number of instructions that may be scheduled in - // the same per-cycle group. - unsigned IssueWidth; - static const unsigned DefaultIssueWidth = 1; - - // MinLatency is the minimum latency between a register write - // followed by a data dependent read. This determines which - // instructions may be scheduled in the same per-cycle group. This - // is distinct from *expected* latency, which determines the likely - // critical path but does not guarantee a pipeline - // hazard. MinLatency can always be overridden by the number of - // InstrStage cycles. - // - // (-1) Standard in-order processor. - // Use InstrItinerary OperandCycles as MinLatency. - // If no OperandCycles exist, then use the cycle of the last InstrStage. - // - // (0) Out-of-order processor, or in-order with bundled dependencies. - // RAW dependencies may be dispatched in the same cycle. - // Optional InstrItinerary OperandCycles provides expected latency. - // - // (>0) In-order processor with variable latencies. - // Use the greater of this value or the cycle of the last InstrStage. - // Optional InstrItinerary OperandCycles provides expected latency. - // TODO: can't yet specify both min and expected latency per operand. - int MinLatency; - static const unsigned DefaultMinLatency = -1; - - // LoadLatency is the expected latency of load instructions. - // - // If MinLatency >= 0, this may be overriden for individual load opcodes by - // InstrItinerary OperandCycles. - unsigned LoadLatency; - static const unsigned DefaultLoadLatency = 4; - - // HighLatency is the expected latency of "very high latency" operations. - // See TargetInstrInfo::isHighLatencyDef(). - // By default, this is set to an arbitrarily high number of cycles - // likely to have some impact on scheduling heuristics. - // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles. - unsigned HighLatency; - static const unsigned DefaultHighLatency = 10; - - // Default's must be specified as static const literals so that tablegenerated - // target code can use it in static initializers. The defaults need to be - // initialized in this default ctor because some clients directly instantiate - // InstrItineraryData instead of using a generated itinerary. - InstrItineraryProps(): IssueWidth(DefaultMinLatency), - MinLatency(DefaultMinLatency), - LoadLatency(DefaultLoadLatency), - HighLatency(DefaultHighLatency) {} - - InstrItineraryProps(unsigned iw, int ml, unsigned ll, unsigned hl): - IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl) {} -}; - -//===----------------------------------------------------------------------===// -/// Encapsulate all subtarget specific information for scheduling for use with -/// SubtargetInfoKV. -struct InstrItinerarySubtargetValue { - const InstrItineraryProps *Props; - const InstrItinerary *Itineraries; -}; - -//===----------------------------------------------------------------------===// /// Instruction itinerary Data - Itinerary data supplied by a subtarget to be /// used by a target. /// class InstrItineraryData { public: - InstrItineraryProps Props; + const MCSchedModel *SchedModel; ///< Basic machine properties. const InstrStage *Stages; ///< Array of stages selected const unsigned *OperandCycles; ///< Array of operand cycles selected const unsigned *Forwardings; ///< Array of pipeline forwarding pathes @@ -186,13 +118,14 @@ public: /// Ctors. /// - InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0), - Itineraries(0) {} + InstrItineraryData() : SchedModel(&MCSchedModel::DefaultSchedModel), + Stages(0), OperandCycles(0), + Forwardings(0), Itineraries(0) {} - InstrItineraryData(const InstrItineraryProps *P, const InstrStage *S, - const unsigned *OS, const unsigned *F, - const InstrItinerary *I) - : Props(*P), Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {} + InstrItineraryData(const MCSchedModel *SM, const InstrStage *S, + const unsigned *OS, const unsigned *F) + : SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F), + Itineraries(SchedModel->InstrItineraries) {} /// isEmpty - Returns true if there are no itineraries. /// @@ -232,13 +165,9 @@ public: /// then it defaults to one cycle. unsigned getStageLatency(unsigned ItinClassIndx) const { // If the target doesn't provide itinerary information, use a simple - // non-zero default value for all instructions. Some target's provide a - // dummy (Generic) itinerary which should be handled as if it's itinerary is - // empty. We identify this by looking for a reference to stage zero (invalid - // stage). This is different from beginStage == endStage != 0, which could - // be used for zero-latency pseudo ops. - if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0) - return (Props.MinLatency < 0) ? 1 : Props.MinLatency; + // non-zero default value for all instructions. + if (isEmpty()) + return SchedModel->MinLatency < 0 ? 1 : SchedModel->MinLatency; // Calculate the maximum completion time for any stage. unsigned Latency = 0, StartCycle = 0; diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h new file mode 100644 index 0000000000..49e3fee9c2 --- /dev/null +++ b/include/llvm/MC/MCSchedule.h @@ -0,0 +1,108 @@ +//===-- llvm/MC/MCSchedule.h - Scheduling -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the classes used to describe a subtarget's machine model +// for scheduling and other instruction cost heuristics. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSCHEDMODEL_H +#define LLVM_MC_MCSCHEDMODEL_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +struct InstrItinerary; + +/// Machine model for scheduling, bundling, and heuristics. +/// +/// The machine model directly provides basic information about the +/// microarchitecture to the scheduler in the form of properties. It also +/// optionally refers to scheduler resources tables and itinerary +/// tables. Scheduler resources tables model the latency and cost for each +/// instruction type. Itinerary tables are an independant mechanism that +/// provides a detailed reservation table describing each cycle of instruction +/// execution. Subtargets may define any or all of the above categories of data +/// depending on the type of CPU and selected scheduler. +class MCSchedModel { +public: + static MCSchedModel DefaultSchedModel; // For unknown processors. + + // IssueWidth is the maximum number of instructions that may be scheduled in + // the same per-cycle group. + unsigned IssueWidth; + static const unsigned DefaultIssueWidth = 1; + + // MinLatency is the minimum latency between a register write + // followed by a data dependent read. This determines which + // instructions may be scheduled in the same per-cycle group. This + // is distinct from *expected* latency, which determines the likely + // critical path but does not guarantee a pipeline + // hazard. MinLatency can always be overridden by the number of + // InstrStage cycles. + // + // (-1) Standard in-order processor. + // Use InstrItinerary OperandCycles as MinLatency. + // If no OperandCycles exist, then use the cycle of the last InstrStage. + // + // (0) Out-of-order processor, or in-order with bundled dependencies. + // RAW dependencies may be dispatched in the same cycle. + // Optional InstrItinerary OperandCycles provides expected latency. + // + // (>0) In-order processor with variable latencies. + // Use the greater of this value or the cycle of the last InstrStage. + // Optional InstrItinerary OperandCycles provides expected latency. + // TODO: can't yet specify both min and expected latency per operand. + int MinLatency; + static const unsigned DefaultMinLatency = -1; + + // LoadLatency is the expected latency of load instructions. + // + // If MinLatency >= 0, this may be overriden for individual load opcodes by + // InstrItinerary OperandCycles. + unsigned LoadLatency; + static const unsigned DefaultLoadLatency = 4; + + // HighLatency is the expected latency of "very high latency" operations. + // See TargetInstrInfo::isHighLatencyDef(). + // By default, this is set to an arbitrarily high number of cycles + // likely to have some impact on scheduling heuristics. + // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles. + unsigned HighLatency; + static const unsigned DefaultHighLatency = 10; + +private: + // TODO: Add a reference to proc resource types and sched resource tables. + + // Instruction itinerary tables used by InstrItineraryData. + friend class InstrItineraryData; + const InstrItinerary *InstrItineraries; + +public: + // Default's must be specified as static const literals so that tablegenerated + // target code can use it in static initializers. The defaults need to be + // initialized in this default ctor because some clients directly instantiate + // MCSchedModel instead of using a generated itinerary. + MCSchedModel(): IssueWidth(DefaultMinLatency), + MinLatency(DefaultMinLatency), + LoadLatency(DefaultLoadLatency), + HighLatency(DefaultHighLatency), + InstrItineraries(0) {} + + // Table-gen driven ctor. + MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, + const InstrItinerary *ii): + IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), + InstrItineraries(ii){} +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 82730d469e..31d632de60 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -30,9 +30,9 @@ class MCSubtargetInfo { std::string TargetTriple; // Target triple const SubtargetFeatureKV *ProcFeatures; // Processor feature list const SubtargetFeatureKV *ProcDesc; // Processor descriptions - const SubtargetInfoKV *ProcItins; // Scheduling itineraries - const InstrStage *Stages; // Instruction stages - const unsigned *OperandCycles; // Operand cycles + const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model + const InstrStage *Stages; // Instruction itinerary stages + const unsigned *OperandCycles; // Itinerary operand cycles const unsigned *ForwardingPaths; // Forwarding paths unsigned NumFeatures; // Number of processor features unsigned NumProcs; // Number of processors @@ -42,7 +42,8 @@ public: void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, const SubtargetFeatureKV *PF, const SubtargetFeatureKV *PD, - const SubtargetInfoKV *PI, const InstrStage *IS, + const SubtargetInfoKV *ProcSched, + const InstrStage *IS, const unsigned *OC, const unsigned *FP, unsigned NF, unsigned NP); @@ -69,6 +70,10 @@ public: /// bits. This version will also change all implied bits. uint64_t ToggleFeature(StringRef FS); + /// getSchedModelForCPU - Get the machine model of a CPU. + /// + MCSchedModel *getSchedModelForCPU(StringRef CPU) const; + /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. /// InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 5227bab4cf..440cf65d47 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -933,6 +933,10 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> { // string Name = n; + // SchedModel - The machine model for scheduling and instruction cost. + // + SchedMachineModel SchedModel = NoSchedModel; + // ProcItin - The scheduling information for the target processor. // ProcessorItineraries ProcItin = pi; @@ -941,6 +945,14 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> { list<SubtargetFeature> Features = f; } +// ProcessorModel allows subtargets to specify the more general +// SchedMachineModel instead if a ProcessorItinerary. Subtargets will +// gradually move to this newer form. +class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f> + : Processor<n, NoItineraries, f> { + let SchedModel = m; +} + //===----------------------------------------------------------------------===// // Pull in the common support for calling conventions. // diff --git a/include/llvm/Target/TargetItinerary.td b/include/llvm/Target/TargetItinerary.td new file mode 100644 index 0000000000..cc74006dc9 --- /dev/null +++ b/include/llvm/Target/TargetItinerary.td @@ -0,0 +1,136 @@ +//===- TargetItinerary.td - Target Itinierary Description --*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the target-independent scheduling interfaces +// which should be implemented by each target that uses instruction +// itineraries for scheduling. Itineraries are details reservation +// tables for each instruction class. They are most appropriate for +// in-order machine with complicated scheduling or bundling constraints. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Processor functional unit - These values represent the function units +// available across all chip sets for the target. Eg., IntUnit, FPUnit, ... +// These may be independent values for each chip set or may be shared across +// all chip sets of the target. Each functional unit is treated as a resource +// during scheduling and has an affect instruction order based on availability +// during a time interval. +// +class FuncUnit; + +//===----------------------------------------------------------------------===// +// Pipeline bypass / forwarding - These values specifies the symbolic names of +// pipeline bypasses which can be used to forward results of instructions +// that are forwarded to uses. +class Bypass; +def NoBypass : Bypass; + +class ReservationKind<bits<1> val> { + int Value = val; +} + +def Required : ReservationKind<0>; +def Reserved : ReservationKind<1>; + +//===----------------------------------------------------------------------===// +// Instruction stage - These values represent a non-pipelined step in +// the execution of an instruction. Cycles represents the number of +// discrete time slots needed to complete the stage. Units represent +// the choice of functional units that can be used to complete the +// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many +// cycles should elapse from the start of this stage to the start of +// the next stage in the itinerary. For example: +// +// A stage is specified in one of two ways: +// +// InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles +// InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit +// + +class InstrStage<int cycles, list<FuncUnit> units, + int timeinc = -1, + ReservationKind kind = Required> { + int Cycles = cycles; // length of stage in machine cycles + list<FuncUnit> Units = units; // choice of functional units + int TimeInc = timeinc; // cycles till start of next stage + int Kind = kind.Value; // kind of FU reservation +} + +//===----------------------------------------------------------------------===// +// Instruction itinerary - An itinerary represents a sequential series of steps +// required to complete an instruction. Itineraries are represented as lists of +// instruction stages. +// + +//===----------------------------------------------------------------------===// +// Instruction itinerary classes - These values represent 'named' instruction +// itinerary. Using named itineraries simplifies managing groups of +// instructions across chip sets. An instruction uses the same itinerary class +// across all chip sets. Thus a new chip set can be added without modifying +// instruction information. +// +class InstrItinClass; +def NoItinerary : InstrItinClass; + +//===----------------------------------------------------------------------===// +// Instruction itinerary data - These values provide a runtime map of an +// instruction itinerary class (name) to its itinerary data. +// +// NumMicroOps represents the number of micro-operations that each instruction +// in the class are decoded to. If the number is zero, then it means the +// instruction can decode into variable number of micro-ops and it must be +// determined dynamically. This directly relates to the itineraries +// global IssueWidth property, which constrains the number of microops +// that can issue per cycle. +// +// OperandCycles are optional "cycle counts". They specify the cycle after +// instruction issue the values which correspond to specific operand indices +// are defined or read. Bypasses are optional "pipeline forwarding pathes", if +// a def by an instruction is available on a specific bypass and the use can +// read from the same bypass, then the operand use latency is reduced by one. +// +// InstrItinData<IIC_iLoad_i , [InstrStage<1, [A9_Pipe1]>, +// InstrStage<1, [A9_AGU]>], +// [3, 1], [A9_LdBypass]>, +// InstrItinData<IIC_iMVNr , [InstrStage<1, [A9_Pipe0, A9_Pipe1]>], +// [1, 1], [NoBypass, A9_LdBypass]>, +// +// In this example, the instruction of IIC_iLoadi reads its input on cycle 1 +// (after issue) and the result of the load is available on cycle 3. The result +// is available via forwarding path A9_LdBypass. If it's used by the first +// source operand of instructions of IIC_iMVNr class, then the operand latency +// is reduced by 1. +class InstrItinData<InstrItinClass Class, list<InstrStage> stages, + list<int> operandcycles = [], + list<Bypass> bypasses = [], int uops = 1> { + InstrItinClass TheClass = Class; + int NumMicroOps = uops; + list<InstrStage> Stages = stages; + list<int> OperandCycles = operandcycles; + list<Bypass> Bypasses = bypasses; +} + +//===----------------------------------------------------------------------===// +// Processor itineraries - These values represent the set of all itinerary +// classes for a given chip set. +// +// Set property values to -1 to use the default. +// See InstrItineraryProps for comments and defaults. +class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp, + list<InstrItinData> iid> { + list<FuncUnit> FU = fu; + list<Bypass> BP = bp; + list<InstrItinData> IID = iid; +} + +// NoItineraries - A marker that can be used by processors without schedule +// info. Subtargets using NoItineraries can bypass the scheduler's +// expensive HazardRecognizer because no reservation table is needed. +def NoItineraries : ProcessorItineraries<[], [], []>; diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index caa5a84c83..5bbed58c87 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -12,141 +12,29 @@ // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// Processor functional unit - These values represent the function units -// available across all chip sets for the target. Eg., IntUnit, FPUnit, ... -// These may be independent values for each chip set or may be shared across -// all chip sets of the target. Each functional unit is treated as a resource -// during scheduling and has an affect instruction order based on availability -// during a time interval. -// -class FuncUnit; - -//===----------------------------------------------------------------------===// -// Pipeline bypass / forwarding - These values specifies the symbolic names of -// pipeline bypasses which can be used to forward results of instructions -// that are forwarded to uses. -class Bypass; -def NoBypass : Bypass; - -class ReservationKind<bits<1> val> { - int Value = val; -} - -def Required : ReservationKind<0>; -def Reserved : ReservationKind<1>; - -//===----------------------------------------------------------------------===// -// Instruction stage - These values represent a non-pipelined step in -// the execution of an instruction. Cycles represents the number of -// discrete time slots needed to complete the stage. Units represent -// the choice of functional units that can be used to complete the -// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many -// cycles should elapse from the start of this stage to the start of -// the next stage in the itinerary. For example: -// -// A stage is specified in one of two ways: -// -// InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles -// InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit -// +include "llvm/Target/TargetItinerary.td" -class InstrStage<int cycles, list<FuncUnit> units, - int timeinc = -1, - ReservationKind kind = Required> { - int Cycles = cycles; // length of stage in machine cycles - list<FuncUnit> Units = units; // choice of functional units - int TimeInc = timeinc; // cycles till start of next stage - int Kind = kind.Value; // kind of FU reservation -} - -//===----------------------------------------------------------------------===// -// Instruction itinerary - An itinerary represents a sequential series of steps -// required to complete an instruction. Itineraries are represented as lists of -// instruction stages. +// The SchedMachineModel is defined by subtargets for three categories of data: +// 1) Basic properties for coarse grained instruction cost model. +// 2) Scheduler Read/Write resources for simple per-opcode cost model. +// 3) Instruction itineraties for detailed reservation tables. // - -//===----------------------------------------------------------------------===// -// Instruction itinerary classes - These values represent 'named' instruction -// itinerary. Using named itineraries simplifies managing groups of -// instructions across chip sets. An instruction uses the same itinerary class -// across all chip sets. Thus a new chip set can be added without modifying -// instruction information. -// -class InstrItinClass; -def NoItinerary : InstrItinClass; - -//===----------------------------------------------------------------------===// -// Instruction itinerary data - These values provide a runtime map of an -// instruction itinerary class (name) to its itinerary data. -// -// NumMicroOps represents the number of micro-operations that each instruction -// in the class are decoded to. If the number is zero, then it means the -// instruction can decode into variable number of micro-ops and it must be -// determined dynamically. This directly relates to the itineraries -// global IssueWidth property, which constrains the number of microops -// that can issue per cycle. -// -// OperandCycles are optional "cycle counts". They specify the cycle after -// instruction issue the values which correspond to specific operand indices -// are defined or read. Bypasses are optional "pipeline forwarding pathes", if -// a def by an instruction is available on a specific bypass and the use can -// read from the same bypass, then the operand use latency is reduced by one. -// -// InstrItinData<IIC_iLoad_i , [InstrStage<1, [A9_Pipe1]>, -// InstrStage<1, [A9_AGU]>], -// [3, 1], [A9_LdBypass]>, -// InstrItinData<IIC_iMVNr , [InstrStage<1, [A9_Pipe0, A9_Pipe1]>], -// [1, 1], [NoBypass, A9_LdBypass]>, -// -// In this example, the instruction of IIC_iLoadi reads its input on cycle 1 -// (after issue) and the result of the load is available on cycle 3. The result -// is available via forwarding path A9_LdBypass. If it's used by the first -// source operand of instructions of IIC_iMVNr class, then the operand latency -// is reduced by 1. -class InstrItinData<InstrItinClass Class, list<InstrStage> stages, - list<int> operandcycles = [], - list<Bypass> bypasses = [], int uops = 1> { - InstrItinClass TheClass = Class; - int NumMicroOps = uops; - list<InstrStage> Stages = stages; - list<int> OperandCycles = operandcycles; - list<Bypass> Bypasses = bypasses; -} - -//===----------------------------------------------------------------------===// -// Processor itineraries - These values represent the set of all itinerary -// classes for a given chip set. -// -// Set property values to -1 to use the default. -// See InstrItineraryProps for comments and defaults. -class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp, - list<InstrItinData> iid> { +// Default values for basic properties are defined in MCSchedModel. "-1" +// indicates that the property is not overriden by the target description. +class SchedMachineModel { int IssueWidth = -1; // Max instructions that may be scheduled per cycle. int MinLatency = -1; // Determines which instrucions are allowed in a group. // (-1) inorder (0) ooo, (1): inorder +var latencies. int LoadLatency = -1; // Cycles for loads to access the cache. int HighLatency = -1; // Approximation of cycles for "high latency" ops. - list<FuncUnit> FU = fu; - list<Bypass> BP = bp; - list<InstrItinData> IID = iid; -} + ProcessorItineraries Itineraries = NoItineraries; -// NoItineraries - A marker that can be used by processors without schedule -// info. Subtargets using NoItineraries can bypass the scheduler's -// expensive HazardRecognizer because no reservation table is needed. -def NoItineraries : ProcessorItineraries<[], [], []>; + bit NoModel = 0; // Special tag to indicate missing machine model. +} -// Processor itineraries with non-unit issue width. This allows issue -// width to be explicity specified at the beginning of the itinerary. -class MultiIssueItineraries<int issuewidth, int minlatency, - int loadlatency, int highlatency, - list<FuncUnit> fu, list<Bypass> bp, - list<InstrItinData> iid> - : ProcessorItineraries<fu, bp, iid> { - let IssueWidth = issuewidth; - let MinLatency = minlatency; - let LoadLatency = loadlatency; - let HighLatency = highlatency; +def NoSchedModel : SchedMachineModel { + let NoModel = 1; } + +// TODO: Define classes for processor and scheduler resources. diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 847bf1e76e..098ec4741f 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -403,7 +403,8 @@ public: /// getIssueWidth - Return the max instructions per scheduling group. unsigned getIssueWidth() const { - return InstrItins ? InstrItins->Props.IssueWidth : 1; + return (InstrItins && InstrItins->SchedModel) + ? InstrItins->SchedModel->IssueWidth : 1; } /// getNumMicroOps - Return the number of issue slots required for this MI. diff --git a/lib/CodeGen/ScoreboardHazardRecognizer.cpp b/lib/CodeGen/ScoreboardHazardRecognizer.cpp index 7110b7566a..e675366485 100644 --- a/lib/CodeGen/ScoreboardHazardRecognizer.cpp +++ b/lib/CodeGen/ScoreboardHazardRecognizer.cpp @@ -72,10 +72,12 @@ ScoreboardHazardRecognizer(const InstrItineraryData *II, ReservedScoreboard.reset(ScoreboardDepth); RequiredScoreboard.reset(ScoreboardDepth); + // If MaxLookAhead is not set above, then we are not enabled. if (!isEnabled()) DEBUG(dbgs() << "Disabled scoreboard hazard recognizer\n"); else { - IssueWidth = ItinData->Props.IssueWidth; + // A nonempty itinerary must have a SchedModel. + IssueWidth = ItinData->SchedModel->IssueWidth; DEBUG(dbgs() << "Using scoreboard hazard recognizer: Depth = " << ScoreboardDepth << '\n'); } diff --git a/lib/CodeGen/SelectionDAG/ResourcePriorityQueue.cpp b/lib/CodeGen/SelectionDAG/ResourcePriorityQueue.cpp index 01622cb295..c3794d5f78 100644 --- a/lib/CodeGen/SelectionDAG/ResourcePriorityQueue.cpp +++ b/lib/CodeGen/SelectionDAG/ResourcePriorityQueue.cpp @@ -318,7 +318,7 @@ void ResourcePriorityQueue:: |