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