summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen/RegisterInfoEmitter.cpp
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-09-14 16:56:21 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-09-14 16:56:21 +0000
commit779d98e1c008b30a211375a76f3f2c97502a02b5 (patch)
tree1487ccf61f066616188b089b38a1ace6ac1f7637 /llvm/utils/TableGen/RegisterInfoEmitter.cpp
parenta0e55b6403b75e6884efc1ab11599e0677d48903 (diff)
downloadbcm5719-llvm-779d98e1c008b30a211375a76f3f2c97502a02b5.tar.gz
bcm5719-llvm-779d98e1c008b30a211375a76f3f2c97502a02b5.zip
TableGen support for parameterized register class information
This replaces TableGen's type inference to operate on parameterized types instead of MVTs, and as a consequence, some interfaces have changed: - Uses of MVTs are replaced by ValueTypeByHwMode. - EEVT::TypeSet is replaced by TypeSetByHwMode. This affects the way that types and type sets are printed, and the tests relying on that have been updated. There are certain users of the inferred types outside of TableGen itself, namely FastISel and GlobalISel. For those users, the way that the types are accessed have changed. For typical scenarios, these replacements can be used: - TreePatternNode::getType(ResNo) -> getSimpleType(ResNo) - TreePatternNode::hasTypeSet(ResNo) -> hasConcreteType(ResNo) - TypeSet::isConcrete -> TypeSetByHwMode::isValueTypeByHwMode(false) For more information, please refer to the review page. Differential Revision: https://reviews.llvm.org/D31951 llvm-svn: 313271
Diffstat (limited to 'llvm/utils/TableGen/RegisterInfoEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/RegisterInfoEmitter.cpp84
1 files changed, 64 insertions, 20 deletions
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 410b3d9590e..e5f3cb3d6ef 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1037,13 +1037,14 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
for (const auto &RC : RegisterClasses) {
assert(isInt<8>(RC.CopyCost) && "Copy cost too large.");
- // Register size and spill size will become independent, but are not at
- // the moment. For now use SpillSize as the register size.
+ uint32_t RegSize = 0;
+ if (RC.RSI.isSimple())
+ RegSize = RC.RSI.getSimple().RegSize;
OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
<< RegClassStrings.get(RC.getName()) << ", "
<< RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
<< RC.getQualifiedName() + "RegClassID" << ", "
- << RC.SpillSize/8 << ", "
+ << RegSize/8 << ", "
<< RC.CopyCost << ", "
<< ( RC.Allocatable ? "true" : "false" ) << " },\n";
}
@@ -1111,7 +1112,8 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
- << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n";
+ << "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"
+ << " unsigned PC = 0, unsigned HwMode = 0);\n";
if (!RegBank.getSubRegIndices().empty()) {
OS << " unsigned composeSubRegIndicesImpl"
<< "(unsigned, unsigned) const override;\n"
@@ -1190,10 +1192,19 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
AllocatableRegs.insert(Order.begin(), Order.end());
}
+ const CodeGenHwModes &CGH = Target.getHwModes();
+ unsigned NumModes = CGH.getNumModeIds();
+
// Build a shared array of value types.
- SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
- for (const auto &RC : RegisterClasses)
- VTSeqs.add(RC.VTs);
+ SequenceToOffsetTable<std::vector<MVT::SimpleValueType>> VTSeqs;
+ for (unsigned M = 0; M < NumModes; ++M) {
+ for (const auto &RC : RegisterClasses) {
+ std::vector<MVT::SimpleValueType> S;
+ for (const ValueTypeByHwMode &VVT : RC.VTs)
+ S.push_back(VVT.get(M).SimpleTy);
+ VTSeqs.add(S);
+ }
+ }
VTSeqs.layout();
OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
@@ -1221,6 +1232,31 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
// Now that all of the structs have been emitted, emit the instances.
if (!RegisterClasses.empty()) {
+ OS << "\nstatic const TargetRegisterInfo::RegClassInfo RegClassInfos[]"
+ << " = {\n";
+ for (unsigned M = 0; M < NumModes; ++M) {
+ unsigned EV = 0;
+ OS << " // Mode = " << M << " (";
+ if (M == 0)
+ OS << "Default";
+ else
+ OS << CGH.getMode(M).Name;
+ OS << ")\n";
+ for (const auto &RC : RegisterClasses) {
+ assert(RC.EnumValue == EV++ && "Unexpected order of register classes");
+ const RegSizeInfo &RI = RC.RSI.get(M);
+ OS << " { " << RI.RegSize << ", " << RI.SpillSize << ", "
+ << RI.SpillAlignment;
+ std::vector<MVT::SimpleValueType> VTs;
+ for (const ValueTypeByHwMode &VVT : RC.VTs)
+ VTs.push_back(VVT.get(M).SimpleTy);
+ OS << ", VTLists+" << VTSeqs.get(VTs) << " }, // "
+ << RC.getName() << '\n';
+ }
+ }
+ OS << "};\n";
+
+
OS << "\nstatic const TargetRegisterClass *const "
<< "NullRegClasses[] = { nullptr };\n\n";
@@ -1327,15 +1363,10 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
<< " { // Register class instances\n";
for (const auto &RC : RegisterClasses) {
- assert(isUInt<16>(RC.SpillSize/8) && "SpillSize too large.");
- assert(isUInt<16>(RC.SpillAlignment/8) && "SpillAlignment too large.");
OS << " extern const TargetRegisterClass " << RC.getName()
<< "RegClass = {\n " << '&' << Target.getName()
<< "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "
- << RC.SpillSize/8 << ", /* SpillSize */\n "
- << RC.SpillAlignment/8 << ", /* SpillAlignment */\n "
- << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " << RC.getName()
- << "SubClassMask,\n SuperRegIdxSeqs + "
+ << RC.getName() << "SubClassMask,\n SuperRegIdxSeqs + "
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n ";
printMask(OS, RC.LaneMask);
OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
@@ -1439,12 +1470,14 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
EmitRegMappingTables(OS, Regs, true);
OS << ClassName << "::\n" << ClassName
- << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
+ << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,\n"
+ " unsigned PC, unsigned HwMode)\n"
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
- << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
- << " SubRegIndexNameTable, SubRegIndexLaneMaskTable, ";
+ << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() << ",\n"
+ << " SubRegIndexNameTable, SubRegIndexLaneMaskTable,\n"
+ << " ";
printMask(OS, RegBank.CoveringLanes);
- OS << ") {\n"
+ OS << ", RegClassInfos, HwMode) {\n"
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size() + 1
<< ", RA, PC,\n " << TargetName
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
@@ -1547,12 +1580,23 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
CodeGenRegBank &RegBank = Target.getRegBank();
+ const CodeGenHwModes &CGH = Target.getHwModes();
+ unsigned NumModes = CGH.getNumModeIds();
+ auto getModeName = [CGH] (unsigned M) -> StringRef {
+ if (M == 0)
+ return "Default";
+ return CGH.getMode(M).Name;
+ };
for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {
OS << "RegisterClass " << RC.getName() << ":\n";
- OS << "\tSpillSize: " << RC.SpillSize << '\n';
- OS << "\tSpillAlignment: " << RC.SpillAlignment << '\n';
- OS << "\tNumRegs: " << RC.getMembers().size() << '\n';
+ OS << "\tSpillSize: {";
+ for (unsigned M = 0; M != NumModes; ++M)
+ OS << ' ' << getModeName(M) << ':' << RC.RSI.get(M).SpillSize;
+ OS << " }\n\tSpillAlignment: {";
+ for (unsigned M = 0; M != NumModes; ++M)
+ OS << ' ' << getModeName(M) << ':' << RC.RSI.get(M).SpillAlignment;
+ OS << " }\n\tNumRegs: " << RC.getMembers().size() << '\n';
OS << "\tLaneMask: " << PrintLaneMask(RC.LaneMask) << '\n';
OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
OpenPOWER on IntegriCloud