Index: include/llvm/Target/TargetSchedule.td =================================================================== --- include/llvm/Target/TargetSchedule.td +++ include/llvm/Target/TargetSchedule.td @@ -406,6 +406,11 @@ SchedMachineModel SchedModel = ?; } +class UnsupportedFeatures { + string Predicates = predicates; + SchedMachineModel SchedModel = ?; +} + // Alias a target-defined SchedReadWrite to a processor specific // SchedReadWrite. This allows a subtarget to easily map a // SchedReadWrite type onto a WriteSequence, SchedWriteVariant, or Index: lib/CodeGen/TargetSchedule.cpp =================================================================== --- lib/CodeGen/TargetSchedule.cpp +++ lib/CodeGen/TargetSchedule.cpp @@ -212,7 +212,7 @@ && !DefMI->getDesc().OpInfo[DefOperIdx].isOptionalDef() && SchedModel.isComplete()) { errs() << "DefIdx " << DefIdx << " exceeds machine model writes for " - << *DefMI << " (Try with MCSchedModel.CompleteModel set to false)"; + << *DefMI << " (Try with MCSchedModel.CompleteModel set to false)\n"; llvm_unreachable("incomplete machine model"); } #endif Index: utils/TableGen/CodeGenSchedule.h =================================================================== --- utils/TableGen/CodeGenSchedule.h +++ utils/TableGen/CodeGenSchedule.h @@ -189,6 +189,10 @@ // This list is empty if no ItinRW refers to this Processor. RecVec ItinRWDefs; + // List of unsupported feature combinations. + // This list is empty if no UnsupportedFeature refers to this Processor. + RecVec UnsupportedFeaturesDefs; + // All read/write resources associated with this processor. RecVec WriteResDefs; RecVec ReadAdvanceDefs; @@ -211,6 +215,8 @@ unsigned getProcResourceIdx(Record *PRDef) const; + bool isUnsupported(const CodeGenInstruction &Inst) const; + #ifndef NDEBUG void dump() const; #endif @@ -399,6 +405,8 @@ void collectProcItinRW(); + void collectProcUnsupportedFeatures(); + void inferSchedClasses(); void checkCompleteness(); Index: utils/TableGen/CodeGenSchedule.cpp =================================================================== --- utils/TableGen/CodeGenSchedule.cpp +++ utils/TableGen/CodeGenSchedule.cpp @@ -120,6 +120,10 @@ // (For per-operand resources mapped to itinerary classes). collectProcItinRW(); + // Find UnsupportedFeatures records for each processor. + // (For per-operand resources mapped to itinerary classes). + collectProcUnsupportedFeatures(); + // Infer new SchedClasses from SchedVariant. inferSchedClasses(); @@ -829,6 +833,31 @@ } } +// Gather the unsupported features for a processor model. +void CodeGenSchedModels::collectProcUnsupportedFeatures() { + RecVec UnsupportedFeaturesDefs = + Records.getAllDerivedDefinitions("UnsupportedFeatures"); + std::sort(UnsupportedFeaturesDefs.begin(), UnsupportedFeaturesDefs.end(), + LessRecord()); + for (RecIter II = UnsupportedFeaturesDefs.begin(), + IE = UnsupportedFeaturesDefs.end(); + II != IE; ++II) { + if (!(*II)->getValueInit("SchedModel")->isComplete()) + PrintFatalError((*II)->getLoc(), "SchedModel is undefined"); + auto InsnPredicate = (*II)->getValue("Predicates")->getValue(); + if (!Records.getDef(InsnPredicate->getAsUnquotedString())) + PrintFatalError((*II)->getLoc(), + "Unknown Predicate: " + InsnPredicate->getAsString()); + Record *ModelDef = (*II)->getValueAsDef("SchedModel"); + ProcModelMapTy::const_iterator I = ProcModelMap.find(ModelDef); + if (I == ProcModelMap.end()) { + PrintFatalError((*II)->getLoc(), "Undefined SchedMachineModel " + + ModelDef->getName()); + } + ProcModels[I->second].UnsupportedFeaturesDefs.push_back(*II); + } +} + /// Infer new classes from existing classes. In the process, this may create new /// SchedWrites from sequences of existing SchedWrites. void CodeGenSchedModels::inferSchedClasses() { @@ -1534,6 +1563,8 @@ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { if (Inst->hasNoSchedulingInfo) continue; + if (ProcModel.isUnsupported(*Inst)) + continue; unsigned SCIdx = getSchedClassIdx(*Inst); if (!SCIdx) { if (Inst->TheDef->isValueUnset("SchedRW") && !HadCompleteModel) { @@ -1751,6 +1782,16 @@ return 1 + (PRPos - ProcResourceDefs.begin()); } +bool CodeGenProcModel::isUnsupported(const CodeGenInstruction &Inst) const { + for (const Record *TheDef : UnsupportedFeaturesDefs) { + for (const Record *PredDef : Inst.TheDef->getValueAsListOfDefs("Predicates")) { + if (TheDef->getValueAsString("Predicates") == PredDef->getName()) + return true; + } + } + return false; +} + #ifndef NDEBUG void CodeGenProcModel::dump() const { dbgs() << Index << ": " << ModelName << " "