comparison utils/TableGen/SubtargetEmitter.cpp @ 95:afa8332a0e37 LLVM3.8

LLVM 3.8
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Tue, 13 Oct 2015 17:48:58 +0900
parents 60c9769439b8
children 7d135dc70f03
comparison
equal deleted inserted replaced
84:f3e34b893a5f 95:afa8332a0e37
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/STLExtras.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/SubtargetFeature.h"
19 #include "llvm/Support/Debug.h" 20 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/Format.h" 21 #include "llvm/Support/Format.h"
21 #include "llvm/TableGen/Error.h" 22 #include "llvm/TableGen/Error.h"
22 #include "llvm/TableGen/Record.h" 23 #include "llvm/TableGen/Record.h"
23 #include "llvm/TableGen/TableGenBackend.h" 24 #include "llvm/TableGen/TableGenBackend.h"
24 #include <algorithm> 25 #include <algorithm>
25 #include <map> 26 #include <map>
26 #include <string> 27 #include <string>
27 #include <vector> 28 #include <vector>
29
28 using namespace llvm; 30 using namespace llvm;
29 31
30 #define DEBUG_TYPE "subtarget-emitter" 32 #define DEBUG_TYPE "subtarget-emitter"
31 33
32 namespace { 34 namespace {
60 62
61 RecordKeeper &Records; 63 RecordKeeper &Records;
62 CodeGenSchedModels &SchedModels; 64 CodeGenSchedModels &SchedModels;
63 std::string Target; 65 std::string Target;
64 66
65 void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); 67 void Enumeration(raw_ostream &OS, const char *ClassName);
66 unsigned FeatureKeyValues(raw_ostream &OS); 68 unsigned FeatureKeyValues(raw_ostream &OS);
67 unsigned CPUKeyValues(raw_ostream &OS); 69 unsigned CPUKeyValues(raw_ostream &OS);
68 void FormItineraryStageString(const std::string &Names, 70 void FormItineraryStageString(const std::string &Names,
69 Record *ItinData, std::string &ItinString, 71 Record *ItinData, std::string &ItinString,
70 unsigned &NStages); 72 unsigned &NStages);
102 public: 104 public:
103 SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT): 105 SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT):
104 Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {} 106 Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {}
105 107
106 void run(raw_ostream &o); 108 void run(raw_ostream &o);
107
108 }; 109 };
109 } // End anonymous namespace 110 } // end anonymous namespace
110 111
111 // 112 //
112 // Enumeration - Emit the specified class as an enumeration. 113 // Enumeration - Emit the specified class as an enumeration.
113 // 114 //
114 void SubtargetEmitter::Enumeration(raw_ostream &OS, 115 void SubtargetEmitter::Enumeration(raw_ostream &OS,
115 const char *ClassName, 116 const char *ClassName) {
116 bool isBits) {
117 // Get all records of class and sort 117 // Get all records of class and sort
118 std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName); 118 std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
119 std::sort(DefList.begin(), DefList.end(), LessRecord()); 119 std::sort(DefList.begin(), DefList.end(), LessRecord());
120 120
121 unsigned N = DefList.size(); 121 unsigned N = DefList.size();
122 if (N == 0) 122 if (N == 0)
123 return; 123 return;
124 if (N > 64) { 124 if (N > MAX_SUBTARGET_FEATURES)
125 errs() << "Too many (> 64) subtarget features!\n"; 125 PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");
126 exit(1);
127 }
128 126
129 OS << "namespace " << Target << " {\n"; 127 OS << "namespace " << Target << " {\n";
130 128
131 // For bit flag enumerations with more than 32 items, emit constants. 129 // Open enumeration. Use a 64-bit underlying type.
132 // Emit an enum for everything else. 130 OS << "enum : uint64_t {\n";
133 if (isBits && N > 32) { 131
134 // For each record 132 // For each record
135 for (unsigned i = 0; i < N; i++) { 133 for (unsigned i = 0; i < N;) {
136 // Next record 134 // Next record
137 Record *Def = DefList[i]; 135 Record *Def = DefList[i];
138 136
139 // Get and emit name and expression (1 << i) 137 // Get and emit name
140 OS << " const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n"; 138 OS << " " << Def->getName() << " = " << i;
141 } 139 if (++i < N) OS << ",";
142 } else { 140
143 // Open enumeration 141 OS << "\n";
144 OS << "enum {\n"; 142 }
145 143
146 // For each record 144 // Close enumeration and namespace
147 for (unsigned i = 0; i < N;) { 145 OS << "};\n}\n";
148 // Next record
149 Record *Def = DefList[i];
150
151 // Get and emit name
152 OS << " " << Def->getName();
153
154 // If bit flags then emit expression (1 << i)
155 if (isBits) OS << " = " << " 1ULL << " << i;
156
157 // Depending on 'if more in the list' emit comma
158 if (++i < N) OS << ",";
159
160 OS << "\n";
161 }
162
163 // Close enumeration
164 OS << "};\n";
165 }
166
167 OS << "}\n";
168 } 146 }
169 147
170 // 148 //
171 // FeatureKeyValues - Emit data of all the subtarget features. Used by the 149 // FeatureKeyValues - Emit data of all the subtarget features. Used by the
172 // command line. 150 // command line.
196 const std::string &CommandLineName = Feature->getValueAsString("Name"); 174 const std::string &CommandLineName = Feature->getValueAsString("Name");
197 const std::string &Desc = Feature->getValueAsString("Desc"); 175 const std::string &Desc = Feature->getValueAsString("Desc");
198 176
199 if (CommandLineName.empty()) continue; 177 if (CommandLineName.empty()) continue;
200 178
201 // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in } 179 // Emit as { "feature", "description", { featureEnum }, { i1 , i2 , ... , in } }
202 OS << " { " 180 OS << " { "
203 << "\"" << CommandLineName << "\", " 181 << "\"" << CommandLineName << "\", "
204 << "\"" << Desc << "\", " 182 << "\"" << Desc << "\", "
205 << Target << "::" << Name << ", "; 183 << "{ " << Target << "::" << Name << " }, ";
206 184
207 const std::vector<Record*> &ImpliesList = 185 const std::vector<Record*> &ImpliesList =
208 Feature->getValueAsListOfDefs("Implies"); 186 Feature->getValueAsListOfDefs("Implies");
209 187
210 if (ImpliesList.empty()) { 188 if (ImpliesList.empty()) {
211 OS << "0ULL"; 189 OS << "{ }";
212 } else { 190 } else {
191 OS << "{ ";
213 for (unsigned j = 0, M = ImpliesList.size(); j < M;) { 192 for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
214 OS << Target << "::" << ImpliesList[j]->getName(); 193 OS << Target << "::" << ImpliesList[j]->getName();
215 if (++j < M) OS << " | "; 194 if (++j < M) OS << ", ";
216 } 195 }
196 OS << " }";
217 } 197 }
218 198
219 OS << " }"; 199 OS << " }";
220 ++NumFeatures; 200 ++NumFeatures;
221 201
253 233
254 const std::string &Name = Processor->getValueAsString("Name"); 234 const std::string &Name = Processor->getValueAsString("Name");
255 const std::vector<Record*> &FeatureList = 235 const std::vector<Record*> &FeatureList =
256 Processor->getValueAsListOfDefs("Features"); 236 Processor->getValueAsListOfDefs("Features");
257 237
258 // Emit as { "cpu", "description", f1 | f2 | ... fn }, 238 // Emit as { "cpu", "description", { f1 , f2 , ... fn } },
259 OS << " { " 239 OS << " { "
260 << "\"" << Name << "\", " 240 << "\"" << Name << "\", "
261 << "\"Select the " << Name << " processor\", "; 241 << "\"Select the " << Name << " processor\", ";
262 242
263 if (FeatureList.empty()) { 243 if (FeatureList.empty()) {
264 OS << "0ULL"; 244 OS << "{ }";
265 } else { 245 } else {
246 OS << "{ ";
266 for (unsigned j = 0, M = FeatureList.size(); j < M;) { 247 for (unsigned j = 0, M = FeatureList.size(); j < M;) {
267 OS << Target << "::" << FeatureList[j]->getName(); 248 OS << Target << "::" << FeatureList[j]->getName();
268 if (++j < M) OS << " | "; 249 if (++j < M) OS << ", ";
269 } 250 }
270 } 251 OS << " }";
271 252 }
272 // The "0" is for the "implies" section of this data structure. 253
273 OS << ", 0ULL }"; 254 // The { } is for the "implies" section of this data structure.
255 OS << ", { } }";
274 256
275 // Depending on 'if more in the list' emit comma 257 // Depending on 'if more in the list' emit comma
276 if (++i < N) OS << ","; 258 if (++i < N) OS << ",";
277 259
278 OS << "\n"; 260 OS << "\n";
1215 << " " << PI->ModelName << "SchedClasses" << ",\n" 1197 << " " << PI->ModelName << "SchedClasses" << ",\n"
1216 << " " << PI->ProcResourceDefs.size()+1 << ",\n" 1198 << " " << PI->ProcResourceDefs.size()+1 << ",\n"
1217 << " " << (SchedModels.schedClassEnd() 1199 << " " << (SchedModels.schedClassEnd()
1218 - SchedModels.schedClassBegin()) << ",\n"; 1200 - SchedModels.schedClassBegin()) << ",\n";
1219 else 1201 else
1220 OS << " 0, 0, 0, 0, // No instruction-level machine model.\n"; 1202 OS << " nullptr, nullptr, 0, 0,"
1203 << " // No instruction-level machine model.\n";
1221 if (PI->hasItineraries()) 1204 if (PI->hasItineraries())
1222 OS << " " << PI->ItinsDef->getName() << "};\n"; 1205 OS << " " << PI->ItinsDef->getName() << "};\n";
1223 else 1206 else
1224 OS << " nullptr}; // No Itinerary\n"; 1207 OS << " nullptr}; // No Itinerary\n";
1225 } 1208 }
1396 OS << "}\n"; 1379 OS << "}\n";
1397 return; 1380 return;
1398 } 1381 }
1399 1382
1400 OS << " InitMCProcessorInfo(CPU, FS);\n" 1383 OS << " InitMCProcessorInfo(CPU, FS);\n"
1401 << " uint64_t Bits = getFeatureBits();\n"; 1384 << " const FeatureBitset& Bits = getFeatureBits();\n";
1402 1385
1403 for (unsigned i = 0; i < Features.size(); i++) { 1386 for (unsigned i = 0; i < Features.size(); i++) {
1404 // Next record 1387 // Next record
1405 Record *R = Features[i]; 1388 Record *R = Features[i];
1406 const std::string &Instance = R->getName(); 1389 const std::string &Instance = R->getName();
1407 const std::string &Value = R->getValueAsString("Value"); 1390 const std::string &Value = R->getValueAsString("Value");
1408 const std::string &Attribute = R->getValueAsString("Attribute"); 1391 const std::string &Attribute = R->getValueAsString("Attribute");
1409 1392
1410 if (Value=="true" || Value=="false") 1393 if (Value=="true" || Value=="false")
1411 OS << " if ((Bits & " << Target << "::" 1394 OS << " if (Bits[" << Target << "::"
1412 << Instance << ") != 0) " 1395 << Instance << "]) "
1413 << Attribute << " = " << Value << ";\n"; 1396 << Attribute << " = " << Value << ";\n";
1414 else 1397 else
1415 OS << " if ((Bits & " << Target << "::" 1398 OS << " if (Bits[" << Target << "::"
1416 << Instance << ") != 0 && " 1399 << Instance << "] && "
1417 << Attribute << " < " << Value << ") " 1400 << Attribute << " < " << Value << ") "
1418 << Attribute << " = " << Value << ";\n"; 1401 << Attribute << " = " << Value << ";\n";
1419 } 1402 }
1420 1403
1421 OS << "}\n"; 1404 OS << "}\n";
1429 1412
1430 OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; 1413 OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
1431 OS << "#undef GET_SUBTARGETINFO_ENUM\n"; 1414 OS << "#undef GET_SUBTARGETINFO_ENUM\n";
1432 1415
1433 OS << "namespace llvm {\n"; 1416 OS << "namespace llvm {\n";
1434 Enumeration(OS, "SubtargetFeature", true); 1417 Enumeration(OS, "SubtargetFeature");
1435 OS << "} // End llvm namespace \n"; 1418 OS << "} // end llvm namespace\n";
1436 OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; 1419 OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
1437 1420
1438 OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; 1421 OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
1439 OS << "#undef GET_SUBTARGETINFO_MC_DESC\n"; 1422 OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
1440 1423
1451 #if 0 1434 #if 0
1452 OS << "}\n"; 1435 OS << "}\n";
1453 #endif 1436 #endif
1454 1437
1455 // MCInstrInfo initialization routine. 1438 // MCInstrInfo initialization routine.
1456 OS << "static inline void Init" << Target 1439 OS << "static inline MCSubtargetInfo *create" << Target
1457 << "MCSubtargetInfo(MCSubtargetInfo *II, " 1440 << "MCSubtargetInfoImpl("
1458 << "StringRef TT, StringRef CPU, StringRef FS) {\n"; 1441 << "const Triple &TT, StringRef CPU, StringRef FS) {\n";
1459 OS << " II->InitMCSubtargetInfo(TT, CPU, FS, "; 1442 OS << " return new MCSubtargetInfo(TT, CPU, FS, ";
1460 if (NumFeatures) 1443 if (NumFeatures)
1461 OS << Target << "FeatureKV, "; 1444 OS << Target << "FeatureKV, ";
1462 else 1445 else
1463 OS << "None, "; 1446 OS << "None, ";
1464 if (NumProcs) 1447 if (NumProcs)
1477 << Target << "ForwardingPaths"; 1460 << Target << "ForwardingPaths";
1478 } else 1461 } else
1479 OS << "0, 0, 0"; 1462 OS << "0, 0, 0";
1480 OS << ");\n}\n\n"; 1463 OS << ");\n}\n\n";
1481 1464
1482 OS << "} // End llvm namespace \n"; 1465 OS << "} // end llvm namespace\n";
1483 1466
1484 OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; 1467 OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
1485 1468
1486 OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; 1469 OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
1487 OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n"; 1470 OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
1488 1471
1489 OS << "#include \"llvm/Support/Debug.h\"\n"; 1472 OS << "#include \"llvm/Support/Debug.h\"\n";
1473 OS << "#include \"llvm/Support/raw_ostream.h\"\n";
1490 ParseFeaturesFunction(OS, NumFeatures, NumProcs); 1474 ParseFeaturesFunction(OS, NumFeatures, NumProcs);
1491 1475
1492 OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; 1476 OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
1493 1477
1494 // Create a TargetSubtargetInfo subclass to hide the MC layer initialization. 1478 // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
1497 1481
1498 std::string ClassName = Target + "GenSubtargetInfo"; 1482 std::string ClassName = Target + "GenSubtargetInfo";
1499 OS << "namespace llvm {\n"; 1483 OS << "namespace llvm {\n";
1500 OS << "class DFAPacketizer;\n"; 1484 OS << "class DFAPacketizer;\n";
1501 OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" 1485 OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
1502 << " explicit " << ClassName << "(StringRef TT, StringRef CPU, " 1486 << " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
1503 << "StringRef FS);\n" 1487 << "StringRef FS);\n"
1504 << "public:\n" 1488 << "public:\n"
1505 << " unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *DefMI," 1489 << " unsigned resolveSchedClass(unsigned SchedClass, "
1490 << " const MachineInstr *DefMI,"
1506 << " const TargetSchedModel *SchedModel) const override;\n" 1491 << " const TargetSchedModel *SchedModel) const override;\n"
1507 << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" 1492 << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
1508 << " const;\n" 1493 << " const;\n"
1509 << "};\n"; 1494 << "};\n";
1510 OS << "} // End llvm namespace \n"; 1495 OS << "} // end llvm namespace\n";
1511 1496
1512 OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; 1497 OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
1513 1498
1514 OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; 1499 OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
1515 OS << "#undef GET_SUBTARGETINFO_CTOR\n"; 1500 OS << "#undef GET_SUBTARGETINFO_CTOR\n";
1530 OS << "extern const llvm::InstrStage " << Target << "Stages[];\n"; 1515 OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
1531 OS << "extern const unsigned " << Target << "OperandCycles[];\n"; 1516 OS << "extern const unsigned " << Target << "OperandCycles[];\n";
1532 OS << "extern const unsigned " << Target << "ForwardingPaths[];\n"; 1517 OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
1533 } 1518 }
1534 1519
1535 OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, " 1520 OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, "
1536 << "StringRef FS)\n" 1521 << "StringRef FS)\n"
1537 << " : TargetSubtargetInfo() {\n" 1522 << " : TargetSubtargetInfo(TT, CPU, FS, ";
1538 << " InitMCSubtargetInfo(TT, CPU, FS, ";
1539 if (NumFeatures) 1523 if (NumFeatures)
1540 OS << "makeArrayRef(" << Target << "FeatureKV, " << NumFeatures << "), "; 1524 OS << "makeArrayRef(" << Target << "FeatureKV, " << NumFeatures << "), ";
1541 else 1525 else
1542 OS << "None, "; 1526 OS << "None, ";
1543 if (NumProcs) 1527 if (NumProcs)
1544 OS << "makeArrayRef(" << Target << "SubTypeKV, " << NumProcs << "), "; 1528 OS << "makeArrayRef(" << Target << "SubTypeKV, " << NumProcs << "), ";
1545 else 1529 else
1546 OS << "None, "; 1530 OS << "None, ";
1547 OS << '\n'; OS.indent(22); 1531 OS << '\n'; OS.indent(24);
1548 OS << Target << "ProcSchedKV, " 1532 OS << Target << "ProcSchedKV, "
1549 << Target << "WriteProcResTable, " 1533 << Target << "WriteProcResTable, "
1550 << Target << "WriteLatencyTable, " 1534 << Target << "WriteLatencyTable, "
1551 << Target << "ReadAdvanceTable, "; 1535 << Target << "ReadAdvanceTable, ";
1552 OS << '\n'; OS.indent(22); 1536 OS << '\n'; OS.indent(24);
1553 if (SchedModels.hasItineraries()) { 1537 if (SchedModels.hasItineraries()) {
1554 OS << Target << "Stages, " 1538 OS << Target << "Stages, "
1555 << Target << "OperandCycles, " 1539 << Target << "OperandCycles, "
1556 << Target << "ForwardingPaths"; 1540 << Target << "ForwardingPaths";
1557 } else 1541 } else
1558 OS << "0, 0, 0"; 1542 OS << "0, 0, 0";
1559 OS << ");\n}\n\n"; 1543 OS << ") {}\n\n";
1560 1544
1561 EmitSchedModelHelpers(ClassName, OS); 1545 EmitSchedModelHelpers(ClassName, OS);
1562 1546
1563 OS << "} // End llvm namespace \n"; 1547 OS << "} // end llvm namespace\n";
1564 1548
1565 OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; 1549 OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
1566 } 1550 }
1567 1551
1568 namespace llvm { 1552 namespace llvm {
1570 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) { 1554 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) {
1571 CodeGenTarget CGTarget(RK); 1555 CodeGenTarget CGTarget(RK);
1572 SubtargetEmitter(RK, CGTarget).run(OS); 1556 SubtargetEmitter(RK, CGTarget).run(OS);
1573 } 1557 }
1574 1558
1575 } // End llvm namespace 1559 } // end llvm namespace