1cde4d5a6SJacques Pienaar //===- Attribute.cpp - Attribute wrapper class ----------------------------===// 29b034f0bSLei Zhang // 330857107SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 456222a06SMehdi Amini // See https://llvm.org/LICENSE.txt for license information. 556222a06SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69b034f0bSLei Zhang // 756222a06SMehdi Amini //===----------------------------------------------------------------------===// 89b034f0bSLei Zhang // 99b034f0bSLei Zhang // Attribute wrapper to simplify using TableGen Record defining a MLIR 109b034f0bSLei Zhang // Attribute. 119b034f0bSLei Zhang // 129b034f0bSLei Zhang //===----------------------------------------------------------------------===// 139b034f0bSLei Zhang 14138c972dSLei Zhang #include "mlir/TableGen/Format.h" 159b034f0bSLei Zhang #include "mlir/TableGen/Operator.h" 169b034f0bSLei Zhang #include "llvm/TableGen/Record.h" 179b034f0bSLei Zhang 189b034f0bSLei Zhang using namespace mlir; 1912d16de5SRahul Joshi using namespace mlir::tblgen; 209b034f0bSLei Zhang 21138c972dSLei Zhang using llvm::DefInit; 22138c972dSLei Zhang using llvm::Init; 23138c972dSLei Zhang using llvm::Record; 24138c972dSLei Zhang using llvm::StringInit; 25138c972dSLei Zhang 269b034f0bSLei Zhang // Returns the initializer's value as string if the given TableGen initializer 279b034f0bSLei Zhang // is a code or string initializer. Returns the empty StringRef otherwise. 28138c972dSLei Zhang static StringRef getValueAsString(const Init *init) { 2912d16de5SRahul Joshi if (const auto *str = dyn_cast<StringInit>(init)) 309b034f0bSLei Zhang return str->getValue().trim(); 319b034f0bSLei Zhang return {}; 329b034f0bSLei Zhang } 339b034f0bSLei Zhang 3412d16de5SRahul Joshi bool AttrConstraint::isSubClassOf(StringRef className) const { 35aa9dc944SLei Zhang return def->isSubClassOf(className); 36aa9dc944SLei Zhang } 37aa9dc944SLei Zhang 3812d16de5SRahul Joshi Attribute::Attribute(const Record *record) : AttrConstraint(record) { 390fbf4ff2SJacques Pienaar assert(record->isSubClassOf("Attr") && 409b034f0bSLei Zhang "must be subclass of TableGen 'Attr' class"); 419b034f0bSLei Zhang } 429b034f0bSLei Zhang 4312d16de5SRahul Joshi Attribute::Attribute(const DefInit *init) : Attribute(init->getDef()) {} 449b034f0bSLei Zhang 4512d16de5SRahul Joshi bool Attribute::isDerivedAttr() const { return isSubClassOf("DerivedAttr"); } 469b034f0bSLei Zhang 4712d16de5SRahul Joshi bool Attribute::isTypeAttr() const { return isSubClassOf("TypeAttrBase"); } 48c489f50eSFeng Liu 49c0958b7bSRiver Riddle bool Attribute::isSymbolRefAttr() const { 50c0958b7bSRiver Riddle StringRef defName = def->getName(); 51c0958b7bSRiver Riddle if (defName == "SymbolRefAttr" || defName == "FlatSymbolRefAttr") 52c0958b7bSRiver Riddle return true; 53c0958b7bSRiver Riddle return isSubClassOf("SymbolRefAttr") || isSubClassOf("FlatSymbolRefAttr"); 54c0958b7bSRiver Riddle } 55c0958b7bSRiver Riddle 5612d16de5SRahul Joshi bool Attribute::isEnumAttr() const { return isSubClassOf("EnumAttrInfo"); } 57c6cfebf1SMahesh Ravishankar 5812d16de5SRahul Joshi StringRef Attribute::getStorageType() const { 59a5827fc9SJacques Pienaar const auto *init = def->getValueInit("storageType"); 609b034f0bSLei Zhang auto type = getValueAsString(init); 619b034f0bSLei Zhang if (type.empty()) 620235e3c7SMarkus Böck return "::mlir::Attribute"; 639b034f0bSLei Zhang return type; 649b034f0bSLei Zhang } 659b034f0bSLei Zhang 6612d16de5SRahul Joshi StringRef Attribute::getReturnType() const { 67a5827fc9SJacques Pienaar const auto *init = def->getValueInit("returnType"); 689b034f0bSLei Zhang return getValueAsString(init); 699b034f0bSLei Zhang } 709b034f0bSLei Zhang 711b2c16f2SRiver Riddle // Return the type constraint corresponding to the type of this attribute, or 724f81805aSKazu Hirata // std::nullopt if this is not a TypedAttr. 733cfe412eSFangrui Song std::optional<Type> Attribute::getValueType() const { 74*659192b1SRahul Joshi if (const auto *defInit = dyn_cast<DefInit>(def->getValueInit("valueType"))) 7512d16de5SRahul Joshi return Type(defInit->getDef()); 761a36588eSKazu Hirata return std::nullopt; 771b2c16f2SRiver Riddle } 781b2c16f2SRiver Riddle 7912d16de5SRahul Joshi StringRef Attribute::getConvertFromStorageCall() const { 80a5827fc9SJacques Pienaar const auto *init = def->getValueInit("convertFromStorage"); 819b034f0bSLei Zhang return getValueAsString(init); 829b034f0bSLei Zhang } 839b034f0bSLei Zhang 8412d16de5SRahul Joshi bool Attribute::isConstBuildable() const { 85a5827fc9SJacques Pienaar const auto *init = def->getValueInit("constBuilderCall"); 86bd161ae5SAlex Zinenko return !getValueAsString(init).empty(); 87bd161ae5SAlex Zinenko } 88bd161ae5SAlex Zinenko 8912d16de5SRahul Joshi StringRef Attribute::getConstBuilderTemplate() const { 90a5827fc9SJacques Pienaar const auto *init = def->getValueInit("constBuilderCall"); 91bd161ae5SAlex Zinenko return getValueAsString(init); 92bd161ae5SAlex Zinenko } 93bd161ae5SAlex Zinenko 9412d16de5SRahul Joshi Attribute Attribute::getBaseAttr() const { 95*659192b1SRahul Joshi if (const auto *defInit = dyn_cast<DefInit>(def->getValueInit("baseAttr"))) { 96765b77ccSLei Zhang return Attribute(defInit).getBaseAttr(); 97765b77ccSLei Zhang } 98765b77ccSLei Zhang return *this; 99765b77ccSLei Zhang } 100765b77ccSLei Zhang 10112d16de5SRahul Joshi bool Attribute::hasDefaultValue() const { 10234c6f8c6SJacques Pienaar const auto *init = def->getValueInit("defaultValue"); 10334c6f8c6SJacques Pienaar return !getValueAsString(init).empty(); 10434c6f8c6SJacques Pienaar } 10534c6f8c6SJacques Pienaar 10612d16de5SRahul Joshi StringRef Attribute::getDefaultValue() const { 107138c972dSLei Zhang const auto *init = def->getValueInit("defaultValue"); 108138c972dSLei Zhang return getValueAsString(init); 109c81b16e2SStella Laurenzo } 110c81b16e2SStella Laurenzo 11112d16de5SRahul Joshi bool Attribute::isOptional() const { return def->getValueAsBit("isOptional"); } 11234c6f8c6SJacques Pienaar 11312d16de5SRahul Joshi StringRef Attribute::getAttrDefName() const { 114765b77ccSLei Zhang if (def->isAnonymous()) { 115765b77ccSLei Zhang return getBaseAttr().def->getName(); 116765b77ccSLei Zhang } 117a5827fc9SJacques Pienaar return def->getName(); 118bd161ae5SAlex Zinenko } 119bd161ae5SAlex Zinenko 12012d16de5SRahul Joshi StringRef Attribute::getDerivedCodeBody() const { 1219b034f0bSLei Zhang assert(isDerivedAttr() && "only derived attribute has 'body' field"); 122a5827fc9SJacques Pienaar return def->getValueAsString("body"); 1239b034f0bSLei Zhang } 124e0774c00SLei Zhang 12512d16de5SRahul Joshi Dialect Attribute::getDialect() const { 126a3942308SFederico Lebrón const llvm::RecordVal *record = def->getValue("dialect"); 127a3942308SFederico Lebrón if (record && record->getValue()) { 128e768b076SRahul Joshi if (const DefInit *init = dyn_cast<DefInit>(record->getValue())) 129a3942308SFederico Lebrón return Dialect(init->getDef()); 130a3942308SFederico Lebrón } 131a3942308SFederico Lebrón return Dialect(nullptr); 132429d792fSRiver Riddle } 133429d792fSRiver Riddle 134*659192b1SRahul Joshi const Record &Attribute::getDef() const { return *def; } 135a29fffc4SLei Zhang 13612d16de5SRahul Joshi ConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) { 137e0774c00SLei Zhang assert(def->isSubClassOf("ConstantAttr") && 138e0774c00SLei Zhang "must be subclass of TableGen 'ConstantAttr' class"); 139e0774c00SLei Zhang } 140e0774c00SLei Zhang 14112d16de5SRahul Joshi Attribute ConstantAttr::getAttribute() const { 142e0774c00SLei Zhang return Attribute(def->getValueAsDef("attr")); 143e0774c00SLei Zhang } 144e0774c00SLei Zhang 14512d16de5SRahul Joshi StringRef ConstantAttr::getConstantValue() const { 146e0774c00SLei Zhang return def->getValueAsString("value"); 147e0774c00SLei Zhang } 148b9e38a79SLei Zhang 149*659192b1SRahul Joshi EnumAttrCase::EnumAttrCase(const Record *record) : Attribute(record) { 150aa9dc944SLei Zhang assert(isSubClassOf("EnumAttrCaseInfo") && 1519dd182e0SLei Zhang "must be subclass of TableGen 'EnumAttrInfo' class"); 1529dd182e0SLei Zhang } 1539dd182e0SLei Zhang 154*659192b1SRahul Joshi EnumAttrCase::EnumAttrCase(const DefInit *init) 155267483acSLei Zhang : EnumAttrCase(init->getDef()) {} 156267483acSLei Zhang 15712d16de5SRahul Joshi StringRef EnumAttrCase::getSymbol() const { 158b9e38a79SLei Zhang return def->getValueAsString("symbol"); 159b9e38a79SLei Zhang } 160b9e38a79SLei Zhang 16112d16de5SRahul Joshi StringRef EnumAttrCase::getStr() const { return def->getValueAsString("str"); } 162fdc496a3SAlex Zinenko 16312d16de5SRahul Joshi int64_t EnumAttrCase::getValue() const { return def->getValueAsInt("value"); } 1641be9fc66SLei Zhang 165*659192b1SRahul Joshi const Record &EnumAttrCase::getDef() const { return *def; } 166a81cb1b8SLei Zhang 167*659192b1SRahul Joshi EnumAttr::EnumAttr(const Record *record) : Attribute(record) { 168aa9dc944SLei Zhang assert(isSubClassOf("EnumAttrInfo") && 169b9e38a79SLei Zhang "must be subclass of TableGen 'EnumAttr' class"); 170b9e38a79SLei Zhang } 171b9e38a79SLei Zhang 172*659192b1SRahul Joshi EnumAttr::EnumAttr(const Record &record) : Attribute(&record) {} 1731be9fc66SLei Zhang 174*659192b1SRahul Joshi EnumAttr::EnumAttr(const DefInit *init) : EnumAttr(init->getDef()) {} 175b9e38a79SLei Zhang 17612d16de5SRahul Joshi bool EnumAttr::classof(const Attribute *attr) { 177a81cb1b8SLei Zhang return attr->isSubClassOf("EnumAttrInfo"); 178a81cb1b8SLei Zhang } 179a81cb1b8SLei Zhang 18012d16de5SRahul Joshi bool EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); } 1816934a337SLei Zhang 18212d16de5SRahul Joshi StringRef EnumAttr::getEnumClassName() const { 183b9e38a79SLei Zhang return def->getValueAsString("className"); 184b9e38a79SLei Zhang } 185b9e38a79SLei Zhang 18612d16de5SRahul Joshi StringRef EnumAttr::getCppNamespace() const { 1871be9fc66SLei Zhang return def->getValueAsString("cppNamespace"); 1881be9fc66SLei Zhang } 1891be9fc66SLei Zhang 19012d16de5SRahul Joshi StringRef EnumAttr::getUnderlyingType() const { 1911be9fc66SLei Zhang return def->getValueAsString("underlyingType"); 1921be9fc66SLei Zhang } 1931be9fc66SLei Zhang 19412d16de5SRahul Joshi StringRef EnumAttr::getUnderlyingToSymbolFnName() const { 1958f77d2afSLei Zhang return def->getValueAsString("underlyingToSymbolFnName"); 1968f77d2afSLei Zhang } 1978f77d2afSLei Zhang 19812d16de5SRahul Joshi StringRef EnumAttr::getStringToSymbolFnName() const { 1991be9fc66SLei Zhang return def->getValueAsString("stringToSymbolFnName"); 2001be9fc66SLei Zhang } 2011be9fc66SLei Zhang 20212d16de5SRahul Joshi StringRef EnumAttr::getSymbolToStringFnName() const { 2031be9fc66SLei Zhang return def->getValueAsString("symbolToStringFnName"); 2041be9fc66SLei Zhang } 2051be9fc66SLei Zhang 20612d16de5SRahul Joshi StringRef EnumAttr::getSymbolToStringFnRetType() const { 2076934a337SLei Zhang return def->getValueAsString("symbolToStringFnRetType"); 2086934a337SLei Zhang } 2096934a337SLei Zhang 21012d16de5SRahul Joshi StringRef EnumAttr::getMaxEnumValFnName() const { 211d7ba69e8SMahesh Ravishankar return def->getValueAsString("maxEnumValFnName"); 212d7ba69e8SMahesh Ravishankar } 213d7ba69e8SMahesh Ravishankar 21412d16de5SRahul Joshi std::vector<EnumAttrCase> EnumAttr::getAllCases() const { 215b9e38a79SLei Zhang const auto *inits = def->getValueAsListInit("enumerants"); 216b9e38a79SLei Zhang 21712d16de5SRahul Joshi std::vector<EnumAttrCase> cases; 218b9e38a79SLei Zhang cases.reserve(inits->size()); 219b9e38a79SLei Zhang 220*659192b1SRahul Joshi for (const Init *init : *inits) { 221*659192b1SRahul Joshi cases.emplace_back(cast<DefInit>(init)); 222b9e38a79SLei Zhang } 223b9e38a79SLei Zhang 224b9e38a79SLei Zhang return cases; 225b9e38a79SLei Zhang } 2268f90a442SRob Suderman 227fee90542SVladislav Vinogradov bool EnumAttr::genSpecializedAttr() const { 228fee90542SVladislav Vinogradov return def->getValueAsBit("genSpecializedAttr"); 229fee90542SVladislav Vinogradov } 230fee90542SVladislav Vinogradov 231*659192b1SRahul Joshi const Record *EnumAttr::getBaseAttrClass() const { 232fee90542SVladislav Vinogradov return def->getValueAsDef("baseAttrClass"); 233fee90542SVladislav Vinogradov } 234fee90542SVladislav Vinogradov 235fee90542SVladislav Vinogradov StringRef EnumAttr::getSpecializedAttrClassName() const { 236fee90542SVladislav Vinogradov return def->getValueAsString("specializedAttrClassName"); 237fee90542SVladislav Vinogradov } 238fee90542SVladislav Vinogradov 2394e5dee2fSjfurtek bool EnumAttr::printBitEnumPrimaryGroups() const { 2404e5dee2fSjfurtek return def->getValueAsBit("printBitEnumPrimaryGroups"); 2414e5dee2fSjfurtek } 2424e5dee2fSjfurtek 24312d16de5SRahul Joshi const char * ::mlir::tblgen::inferTypeOpInterface = "InferTypeOpInterface"; 244