[misched] Extend scheduler to handle unsupported features
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 llvm-svn: 273551
This commit is contained in:
parent
e440f99913
commit
081e4bb14c
|
@ -55,6 +55,8 @@ include "llvm/Target/TargetItinerary.td"
|
||||||
|
|
||||||
class Instruction; // Forward def
|
class Instruction; // Forward def
|
||||||
|
|
||||||
|
class Predicate; // Forward def
|
||||||
|
|
||||||
// DAG operator that interprets the DAG args as Instruction defs.
|
// DAG operator that interprets the DAG args as Instruction defs.
|
||||||
def instrs;
|
def instrs;
|
||||||
|
|
||||||
|
@ -97,6 +99,20 @@ class SchedMachineModel {
|
||||||
// resulting from changes to the instruction definitions.
|
// resulting from changes to the instruction definitions.
|
||||||
bit CompleteModel = 1;
|
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.
|
bit NoModel = 0; // Special tag to indicate missing machine model.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,10 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
|
||||||
// (For per-operand resources mapped to itinerary classes).
|
// (For per-operand resources mapped to itinerary classes).
|
||||||
collectProcItinRW();
|
collectProcItinRW();
|
||||||
|
|
||||||
|
// Find UnsupportedFeatures records for each processor.
|
||||||
|
// (For per-operand resources mapped to itinerary classes).
|
||||||
|
collectProcUnsupportedFeatures();
|
||||||
|
|
||||||
// Infer new SchedClasses from SchedVariant.
|
// Infer new SchedClasses from SchedVariant.
|
||||||
inferSchedClasses();
|
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
|
/// Infer new classes from existing classes. In the process, this may create new
|
||||||
/// SchedWrites from sequences of existing SchedWrites.
|
/// SchedWrites from sequences of existing SchedWrites.
|
||||||
void CodeGenSchedModels::inferSchedClasses() {
|
void CodeGenSchedModels::inferSchedClasses() {
|
||||||
|
@ -1540,6 +1553,8 @@ void CodeGenSchedModels::checkCompleteness() {
|
||||||
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
|
for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
|
||||||
if (Inst->hasNoSchedulingInfo)
|
if (Inst->hasNoSchedulingInfo)
|
||||||
continue;
|
continue;
|
||||||
|
if (ProcModel.isUnsupported(*Inst))
|
||||||
|
continue;
|
||||||
unsigned SCIdx = getSchedClassIdx(*Inst);
|
unsigned SCIdx = getSchedClassIdx(*Inst);
|
||||||
if (!SCIdx) {
|
if (!SCIdx) {
|
||||||
if (Inst->TheDef->isValueUnset("SchedRW") && !HadCompleteModel) {
|
if (Inst->TheDef->isValueUnset("SchedRW") && !HadCompleteModel) {
|
||||||
|
@ -1575,7 +1590,10 @@ void CodeGenSchedModels::checkCompleteness() {
|
||||||
<< "- Consider setting 'CompleteModel = 0' while developing new models.\n"
|
<< "- Consider setting 'CompleteModel = 0' while developing new models.\n"
|
||||||
<< "- Pseudo instructions can be marked with 'hasNoSchedulingInfo = 1'.\n"
|
<< "- Pseudo instructions can be marked with 'hasNoSchedulingInfo = 1'.\n"
|
||||||
<< "- Instructions should usually have Sched<[...]> as a superclass, "
|
<< "- 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");
|
PrintFatalError("Incomplete schedule model");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1756,6 +1774,16 @@ unsigned CodeGenProcModel::getProcResourceIdx(Record *PRDef) const {
|
||||||
return 1 + (PRPos - ProcResourceDefs.begin());
|
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
|
#ifndef NDEBUG
|
||||||
void CodeGenProcModel::dump() const {
|
void CodeGenProcModel::dump() const {
|
||||||
dbgs() << Index << ": " << ModelName << " "
|
dbgs() << Index << ": " << ModelName << " "
|
||||||
|
|
|
@ -189,6 +189,10 @@ struct CodeGenProcModel {
|
||||||
// This list is empty if no ItinRW refers to this Processor.
|
// This list is empty if no ItinRW refers to this Processor.
|
||||||
RecVec ItinRWDefs;
|
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.
|
// All read/write resources associated with this processor.
|
||||||
RecVec WriteResDefs;
|
RecVec WriteResDefs;
|
||||||
RecVec ReadAdvanceDefs;
|
RecVec ReadAdvanceDefs;
|
||||||
|
@ -211,6 +215,8 @@ struct CodeGenProcModel {
|
||||||
|
|
||||||
unsigned getProcResourceIdx(Record *PRDef) const;
|
unsigned getProcResourceIdx(Record *PRDef) const;
|
||||||
|
|
||||||
|
bool isUnsupported(const CodeGenInstruction &Inst) const;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void dump() const;
|
void dump() const;
|
||||||
#endif
|
#endif
|
||||||
|
@ -402,6 +408,8 @@ private:
|
||||||
|
|
||||||
void collectProcItinRW();
|
void collectProcItinRW();
|
||||||
|
|
||||||
|
void collectProcUnsupportedFeatures();
|
||||||
|
|
||||||
void inferSchedClasses();
|
void inferSchedClasses();
|
||||||
|
|
||||||
void checkCompleteness();
|
void checkCompleteness();
|
||||||
|
|
Loading…
Reference in New Issue