xref: /llvm-project/llvm/utils/TableGen/Basic/VTEmitter.cpp (revision 1714facf4f7d7f4ef5a1846aded769fec8e684ac)
127f30029SMichael Kruse //===- VTEmitter.cpp - Generate properties from ValueTypes.td -------------===//
227f30029SMichael Kruse //
327f30029SMichael Kruse // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
427f30029SMichael Kruse // See https://llvm.org/LICENSE.txt for license information.
527f30029SMichael Kruse // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
627f30029SMichael Kruse //
727f30029SMichael Kruse //===----------------------------------------------------------------------===//
827f30029SMichael Kruse 
927f30029SMichael Kruse #include "llvm/ADT/StringRef.h"
1027f30029SMichael Kruse #include "llvm/Support/raw_ostream.h"
1127f30029SMichael Kruse #include "llvm/TableGen/Record.h"
1227f30029SMichael Kruse #include "llvm/TableGen/TableGenBackend.h"
1327f30029SMichael Kruse #include <cassert>
1427f30029SMichael Kruse #include <map>
1527f30029SMichael Kruse using namespace llvm;
1627f30029SMichael Kruse 
1727f30029SMichael Kruse namespace {
1827f30029SMichael Kruse 
1927f30029SMichael Kruse class VTEmitter {
2027f30029SMichael Kruse private:
2127f30029SMichael Kruse   const RecordKeeper &Records;
2227f30029SMichael Kruse 
2327f30029SMichael Kruse public:
2427f30029SMichael Kruse   VTEmitter(const RecordKeeper &R) : Records(R) {}
2527f30029SMichael Kruse 
2627f30029SMichael Kruse   void run(raw_ostream &OS);
2727f30029SMichael Kruse };
2827f30029SMichael Kruse 
2927f30029SMichael Kruse } // End anonymous namespace.
3027f30029SMichael Kruse 
3127f30029SMichael Kruse static void vTtoGetLlvmTyString(raw_ostream &OS, const Record *VT) {
3227f30029SMichael Kruse   bool IsVector = VT->getValueAsBit("isVector");
3327f30029SMichael Kruse   bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
3427f30029SMichael Kruse 
3527f30029SMichael Kruse   if (IsRISCVVecTuple) {
3627f30029SMichael Kruse     unsigned NElem = VT->getValueAsInt("nElem");
3727f30029SMichael Kruse     unsigned Sz = VT->getValueAsInt("Size");
3827f30029SMichael Kruse     OS << "TargetExtType::get(Context, \"riscv.vector.tuple\", "
3927f30029SMichael Kruse           "ScalableVectorType::get(Type::getInt8Ty(Context), "
4027f30029SMichael Kruse        << (Sz / (NElem * 8)) << "), " << NElem << ")";
4127f30029SMichael Kruse     return;
4227f30029SMichael Kruse   }
4327f30029SMichael Kruse 
4427f30029SMichael Kruse   if (IsVector)
4527f30029SMichael Kruse     OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed")
4627f30029SMichael Kruse        << "VectorType::get(";
4727f30029SMichael Kruse 
4827f30029SMichael Kruse   auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT;
4927f30029SMichael Kruse   int64_t OutputVTSize = OutputVT->getValueAsInt("Size");
5027f30029SMichael Kruse 
5127f30029SMichael Kruse   if (OutputVT->getValueAsBit("isFP")) {
5227f30029SMichael Kruse     StringRef FloatTy;
5327f30029SMichael Kruse     auto OutputVTName = OutputVT->getValueAsString("LLVMName");
5427f30029SMichael Kruse     switch (OutputVTSize) {
5527f30029SMichael Kruse     default:
5627f30029SMichael Kruse       llvm_unreachable("Unhandled case");
5727f30029SMichael Kruse     case 16:
5827f30029SMichael Kruse       FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy";
5927f30029SMichael Kruse       break;
6027f30029SMichael Kruse     case 32:
6127f30029SMichael Kruse       FloatTy = "FloatTy";
6227f30029SMichael Kruse       break;
6327f30029SMichael Kruse     case 64:
6427f30029SMichael Kruse       FloatTy = "DoubleTy";
6527f30029SMichael Kruse       break;
6627f30029SMichael Kruse     case 80:
6727f30029SMichael Kruse       FloatTy = "X86_FP80Ty";
6827f30029SMichael Kruse       break;
6927f30029SMichael Kruse     case 128:
7027f30029SMichael Kruse       FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty";
7127f30029SMichael Kruse       break;
7227f30029SMichael Kruse     }
7327f30029SMichael Kruse     OS << "Type::get" << FloatTy << "(Context)";
7427f30029SMichael Kruse   } else if (OutputVT->getValueAsBit("isInteger")) {
7527f30029SMichael Kruse     // We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int128
7627f30029SMichael Kruse     if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 &&
7727f30029SMichael Kruse          OutputVTSize <= 128) ||
7827f30029SMichael Kruse         OutputVTSize == 1)
7927f30029SMichael Kruse       OS << "Type::getInt" << OutputVTSize << "Ty(Context)";
8027f30029SMichael Kruse     else
8127f30029SMichael Kruse       OS << "Type::getIntNTy(Context, " << OutputVTSize << ")";
8227f30029SMichael Kruse   } else
8327f30029SMichael Kruse     llvm_unreachable("Unhandled case");
8427f30029SMichael Kruse 
8527f30029SMichael Kruse   if (IsVector)
8627f30029SMichael Kruse     OS << ", " << VT->getValueAsInt("nElem") << ")";
8727f30029SMichael Kruse }
8827f30029SMichael Kruse 
8927f30029SMichael Kruse void VTEmitter::run(raw_ostream &OS) {
9027f30029SMichael Kruse   emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);
9127f30029SMichael Kruse 
9227f30029SMichael Kruse   std::vector<const Record *> VTsByNumber{512};
9327f30029SMichael Kruse   for (auto *VT : Records.getAllDerivedDefinitions("ValueType")) {
9427f30029SMichael Kruse     auto Number = VT->getValueAsInt("Value");
9527f30029SMichael Kruse     assert(0 <= Number && Number < (int)VTsByNumber.size() &&
9627f30029SMichael Kruse            "ValueType should be uint16_t");
9727f30029SMichael Kruse     assert(!VTsByNumber[Number] && "Duplicate ValueType");
9827f30029SMichael Kruse     VTsByNumber[Number] = VT;
9927f30029SMichael Kruse   }
10027f30029SMichael Kruse 
10127f30029SMichael Kruse   struct VTRange {
10227f30029SMichael Kruse     StringRef First;
10327f30029SMichael Kruse     StringRef Last;
10427f30029SMichael Kruse     bool Closed;
10527f30029SMichael Kruse   };
10627f30029SMichael Kruse 
10727f30029SMichael Kruse   std::map<StringRef, VTRange> VTRanges;
10827f30029SMichael Kruse 
10927f30029SMichael Kruse   auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name,
11027f30029SMichael Kruse                                    bool Valid) {
11127f30029SMichael Kruse     if (Valid) {
112*1714facfSKazu Hirata       auto [It, Inserted] = VTRanges.try_emplace(Key);
113*1714facfSKazu Hirata       if (Inserted)
114*1714facfSKazu Hirata         It->second.First = Name;
115*1714facfSKazu Hirata       assert(!It->second.Closed && "Gap detected!");
116*1714facfSKazu Hirata       It->second.Last = Name;
117*1714facfSKazu Hirata     } else if (auto It = VTRanges.find(Key); It != VTRanges.end()) {
118*1714facfSKazu Hirata       It->second.Closed = true;
11927f30029SMichael Kruse     }
12027f30029SMichael Kruse   };
12127f30029SMichael Kruse 
12227f30029SMichael Kruse   OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, "
12327f30029SMichael Kruse         "NElem, EltTy)\n";
12427f30029SMichael Kruse   for (const auto *VT : VTsByNumber) {
12527f30029SMichael Kruse     if (!VT)
12627f30029SMichael Kruse       continue;
12727f30029SMichael Kruse     auto Name = VT->getValueAsString("LLVMName");
12827f30029SMichael Kruse     auto Value = VT->getValueAsInt("Value");
12927f30029SMichael Kruse     bool IsInteger = VT->getValueAsBit("isInteger");
13027f30029SMichael Kruse     bool IsFP = VT->getValueAsBit("isFP");
13127f30029SMichael Kruse     bool IsVector = VT->getValueAsBit("isVector");
13227f30029SMichael Kruse     bool IsScalable = VT->getValueAsBit("isScalable");
13327f30029SMichael Kruse     bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
13427f30029SMichael Kruse     int64_t NF = VT->getValueAsInt("NF");
13527f30029SMichael Kruse     bool IsNormalValueType =  VT->getValueAsBit("isNormalValueType");
13627f30029SMichael Kruse     int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0;
13727f30029SMichael Kruse     StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName()
13827f30029SMichael Kruse                                  : "INVALID_SIMPLE_VALUE_TYPE";
13927f30029SMichael Kruse 
14027f30029SMichael Kruse     UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name,
14127f30029SMichael Kruse                   IsInteger && IsVector && !IsScalable);
14227f30029SMichael Kruse     UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name,
14327f30029SMichael Kruse                   IsInteger && IsScalable);
14427f30029SMichael Kruse     UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name,
14527f30029SMichael Kruse                   IsFP && IsVector && !IsScalable);
14627f30029SMichael Kruse     UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable);
14727f30029SMichael Kruse     UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable);
14827f30029SMichael Kruse     UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable);
14927f30029SMichael Kruse     UpdateVTRange("RISCV_VECTOR_TUPLE_VALUETYPE", Name, IsRISCVVecTuple);
15027f30029SMichael Kruse     UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector);
15127f30029SMichael Kruse     UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector);
15227f30029SMichael Kruse     UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector);
15327f30029SMichael Kruse     UpdateVTRange("VALUETYPE", Name, IsNormalValueType);
15427f30029SMichael Kruse 
15527f30029SMichael Kruse     // clang-format off
15627f30029SMichael Kruse     OS << "  GET_VT_ATTR("
15727f30029SMichael Kruse        << Name << ", "
15827f30029SMichael Kruse        << Value << ", "
15927f30029SMichael Kruse        << VT->getValueAsInt("Size") << ", "
16027f30029SMichael Kruse        << VT->getValueAsBit("isOverloaded") << ", "
16127f30029SMichael Kruse        << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", "
16227f30029SMichael Kruse        << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", "
16327f30029SMichael Kruse        << IsVector << ", "
16427f30029SMichael Kruse        << IsScalable << ", "
16527f30029SMichael Kruse        << IsRISCVVecTuple << ", "
16627f30029SMichael Kruse        << NF << ", "
16727f30029SMichael Kruse        << NElem << ", "
16827f30029SMichael Kruse        << EltName << ")\n";
16927f30029SMichael Kruse     // clang-format on
17027f30029SMichael Kruse   }
17127f30029SMichael Kruse   OS << "#endif\n\n";
17227f30029SMichael Kruse 
17327f30029SMichael Kruse   OS << "#ifdef GET_VT_RANGES\n";
17427f30029SMichael Kruse   for (const auto &KV : VTRanges) {
17527f30029SMichael Kruse     assert(KV.second.Closed);
17627f30029SMichael Kruse     OS << "  FIRST_" << KV.first << " = " << KV.second.First << ",\n"
17727f30029SMichael Kruse        << "  LAST_" << KV.first << " = " << KV.second.Last << ",\n";
17827f30029SMichael Kruse   }
17927f30029SMichael Kruse   OS << "#endif\n\n";
18027f30029SMichael Kruse 
18127f30029SMichael Kruse   OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, Tup, nElem, ElTy)\n";
18227f30029SMichael Kruse   for (const auto *VT : VTsByNumber) {
18327f30029SMichael Kruse     if (!VT || !VT->getValueAsBit("isVector"))
18427f30029SMichael Kruse       continue;
18527f30029SMichael Kruse     const auto *ElTy = VT->getValueAsDef("ElementType");
18627f30029SMichael Kruse     assert(ElTy);
18727f30029SMichael Kruse     // clang-format off
18827f30029SMichael Kruse     OS << "  GET_VT_VECATTR("
18927f30029SMichael Kruse        << VT->getValueAsString("LLVMName") << ", "
19027f30029SMichael Kruse        << VT->getValueAsBit("isScalable") << ", "
19127f30029SMichael Kruse        << VT->getValueAsBit("isRISCVVecTuple") << ", "
19227f30029SMichael Kruse        << VT->getValueAsInt("nElem") << ", "
19327f30029SMichael Kruse        << ElTy->getName() << ")\n";
19427f30029SMichael Kruse     // clang-format on
19527f30029SMichael Kruse   }
19627f30029SMichael Kruse   OS << "#endif\n\n";
19727f30029SMichael Kruse 
19827f30029SMichael Kruse   OS << "#ifdef GET_VT_EVT\n";
19927f30029SMichael Kruse   for (const auto *VT : VTsByNumber) {
20027f30029SMichael Kruse     if (!VT)
20127f30029SMichael Kruse       continue;
20227f30029SMichael Kruse     bool IsInteger = VT->getValueAsBit("isInteger");
20327f30029SMichael Kruse     bool IsVector = VT->getValueAsBit("isVector");
20427f30029SMichael Kruse     bool IsFP = VT->getValueAsBit("isFP");
20527f30029SMichael Kruse     bool IsRISCVVecTuple = VT->getValueAsBit("isRISCVVecTuple");
20627f30029SMichael Kruse 
20727f30029SMichael Kruse     if (!IsInteger && !IsVector && !IsFP && !IsRISCVVecTuple)
20827f30029SMichael Kruse       continue;
20927f30029SMichael Kruse 
21027f30029SMichael Kruse     OS << "  GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", ";
21127f30029SMichael Kruse     vTtoGetLlvmTyString(OS, VT);
21227f30029SMichael Kruse     OS << ")\n";
21327f30029SMichael Kruse   }
21427f30029SMichael Kruse   OS << "#endif\n\n";
21527f30029SMichael Kruse }
21627f30029SMichael Kruse 
21727f30029SMichael Kruse static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType");
218