]> granicus.if.org Git - llvm/commitdiff
[misched] Extend scheduler to handle unsupported features
authorSimon Dardis <simon.dardis@imgtec.com>
Thu, 23 Jun 2016 09:22:11 +0000 (09:22 +0000)
committerSimon Dardis <simon.dardis@imgtec.com>
Thu, 23 Jun 2016 09:22:11 +0000 (09:22 +0000)
Currently isComplete = 1 requires that every instruction must
be described, declared unsupported or marked as having no
scheduling information for a processor.

For some backends such as MIPS, this requirement entails
long regex lists of instructions that are unsupported.

This patch teaches Tablegen to skip over instructions that
are associated with unsupported feature when checking if the
scheduling model is complete.

Patch by: Daniel Sanders

Contributions by: Simon Dardis

Reviewers: MatzeB

Differential Reviewer: http://reviews.llvm.org/D20522

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

include/llvm/Target/TargetSchedule.td
utils/TableGen/CodeGenSchedule.cpp
utils/TableGen/CodeGenSchedule.h

index 7f92e8b65564d42be823589c2fc7ba18ea5e14bb..74b98ac5f6c5d30f2b10889d628c610668b826ed 100644 (file)
@@ -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<Predicate> 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<Predicate> UnsupportedFeatures = [];
+
   bit NoModel = 0; // Special tag to indicate missing machine model.
 }
 
index 57a426bffb3699051bd1ab93b84eb9c354c7365b..d1b141e3160f562fd08b83d1d04cc67def721115 100644 (file)
@@ -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<Predicate> 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 << " "
index 7a236ad0dd816520d6c7689e6726d5f5492358a1..755ffd25b0cbc92b6696acb52ab4db4dd8576c10 100644 (file)
@@ -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();