Mercurial > hg > CbC > CbC_llvm
comparison utils/TableGen/SubtargetEmitter.cpp @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | 7d135dc70f03 |
children | 803732b1fca8 |
comparison
equal
deleted
inserted
replaced
101:34baf5011add | 120:1172e4bd9c6f |
---|---|
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "CodeGenTarget.h" | 14 #include "CodeGenTarget.h" |
15 #include "CodeGenSchedule.h" | 15 #include "CodeGenSchedule.h" |
16 #include "llvm/ADT/STLExtras.h" | 16 #include "llvm/ADT/SmallPtrSet.h" |
17 #include "llvm/ADT/StringExtras.h" | 17 #include "llvm/ADT/StringExtras.h" |
18 #include "llvm/MC/MCInstrItineraries.h" | 18 #include "llvm/MC/MCInstrItineraries.h" |
19 #include "llvm/MC/MCSchedule.h" | |
19 #include "llvm/MC/SubtargetFeature.h" | 20 #include "llvm/MC/SubtargetFeature.h" |
20 #include "llvm/Support/Debug.h" | 21 #include "llvm/Support/Debug.h" |
21 #include "llvm/Support/Format.h" | 22 #include "llvm/Support/Format.h" |
23 #include "llvm/Support/raw_ostream.h" | |
22 #include "llvm/TableGen/Error.h" | 24 #include "llvm/TableGen/Error.h" |
23 #include "llvm/TableGen/Record.h" | 25 #include "llvm/TableGen/Record.h" |
24 #include "llvm/TableGen/TableGenBackend.h" | 26 #include "llvm/TableGen/TableGenBackend.h" |
25 #include <algorithm> | 27 #include <algorithm> |
28 #include <cassert> | |
29 #include <cstdint> | |
26 #include <map> | 30 #include <map> |
27 #include <string> | 31 #include <string> |
28 #include <vector> | 32 #include <vector> |
29 | 33 |
30 using namespace llvm; | 34 using namespace llvm; |
31 | 35 |
32 #define DEBUG_TYPE "subtarget-emitter" | 36 #define DEBUG_TYPE "subtarget-emitter" |
33 | 37 |
34 namespace { | 38 namespace { |
39 | |
35 class SubtargetEmitter { | 40 class SubtargetEmitter { |
36 // Each processor has a SchedClassDesc table with an entry for each SchedClass. | 41 // Each processor has a SchedClassDesc table with an entry for each SchedClass. |
37 // The SchedClassDesc table indexes into a global write resource table, write | 42 // The SchedClassDesc table indexes into a global write resource table, write |
38 // latency table, and read advance table. | 43 // latency table, and read advance table. |
39 struct SchedClassTables { | 44 struct SchedClassTables { |
62 | 67 |
63 RecordKeeper &Records; | 68 RecordKeeper &Records; |
64 CodeGenSchedModels &SchedModels; | 69 CodeGenSchedModels &SchedModels; |
65 std::string Target; | 70 std::string Target; |
66 | 71 |
67 void Enumeration(raw_ostream &OS, const char *ClassName); | 72 void Enumeration(raw_ostream &OS); |
68 unsigned FeatureKeyValues(raw_ostream &OS); | 73 unsigned FeatureKeyValues(raw_ostream &OS); |
69 unsigned CPUKeyValues(raw_ostream &OS); | 74 unsigned CPUKeyValues(raw_ostream &OS); |
70 void FormItineraryStageString(const std::string &Names, | 75 void FormItineraryStageString(const std::string &Names, |
71 Record *ItinData, std::string &ItinString, | 76 Record *ItinData, std::string &ItinString, |
72 unsigned &NStages); | 77 unsigned &NStages); |
79 std::vector<std::vector<InstrItinerary> > | 84 std::vector<std::vector<InstrItinerary> > |
80 &ProcItinLists); | 85 &ProcItinLists); |
81 void EmitItineraries(raw_ostream &OS, | 86 void EmitItineraries(raw_ostream &OS, |
82 std::vector<std::vector<InstrItinerary> > | 87 std::vector<std::vector<InstrItinerary> > |
83 &ProcItinLists); | 88 &ProcItinLists); |
84 void EmitProcessorProp(raw_ostream &OS, const Record *R, const char *Name, | 89 void EmitProcessorProp(raw_ostream &OS, const Record *R, StringRef Name, |
85 char Separator); | 90 char Separator); |
86 void EmitProcessorResources(const CodeGenProcModel &ProcModel, | 91 void EmitProcessorResources(const CodeGenProcModel &ProcModel, |
87 raw_ostream &OS); | 92 raw_ostream &OS); |
88 Record *FindWriteResources(const CodeGenSchedRW &SchedWrite, | 93 Record *FindWriteResources(const CodeGenSchedRW &SchedWrite, |
89 const CodeGenProcModel &ProcModel); | 94 const CodeGenProcModel &ProcModel); |
94 void GenSchedClassTables(const CodeGenProcModel &ProcModel, | 99 void GenSchedClassTables(const CodeGenProcModel &ProcModel, |
95 SchedClassTables &SchedTables); | 100 SchedClassTables &SchedTables); |
96 void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS); | 101 void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS); |
97 void EmitProcessorModels(raw_ostream &OS); | 102 void EmitProcessorModels(raw_ostream &OS); |
98 void EmitProcessorLookup(raw_ostream &OS); | 103 void EmitProcessorLookup(raw_ostream &OS); |
99 void EmitSchedModelHelpers(std::string ClassName, raw_ostream &OS); | 104 void EmitSchedModelHelpers(const std::string &ClassName, raw_ostream &OS); |
100 void EmitSchedModel(raw_ostream &OS); | 105 void EmitSchedModel(raw_ostream &OS); |
101 void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, | 106 void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, |
102 unsigned NumProcs); | 107 unsigned NumProcs); |
103 | 108 |
104 public: | 109 public: |
105 SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT): | 110 SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT): |
106 Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {} | 111 Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {} |
107 | 112 |
108 void run(raw_ostream &o); | 113 void run(raw_ostream &o); |
109 }; | 114 }; |
115 | |
110 } // end anonymous namespace | 116 } // end anonymous namespace |
111 | 117 |
112 // | 118 // |
113 // Enumeration - Emit the specified class as an enumeration. | 119 // Enumeration - Emit the specified class as an enumeration. |
114 // | 120 // |
115 void SubtargetEmitter::Enumeration(raw_ostream &OS, | 121 void SubtargetEmitter::Enumeration(raw_ostream &OS) { |
116 const char *ClassName) { | |
117 // Get all records of class and sort | 122 // Get all records of class and sort |
118 std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName); | 123 std::vector<Record*> DefList = |
124 Records.getAllDerivedDefinitions("SubtargetFeature"); | |
119 std::sort(DefList.begin(), DefList.end(), LessRecord()); | 125 std::sort(DefList.begin(), DefList.end(), LessRecord()); |
120 | 126 |
121 unsigned N = DefList.size(); | 127 unsigned N = DefList.size(); |
122 if (N == 0) | 128 if (N == 0) |
123 return; | 129 return; |
124 if (N > MAX_SUBTARGET_FEATURES) | 130 if (N > MAX_SUBTARGET_FEATURES) |
125 PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES."); | 131 PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES."); |
126 | 132 |
127 OS << "namespace " << Target << " {\n"; | 133 OS << "namespace " << Target << " {\n"; |
128 | 134 |
129 // Open enumeration. Use a 64-bit underlying type. | 135 // Open enumeration. |
130 OS << "enum : uint64_t {\n"; | 136 OS << "enum {\n"; |
131 | 137 |
132 // For each record | 138 // For each record |
133 for (unsigned i = 0; i < N;) { | 139 for (unsigned i = 0; i < N;) { |
134 // Next record | 140 // Next record |
135 Record *Def = DefList[i]; | 141 Record *Def = DefList[i]; |
140 | 146 |
141 OS << "\n"; | 147 OS << "\n"; |
142 } | 148 } |
143 | 149 |
144 // Close enumeration and namespace | 150 // Close enumeration and namespace |
145 OS << "};\n}\n"; | 151 OS << "};\n"; |
152 OS << "} // end namespace " << Target << "\n"; | |
146 } | 153 } |
147 | 154 |
148 // | 155 // |
149 // FeatureKeyValues - Emit data of all the subtarget features. Used by the | 156 // FeatureKeyValues - Emit data of all the subtarget features. Used by the |
150 // command line. | 157 // command line. |
355 | 362 |
356 // Multiple processor models may share an itinerary record. Emit it once. | 363 // Multiple processor models may share an itinerary record. Emit it once. |
357 SmallPtrSet<Record*, 8> ItinsDefSet; | 364 SmallPtrSet<Record*, 8> ItinsDefSet; |
358 | 365 |
359 // Emit functional units for all the itineraries. | 366 // Emit functional units for all the itineraries. |
360 for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), | 367 for (const CodeGenProcModel &ProcModel : SchedModels.procModels()) { |
361 PE = SchedModels.procModelEnd(); PI != PE; ++PI) { | 368 |
362 | 369 if (!ItinsDefSet.insert(ProcModel.ItinsDef).second) |
363 if (!ItinsDefSet.insert(PI->ItinsDef).second) | |
364 continue; | 370 continue; |
365 | 371 |
366 std::vector<Record*> FUs = PI->ItinsDef->getValueAsListOfDefs("FU"); | 372 std::vector<Record*> FUs = ProcModel.ItinsDef->getValueAsListOfDefs("FU"); |
367 if (FUs.empty()) | 373 if (FUs.empty()) |
368 continue; | 374 continue; |
369 | 375 |
370 const std::string &Name = PI->ItinsDef->getName(); | 376 const std::string &Name = ProcModel.ItinsDef->getName(); |
371 OS << "\n// Functional units for \"" << Name << "\"\n" | 377 OS << "\n// Functional units for \"" << Name << "\"\n" |
372 << "namespace " << Name << "FU {\n"; | 378 << "namespace " << Name << "FU {\n"; |
373 | 379 |
374 for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j) | 380 for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j) |
375 OS << " const unsigned " << FUs[j]->getName() | 381 OS << " const unsigned " << FUs[j]->getName() |
376 << " = 1 << " << j << ";\n"; | 382 << " = 1 << " << j << ";\n"; |
377 | 383 |
378 OS << "}\n"; | 384 OS << "} // end namespace " << Name << "FU\n"; |
379 | 385 |
380 std::vector<Record*> BPs = PI->ItinsDef->getValueAsListOfDefs("BP"); | 386 std::vector<Record*> BPs = ProcModel.ItinsDef->getValueAsListOfDefs("BP"); |
381 if (!BPs.empty()) { | 387 if (!BPs.empty()) { |
382 OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name | 388 OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name |
383 << "\"\n" << "namespace " << Name << "Bypass {\n"; | 389 << "\"\n" << "namespace " << Name << "Bypass {\n"; |
384 | 390 |
385 OS << " const unsigned NoBypass = 0;\n"; | 391 OS << " const unsigned NoBypass = 0;\n"; |
386 for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j) | 392 for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j) |
387 OS << " const unsigned " << BPs[j]->getName() | 393 OS << " const unsigned " << BPs[j]->getName() |
388 << " = 1 << " << j << ";\n"; | 394 << " = 1 << " << j << ";\n"; |
389 | 395 |
390 OS << "}\n"; | 396 OS << "} // end namespace " << Name << "Bypass\n"; |
391 } | 397 } |
392 } | 398 } |
393 | 399 |
394 // Begin stages table | 400 // Begin stages table |
395 std::string StageTable = "\nextern const llvm::InstrStage " + Target + | 401 std::string StageTable = "\nextern const llvm::InstrStage " + Target + |
409 // For each Itinerary across all processors, add a unique entry to the stages, | 415 // For each Itinerary across all processors, add a unique entry to the stages, |
410 // operand cycles, and pipepine bypess tables. Then add the new Itinerary | 416 // operand cycles, and pipepine bypess tables. Then add the new Itinerary |
411 // object with computed offsets to the ProcItinLists result. | 417 // object with computed offsets to the ProcItinLists result. |
412 unsigned StageCount = 1, OperandCycleCount = 1; | 418 unsigned StageCount = 1, OperandCycleCount = 1; |
413 std::map<std::string, unsigned> ItinStageMap, ItinOperandMap; | 419 std::map<std::string, unsigned> ItinStageMap, ItinOperandMap; |
414 for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), | 420 for (const CodeGenProcModel &ProcModel : SchedModels.procModels()) { |
415 PE = SchedModels.procModelEnd(); PI != PE; ++PI) { | |
416 const CodeGenProcModel &ProcModel = *PI; | |
417 | |
418 // Add process itinerary to the list. | 421 // Add process itinerary to the list. |
419 ProcItinLists.resize(ProcItinLists.size()+1); | 422 ProcItinLists.resize(ProcItinLists.size()+1); |
420 | 423 |
421 // If this processor defines no itineraries, then leave the itinerary list | 424 // If this processor defines no itineraries, then leave the itinerary list |
422 // empty. | 425 // empty. |
582 | 585 |
583 // Emit either the value defined in the TableGen Record, or the default | 586 // Emit either the value defined in the TableGen Record, or the default |
584 // value defined in the C++ header. The Record is null if the processor does not | 587 // value defined in the C++ header. The Record is null if the processor does not |
585 // define a model. | 588 // define a model. |
586 void SubtargetEmitter::EmitProcessorProp(raw_ostream &OS, const Record *R, | 589 void SubtargetEmitter::EmitProcessorProp(raw_ostream &OS, const Record *R, |
587 const char *Name, char Separator) { | 590 StringRef Name, char Separator) { |
588 OS << " "; | 591 OS << " "; |
589 int V = R ? R->getValueAsInt(Name) : -1; | 592 int V = R ? R->getValueAsInt(Name) : -1; |
590 if (V >= 0) | 593 if (V >= 0) |
591 OS << V << Separator << " // " << Name; | 594 OS << V << Separator << " // " << Name; |
592 else | 595 else |
610 unsigned SuperIdx = 0; | 613 unsigned SuperIdx = 0; |
611 unsigned NumUnits = 0; | 614 unsigned NumUnits = 0; |
612 int BufferSize = PRDef->getValueAsInt("BufferSize"); | 615 int BufferSize = PRDef->getValueAsInt("BufferSize"); |
613 if (PRDef->isSubClassOf("ProcResGroup")) { | 616 if (PRDef->isSubClassOf("ProcResGroup")) { |
614 RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources"); | 617 RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources"); |
615 for (RecIter RUI = ResUnits.begin(), RUE = ResUnits.end(); | 618 for (Record *RU : ResUnits) { |
616 RUI != RUE; ++RUI) { | 619 NumUnits += RU->getValueAsInt("NumUnits"); |
617 NumUnits += (*RUI)->getValueAsInt("NumUnits"); | |
618 } | 620 } |
619 } | 621 } |
620 else { | 622 else { |
621 // Find the SuperIdx | 623 // Find the SuperIdx |
622 if (PRDef->getValueInit("Super")->isComplete()) { | 624 if (PRDef->getValueInit("Super")->isComplete()) { |
650 // specifies a set of processor resources. | 652 // specifies a set of processor resources. |
651 if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes")) | 653 if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes")) |
652 return SchedWrite.TheDef; | 654 return SchedWrite.TheDef; |
653 | 655 |
654 Record *AliasDef = nullptr; | 656 Record *AliasDef = nullptr; |
655 for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end(); | 657 for (Record *A : SchedWrite.Aliases) { |
656 AI != AE; ++AI) { | |
657 const CodeGenSchedRW &AliasRW = | 658 const CodeGenSchedRW &AliasRW = |
658 SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW")); | 659 SchedModels.getSchedRW(A->getValueAsDef("AliasRW")); |
659 if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) { | 660 if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) { |
660 Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); | 661 Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); |
661 if (&SchedModels.getProcModel(ModelDef) != &ProcModel) | 662 if (&SchedModels.getProcModel(ModelDef) != &ProcModel) |
662 continue; | 663 continue; |
663 } | 664 } |
670 if (AliasDef && AliasDef->isSubClassOf("SchedWriteRes")) | 671 if (AliasDef && AliasDef->isSubClassOf("SchedWriteRes")) |
671 return AliasDef; | 672 return AliasDef; |
672 | 673 |
673 // Check this processor's list of write resources. | 674 // Check this processor's list of write resources. |
674 Record *ResDef = nullptr; | 675 Record *ResDef = nullptr; |
675 for (RecIter WRI = ProcModel.WriteResDefs.begin(), | 676 for (Record *WR : ProcModel.WriteResDefs) { |
676 WRE = ProcModel.WriteResDefs.end(); WRI != WRE; ++WRI) { | 677 if (!WR->isSubClassOf("WriteRes")) |
677 if (!(*WRI)->isSubClassOf("WriteRes")) | |
678 continue; | 678 continue; |
679 if (AliasDef == (*WRI)->getValueAsDef("WriteType") | 679 if (AliasDef == WR->getValueAsDef("WriteType") |
680 || SchedWrite.TheDef == (*WRI)->getValueAsDef("WriteType")) { | 680 || SchedWrite.TheDef == WR->getValueAsDef("WriteType")) { |
681 if (ResDef) { | 681 if (ResDef) { |
682 PrintFatalError((*WRI)->getLoc(), "Resources are defined for both " | 682 PrintFatalError(WR->getLoc(), "Resources are defined for both " |
683 "SchedWrite and its alias on processor " + | 683 "SchedWrite and its alias on processor " + |
684 ProcModel.ModelName); | 684 ProcModel.ModelName); |
685 } | 685 } |
686 ResDef = *WRI; | 686 ResDef = WR; |
687 } | 687 } |
688 } | 688 } |
689 // TODO: If ProcModel has a base model (previous generation processor), | 689 // TODO: If ProcModel has a base model (previous generation processor), |
690 // then call FindWriteResources recursively with that model here. | 690 // then call FindWriteResources recursively with that model here. |
691 if (!ResDef) { | 691 if (!ResDef) { |
704 if (SchedRead.TheDef->isSubClassOf("SchedReadAdvance")) | 704 if (SchedRead.TheDef->isSubClassOf("SchedReadAdvance")) |
705 return SchedRead.TheDef; | 705 return SchedRead.TheDef; |
706 | 706 |
707 // Check this processor's list of aliases for SchedRead. | 707 // Check this processor's list of aliases for SchedRead. |
708 Record *AliasDef = nullptr; | 708 Record *AliasDef = nullptr; |
709 for (RecIter AI = SchedRead.Aliases.begin(), AE = SchedRead.Aliases.end(); | 709 for (Record *A : SchedRead.Aliases) { |
710 AI != AE; ++AI) { | |
711 const CodeGenSchedRW &AliasRW = | 710 const CodeGenSchedRW &AliasRW = |
712 SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW")); | 711 SchedModels.getSchedRW(A->getValueAsDef("AliasRW")); |
713 if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) { | 712 if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) { |
714 Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); | 713 Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel"); |
715 if (&SchedModels.getProcModel(ModelDef) != &ProcModel) | 714 if (&SchedModels.getProcModel(ModelDef) != &ProcModel) |
716 continue; | 715 continue; |
717 } | 716 } |
724 if (AliasDef && AliasDef->isSubClassOf("SchedReadAdvance")) | 723 if (AliasDef && AliasDef->isSubClassOf("SchedReadAdvance")) |
725 return AliasDef; | 724 return AliasDef; |
726 | 725 |
727 // Check this processor's ReadAdvanceList. | 726 // Check this processor's ReadAdvanceList. |
728 Record *ResDef = nullptr; | 727 Record *ResDef = nullptr; |
729 for (RecIter RAI = ProcModel.ReadAdvanceDefs.begin(), | 728 for (Record *RA : ProcModel.ReadAdvanceDefs) { |
730 RAE = ProcModel.ReadAdvanceDefs.end(); RAI != RAE; ++RAI) { | 729 if (!RA->isSubClassOf("ReadAdvance")) |
731 if (!(*RAI)->isSubClassOf("ReadAdvance")) | |
732 continue; | 730 continue; |
733 if (AliasDef == (*RAI)->getValueAsDef("ReadType") | 731 if (AliasDef == RA->getValueAsDef("ReadType") |
734 || SchedRead.TheDef == (*RAI)->getValueAsDef("ReadType")) { | 732 || SchedRead.TheDef == RA->getValueAsDef("ReadType")) { |
735 if (ResDef) { | 733 if (ResDef) { |
736 PrintFatalError((*RAI)->getLoc(), "Resources are defined for both " | 734 PrintFatalError(RA->getLoc(), "Resources are defined for both " |
737 "SchedRead and its alias on processor " + | 735 "SchedRead and its alias on processor " + |
738 ProcModel.ModelName); | 736 ProcModel.ModelName); |
739 } | 737 } |
740 ResDef = *RAI; | 738 ResDef = RA; |
741 } | 739 } |
742 } | 740 } |
743 // TODO: If ProcModel has a base model (previous generation processor), | 741 // TODO: If ProcModel has a base model (previous generation processor), |
744 // then call FindReadAdvance recursively with that model here. | 742 // then call FindReadAdvance recursively with that model here. |
745 if (!ResDef && SchedRead.TheDef->getName() != "ReadDefault") { | 743 if (!ResDef && SchedRead.TheDef->getName() != "ReadDefault") { |
777 PRVec.push_back(SuperDef); | 775 PRVec.push_back(SuperDef); |
778 Cycles.push_back(Cycles[i]); | 776 Cycles.push_back(Cycles[i]); |
779 SubDef = SuperDef; | 777 SubDef = SuperDef; |
780 } | 778 } |
781 } | 779 } |
782 for (RecIter PRI = PM.ProcResourceDefs.begin(), | 780 for (Record *PR : PM.ProcResourceDefs) { |
783 PRE = PM.ProcResourceDefs.end(); | 781 if (PR == PRDef || !PR->isSubClassOf("ProcResGroup")) |
784 PRI != PRE; ++PRI) { | |
785 if (*PRI == PRDef || !(*PRI)->isSubClassOf("ProcResGroup")) | |
786 continue; | 782 continue; |
787 RecVec SuperResources = (*PRI)->getValueAsListOfDefs("Resources"); | 783 RecVec SuperResources = PR->getValueAsListOfDefs("Resources"); |
788 RecIter SubI = SubResources.begin(), SubE = SubResources.end(); | 784 RecIter SubI = SubResources.begin(), SubE = SubResources.end(); |
789 for( ; SubI != SubE; ++SubI) { | 785 for( ; SubI != SubE; ++SubI) { |
790 if (std::find(SuperResources.begin(), SuperResources.end(), *SubI) | 786 if (!is_contained(SuperResources, *SubI)) { |
791 == SuperResources.end()) { | |
792 break; | 787 break; |
793 } | 788 } |
794 } | 789 } |
795 if (SubI == SubE) { | 790 if (SubI == SubE) { |
796 PRVec.push_back(*PRI); | 791 PRVec.push_back(PR); |
797 Cycles.push_back(Cycles[i]); | 792 Cycles.push_back(Cycles[i]); |
798 } | 793 } |
799 } | 794 } |
800 } | 795 } |
801 } | 796 } |
807 SchedTables.ProcSchedClasses.resize(SchedTables.ProcSchedClasses.size() + 1); | 802 SchedTables.ProcSchedClasses.resize(SchedTables.ProcSchedClasses.size() + 1); |
808 if (!ProcModel.hasInstrSchedModel()) | 803 if (!ProcModel.hasInstrSchedModel()) |
809 return; | 804 return; |
810 | 805 |
811 std::vector<MCSchedClassDesc> &SCTab = SchedTables.ProcSchedClasses.back(); | 806 std::vector<MCSchedClassDesc> &SCTab = SchedTables.ProcSchedClasses.back(); |
812 for (CodeGenSchedModels::SchedClassIter SCI = SchedModels.schedClassBegin(), | 807 for (const CodeGenSchedClass &SC : SchedModels.schedClasses()) { |
813 SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) { | 808 DEBUG(SC.dump(&SchedModels)); |
814 DEBUG(SCI->dump(&SchedModels)); | |
815 | 809 |
816 SCTab.resize(SCTab.size() + 1); | 810 SCTab.resize(SCTab.size() + 1); |
817 MCSchedClassDesc &SCDesc = SCTab.back(); | 811 MCSchedClassDesc &SCDesc = SCTab.back(); |
818 // SCDesc.Name is guarded by NDEBUG | 812 // SCDesc.Name is guarded by NDEBUG |
819 SCDesc.NumMicroOps = 0; | 813 SCDesc.NumMicroOps = 0; |
824 SCDesc.ReadAdvanceIdx = 0; | 818 SCDesc.ReadAdvanceIdx = 0; |
825 | 819 |
826 // A Variant SchedClass has no resources of its own. | 820 // A Variant SchedClass has no resources of its own. |
827 bool HasVariants = false; | 821 bool HasVariants = false; |
828 for (std::vector<CodeGenSchedTransition>::const_iterator | 822 for (std::vector<CodeGenSchedTransition>::const_iterator |
829 TI = SCI->Transitions.begin(), TE = SCI->Transitions.end(); | 823 TI = SC.Transitions.begin(), TE = SC.Transitions.end(); |
830 TI != TE; ++TI) { | 824 TI != TE; ++TI) { |
831 if (TI->ProcIndices[0] == 0) { | 825 if (TI->ProcIndices[0] == 0) { |
832 HasVariants = true; | 826 HasVariants = true; |
833 break; | 827 break; |
834 } | 828 } |
835 IdxIter PIPos = std::find(TI->ProcIndices.begin(), | 829 if (is_contained(TI->ProcIndices, ProcModel.Index)) { |
836 TI->ProcIndices.end(), ProcModel.Index); | |
837 if (PIPos != TI->ProcIndices.end()) { | |
838 HasVariants = true; | 830 HasVariants = true; |
839 break; | 831 break; |
840 } | 832 } |
841 } | 833 } |
842 if (HasVariants) { | 834 if (HasVariants) { |
845 } | 837 } |
846 | 838 |
847 // Determine if the SchedClass is actually reachable on this processor. If | 839 // Determine if the SchedClass is actually reachable on this processor. If |
848 // not don't try to locate the processor resources, it will fail. | 840 // not don't try to locate the processor resources, it will fail. |
849 // If ProcIndices contains 0, this class applies to all processors. | 841 // If ProcIndices contains 0, this class applies to all processors. |
850 assert(!SCI->ProcIndices.empty() && "expect at least one procidx"); | 842 assert(!SC.ProcIndices.empty() && "expect at least one procidx"); |
851 if (SCI->ProcIndices[0] != 0) { | 843 if (SC.ProcIndices[0] != 0) { |
852 IdxIter PIPos = std::find(SCI->ProcIndices.begin(), | 844 if (!is_contained(SC.ProcIndices, ProcModel.Index)) |
853 SCI->ProcIndices.end(), ProcModel.Index); | |
854 if (PIPos == SCI->ProcIndices.end()) | |
855 continue; | 845 continue; |
856 } | 846 } |
857 IdxVec Writes = SCI->Writes; | 847 IdxVec Writes = SC.Writes; |
858 IdxVec Reads = SCI->Reads; | 848 IdxVec Reads = SC.Reads; |
859 if (!SCI->InstRWs.empty()) { | 849 if (!SC.InstRWs.empty()) { |
860 // This class has a default ReadWrite list which can be overriden by | 850 // This class has a default ReadWrite list which can be overriden by |
861 // InstRW definitions. | 851 // InstRW definitions. |
862 Record *RWDef = nullptr; | 852 Record *RWDef = nullptr; |
863 for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end(); | 853 for (Record *RW : SC.InstRWs) { |
864 RWI != RWE; ++RWI) { | 854 Record *RWModelDef = RW->getValueAsDef("SchedModel"); |
865 Record *RWModelDef = (*RWI)->getValueAsDef("SchedModel"); | |
866 if (&ProcModel == &SchedModels.getProcModel(RWModelDef)) { | 855 if (&ProcModel == &SchedModels.getProcModel(RWModelDef)) { |
867 RWDef = *RWI; | 856 RWDef = RW; |
868 break; | 857 break; |
869 } | 858 } |
870 } | 859 } |
871 if (RWDef) { | 860 if (RWDef) { |
872 Writes.clear(); | 861 Writes.clear(); |
875 Writes, Reads); | 864 Writes, Reads); |
876 } | 865 } |
877 } | 866 } |
878 if (Writes.empty()) { | 867 if (Writes.empty()) { |
879 // Check this processor's itinerary class resources. | 868 // Check this processor's itinerary class resources. |
880 for (RecIter II = ProcModel.ItinRWDefs.begin(), | 869 for (Record *I : ProcModel.ItinRWDefs) { |
881 IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) { | 870 RecVec Matched = I->getValueAsListOfDefs("MatchedItinClasses"); |
882 RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses"); | 871 if (is_contained(Matched, SC.ItinClassDef)) { |
883 if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef) | 872 SchedModels.findRWs(I->getValueAsListOfDefs("OperandReadWrites"), |
884 != Matched.end()) { | |
885 SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"), | |
886 Writes, Reads); | 873 Writes, Reads); |
887 break; | 874 break; |
888 } | 875 } |
889 } | 876 } |
890 if (Writes.empty()) { | 877 if (Writes.empty()) { |
891 DEBUG(dbgs() << ProcModel.ModelName | 878 DEBUG(dbgs() << ProcModel.ModelName |
892 << " does not have resources for class " << SCI->Name << '\n'); | 879 << " does not have resources for class " << SC.Name << '\n'); |
893 } | 880 } |
894 } | 881 } |
895 // Sum resources across all operand writes. | 882 // Sum resources across all operand writes. |
896 std::vector<MCWriteProcResEntry> WriteProcResources; | 883 std::vector<MCWriteProcResEntry> WriteProcResources; |
897 std::vector<MCWriteLatencyEntry> WriteLatencies; | 884 std::vector<MCWriteLatencyEntry> WriteLatencies; |
898 std::vector<std::string> WriterNames; | 885 std::vector<std::string> WriterNames; |
899 std::vector<MCReadAdvanceEntry> ReadAdvanceEntries; | 886 std::vector<MCReadAdvanceEntry> ReadAdvanceEntries; |
900 for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) { | 887 for (unsigned W : Writes) { |
901 IdxVec WriteSeq; | 888 IdxVec WriteSeq; |
902 SchedModels.expandRWSeqForProc(*WI, WriteSeq, /*IsRead=*/false, | 889 SchedModels.expandRWSeqForProc(W, WriteSeq, /*IsRead=*/false, |
903 ProcModel); | 890 ProcModel); |
904 | 891 |
905 // For each operand, create a latency entry. | 892 // For each operand, create a latency entry. |
906 MCWriteLatencyEntry WLEntry; | 893 MCWriteLatencyEntry WLEntry; |
907 WLEntry.Cycles = 0; | 894 WLEntry.Cycles = 0; |
913 SchedModels.getSchedWrite(WriteID).TheDef)) { | 900 SchedModels.getSchedWrite(WriteID).TheDef)) { |
914 WriteID = 0; | 901 WriteID = 0; |
915 } | 902 } |
916 WLEntry.WriteResourceID = WriteID; | 903 WLEntry.WriteResourceID = WriteID; |
917 | 904 |
918 for (IdxIter WSI = WriteSeq.begin(), WSE = WriteSeq.end(); | 905 for (unsigned WS : WriteSeq) { |
919 WSI != WSE; ++WSI) { | |
920 | 906 |
921 Record *WriteRes = | 907 Record *WriteRes = |
922 FindWriteResources(SchedModels.getSchedWrite(*WSI), ProcModel); | 908 FindWriteResources(SchedModels.getSchedWrite(WS), ProcModel); |
923 | 909 |
924 // Mark the parent class as invalid for unsupported write types. | 910 // Mark the parent class as invalid for unsupported write types. |
925 if (WriteRes->getValueAsBit("Unsupported")) { | 911 if (WriteRes->getValueAsBit("Unsupported")) { |
926 SCDesc.NumMicroOps = MCSchedClassDesc::InvalidNumMicroOps; | 912 SCDesc.NumMicroOps = MCSchedClassDesc::InvalidNumMicroOps; |
927 break; | 913 break; |
979 RecVec ValidWrites = ReadAdvance->getValueAsListOfDefs("ValidWrites"); | 965 RecVec ValidWrites = ReadAdvance->getValueAsListOfDefs("ValidWrites"); |
980 IdxVec WriteIDs; | 966 IdxVec WriteIDs; |
981 if (ValidWrites.empty()) | 967 if (ValidWrites.empty()) |
982 WriteIDs.push_back(0); | 968 WriteIDs.push_back(0); |
983 else { | 969 else { |
984 for (RecIter VWI = ValidWrites.begin(), VWE = ValidWrites.end(); | 970 for (Record *VW : ValidWrites) { |
985 VWI != VWE; ++VWI) { | 971 WriteIDs.push_back(SchedModels.getSchedRWIdx(VW, /*IsRead=*/false)); |
986 WriteIDs.push_back(SchedModels.getSchedRWIdx(*VWI, /*IsRead=*/false)); | |
987 } | 972 } |
988 } | 973 } |
989 std::sort(WriteIDs.begin(), WriteIDs.end()); | 974 std::sort(WriteIDs.begin(), WriteIDs.end()); |
990 for(IdxIter WI = WriteIDs.begin(), WE = WriteIDs.end(); WI != WE; ++WI) { | 975 for(unsigned W : WriteIDs) { |
991 MCReadAdvanceEntry RAEntry; | 976 MCReadAdvanceEntry RAEntry; |
992 RAEntry.UseIdx = UseIdx; | 977 RAEntry.UseIdx = UseIdx; |
993 RAEntry.WriteResourceID = *WI; | 978 RAEntry.WriteResourceID = W; |
994 RAEntry.Cycles = ReadAdvance->getValueAsInt("Cycles"); | 979 RAEntry.Cycles = ReadAdvance->getValueAsInt("Cycles"); |
995 ReadAdvanceEntries.push_back(RAEntry); | 980 ReadAdvanceEntries.push_back(RAEntry); |
996 } | 981 } |
997 } | 982 } |
998 if (SCDesc.NumMicroOps == MCSchedClassDesc::InvalidNumMicroOps) { | 983 if (SCDesc.NumMicroOps == MCSchedClassDesc::InvalidNumMicroOps) { |
1128 // name and position. | 1113 // name and position. |
1129 assert(SchedModels.getSchedClass(0).Name == "NoInstrModel" | 1114 assert(SchedModels.getSchedClass(0).Name == "NoInstrModel" |
1130 && "invalid class not first"); | 1115 && "invalid class not first"); |
1131 OS << " {DBGFIELD(\"InvalidSchedClass\") " | 1116 OS << " {DBGFIELD(\"InvalidSchedClass\") " |
1132 << MCSchedClassDesc::InvalidNumMicroOps | 1117 << MCSchedClassDesc::InvalidNumMicroOps |
1133 << ", 0, 0, 0, 0, 0, 0, 0, 0},\n"; | 1118 << ", false, false, 0, 0, 0, 0, 0, 0},\n"; |
1134 | 1119 |
1135 for (unsigned SCIdx = 1, SCEnd = SCTab.size(); SCIdx != SCEnd; ++SCIdx) { | 1120 for (unsigned SCIdx = 1, SCEnd = SCTab.size(); SCIdx != SCEnd; ++SCIdx) { |
1136 MCSchedClassDesc &MCDesc = SCTab[SCIdx]; | 1121 MCSchedClassDesc &MCDesc = SCTab[SCIdx]; |
1137 const CodeGenSchedClass &SchedClass = SchedModels.getSchedClass(SCIdx); | 1122 const CodeGenSchedClass &SchedClass = SchedModels.getSchedClass(SCIdx); |
1138 OS << " {DBGFIELD(\"" << SchedClass.Name << "\") "; | 1123 OS << " {DBGFIELD(\"" << SchedClass.Name << "\") "; |
1139 if (SchedClass.Name.size() < 18) | 1124 if (SchedClass.Name.size() < 18) |
1140 OS.indent(18 - SchedClass.Name.size()); | 1125 OS.indent(18 - SchedClass.Name.size()); |
1141 OS << MCDesc.NumMicroOps | 1126 OS << MCDesc.NumMicroOps |
1142 << ", " << MCDesc.BeginGroup << ", " << MCDesc.EndGroup | 1127 << ", " << ( MCDesc.BeginGroup ? "true" : "false" ) |
1128 << ", " << ( MCDesc.EndGroup ? "true" : "false" ) | |
1143 << ", " << format("%2d", MCDesc.WriteProcResIdx) | 1129 << ", " << format("%2d", MCDesc.WriteProcResIdx) |
1144 << ", " << MCDesc.NumWriteProcResEntries | 1130 << ", " << MCDesc.NumWriteProcResEntries |
1145 << ", " << format("%2d", MCDesc.WriteLatencyIdx) | 1131 << ", " << format("%2d", MCDesc.WriteLatencyIdx) |
1146 << ", " << MCDesc.NumWriteLatencyEntries | 1132 << ", " << MCDesc.NumWriteLatencyEntries |
1147 << ", " << format("%2d", MCDesc.ReadAdvanceIdx) | 1133 << ", " << format("%2d", MCDesc.ReadAdvanceIdx) |
1154 } | 1140 } |
1155 } | 1141 } |
1156 | 1142 |
1157 void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) { | 1143 void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) { |
1158 // For each processor model. | 1144 // For each processor model. |
1159 for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), | 1145 for (const CodeGenProcModel &PM : SchedModels.procModels()) { |
1160 PE = SchedModels.procModelEnd(); PI != PE; ++PI) { | |
1161 // Emit processor resource table. | 1146 // Emit processor resource table. |
1162 if (PI->hasInstrSchedModel()) | 1147 if (PM.hasInstrSchedModel()) |
1163 EmitProcessorResources(*PI, OS); | 1148 EmitProcessorResources(PM, OS); |
1164 else if(!PI->ProcResourceDefs.empty()) | 1149 else if(!PM.ProcResourceDefs.empty()) |
1165 PrintFatalError(PI->ModelDef->getLoc(), "SchedMachineModel defines " | 1150 PrintFatalError(PM.ModelDef->getLoc(), "SchedMachineModel defines " |
1166 "ProcResources without defining WriteRes SchedWriteRes"); | 1151 "ProcResources without defining WriteRes SchedWriteRes"); |
1167 | 1152 |
1168 // Begin processor itinerary properties | 1153 // Begin processor itinerary properties |
1169 OS << "\n"; | 1154 OS << "\n"; |
1170 OS << "static const llvm::MCSchedModel " << PI->ModelName << " = {\n"; | 1155 OS << "static const llvm::MCSchedModel " << PM.ModelName << " = {\n"; |
1171 EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ','); | 1156 EmitProcessorProp(OS, PM.ModelDef, "IssueWidth", ','); |
1172 EmitProcessorProp(OS, PI->ModelDef, "MicroOpBufferSize", ','); | 1157 EmitProcessorProp(OS, PM.ModelDef, "MicroOpBufferSize", ','); |
1173 EmitProcessorProp(OS, PI->ModelDef, "LoopMicroOpBufferSize", ','); | 1158 EmitProcessorProp(OS, PM.ModelDef, "LoopMicroOpBufferSize", ','); |
1174 EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ','); | 1159 EmitProcessorProp(OS, PM.ModelDef, "LoadLatency", ','); |
1175 EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ','); | 1160 EmitProcessorProp(OS, PM.ModelDef, "HighLatency", ','); |
1176 EmitProcessorProp(OS, PI->ModelDef, "MispredictPenalty", ','); | 1161 EmitProcessorProp(OS, PM.ModelDef, "MispredictPenalty", ','); |
1177 | 1162 |
1178 OS << " " << (bool)(PI->ModelDef ? | 1163 bool PostRAScheduler = |
1179 PI->ModelDef->getValueAsBit("PostRAScheduler") : 0) | 1164 (PM.ModelDef ? PM.ModelDef->getValueAsBit("PostRAScheduler") : false); |
1180 << ", // " << "PostRAScheduler\n"; | 1165 |
1181 | 1166 OS << " " << (PostRAScheduler ? "true" : "false") << ", // " |
1182 OS << " " << (bool)(PI->ModelDef ? | 1167 << "PostRAScheduler\n"; |
1183 PI->ModelDef->getValueAsBit("CompleteModel") : 0) | 1168 |
1184 << ", // " << "CompleteModel\n"; | 1169 bool CompleteModel = |
1185 | 1170 (PM.ModelDef ? PM.ModelDef->getValueAsBit("CompleteModel") : false); |
1186 OS << " " << PI->Index << ", // Processor ID\n"; | 1171 |
1187 if (PI->hasInstrSchedModel()) | 1172 OS << " " << (CompleteModel ? "true" : "false") << ", // " |
1188 OS << " " << PI->ModelName << "ProcResources" << ",\n" | 1173 << "CompleteModel\n"; |
1189 << " " << PI->ModelName << "SchedClasses" << ",\n" | 1174 |
1190 << " " << PI->ProcResourceDefs.size()+1 << ",\n" | 1175 OS << " " << PM.Index << ", // Processor ID\n"; |
1176 if (PM.hasInstrSchedModel()) | |
1177 OS << " " << PM.ModelName << "ProcResources" << ",\n" | |
1178 << " " << PM.ModelName << "SchedClasses" << ",\n" | |
1179 << " " << PM.ProcResourceDefs.size()+1 << ",\n" | |
1191 << " " << (SchedModels.schedClassEnd() | 1180 << " " << (SchedModels.schedClassEnd() |
1192 - SchedModels.schedClassBegin()) << ",\n"; | 1181 - SchedModels.schedClassBegin()) << ",\n"; |
1193 else | 1182 else |
1194 OS << " nullptr, nullptr, 0, 0," | 1183 OS << " nullptr, nullptr, 0, 0," |
1195 << " // No instruction-level machine model.\n"; | 1184 << " // No instruction-level machine model.\n"; |
1196 if (PI->hasItineraries()) | 1185 if (PM.hasItineraries()) |
1197 OS << " " << PI->ItinsDef->getName() << "};\n"; | 1186 OS << " " << PM.ItinsDef->getName() << "};\n"; |
1198 else | 1187 else |
1199 OS << " nullptr}; // No Itinerary\n"; | 1188 OS << " nullptr}; // No Itinerary\n"; |
1200 } | 1189 } |
1201 } | 1190 } |
1202 | 1191 |
1258 } | 1247 } |
1259 OS << "\n// ===============================================================\n" | 1248 OS << "\n// ===============================================================\n" |
1260 << "// Data tables for the new per-operand machine model.\n"; | 1249 << "// Data tables for the new per-operand machine model.\n"; |
1261 | 1250 |
1262 SchedClassTables SchedTables; | 1251 SchedClassTables SchedTables; |
1263 for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(), | 1252 for (const CodeGenProcModel &ProcModel : SchedModels.procModels()) { |
1264 PE = SchedModels.procModelEnd(); PI != PE; ++PI) { | 1253 GenSchedClassTables(ProcModel, SchedTables); |
1265 GenSchedClassTables(*PI, SchedTables); | |
1266 } | 1254 } |
1267 EmitSchedClassTables(SchedTables, OS); | 1255 EmitSchedClassTables(SchedTables, OS); |
1268 | 1256 |
1269 // Emit the processor machine model | 1257 // Emit the processor machine model |
1270 EmitProcessorModels(OS); | 1258 EmitProcessorModels(OS); |
1272 EmitProcessorLookup(OS); | 1260 EmitProcessorLookup(OS); |
1273 | 1261 |
1274 OS << "#undef DBGFIELD"; | 1262 OS << "#undef DBGFIELD"; |
1275 } | 1263 } |
1276 | 1264 |
1277 void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName, | 1265 void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName, |
1278 raw_ostream &OS) { | 1266 raw_ostream &OS) { |
1279 OS << "unsigned " << ClassName | 1267 OS << "unsigned " << ClassName |
1280 << "\n::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI," | 1268 << "\n::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI," |
1281 << " const TargetSchedModel *SchedModel) const {\n"; | 1269 << " const TargetSchedModel *SchedModel) const {\n"; |
1282 | 1270 |
1283 std::vector<Record*> Prologs = Records.getAllDerivedDefinitions("PredicateProlog"); | 1271 std::vector<Record*> Prologs = Records.getAllDerivedDefinitions("PredicateProlog"); |
1284 std::sort(Prologs.begin(), Prologs.end(), LessRecord()); | 1272 std::sort(Prologs.begin(), Prologs.end(), LessRecord()); |
1285 for (std::vector<Record*>::const_iterator | 1273 for (Record *P : Prologs) { |
1286 PI = Prologs.begin(), PE = Prologs.end(); PI != PE; ++PI) { | 1274 OS << P->getValueAsString("Code") << '\n'; |
1287 OS << (*PI)->getValueAsString("Code") << '\n'; | |
1288 } | 1275 } |
1289 IdxVec VariantClasses; | 1276 IdxVec VariantClasses; |
1290 for (CodeGenSchedModels::SchedClassIter SCI = SchedModels.schedClassBegin(), | 1277 for (const CodeGenSchedClass &SC : SchedModels.schedClasses()) { |
1291 SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) { | 1278 if (SC.Transitions.empty()) |
1292 if (SCI->Transitions.empty()) | |
1293 continue; | 1279 continue; |
1294 VariantClasses.push_back(SCI->Index); | 1280 VariantClasses.push_back(SC.Index); |
1295 } | 1281 } |
1296 if (!VariantClasses.empty()) { | 1282 if (!VariantClasses.empty()) { |
1297 OS << " switch (SchedClass) {\n"; | 1283 OS << " switch (SchedClass) {\n"; |
1298 for (IdxIter VCI = VariantClasses.begin(), VCE = VariantClasses.end(); | 1284 for (unsigned VC : VariantClasses) { |
1299 VCI != VCE; ++VCI) { | 1285 const CodeGenSchedClass &SC = SchedModels.getSchedClass(VC); |
1300 const CodeGenSchedClass &SC = SchedModels.getSchedClass(*VCI); | 1286 OS << " case " << VC << ": // " << SC.Name << '\n'; |
1301 OS << " case " << *VCI << ": // " << SC.Name << '\n'; | |
1302 IdxVec ProcIndices; | 1287 IdxVec ProcIndices; |
1303 for (std::vector<CodeGenSchedTransition>::const_iterator | 1288 for (const CodeGenSchedTransition &T : SC.Transitions) { |
1304 TI = SC.Transitions.begin(), TE = SC.Transitions.end(); | |
1305 TI != TE; ++TI) { | |
1306 IdxVec PI; | 1289 IdxVec PI; |
1307 std::set_union(TI->ProcIndices.begin(), TI->ProcIndices.end(), | 1290 std::set_union(T.ProcIndices.begin(), T.ProcIndices.end(), |
1308 ProcIndices.begin(), ProcIndices.end(), | 1291 ProcIndices.begin(), ProcIndices.end(), |
1309 std::back_inserter(PI)); | 1292 std::back_inserter(PI)); |
1310 ProcIndices.swap(PI); | 1293 ProcIndices.swap(PI); |
1311 } | 1294 } |
1312 for (IdxIter PI = ProcIndices.begin(), PE = ProcIndices.end(); | 1295 for (unsigned PI : ProcIndices) { |
1313 PI != PE; ++PI) { | |
1314 OS << " "; | 1296 OS << " "; |
1315 if (*PI != 0) | 1297 if (PI != 0) |
1316 OS << "if (SchedModel->getProcessorID() == " << *PI << ") "; | 1298 OS << "if (SchedModel->getProcessorID() == " << PI << ") "; |
1317 OS << "{ // " << (SchedModels.procModelBegin() + *PI)->ModelName | 1299 OS << "{ // " << (SchedModels.procModelBegin() + PI)->ModelName |
1318 << '\n'; | 1300 << '\n'; |
1319 for (std::vector<CodeGenSchedTransition>::const_iterator | 1301 for (const CodeGenSchedTransition &T : SC.Transitions) { |
1320 TI = SC.Transitions.begin(), TE = SC.Transitions.end(); | 1302 if (PI != 0 && !std::count(T.ProcIndices.begin(), |
1321 TI != TE; ++TI) { | 1303 T.ProcIndices.end(), PI)) { |
1322 if (*PI != 0 && !std::count(TI->ProcIndices.begin(), | |
1323 TI->ProcIndices.end(), *PI)) { | |
1324 continue; | 1304 continue; |
1325 } | 1305 } |
1326 OS << " if ("; | 1306 OS << " if ("; |
1327 for (RecIter RI = TI->PredTerm.begin(), RE = TI->PredTerm.end(); | 1307 for (RecIter RI = T.PredTerm.begin(), RE = T.PredTerm.end(); |
1328 RI != RE; ++RI) { | 1308 RI != RE; ++RI) { |
1329 if (RI != TI->PredTerm.begin()) | 1309 if (RI != T.PredTerm.begin()) |
1330 OS << "\n && "; | 1310 OS << "\n && "; |
1331 OS << "(" << (*RI)->getValueAsString("Predicate") << ")"; | 1311 OS << "(" << (*RI)->getValueAsString("Predicate") << ")"; |
1332 } | 1312 } |
1333 OS << ")\n" | 1313 OS << ")\n" |
1334 << " return " << TI->ToClassIdx << "; // " | 1314 << " return " << T.ToClassIdx << "; // " |
1335 << SchedModels.getSchedClass(TI->ToClassIdx).Name << '\n'; | 1315 << SchedModels.getSchedClass(T.ToClassIdx).Name << '\n'; |
1336 } | 1316 } |
1337 OS << " }\n"; | 1317 OS << " }\n"; |
1338 if (*PI == 0) | 1318 if (PI == 0) |
1339 break; | 1319 break; |
1340 } | 1320 } |
1341 if (SC.isInferred()) | 1321 if (SC.isInferred()) |
1342 OS << " return " << SC.Index << ";\n"; | 1322 OS << " return " << SC.Index << ";\n"; |
1343 OS << " break;\n"; | 1323 OS << " break;\n"; |
1373 } | 1353 } |
1374 | 1354 |
1375 OS << " InitMCProcessorInfo(CPU, FS);\n" | 1355 OS << " InitMCProcessorInfo(CPU, FS);\n" |
1376 << " const FeatureBitset& Bits = getFeatureBits();\n"; | 1356 << " const FeatureBitset& Bits = getFeatureBits();\n"; |
1377 | 1357 |
1378 for (unsigned i = 0; i < Features.size(); i++) { | 1358 for (Record *R : Features) { |
1379 // Next record | 1359 // Next record |
1380 Record *R = Features[i]; | |
1381 const std::string &Instance = R->getName(); | 1360 const std::string &Instance = R->getName(); |
1382 const std::string &Value = R->getValueAsString("Value"); | 1361 const std::string &Value = R->getValueAsString("Value"); |
1383 const std::string &Attribute = R->getValueAsString("Attribute"); | 1362 const std::string &Attribute = R->getValueAsString("Attribute"); |
1384 | 1363 |
1385 if (Value=="true" || Value=="false") | 1364 if (Value=="true" || Value=="false") |
1401 // | 1380 // |
1402 void SubtargetEmitter::run(raw_ostream &OS) { | 1381 void SubtargetEmitter::run(raw_ostream &OS) { |
1403 emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); | 1382 emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); |
1404 | 1383 |
1405 OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; | 1384 OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; |
1406 OS << "#undef GET_SUBTARGETINFO_ENUM\n"; | 1385 OS << "#undef GET_SUBTARGETINFO_ENUM\n\n"; |
1407 | 1386 |
1408 OS << "namespace llvm {\n"; | 1387 OS << "namespace llvm {\n"; |
1409 Enumeration(OS, "SubtargetFeature"); | 1388 Enumeration(OS); |
1410 OS << "} // end llvm namespace\n"; | 1389 OS << "} // end namespace llvm\n\n"; |
1411 OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; | 1390 OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; |
1412 | 1391 |
1413 OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; | 1392 OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; |
1414 OS << "#undef GET_SUBTARGETINFO_MC_DESC\n"; | 1393 OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n"; |
1415 | 1394 |
1416 OS << "namespace llvm {\n"; | 1395 OS << "namespace llvm {\n"; |
1417 #if 0 | 1396 #if 0 |
1418 OS << "namespace {\n"; | 1397 OS << "namespace {\n"; |
1419 #endif | 1398 #endif |
1422 unsigned NumProcs = CPUKeyValues(OS); | 1401 unsigned NumProcs = CPUKeyValues(OS); |
1423 OS << "\n"; | 1402 OS << "\n"; |
1424 EmitSchedModel(OS); | 1403 EmitSchedModel(OS); |
1425 OS << "\n"; | 1404 OS << "\n"; |
1426 #if 0 | 1405 #if 0 |
1427 OS << "}\n"; | 1406 OS << "} // end anonymous namespace\n\n"; |
1428 #endif | 1407 #endif |
1429 | 1408 |
1430 // MCInstrInfo initialization routine. | 1409 // MCInstrInfo initialization routine. |
1431 OS << "static inline MCSubtargetInfo *create" << Target | 1410 OS << "static inline MCSubtargetInfo *create" << Target |
1432 << "MCSubtargetInfoImpl(" | 1411 << "MCSubtargetInfoImpl(" |
1452 << Target << "ForwardingPaths"; | 1431 << Target << "ForwardingPaths"; |
1453 } else | 1432 } else |
1454 OS << "0, 0, 0"; | 1433 OS << "0, 0, 0"; |
1455 OS << ");\n}\n\n"; | 1434 OS << ");\n}\n\n"; |
1456 | 1435 |
1457 OS << "} // end llvm namespace\n"; | 1436 OS << "} // end namespace llvm\n\n"; |
1458 | 1437 |
1459 OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; | 1438 OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; |
1460 | 1439 |
1461 OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; | 1440 OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; |
1462 OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n"; | 1441 OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n\n"; |
1463 | 1442 |
1464 OS << "#include \"llvm/Support/Debug.h\"\n"; | 1443 OS << "#include \"llvm/Support/Debug.h\"\n"; |
1465 OS << "#include \"llvm/Support/raw_ostream.h\"\n"; | 1444 OS << "#include \"llvm/Support/raw_ostream.h\"\n\n"; |
1466 ParseFeaturesFunction(OS, NumFeatures, NumProcs); | 1445 ParseFeaturesFunction(OS, NumFeatures, NumProcs); |
1467 | 1446 |
1468 OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; | 1447 OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; |
1469 | 1448 |
1470 // Create a TargetSubtargetInfo subclass to hide the MC layer initialization. | 1449 // Create a TargetSubtargetInfo subclass to hide the MC layer initialization. |
1471 OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n"; | 1450 OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n"; |
1472 OS << "#undef GET_SUBTARGETINFO_HEADER\n"; | 1451 OS << "#undef GET_SUBTARGETINFO_HEADER\n\n"; |
1473 | 1452 |
1474 std::string ClassName = Target + "GenSubtargetInfo"; | 1453 std::string ClassName = Target + "GenSubtargetInfo"; |
1475 OS << "namespace llvm {\n"; | 1454 OS << "namespace llvm {\n"; |
1476 OS << "class DFAPacketizer;\n"; | 1455 OS << "class DFAPacketizer;\n"; |
1477 OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" | 1456 OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" |
1482 << " const MachineInstr *DefMI," | 1461 << " const MachineInstr *DefMI," |
1483 << " const TargetSchedModel *SchedModel) const override;\n" | 1462 << " const TargetSchedModel *SchedModel) const override;\n" |
1484 << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" | 1463 << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" |
1485 << " const;\n" | 1464 << " const;\n" |
1486 << "};\n"; | 1465 << "};\n"; |
1487 OS << "} // end llvm namespace\n"; | 1466 OS << "} // end namespace llvm\n\n"; |
1488 | 1467 |
1489 OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; | 1468 OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; |
1490 | 1469 |
1491 OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; | 1470 OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; |
1492 OS << "#undef GET_SUBTARGETINFO_CTOR\n"; | 1471 OS << "#undef GET_SUBTARGETINFO_CTOR\n\n"; |
1493 | 1472 |
1494 OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n"; | 1473 OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n\n"; |
1495 OS << "namespace llvm {\n"; | 1474 OS << "namespace llvm {\n"; |
1496 OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n"; | 1475 OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n"; |
1497 OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n"; | 1476 OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n"; |
1498 OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcSchedKV[];\n"; | 1477 OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcSchedKV[];\n"; |
1499 OS << "extern const llvm::MCWriteProcResEntry " | 1478 OS << "extern const llvm::MCWriteProcResEntry " |
1534 OS << "0, 0, 0"; | 1513 OS << "0, 0, 0"; |
1535 OS << ") {}\n\n"; | 1514 OS << ") {}\n\n"; |
1536 | 1515 |
1537 EmitSchedModelHelpers(ClassName, OS); | 1516 EmitSchedModelHelpers(ClassName, OS); |
1538 | 1517 |
1539 OS << "} // end llvm namespace\n"; | 1518 OS << "} // end namespace llvm\n\n"; |
1540 | 1519 |
1541 OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; | 1520 OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; |
1542 } | 1521 } |
1543 | 1522 |
1544 namespace llvm { | 1523 namespace llvm { |
1546 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) { | 1525 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) { |
1547 CodeGenTarget CGTarget(RK); | 1526 CodeGenTarget CGTarget(RK); |
1548 SubtargetEmitter(RK, CGTarget).run(OS); | 1527 SubtargetEmitter(RK, CGTarget).run(OS); |
1549 } | 1528 } |
1550 | 1529 |
1551 } // end llvm namespace | 1530 } // end namespace llvm |