summaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/SDNodeInfoEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/SDNodeInfoEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/SDNodeInfoEmitter.cpp72
1 files changed, 60 insertions, 12 deletions
diff --git a/llvm/utils/TableGen/SDNodeInfoEmitter.cpp b/llvm/utils/TableGen/SDNodeInfoEmitter.cpp
index dd18d29e6c67..5dff3862fa30 100644
--- a/llvm/utils/TableGen/SDNodeInfoEmitter.cpp
+++ b/llvm/utils/TableGen/SDNodeInfoEmitter.cpp
@@ -195,15 +195,29 @@ static StringRef getTypeConstraintKindName(SDTypeConstraint::KindTy Kind) {
#undef CASE
}
-static void emitTypeConstraint(raw_ostream &OS, SDTypeConstraint C) {
+static void emitTypeConstraint(
+ raw_ostream &OS, SDTypeConstraint C,
+ const std::map<ValueTypeByHwMode, unsigned> &VTByHwModeTable) {
unsigned OtherOpNo = 0;
- MVT VT;
+ unsigned NumHwModes = 0;
+ unsigned VTByHwModeOffset = 0;
+ MVT::SimpleValueType VT = MVT::INVALID_SIMPLE_VALUE_TYPE;
switch (C.ConstraintType) {
case SDTypeConstraint::SDTCisVT:
+ // SequenceToOffsetTable::emit() prints a "dummy" (default-constructed)
+ // element if the table would otherwise be empty. VVT is empty in this case.
+ if (C.VVT.empty())
+ break;
+ [[fallthrough]];
case SDTypeConstraint::SDTCVecEltisVT:
- if (C.VVT.isSimple())
- VT = C.VVT.getSimple();
+ if (C.VVT.isSimple()) {
+ VT = C.VVT.getSimple().SimpleTy;
+ } else {
+ NumHwModes = C.VVT.size();
+ assert(NumHwModes && "Empty type set?");
+ VTByHwModeOffset = VTByHwModeTable.at(C.VVT);
+ }
break;
case SDTypeConstraint::SDTCisPtrTy:
case SDTypeConstraint::SDTCisInt:
@@ -221,15 +235,22 @@ static void emitTypeConstraint(raw_ostream &OS, SDTypeConstraint C) {
break;
}
- StringRef KindName = getTypeConstraintKindName(C.ConstraintType);
- StringRef VTName = VT.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE
- ? "MVT::INVALID_SIMPLE_VALUE_TYPE"
- : getEnumName(VT.SimpleTy);
- OS << formatv("{{{}, {}, {}, {}}", KindName, C.OperandNo, OtherOpNo, VTName);
+ OS << '{' << getTypeConstraintKindName(C.ConstraintType) << ", "
+ << C.OperandNo << ", " << OtherOpNo << ", " << NumHwModes << ", ";
+ if (NumHwModes) {
+ OS << VTByHwModeOffset;
+ } else {
+ OS << (VT == MVT::INVALID_SIMPLE_VALUE_TYPE
+ ? "MVT::INVALID_SIMPLE_VALUE_TYPE"
+ : getEnumName(VT));
+ }
+ OS << '}';
}
std::vector<std::pair<unsigned, unsigned>>
SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const {
+ std::map<ValueTypeByHwMode, unsigned> VTByHwModeTable;
+
using ConstraintsVecTy = SmallVector<SDTypeConstraint, 0>;
SequenceToOffsetTable<ConstraintsVecTy> ConstraintTable(
/*Terminator=*/std::nullopt);
@@ -258,6 +279,16 @@ SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const {
if (Constraints.empty())
continue;
+ for (const SDTypeConstraint &C : Constraints) {
+ if (C.ConstraintType == SDTypeConstraint::SDTCisVT ||
+ C.ConstraintType == SDTypeConstraint::SDTCVecEltisVT) {
+ if (!C.VVT.isSimple()) {
+ assert(!C.VVT.empty() && "Unexpected empty type set");
+ VTByHwModeTable.try_emplace(C.VVT);
+ }
+ }
+ }
+
// SequenceToOffsetTable reuses the storage if a sequence matches another
// sequence's *suffix*. It is more likely that we have a matching *prefix*,
// so reverse the order to increase the likelihood of a match.
@@ -266,9 +297,26 @@ SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const {
ConstraintTable.layout();
+ OS << "static const VTByHwModePair " << Target.getName()
+ << "VTByHwModeTable[] = {\n";
+ unsigned VTByHwModeOffset = 0;
+ for (auto &[VTByHwMode, Offset] : VTByHwModeTable) {
+ OS << " /* " << VTByHwModeOffset << " */ ";
+ for (auto [Mode, VT] : VTByHwMode)
+ OS << '{' << Mode << ", " << getEnumName(VT.SimpleTy) << "}, ";
+ OS << '\n';
+ Offset = VTByHwModeOffset;
+ VTByHwModeOffset += VTByHwMode.size();
+ }
+ // Avoid "zero size arrays are an extension" warning.
+ if (VTByHwModeTable.empty())
+ OS << " /* dummy */ {0, MVT::INVALID_SIMPLE_VALUE_TYPE}\n";
+ OS << "};\n\n";
+
OS << "static const SDTypeConstraint " << Target.getName()
<< "SDTypeConstraints[] = {\n";
- ConstraintTable.emit(OS, emitTypeConstraint);
+ ConstraintTable.emit(OS, std::bind(emitTypeConstraint, std::placeholders::_1,
+ std::placeholders::_2, VTByHwModeTable));
OS << "};\n\n";
for (const auto &[EnumName, Nodes] : NodesByName) {
@@ -338,8 +386,8 @@ void SDNodeInfoEmitter::emitDescs(raw_ostream &OS) const {
OS << "};\n\n";
OS << formatv("static const SDNodeInfo {0}GenSDNodeInfo(\n"
- " /*NumOpcodes=*/{1}, {0}SDNodeDescs,\n"
- " {0}SDNodeNames, {0}SDTypeConstraints);\n",
+ " /*NumOpcodes=*/{1}, {0}SDNodeDescs, {0}SDNodeNames,\n"
+ " {0}VTByHwModeTable, {0}SDTypeConstraints);\n",
TargetName, NodesByName.size());
}