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. getValueAsString(const Init * init)28138c972dSLei Zhangstatic 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 isSubClassOf(StringRef className) const3412d16de5SRahul Joshibool AttrConstraint::isSubClassOf(StringRef className) const { 35aa9dc944SLei Zhang return def->isSubClassOf(className); 36aa9dc944SLei Zhang } 37aa9dc944SLei Zhang Attribute(const Record * record)3812d16de5SRahul JoshiAttribute::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 Attribute(const DefInit * init)4312d16de5SRahul JoshiAttribute::Attribute(const DefInit *init) : Attribute(init->getDef()) {} 449b034f0bSLei Zhang isDerivedAttr() const4512d16de5SRahul Joshibool Attribute::isDerivedAttr() const { return isSubClassOf("DerivedAttr"); } 469b034f0bSLei Zhang isTypeAttr() const4712d16de5SRahul Joshibool Attribute::isTypeAttr() const { return isSubClassOf("TypeAttrBase"); } 48c489f50eSFeng Liu isSymbolRefAttr() const49c0958b7bSRiver Riddlebool 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 isEnumAttr() const5612d16de5SRahul Joshibool Attribute::isEnumAttr() const { return isSubClassOf("EnumAttrInfo"); } 57c6cfebf1SMahesh Ravishankar getStorageType() const5812d16de5SRahul JoshiStringRef 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 getReturnType() const6612d16de5SRahul JoshiStringRef 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 721b2c16f2SRiver Riddle // None if this is not a TypedAttr. getValueType() const7312d16de5SRahul Joshillvm::Optional<Type> Attribute::getValueType() const { 741b2c16f2SRiver Riddle if (auto *defInit = dyn_cast<llvm::DefInit>(def->getValueInit("valueType"))) 7512d16de5SRahul Joshi return Type(defInit->getDef()); 761b2c16f2SRiver Riddle return llvm::None; 771b2c16f2SRiver Riddle } 781b2c16f2SRiver Riddle getConvertFromStorageCall() const7912d16de5SRahul JoshiStringRef Attribute::getConvertFromStorageCall() const { 80a5827fc9SJacques Pienaar const auto *init = def->getValueInit("convertFromStorage"); 819b034f0bSLei Zhang return getValueAsString(init); 829b034f0bSLei Zhang } 839b034f0bSLei Zhang isConstBuildable() const8412d16de5SRahul Joshibool Attribute::isConstBuildable() const { 85a5827fc9SJacques Pienaar const auto *init = def->getValueInit("constBuilderCall"); 86bd161ae5SAlex Zinenko return !getValueAsString(init).empty(); 87bd161ae5SAlex Zinenko } 88bd161ae5SAlex Zinenko getConstBuilderTemplate() const8912d16de5SRahul JoshiStringRef Attribute::getConstBuilderTemplate() const { 90a5827fc9SJacques Pienaar const auto *init = def->getValueInit("constBuilderCall"); 91bd161ae5SAlex Zinenko return getValueAsString(init); 92bd161ae5SAlex Zinenko } 93bd161ae5SAlex Zinenko getBaseAttr() const9412d16de5SRahul JoshiAttribute Attribute::getBaseAttr() const { 95765b77ccSLei Zhang if (const auto *defInit = 96765b77ccSLei Zhang llvm::dyn_cast<llvm::DefInit>(def->getValueInit("baseAttr"))) { 97765b77ccSLei Zhang return Attribute(defInit).getBaseAttr(); 98765b77ccSLei Zhang } 99765b77ccSLei Zhang return *this; 100765b77ccSLei Zhang } 101765b77ccSLei Zhang hasDefaultValue() const10212d16de5SRahul Joshibool Attribute::hasDefaultValue() const { 10334c6f8c6SJacques Pienaar const auto *init = def->getValueInit("defaultValue"); 10434c6f8c6SJacques Pienaar return !getValueAsString(init).empty(); 10534c6f8c6SJacques Pienaar } 10634c6f8c6SJacques Pienaar getDefaultValue() const10712d16de5SRahul JoshiStringRef Attribute::getDefaultValue() const { 108138c972dSLei Zhang const auto *init = def->getValueInit("defaultValue"); 109138c972dSLei Zhang return getValueAsString(init); 110c81b16e2SStella Laurenzo } 111c81b16e2SStella Laurenzo isOptional() const11212d16de5SRahul Joshibool Attribute::isOptional() const { return def->getValueAsBit("isOptional"); } 11334c6f8c6SJacques Pienaar getAttrDefName() const11412d16de5SRahul JoshiStringRef Attribute::getAttrDefName() const { 115765b77ccSLei Zhang if (def->isAnonymous()) { 116765b77ccSLei Zhang return getBaseAttr().def->getName(); 117765b77ccSLei Zhang } 118a5827fc9SJacques Pienaar return def->getName(); 119bd161ae5SAlex Zinenko } 120bd161ae5SAlex Zinenko getDerivedCodeBody() const12112d16de5SRahul JoshiStringRef Attribute::getDerivedCodeBody() const { 1229b034f0bSLei Zhang assert(isDerivedAttr() && "only derived attribute has 'body' field"); 123a5827fc9SJacques Pienaar return def->getValueAsString("body"); 1249b034f0bSLei Zhang } 125e0774c00SLei Zhang getDialect() const12612d16de5SRahul JoshiDialect Attribute::getDialect() const { 127a3942308SFederico Lebrón const llvm::RecordVal *record = def->getValue("dialect"); 128a3942308SFederico Lebrón if (record && record->getValue()) { 129a3942308SFederico Lebrón if (DefInit *init = dyn_cast<DefInit>(record->getValue())) 130a3942308SFederico Lebrón return Dialect(init->getDef()); 131a3942308SFederico Lebrón } 132a3942308SFederico Lebrón return Dialect(nullptr); 133429d792fSRiver Riddle } 134429d792fSRiver Riddle ConstantAttr(const DefInit * init)13512d16de5SRahul JoshiConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) { 136e0774c00SLei Zhang assert(def->isSubClassOf("ConstantAttr") && 137e0774c00SLei Zhang "must be subclass of TableGen 'ConstantAttr' class"); 138e0774c00SLei Zhang } 139e0774c00SLei Zhang getAttribute() const14012d16de5SRahul JoshiAttribute ConstantAttr::getAttribute() const { 141e0774c00SLei Zhang return Attribute(def->getValueAsDef("attr")); 142e0774c00SLei Zhang } 143e0774c00SLei Zhang getConstantValue() const14412d16de5SRahul JoshiStringRef ConstantAttr::getConstantValue() const { 145e0774c00SLei Zhang return def->getValueAsString("value"); 146e0774c00SLei Zhang } 147b9e38a79SLei Zhang EnumAttrCase(const llvm::Record * record)14812d16de5SRahul JoshiEnumAttrCase::EnumAttrCase(const llvm::Record *record) : Attribute(record) { 149aa9dc944SLei Zhang assert(isSubClassOf("EnumAttrCaseInfo") && 1509dd182e0SLei Zhang "must be subclass of TableGen 'EnumAttrInfo' class"); 1519dd182e0SLei Zhang } 1529dd182e0SLei Zhang EnumAttrCase(const llvm::DefInit * init)15312d16de5SRahul JoshiEnumAttrCase::EnumAttrCase(const llvm::DefInit *init) 154267483acSLei Zhang : EnumAttrCase(init->getDef()) {} 155267483acSLei Zhang getSymbol() const15612d16de5SRahul JoshiStringRef EnumAttrCase::getSymbol() const { 157b9e38a79SLei Zhang return def->getValueAsString("symbol"); 158b9e38a79SLei Zhang } 159b9e38a79SLei Zhang getStr() const16012d16de5SRahul JoshiStringRef EnumAttrCase::getStr() const { return def->getValueAsString("str"); } 161fdc496a3SAlex Zinenko getValue() const16212d16de5SRahul Joshiint64_t EnumAttrCase::getValue() const { return def->getValueAsInt("value"); } 1631be9fc66SLei Zhang getDef() const16412d16de5SRahul Joshiconst llvm::Record &EnumAttrCase::getDef() const { return *def; } 165a81cb1b8SLei Zhang EnumAttr(const llvm::Record * record)16612d16de5SRahul JoshiEnumAttr::EnumAttr(const llvm::Record *record) : Attribute(record) { 167aa9dc944SLei Zhang assert(isSubClassOf("EnumAttrInfo") && 168b9e38a79SLei Zhang "must be subclass of TableGen 'EnumAttr' class"); 169b9e38a79SLei Zhang } 170b9e38a79SLei Zhang EnumAttr(const llvm::Record & record)17112d16de5SRahul JoshiEnumAttr::EnumAttr(const llvm::Record &record) : Attribute(&record) {} 1721be9fc66SLei Zhang EnumAttr(const llvm::DefInit * init)17312d16de5SRahul JoshiEnumAttr::EnumAttr(const llvm::DefInit *init) : EnumAttr(init->getDef()) {} 174b9e38a79SLei Zhang classof(const Attribute * attr)17512d16de5SRahul Joshibool EnumAttr::classof(const Attribute *attr) { 176a81cb1b8SLei Zhang return attr->isSubClassOf("EnumAttrInfo"); 177a81cb1b8SLei Zhang } 178a81cb1b8SLei Zhang isBitEnum() const17912d16de5SRahul Joshibool EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); } 1806934a337SLei Zhang getEnumClassName() const18112d16de5SRahul JoshiStringRef EnumAttr::getEnumClassName() const { 182b9e38a79SLei Zhang return def->getValueAsString("className"); 183b9e38a79SLei Zhang } 184b9e38a79SLei Zhang getCppNamespace() const18512d16de5SRahul JoshiStringRef EnumAttr::getCppNamespace() const { 1861be9fc66SLei Zhang return def->getValueAsString("cppNamespace"); 1871be9fc66SLei Zhang } 1881be9fc66SLei Zhang getUnderlyingType() const18912d16de5SRahul JoshiStringRef EnumAttr::getUnderlyingType() const { 1901be9fc66SLei Zhang return def->getValueAsString("underlyingType"); 1911be9fc66SLei Zhang } 1921be9fc66SLei Zhang getUnderlyingToSymbolFnName() const19312d16de5SRahul JoshiStringRef EnumAttr::getUnderlyingToSymbolFnName() const { 1948f77d2afSLei Zhang return def->getValueAsString("underlyingToSymbolFnName"); 1958f77d2afSLei Zhang } 1968f77d2afSLei Zhang getStringToSymbolFnName() const19712d16de5SRahul JoshiStringRef EnumAttr::getStringToSymbolFnName() const { 1981be9fc66SLei Zhang return def->getValueAsString("stringToSymbolFnName"); 1991be9fc66SLei Zhang } 2001be9fc66SLei Zhang getSymbolToStringFnName() const20112d16de5SRahul JoshiStringRef EnumAttr::getSymbolToStringFnName() const { 2021be9fc66SLei Zhang return def->getValueAsString("symbolToStringFnName"); 2031be9fc66SLei Zhang } 2041be9fc66SLei Zhang getSymbolToStringFnRetType() const20512d16de5SRahul JoshiStringRef EnumAttr::getSymbolToStringFnRetType() const { 2066934a337SLei Zhang return def->getValueAsString("symbolToStringFnRetType"); 2076934a337SLei Zhang } 2086934a337SLei Zhang getMaxEnumValFnName() const20912d16de5SRahul JoshiStringRef EnumAttr::getMaxEnumValFnName() const { 210d7ba69e8SMahesh Ravishankar return def->getValueAsString("maxEnumValFnName"); 211d7ba69e8SMahesh Ravishankar } 212d7ba69e8SMahesh Ravishankar getAllCases() const21312d16de5SRahul Joshistd::vector<EnumAttrCase> EnumAttr::getAllCases() const { 214b9e38a79SLei Zhang const auto *inits = def->getValueAsListInit("enumerants"); 215b9e38a79SLei Zhang 21612d16de5SRahul Joshi std::vector<EnumAttrCase> cases; 217b9e38a79SLei Zhang cases.reserve(inits->size()); 218b9e38a79SLei Zhang 219b9e38a79SLei Zhang for (const llvm::Init *init : *inits) { 220e5639b3fSMehdi Amini cases.emplace_back(cast<llvm::DefInit>(init)); 221b9e38a79SLei Zhang } 222b9e38a79SLei Zhang 223b9e38a79SLei Zhang return cases; 224b9e38a79SLei Zhang } 2258f90a442SRob Suderman genSpecializedAttr() const226fee90542SVladislav Vinogradovbool EnumAttr::genSpecializedAttr() const { 227fee90542SVladislav Vinogradov return def->getValueAsBit("genSpecializedAttr"); 228fee90542SVladislav Vinogradov } 229fee90542SVladislav Vinogradov getBaseAttrClass() const230fee90542SVladislav Vinogradovllvm::Record *EnumAttr::getBaseAttrClass() const { 231fee90542SVladislav Vinogradov return def->getValueAsDef("baseAttrClass"); 232fee90542SVladislav Vinogradov } 233fee90542SVladislav Vinogradov getSpecializedAttrClassName() const234fee90542SVladislav VinogradovStringRef EnumAttr::getSpecializedAttrClassName() const { 235fee90542SVladislav Vinogradov return def->getValueAsString("specializedAttrClassName"); 236fee90542SVladislav Vinogradov } 237fee90542SVladislav Vinogradov printBitEnumPrimaryGroups() const238*4e5dee2fSjfurtekbool EnumAttr::printBitEnumPrimaryGroups() const { 239*4e5dee2fSjfurtek return def->getValueAsBit("printBitEnumPrimaryGroups"); 240*4e5dee2fSjfurtek } 241*4e5dee2fSjfurtek 24212d16de5SRahul Joshi const char * ::mlir::tblgen::inferTypeOpInterface = "InferTypeOpInterface"; 243