From 111ec25a8e40a320ec25ea332a65ca3ee327be37 Mon Sep 17 00:00:00 2001 From: Simon Dardis Date: Fri, 24 Jun 2016 08:43:27 +0000 Subject: [PATCH] Revert "Revert "[misched] Extend scheduler to handle unsupported features"" This reverts commit r273565. This was an over-eager revert. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273658 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetSchedule.td | 16 ++++++++++++++ utils/TableGen/CodeGenSchedule.cpp | 30 ++++++++++++++++++++++++++- utils/TableGen/CodeGenSchedule.h | 8 +++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 7f92e8b6556..74b98ac5f6c 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -55,6 +55,8 @@ include "llvm/Target/TargetItinerary.td" class Instruction; // Forward def +class Predicate; // Forward def + // DAG operator that interprets the DAG args as Instruction defs. def instrs; @@ -97,6 +99,20 @@ class SchedMachineModel { // 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. } diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp index 57a426bffb3..d1b141e3160 100644 --- a/utils/TableGen/CodeGenSchedule.cpp +++ b/utils/TableGen/CodeGenSchedule.cpp @@ -120,6 +120,10 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK, // (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 @@ void CodeGenSchedModels::collectProcItinRW() { } } +// 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 @@ void CodeGenSchedModels::checkCompleteness() { 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 @@ void CodeGenSchedModels::checkCompleteness() { << "- 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 @@ unsigned CodeGenProcModel::getProcResourceIdx(Record *PRDef) const { 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 << " " diff --git a/utils/TableGen/CodeGenSchedule.h b/utils/TableGen/CodeGenSchedule.h index 7a236ad0dd8..755ffd25b0c 100644 --- a/utils/TableGen/CodeGenSchedule.h +++ b/utils/TableGen/CodeGenSchedule.h @@ -189,6 +189,10 @@ struct CodeGenProcModel { // 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 @@ struct CodeGenProcModel { unsigned getProcResourceIdx(Record *PRDef) const; + bool isUnsupported(const CodeGenInstruction &Inst) const; + #ifndef NDEBUG void dump() const; #endif @@ -402,6 +408,8 @@ private: void collectProcItinRW(); + void collectProcUnsupportedFeatures(); + void inferSchedClasses(); void checkCompleteness();