Index: include/llvm/Target/TargetSchedule.td =================================================================== --- include/llvm/Target/TargetSchedule.td +++ include/llvm/Target/TargetSchedule.td @@ -55,6 +55,8 @@ class Instruction; // Forward def +class Predicate; // Forward def + // DAG operator that interprets the DAG args as Instruction defs. def instrs; @@ -97,6 +99,20 @@ // resulting from changes to the instruction definitions. bit CompleteModel = 1; + // A processor may only implement part of published ISA, due to either new ISA + // extensions, (e.g. Pentium 4 doesn't have AVX) or implementation + // (ARM/MIPS/PowerPC/SPARC soft float cores). + // + // For a processor which doesn't support some feature(s), the schedule model + // can use: + // + // let UnsupportedFeatures = [HaveA,..,HaveY]; + // + // to skip the checks for scheduling information when building LLVM for + // instructions which have any of the listed predicates in their Predicates + // field. + list UnsupportedFeatures = []; + bit NoModel = 0; // Special tag to indicate missing machine model. } 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. + // This list is empty if the Processor has no UnsupportedFeatures. + 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 @@ -402,6 +408,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,15 @@ } } +// Gather the unsupported features for processor models. +void CodeGenSchedModels::collectProcUnsupportedFeatures() { + for (CodeGenProcModel &ProcModel : ProcModels) { + for (Record *Pred : ProcModel.ModelDef->getValueAsListOfDefs("UnsupportedFeatures")) { + ProcModel.UnsupportedFeaturesDefs.push_back(Pred); + } + } +} + /// Infer new classes from existing classes. In the process, this may create new /// SchedWrites from sequences of existing SchedWrites. void CodeGenSchedModels::inferSchedClasses() { @@ -1540,6 +1553,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) { @@ -1575,7 +1590,10 @@ << "- Consider setting 'CompleteModel = 0' while developing new models.\n" << "- Pseudo instructions can be marked with 'hasNoSchedulingInfo = 1'.\n" << "- Instructions should usually have Sched<[...]> as a superclass, " - "you may temporarily use an empty list.\n\n"; + "you may temporarily use an empty list.\n" + << "- Instructions related to unsupported features can be excluded with " + "list UnsupportedFeatures = [HasA,..,HasY]; in the " + "processor model.\n\n"; PrintFatalError("Incomplete schedule model"); } } @@ -1756,6 +1774,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->getName() == PredDef->getName()) + return true; + } + } + return false; +} + #ifndef NDEBUG void CodeGenProcModel::dump() const { dbgs() << Index << ": " << ModelName << " "