llvm.org GIT mirror llvm / eab2869
TableGen: Check scheduling models for completeness TableGen checks at compiletime that for scheduling models with "CompleteModel = 1" one of the following holds: - Is marked with the hasNoSchedulingInfo flag - The instruction is a subclass of Sched - There are InstRW definitions in the scheduling model Typical steps necessary to complete a model: - Ensure all pseudo instructions that are expanded before machine scheduling (usually everything handled with EmitYYY() functions in XXXTargetLowering). - If a CPU does not support some instructions mark the corresponding resource unsupported: "WriteRes<WriteXXX, []> { let Unsupported = 1; }". - Add missing scheduling information. Differential Revision: http://reviews.llvm.org/D17747 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262384 91177308-0d34-0410-b5e6-96231b3b80d8 Matthias Braun 4 years ago
22 changed file(s) with 79 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
103103
104104 def NoSchedModel : SchedMachineModel {
105105 let NoModel = 1;
106 let CompleteModel = 0;
106107 }
107108
108109 // Define a kind of processor resource that may be common across
2525 let MispredictPenalty = 9; // Based on "Cortex-A53 Software Optimisation
2626 // Specification - Instruction Timings"
2727 // v 1.0 Spreadsheet
28 let CompleteModel = 0;
2829 }
2930
3031
2929 // Enable partial & runtime unrolling. The magic number is chosen based on
3030 // experiments and benchmarking data.
3131 let LoopMicroOpBufferSize = 16;
32 let CompleteModel = 0;
3233 }
3334
3435 //===----------------------------------------------------------------------===//
1616 let MicroOpBufferSize = 192; // Based on the reorder buffer.
1717 let LoadLatency = 4; // Optimistic load latency.
1818 let MispredictPenalty = 16; // 14-19 cycles are typical.
19 let CompleteModel = 0;
1920 }
2021
2122 //===----------------------------------------------------------------------===//
2525 // Enable partial & runtime unrolling. The magic number is chosen based on
2626 // experiments and benchmarking data.
2727 let LoopMicroOpBufferSize = 16;
28 let CompleteModel = 0;
2829 }
2930
3031 //===----------------------------------------------------------------------===//
3838 // instructions and have VALU rates, but write to the SALU (i.e. VOPC
3939 // instructions)
4040
41 def SIFullSpeedModel : SchedMachineModel;
42 def SIQuarterSpeedModel : SchedMachineModel;
41 def SIFullSpeedModel : SchedMachineModel {
42 let CompleteModel = 0;
43 }
44 def SIQuarterSpeedModel : SchedMachineModel {
45 let CompleteModel = 0;
46 }
4347
4448 // BufferSize = 0 means the processors are in-order.
4549 let BufferSize = 0 in {
10691069 // This is overriden by OperandCycles if the
10701070 // Itineraries are queried instead.
10711071 let MispredictPenalty = 13; // Based on estimate of pipeline depth.
1072 let CompleteModel = 0;
10721073
10731074 let Itineraries = CortexA8Itineraries;
10741075 }
198198 let IssueWidth = 4;
199199 let Itineraries = HexagonItinerariesV4;
200200 let LoadLatency = 1;
201 let CompleteModel = 0;
201202 }
202203
203204 //===----------------------------------------------------------------------===//
162162 let IssueWidth = 4;
163163 let Itineraries = HexagonItinerariesV55;
164164 let LoadLatency = 1;
165 let CompleteModel = 0;
165166 }
166167
167168 //===----------------------------------------------------------------------===//
302302 let IssueWidth = 4;
303303 let Itineraries = HexagonItinerariesV60;
304304 let LoadLatency = 1;
305 let CompleteModel = 0;
305306 }
306307
307308 //===----------------------------------------------------------------------===//
1212 int LoadLatency = 4;
1313 int MispredictPenalty = 8; // TODO: Estimated
1414
15 let CompleteModel = 1;
15 let CompleteModel = 0;
1616 }
1717
1818 let SchedModel = MipsP5600Model in {
601601 // This is overriden by OperandCycles if the
602602 // Itineraries are queried instead.
603603
604 let CompleteModel = 0;
605
604606 let Itineraries = PPC440Itineraries;
605607 }
606608
165165 // Itineraries are queried instead.
166166 let MispredictPenalty = 13;
167167
168 let CompleteModel = 0;
169
168170 let Itineraries = PPCA2Itineraries;
169171 }
170172
315315 // This is overriden by OperandCycles if the
316316 // Itineraries are queried instead.
317317
318 let CompleteModel = 0;
319
318320 let Itineraries = PPCE500mcItineraries;
319321 }
375375 // This is overriden by OperandCycles if the
376376 // Itineraries are queried instead.
377377
378 let CompleteModel = 0;
379
378380 let Itineraries = PPCE5500Itineraries;
379381 }
123123 // Itineraries are queried instead.
124124 let MispredictPenalty = 16;
125125
126 let CompleteModel = 0;
127
126128 let Itineraries = G5Itineraries;
127129 }
128130
390390 // Try to make sure we have at least 10 dispatch groups in a loop.
391391 let LoopMicroOpBufferSize = 40;
392392
393 let CompleteModel = 0;
394
393395 let Itineraries = P7Itineraries;
394396 }
395397
399399 // Try to make sure we have at least 10 dispatch groups in a loop.
400400 let LoopMicroOpBufferSize = 60;
401401
402 let CompleteModel = 0;
403
402404 let Itineraries = P8Itineraries;
403405 }
404406
639639 let LoadLatency = 4;
640640 let HighLatency = 10;
641641 let PostRAScheduler = 0;
642 let CompleteModel = 0;
642643 }
643644
644645 include "X86ScheduleAtom.td"
543543 // simple loops, expand by a small factor to hide the backedge cost.
544544 let LoopMicroOpBufferSize = 10;
545545 let PostRAScheduler = 1;
546 let CompleteModel = 0;
546547
547548 let Itineraries = AtomItineraries;
548549 }
125125 // Populate each CodeGenProcModel's WriteResDefs, ReadAdvanceDefs, and
126126 // ProcResourceDefs.
127127 collectProcResources();
128
129 checkCompleteness();
128130 }
129131
130132 /// Gather all processor models.
15221524 }
15231525 }
15241526
1527 void CodeGenSchedModels::checkCompleteness() {
1528 bool Complete = true;
1529 bool HadCompleteModel = false;
1530 for (const CodeGenProcModel &ProcModel : procModels()) {
1531 // Note that long-term we should check "CompleteModel", but for now most
1532 // models that claim to be complete are actually not so we use a separate
1533 // "CheckCompleteness" bit.
1534 if (!ProcModel.ModelDef->getValueAsBit("CompleteModel"))
1535 continue;
1536 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
1537 if (Inst->hasNoSchedulingInfo)
1538 continue;
1539 unsigned SCIdx = getSchedClassIdx(*Inst);
1540 if (!SCIdx) {
1541 if (Inst->TheDef->isValueUnset("SchedRW") && !HadCompleteModel) {
1542 PrintError("No schedule information for instruction '"
1543 + Inst->TheDef->getName() + "'");
1544 Complete = false;
1545 }
1546 continue;
1547 }
1548
1549 const CodeGenSchedClass &SC = getSchedClass(SCIdx);
1550 if (!SC.Writes.empty())
1551 continue;
1552
1553 const RecVec &InstRWs = SC.InstRWs;
1554 auto I = std::find_if(InstRWs.begin(), InstRWs.end(),
1555 [&ProcModel] (const Record *R) {
1556 return R->getValueAsDef("SchedModel") == ProcModel.ModelDef;
1557 });
1558 if (I == InstRWs.end()) {
1559 PrintError("'" + ProcModel.ModelName + "' lacks information for '" +
1560 Inst->TheDef->getName() + "'");
1561 Complete = false;
1562 }
1563 }
1564 HadCompleteModel = true;
1565 }
1566 if (!Complete)
1567 PrintFatalError("Incomplete schedule model");
1568 }
1569
15251570 // Collect itinerary class resources for each processor.
15261571 void CodeGenSchedModels::collectItinProcResources(Record *ItinClassDef) {
15271572 for (unsigned PIdx = 0, PEnd = ProcModels.size(); PIdx != PEnd; ++PIdx) {
400400
401401 void inferSchedClasses();
402402
403 void checkCompleteness();
404
403405 void inferFromRW(ArrayRef OperWrites, ArrayRef OperReads,
404406 unsigned FromClassIdx, ArrayRef ProcIndices);
405407 void inferFromItinClass(Record *ItinClassDef, unsigned FromClassIdx);