diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 673cdf6fb68..1edf204940c 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -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; } diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 575cb83568a..e81a2fbade9 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -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. } diff --git a/lib/CodeGen/TargetSchedule.cpp b/lib/CodeGen/TargetSchedule.cpp index 64ee9d1c464..fd3f49657b0 100644 --- a/lib/CodeGen/TargetSchedule.cpp +++ b/lib/CodeGen/TargetSchedule.cpp @@ -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 " diff --git a/lib/Target/X86/X86SchedHaswell.td b/lib/Target/X86/X86SchedHaswell.td index 62ba2bc1c9e..9748261262d 100644 --- a/lib/Target/X86/X86SchedHaswell.td +++ b/lib/Target/X86/X86SchedHaswell.td @@ -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 { diff --git a/lib/Target/X86/X86SchedSandyBridge.td b/lib/Target/X86/X86SchedSandyBridge.td index 52ead94714d..3011c6d9d64 100644 --- a/lib/Target/X86/X86SchedSandyBridge.td +++ b/lib/Target/X86/X86SchedSandyBridge.td @@ -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 { diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 81bb6f8fd47..b9f9d060394 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -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"