X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FMC%2FMCSchedule.h;h=0c71ee513500ce2f101da62daf768fc3a2f26228;hb=ff233c9e5c3e439fd1eed84b9a9e88a5370572db;hp=49e3fee9c241e61961387ec7981af1dd48f459b1;hpb=2661b411ccc81b1fe19194d3f43b2630cbef3f28;p=oota-llvm.git diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 49e3fee9c24..0c71ee51350 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -16,17 +16,111 @@ #define LLVM_MC_MCSCHEDMODEL_H #include "llvm/Support/DataTypes.h" +#include namespace llvm { struct InstrItinerary; +/// Define a kind of processor resource that will be modeled by the scheduler. +struct MCProcResourceDesc { +#ifndef NDEBUG + const char *Name; +#endif + unsigned NumUnits; // Number of resource of this kind + unsigned SuperIdx; // Index of the resources kind that contains this kind. + + // Buffered resources may be consumed at some indeterminate cycle after + // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered + // resources always consume their resource some fixed number of cycles after + // dispatch (e.g. for instruction interlocking that may stall the pipeline). + bool IsBuffered; + + bool operator==(const MCProcResourceDesc &Other) const { + return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx + && IsBuffered == Other.IsBuffered; + } +}; + +/// Identify one of the processor resource kinds consumed by a particular +/// scheduling class for the specified number of cycles. +struct MCWriteProcResEntry { + unsigned ProcResourceIdx; + unsigned Cycles; + + bool operator==(const MCWriteProcResEntry &Other) const { + return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles; + } +}; + +/// Specify the latency in cpu cycles for a particular scheduling class and def +/// index. -1 indicates an invalid latency. Heuristics would typically consider +/// an instruction with invalid latency to have infinite latency. Also identify +/// the WriteResources of this def. When the operand expands to a sequence of +/// writes, this ID is the last write in the sequence. +struct MCWriteLatencyEntry { + int Cycles; + unsigned WriteResourceID; + + bool operator==(const MCWriteLatencyEntry &Other) const { + return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID; + } +}; + +/// Specify the number of cycles allowed after instruction issue before a +/// particular use operand reads its registers. This effectively reduces the +/// write's latency. Here we allow negative cycles for corner cases where +/// latency increases. This rule only applies when the entry's WriteResource +/// matches the write's WriteResource. +/// +/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by +/// WriteResourceIdx. +struct MCReadAdvanceEntry { + unsigned UseIdx; + unsigned WriteResourceID; + int Cycles; + + bool operator==(const MCReadAdvanceEntry &Other) const { + return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID + && Cycles == Other.Cycles; + } +}; + +/// Summarize the scheduling resources required for an instruction of a +/// particular scheduling class. +/// +/// Defined as an aggregate struct for creating tables with initializer lists. +struct MCSchedClassDesc { + static const unsigned short InvalidNumMicroOps = UINT16_MAX; + static const unsigned short VariantNumMicroOps = UINT16_MAX - 1; + +#ifndef NDEBUG + const char* Name; +#endif + unsigned short NumMicroOps; + bool BeginGroup; + bool EndGroup; + unsigned WriteProcResIdx; // First index into WriteProcResTable. + unsigned NumWriteProcResEntries; + unsigned WriteLatencyIdx; // First index into WriteLatencyTable. + unsigned NumWriteLatencyEntries; + unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable. + unsigned NumReadAdvanceEntries; + + bool isValid() const { + return NumMicroOps != InvalidNumMicroOps; + } + bool isVariant() const { + return NumMicroOps == VariantNumMicroOps; + } +}; + /// 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 +/// optionally refers to scheduler resource tables and itinerary +/// tables. Scheduler resource 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 @@ -78,9 +172,17 @@ public: unsigned HighLatency; static const unsigned DefaultHighLatency = 10; -private: - // TODO: Add a reference to proc resource types and sched resource tables. + // MispredictPenalty is the typical number of extra cycles the processor + // takes to recover from a branch misprediction. + unsigned MispredictPenalty; + static const unsigned DefaultMispredictPenalty = 10; +private: + unsigned ProcID; + const MCProcResourceDesc *ProcResourceTable; + const MCSchedClassDesc *SchedClassTable; + unsigned NumProcResourceKinds; + unsigned NumSchedClasses; // Instruction itinerary tables used by InstrItineraryData. friend class InstrItineraryData; const InstrItinerary *InstrItineraries; @@ -90,17 +192,50 @@ public: // 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), + MCSchedModel(): IssueWidth(DefaultIssueWidth), MinLatency(DefaultMinLatency), LoadLatency(DefaultLoadLatency), HighLatency(DefaultHighLatency), - InstrItineraries(0) {} + MispredictPenalty(DefaultMispredictPenalty), + ProcID(0), ProcResourceTable(0), SchedClassTable(0), + NumProcResourceKinds(0), NumSchedClasses(0), + InstrItineraries(0) { + (void)NumProcResourceKinds; + (void)NumSchedClasses; + } // Table-gen driven ctor. - MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, + MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, + unsigned pi, const MCProcResourceDesc *pr, + const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, const InstrItinerary *ii): IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), - InstrItineraries(ii){} + MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), + SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), + InstrItineraries(ii) {} + + unsigned getProcessorID() const { return ProcID; } + + /// Does this machine model include instruction-level scheduling. + bool hasInstrSchedModel() const { return SchedClassTable; } + + unsigned getNumProcResourceKinds() const { + return NumProcResourceKinds; + } + + const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const { + assert(hasInstrSchedModel() && "No scheduling machine model"); + + assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx"); + return &ProcResourceTable[ProcResourceIdx]; + } + + const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const { + assert(hasInstrSchedModel() && "No scheduling machine model"); + + assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx"); + return &SchedClassTable[SchedClassIdx]; + } }; } // End llvm namespace