diff options
Diffstat (limited to 'llvm/utils/TableGen/SDNodeInfoEmitter.cpp')
| -rw-r--r-- | llvm/utils/TableGen/SDNodeInfoEmitter.cpp | 72 |
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()); } |
