1 //===- VTEmitter.cpp - Generate properties from ValueTypes.td -------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/StringRef.h" 10 #include "llvm/Support/raw_ostream.h" 11 #include "llvm/TableGen/Record.h" 12 #include "llvm/TableGen/TableGenBackend.h" 13 #include <array> 14 #include <cassert> 15 #include <map> 16 using namespace llvm; 17 18 namespace { 19 20 class VTEmitter { 21 private: 22 RecordKeeper &Records; 23 24 public: 25 VTEmitter(RecordKeeper &R) : Records(R) {} 26 27 void run(raw_ostream &OS); 28 }; 29 30 } // End anonymous namespace. 31 32 static void VTtoGetLLVMTyString(raw_ostream &OS, const Record *VT) { 33 bool IsVector = VT->getValueAsBit("isVector"); 34 if (IsVector) 35 OS << (VT->getValueAsBit("isScalable") ? "Scalable" : "Fixed") 36 << "VectorType::get("; 37 38 auto OutputVT = IsVector ? VT->getValueAsDef("ElementType") : VT; 39 int64_t OutputVTSize = OutputVT->getValueAsInt("Size"); 40 41 if (OutputVT->getValueAsBit("isFP")) { 42 StringRef FloatTy; 43 auto OutputVTName = OutputVT->getValueAsString("LLVMName"); 44 switch (OutputVTSize) { 45 default: 46 llvm_unreachable("Unhandled case"); 47 case 16: 48 FloatTy = (OutputVTName == "bf16") ? "BFloatTy" : "HalfTy"; 49 break; 50 case 32: 51 FloatTy = "FloatTy"; 52 break; 53 case 64: 54 FloatTy = "DoubleTy"; 55 break; 56 case 80: 57 FloatTy = "X86_FP80Ty"; 58 break; 59 case 128: 60 FloatTy = (OutputVTName == "ppcf128") ? "PPC_FP128Ty" : "FP128Ty"; 61 break; 62 } 63 OS << "Type::get" << FloatTy << "(Context)"; 64 } else if (OutputVT->getValueAsBit("isInteger")) { 65 // We only have Type::getInt1Ty, Int8, Int16, Int32, Int64, and Int128 66 if ((isPowerOf2_64(OutputVTSize) && OutputVTSize >= 8 && 67 OutputVTSize <= 128) || 68 OutputVTSize == 1) 69 OS << "Type::getInt" << OutputVTSize << "Ty(Context)"; 70 else 71 OS << "Type::getIntNTy(Context, " << OutputVTSize << ")"; 72 } else 73 llvm_unreachable("Unhandled case"); 74 75 if (IsVector) 76 OS << ", " << VT->getValueAsInt("nElem") << ")"; 77 } 78 79 void VTEmitter::run(raw_ostream &OS) { 80 emitSourceFileHeader("ValueTypes Source Fragment", OS, Records); 81 82 std::array<const Record *, 256> VTsByNumber = {}; 83 auto ValueTypes = Records.getAllDerivedDefinitions("ValueType"); 84 for (auto *VT : ValueTypes) { 85 auto Number = VT->getValueAsInt("Value"); 86 assert(0 <= Number && Number < (int)VTsByNumber.size() && 87 "ValueType should be uint8_t"); 88 assert(!VTsByNumber[Number] && "Duplicate ValueType"); 89 VTsByNumber[Number] = VT; 90 } 91 92 struct VTRange { 93 StringRef First; 94 StringRef Last; 95 bool Closed; 96 }; 97 98 std::map<StringRef, VTRange> VTRanges; 99 100 auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name, 101 bool Valid) { 102 if (Valid) { 103 if (!VTRanges.count(Key)) 104 VTRanges[Key].First = Name; 105 assert(!VTRanges[Key].Closed && "Gap detected!"); 106 VTRanges[Key].Last = Name; 107 } else if (VTRanges.count(Key)) { 108 VTRanges[Key].Closed = true; 109 } 110 }; 111 112 OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc)\n"; 113 for (const auto *VT : VTsByNumber) { 114 if (!VT) 115 continue; 116 auto Name = VT->getValueAsString("LLVMName"); 117 auto Value = VT->getValueAsInt("Value"); 118 bool IsInteger = VT->getValueAsBit("isInteger"); 119 bool IsFP = VT->getValueAsBit("isFP"); 120 bool IsVector = VT->getValueAsBit("isVector"); 121 bool IsScalable = VT->getValueAsBit("isScalable"); 122 bool IsNormalValueType = VT->getValueAsBit("isNormalValueType"); 123 int64_t NElem = IsVector ? VT->getValueAsInt("nElem") : 0; 124 StringRef EltName = IsVector ? VT->getValueAsDef("ElementType")->getName() 125 : "INVALID_SIMPLE_VALUE_TYPE"; 126 127 UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name, 128 IsInteger && IsVector && !IsScalable); 129 UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name, 130 IsInteger && IsScalable); 131 UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name, 132 IsFP && IsVector && !IsScalable); 133 UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable); 134 UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable); 135 UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable); 136 UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector); 137 UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector); 138 UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector); 139 UpdateVTRange("VALUETYPE", Name, IsNormalValueType); 140 141 // clang-format off 142 OS << " GET_VT_ATTR(" 143 << Name << ", " 144 << Value << ", " 145 << VT->getValueAsInt("Size") << ", " 146 << VT->getValueAsBit("isOverloaded") << ", " 147 << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", " 148 << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", " 149 << IsVector << ", " 150 << IsScalable << ", " 151 << NElem << ", " 152 << EltName << ")\n"; 153 // clang-format on 154 } 155 OS << "#endif\n\n"; 156 157 OS << "#ifdef GET_VT_RANGES\n"; 158 for (const auto &KV : VTRanges) { 159 assert(KV.second.Closed); 160 OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n" 161 << " LAST_" << KV.first << " = " << KV.second.Last << ",\n"; 162 } 163 OS << "#endif\n\n"; 164 165 OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, nElem, ElTy)\n"; 166 for (const auto *VT : VTsByNumber) { 167 if (!VT || !VT->getValueAsBit("isVector")) 168 continue; 169 const auto *ElTy = VT->getValueAsDef("ElementType"); 170 assert(ElTy); 171 // clang-format off 172 OS << " GET_VT_VECATTR(" 173 << VT->getValueAsString("LLVMName") << ", " 174 << VT->getValueAsBit("isScalable") << ", " 175 << VT->getValueAsInt("nElem") << ", " 176 << ElTy->getName() << ")\n"; 177 // clang-format on 178 } 179 OS << "#endif\n\n"; 180 181 OS << "#ifdef GET_VT_EVT\n"; 182 for (const auto *VT : VTsByNumber) { 183 if (!VT) 184 continue; 185 bool IsInteger = VT->getValueAsBit("isInteger"); 186 bool IsVector = VT->getValueAsBit("isVector"); 187 bool IsFP = VT->getValueAsBit("isFP"); 188 189 if (!IsInteger && !IsVector && !IsFP) 190 continue; 191 192 OS << " GET_VT_EVT(" << VT->getValueAsString("LLVMName") << ", "; 193 VTtoGetLLVMTyString(OS, VT); 194 OS << ")\n"; 195 } 196 OS << "#endif\n\n"; 197 } 198 199 static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType"); 200