Mark the x86 machine model as incomplete. PR17367.
authorAndrew Trick <atrick@apple.com>
Wed, 25 Sep 2013 18:14:12 +0000 (18:14 +0000)
committerAndrew Trick <atrick@apple.com>
Wed, 25 Sep 2013 18:14:12 +0000 (18:14 +0000)
Ideally, the machinel model is added at the time the instructions are
defined. But many instructions in X86InstrSSE.td still need a model.

Without this workaround the scheduler asserts because x86 already has
itinerary classes for these instructions, indicating they should be
modeled by the scheduler. Since we use the new machine model for other
instructions, it expects a new machine model for these too.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191391 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCSchedule.h
include/llvm/Target/TargetSchedule.td
lib/CodeGen/TargetSchedule.cpp
lib/Target/X86/X86SchedHaswell.td
lib/Target/X86/X86SchedSandyBridge.td
utils/TableGen/SubtargetEmitter.cpp

index 673cdf6fb68ce4a1de3e5145a4dadc5ef0a902e8..1edf204940c82b07c7ab57161a7867e40e8612f5 100644 (file)
@@ -174,6 +174,8 @@ public:
   unsigned MispredictPenalty;
   static const unsigned DefaultMispredictPenalty = 10;
 
+  bool CompleteModel;
+
 private:
   unsigned ProcID;
   const MCProcResourceDesc *ProcResourceTable;
@@ -194,6 +196,7 @@ public:
                   LoadLatency(DefaultLoadLatency),
                   HighLatency(DefaultHighLatency),
                   MispredictPenalty(DefaultMispredictPenalty),
+                  CompleteModel(true),
                   ProcID(0), ProcResourceTable(0), SchedClassTable(0),
                   NumProcResourceKinds(0), NumSchedClasses(0),
                   InstrItineraries(0) {
@@ -203,19 +206,23 @@ public:
 
   // Table-gen driven ctor.
   MCSchedModel(unsigned iw, int mbs, unsigned ll, unsigned hl,
-               unsigned mp, unsigned pi, const MCProcResourceDesc *pr,
+               unsigned mp, bool cm, unsigned pi, const MCProcResourceDesc *pr,
                const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
                const InstrItinerary *ii):
     IssueWidth(iw), MicroOpBufferSize(mbs), LoadLatency(ll), HighLatency(hl),
-    MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
-    SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
-    InstrItineraries(ii) {}
+    MispredictPenalty(mp), CompleteModel(cm), 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; }
 
+  /// Return true if this machine model data for all instructions with a
+  /// scheduling class (itinerary class or SchedRW list).
+  bool isComplete() const { return CompleteModel; }
+
   unsigned getNumProcResourceKinds() const {
     return NumProcResourceKinds;
   }
index 575cb83568acb7879eecf596fe6e30a82ce247bc..e81a2fbade9f23eabd7c04967d1f9cc28a497c7b 100644 (file)
@@ -86,6 +86,15 @@ class SchedMachineModel {
   // Per-cycle resources tables.
   ProcessorItineraries Itineraries = NoItineraries;
 
+  // Subtargets that define a model for only a subset of instructions
+  // that have a scheduling class (itinerary class or SchedRW list)
+  // and may actually be generated for that subtarget must clear this
+  // bit. Otherwise, the scheduler considers an unmodelled opcode to
+  // be an error. This should only be set during initial bringup,
+  // or there will be no way to catch simple errors in the model
+  // resulting from changes to the instruction definitions.
+  bit CompleteModel = 1;
+
   bit NoModel = 0; // Special tag to indicate missing machine model.
 }
 
index 64ee9d1c464eac92aba19c80e6ec1b8f7d40b429..fd3f49657b03b60c46107c2e8c70a323cace2849 100644 (file)
@@ -210,7 +210,8 @@ unsigned TargetSchedModel::computeOperandLatency(
   // unit latency (defaultDefLatency may be too conservative).
 #ifndef NDEBUG
   if (SCDesc->isValid() && !DefMI->getOperand(DefOperIdx).isImplicit()
-      && !DefMI->getDesc().OpInfo[DefOperIdx].isOptionalDef()) {
+      && !DefMI->getDesc().OpInfo[DefOperIdx].isOptionalDef()
+      && SchedModel.isComplete()) {
     std::string Err;
     raw_string_ostream ss(Err);
     ss << "DefIdx " << DefIdx << " exceeds machine model writes for "
index 62ba2bc1c9ed27ff7e739d0b6e8277dee7753ad6..9748261262d358182fcadde7136db5f1ee83130c 100644 (file)
@@ -19,6 +19,10 @@ def HaswellModel : SchedMachineModel {
   let MicroOpBufferSize = 192; // Based on the reorder buffer.
   let LoadLatency = 4;
   let MispredictPenalty = 16;
+
+  // FIXME: SSE4 and AVX are unimplemented. This flag is set to allow
+  // the scheduler to assign a default model to unrecognized opcodes.
+  let CompleteModel = 0;
 }
 
 let SchedModel = HaswellModel in {
index 52ead94714dd70988fad8d4e25d9dbcec42d3dd1..3011c6d9d643dc7266fe685f4413e072990c2065 100644 (file)
@@ -20,6 +20,10 @@ def SandyBridgeModel : SchedMachineModel {
   let MicroOpBufferSize = 168; // Based on the reorder buffer.
   let LoadLatency = 4;
   let MispredictPenalty = 16;
+
+  // FIXME: SSE4 and AVX are unimplemented. This flag is set to allow
+  // the scheduler to assign a default model to unrecognized opcodes.
+  let CompleteModel = 0;
 }
 
 let SchedModel = SandyBridgeModel in {
index 81bb6f8fd47f5fc5fb1b0031416cb96eae31e61d..b9f9d060394066abe55b08533218cb7660cf447e 100644 (file)
@@ -1198,6 +1198,11 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
     EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ',');
     EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ',');
     EmitProcessorProp(OS, PI->ModelDef, "MispredictPenalty", ',');
+
+    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"