This patch fails -Wunused-private-field on release builds.<br><br>/Users/craig/Development/clang/llvm/include/llvm/MC/MCSchedule.h:176:12: error: private field 'NumProcResourceKinds' is not used [-Werror,-Wunused-private-field]<br>
unsigned NumProcResourceKinds;<br> ^<br>/Users/craig/Development/clang/llvm/include/llvm/MC/MCSchedule.h:177:12: error: private field 'NumSchedClasses' is not used [-Werror,-Wunused-private-field]<br> unsigned NumSchedClasses;<br>
<br><br><div class="gmail_quote">On Fri, Sep 14, 2012 at 1:26 PM, Andrew Trick <span dir="ltr"><<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: atrick<br>
Date: Fri Sep 14 15:26:41 2012<br>
New Revision: 163933<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=163933&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=163933&view=rev</a><br>
Log:<br>
Define MC data tables for the new scheduling machine model.<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/MC/MCSchedule.h<br>
llvm/trunk/include/llvm/MC/MCSubtargetInfo.h<br>
llvm/trunk/lib/MC/MCSubtargetInfo.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCSchedule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSchedule.h?rev=163933&r1=163932&r2=163933&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSchedule.h?rev=163933&r1=163932&r2=163933&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCSchedule.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCSchedule.h Fri Sep 14 15:26:41 2012<br>
@@ -16,17 +16,102 @@<br>
#define LLVM_MC_MCSCHEDMODEL_H<br>
<br>
#include "llvm/Support/DataTypes.h"<br>
+#include <cassert><br>
<br>
namespace llvm {<br>
<br>
struct InstrItinerary;<br>
<br>
+/// Define a kind of processor resource that will be modeled by the scheduler.<br>
+struct MCProcResourceDesc {<br>
+#ifndef NDEBUG<br>
+ const char *Name;<br>
+#endif<br>
+ unsigned Count; // Number of resource of this kind<br>
+ unsigned SuperIdx; // Index of the resources kind that contains this kind.<br>
+<br>
+ bool operator==(const MCProcResourceDesc &Other) const {<br>
+ return Count == Other.Count && SuperIdx == Other.SuperIdx;<br>
+ }<br>
+};<br>
+<br>
+/// Identify one of the processor resource kinds consumed by a particular<br>
+/// scheduling class for the specified number of cycles.<br>
+struct MCWriteProcResEntry {<br>
+ unsigned ProcResourceIdx;<br>
+ unsigned Cycles;<br>
+<br>
+ bool operator==(const MCWriteProcResEntry &Other) const {<br>
+ return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles;<br>
+ }<br>
+};<br>
+<br>
+/// Specify the latency in cpu cycles for a particular scheduling class and def<br>
+/// index. Also identify the WriteResources of this def. When the operand<br>
+/// expands to a sequence of writes, this ID is the last write in the sequence.<br>
+struct MCWriteLatencyEntry {<br>
+ unsigned Cycles;<br>
+ unsigned WriteResourceID;<br>
+<br>
+ bool operator==(const MCWriteLatencyEntry &Other) const {<br>
+ return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID;<br>
+ }<br>
+};<br>
+<br>
+/// Specify the number of cycles allowed after instruction issue before a<br>
+/// particular use operand reads its registers. This effectively reduces the<br>
+/// write's latency. Here we allow negative cycles for corner cases where<br>
+/// latency increases. This rule only applies when the entry's WriteResource<br>
+/// matches the write's WriteResource.<br>
+///<br>
+/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by<br>
+/// WriteResourceIdx.<br>
+struct MCReadAdvanceEntry {<br>
+ unsigned UseIdx;<br>
+ unsigned WriteResourceID;<br>
+ int Cycles;<br>
+<br>
+ bool operator==(const MCReadAdvanceEntry &Other) const {<br>
+ return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID<br>
+ && Cycles == Other.Cycles;<br>
+ }<br>
+};<br>
+<br>
+/// Summarize the scheduling resources required for an instruction of a<br>
+/// particular scheduling class.<br>
+///<br>
+/// Defined as an aggregate struct for creating tables with initializer lists.<br>
+struct MCSchedClassDesc {<br>
+ static const unsigned short InvalidNumMicroOps = UINT16_MAX;<br>
+ static const unsigned short VariantNumMicroOps = UINT16_MAX - 1;<br>
+<br>
+#ifndef NDEBUG<br>
+ const char* Name;<br>
+#endif<br>
+ unsigned short NumMicroOps;<br>
+ bool BeginGroup;<br>
+ bool EndGroup;<br>
+ unsigned WriteProcResIdx; // First index into WriteProcResTable.<br>
+ unsigned NumWriteProcResEntries;<br>
+ unsigned WriteLatencyIdx; // First index into WriteLatencyTable.<br>
+ unsigned NumWriteLatencyEntries;<br>
+ unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable.<br>
+ unsigned NumReadAdvanceEntries;<br>
+<br>
+ bool isValid() const {<br>
+ return NumMicroOps != InvalidNumMicroOps;<br>
+ }<br>
+ bool isVariant() const {<br>
+ return NumMicroOps == VariantNumMicroOps;<br>
+ }<br>
+};<br>
+<br>
/// Machine model for scheduling, bundling, and heuristics.<br>
///<br>
/// The machine model directly provides basic information about the<br>
/// microarchitecture to the scheduler in the form of properties. It also<br>
-/// optionally refers to scheduler resources tables and itinerary<br>
-/// tables. Scheduler resources tables model the latency and cost for each<br>
+/// optionally refers to scheduler resource tables and itinerary<br>
+/// tables. Scheduler resource tables model the latency and cost for each<br>
/// instruction type. Itinerary tables are an independant mechanism that<br>
/// provides a detailed reservation table describing each cycle of instruction<br>
/// execution. Subtargets may define any or all of the above categories of data<br>
@@ -84,7 +169,12 @@<br>
static const unsigned DefaultMispredictPenalty = 10;<br>
<br>
private:<br>
- // TODO: Add a reference to proc resource types and sched resource tables.<br>
+ unsigned ProcID;<br>
+ const MCProcResourceDesc *ProcResourceTable;<br>
+ const MCSchedClassDesc *SchedClassTable;<br>
+<br>
+ unsigned NumProcResourceKinds;<br>
+ unsigned NumSchedClasses;<br>
<br>
// Instruction itinerary tables used by InstrItineraryData.<br>
friend class InstrItineraryData;<br>
@@ -100,13 +190,38 @@<br>
LoadLatency(DefaultLoadLatency),<br>
HighLatency(DefaultHighLatency),<br>
MispredictPenalty(DefaultMispredictPenalty),<br>
- InstrItineraries(0) {}<br>
+ ProcID(0), InstrItineraries(0) {}<br>
<br>
// Table-gen driven ctor.<br>
MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp,<br>
const InstrItinerary *ii):<br>
IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),<br>
- MispredictPenalty(mp), InstrItineraries(ii){}<br>
+ MispredictPenalty(mp), ProcID(0), ProcResourceTable(0),<br>
+ SchedClassTable(0), InstrItineraries(ii) {}<br>
+<br>
+ /// Does this machine model include instruction-level scheduling.<br>
+ bool hasInstrSchedModel() const {<br>
+ return SchedClassTable;<br>
+ }<br>
+<br>
+ /// Does this machine model include cycle-to-cycle itineraries.<br>
+ bool hasInstrItineraries() const {<br>
+ return InstrItineraries;<br>
+ }<br>
+<br>
+ const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {<br>
+ assert(hasInstrSchedModel() && "No scheduling machine model");<br>
+<br>
+ assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx");<br>
+ return &ProcResourceTable[ProcResourceIdx];<br>
+ }<br>
+<br>
+ const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const {<br>
+ assert(hasInstrSchedModel() && "No scheduling machine model");<br>
+<br>
+ assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");<br>
+ return &SchedClassTable[SchedClassIdx];<br>
+ }<br>
};<br>
<br>
} // End llvm namespace<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCSubtargetInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSubtargetInfo.h?rev=163933&r1=163932&r2=163933&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSubtargetInfo.h?rev=163933&r1=163932&r2=163933&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCSubtargetInfo.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCSubtargetInfo.h Fri Sep 14 15:26:41 2012<br>
@@ -30,7 +30,13 @@<br>
std::string TargetTriple; // Target triple<br>
const SubtargetFeatureKV *ProcFeatures; // Processor feature list<br>
const SubtargetFeatureKV *ProcDesc; // Processor descriptions<br>
- const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model<br>
+<br>
+ // Scheduler machine model<br>
+ const SubtargetInfoKV *ProcSchedModels;<br>
+ const MCWriteProcResEntry *WriteProcResTable;<br>
+ const MCWriteLatencyEntry *WriteLatencyTable;<br>
+ const MCReadAdvanceEntry *ReadAdvanceTable;<br>
+<br>
const InstrStage *Stages; // Instruction itinerary stages<br>
const unsigned *OperandCycles; // Itinerary operand cycles<br>
const unsigned *ForwardingPaths; // Forwarding paths<br>
@@ -74,6 +80,41 @@<br>
///<br>
const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;<br>
<br>
+ /// Return an iterator at the first process resource consumed by the given<br>
+ /// scheduling class.<br>
+ const MCWriteProcResEntry *getWriteProcResBegin(<br>
+ const MCSchedClassDesc *SC) const {<br>
+ return &WriteProcResTable[SC->WriteProcResIdx];<br>
+ }<br>
+ const MCWriteProcResEntry *getWriteProcResEnd(<br>
+ const MCSchedClassDesc *SC) const {<br>
+ return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;<br>
+ }<br>
+<br>
+ const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,<br>
+ unsigned DefIdx) const {<br>
+ assert(DefIdx < SC->NumWriteLatencyEntries &&<br>
+ "MachineModel does not specify a WriteResource for DefIdx");<br>
+<br>
+ return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];<br>
+ }<br>
+<br>
+ int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,<br>
+ unsigned WriteResID) const {<br>
+ for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],<br>
+ *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {<br>
+ if (I->UseIdx < UseIdx)<br>
+ continue;<br>
+ if (I->UseIdx > UseIdx)<br>
+ break;<br>
+ // Find the first WriteResIdx match, which has the highest cycle count.<br>
+ if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {<br>
+ return I->Cycles;<br>
+ }<br>
+ }<br>
+ return 0;<br>
+ }<br>
+<br>
/// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.<br>
///<br>
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;<br>
<br>
Modified: llvm/trunk/lib/MC/MCSubtargetInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSubtargetInfo.cpp?rev=163933&r1=163932&r2=163933&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSubtargetInfo.cpp?rev=163933&r1=163932&r2=163933&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCSubtargetInfo.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCSubtargetInfo.cpp Fri Sep 14 15:26:41 2012<br>
@@ -31,7 +31,7 @@<br>
TargetTriple = TT;<br>
ProcFeatures = PF;<br>
ProcDesc = PD;<br>
- ProcSchedModel = ProcSched;<br>
+ ProcSchedModels = ProcSched;<br>
Stages = IS;<br>
OperandCycles = OC;<br>
ForwardingPaths = FP;<br>
@@ -72,11 +72,11 @@<br>
<br>
const MCSchedModel *<br>
MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {<br>
- assert(ProcSchedModel && "Processor machine model not available!");<br>
+ assert(ProcSchedModels && "Processor machine model not available!");<br>
<br>
#ifndef NDEBUG<br>
for (size_t i = 1; i < NumProcs; i++) {<br>
- assert(strcmp(ProcSchedModel[i - 1].Key, ProcSchedModel[i].Key) < 0 &&<br>
+ assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 &&<br>
"Processor machine model table is not sorted");<br>
}<br>
#endif<br>
@@ -85,8 +85,8 @@<br>
SubtargetInfoKV KV;<br>
KV.Key = CPU.data();<br>
const SubtargetInfoKV *Found =<br>
- std::lower_bound(ProcSchedModel, ProcSchedModel+NumProcs, KV);<br>
- if (Found == ProcSchedModel+NumProcs || StringRef(Found->Key) != CPU) {<br>
+ std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, KV);<br>
+ if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) {<br>
errs() << "'" << CPU<br>
<< "' is not a recognized processor for this target"<br>
<< " (ignoring processor)\n";<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><br>-- <br>~Craig<br>