1cde4d5a6SJacques Pienaar //===- Pattern.cpp - Pattern wrapper class --------------------------------===// 2eb753f4aSLei Zhang // 3eb753f4aSLei Zhang // Copyright 2019 The MLIR Authors. 4eb753f4aSLei Zhang // 5eb753f4aSLei Zhang // Licensed under the Apache License, Version 2.0 (the "License"); 6eb753f4aSLei Zhang // you may not use this file except in compliance with the License. 7eb753f4aSLei Zhang // You may obtain a copy of the License at 8eb753f4aSLei Zhang // 9eb753f4aSLei Zhang // http://www.apache.org/licenses/LICENSE-2.0 10eb753f4aSLei Zhang // 11eb753f4aSLei Zhang // Unless required by applicable law or agreed to in writing, software 12eb753f4aSLei Zhang // distributed under the License is distributed on an "AS IS" BASIS, 13eb753f4aSLei Zhang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14eb753f4aSLei Zhang // See the License for the specific language governing permissions and 15eb753f4aSLei Zhang // limitations under the License. 16eb753f4aSLei Zhang // ============================================================================= 17eb753f4aSLei Zhang // 18eb753f4aSLei Zhang // Pattern wrapper class to simplify using TableGen Record defining a MLIR 19eb753f4aSLei Zhang // Pattern. 20eb753f4aSLei Zhang // 21eb753f4aSLei Zhang //===----------------------------------------------------------------------===// 22eb753f4aSLei Zhang 23eb753f4aSLei Zhang #include "mlir/TableGen/Pattern.h" 24eb753f4aSLei Zhang #include "llvm/ADT/Twine.h" 2504b6d2f3SLei Zhang #include "llvm/Support/FormatVariadic.h" 268f5fa566SLei Zhang #include "llvm/TableGen/Error.h" 27eb753f4aSLei Zhang #include "llvm/TableGen/Record.h" 28eb753f4aSLei Zhang 29eb753f4aSLei Zhang using namespace mlir; 30eb753f4aSLei Zhang 310ea6154bSJacques Pienaar using llvm::formatv; 32eb753f4aSLei Zhang using mlir::tblgen::Operator; 33eb753f4aSLei Zhang 34ac68637bSLei Zhang //===----------------------------------------------------------------------===// 35ac68637bSLei Zhang // DagLeaf 36ac68637bSLei Zhang //===----------------------------------------------------------------------===// 37ac68637bSLei Zhang 38e0774c00SLei Zhang bool tblgen::DagLeaf::isUnspecified() const { 39b9e38a79SLei Zhang return dyn_cast_or_null<llvm::UnsetInit>(def); 40e0774c00SLei Zhang } 41e0774c00SLei Zhang 42e0774c00SLei Zhang bool tblgen::DagLeaf::isOperandMatcher() const { 43e0774c00SLei Zhang // Operand matchers specify a type constraint. 44b9e38a79SLei Zhang return isSubClassOf("TypeConstraint"); 45e0774c00SLei Zhang } 46e0774c00SLei Zhang 47e0774c00SLei Zhang bool tblgen::DagLeaf::isAttrMatcher() const { 48c52a8127SFeng Liu // Attribute matchers specify an attribute constraint. 49b9e38a79SLei Zhang return isSubClassOf("AttrConstraint"); 50e0774c00SLei Zhang } 51e0774c00SLei Zhang 52d0e2019dSLei Zhang bool tblgen::DagLeaf::isNativeCodeCall() const { 53d0e2019dSLei Zhang return isSubClassOf("NativeCodeCall"); 54e0774c00SLei Zhang } 55e0774c00SLei Zhang 56e0774c00SLei Zhang bool tblgen::DagLeaf::isConstantAttr() const { 57b9e38a79SLei Zhang return isSubClassOf("ConstantAttr"); 58b9e38a79SLei Zhang } 59b9e38a79SLei Zhang 60b9e38a79SLei Zhang bool tblgen::DagLeaf::isEnumAttrCase() const { 619dd182e0SLei Zhang return isSubClassOf("EnumAttrCaseInfo"); 62e0774c00SLei Zhang } 63e0774c00SLei Zhang 648f5fa566SLei Zhang tblgen::Constraint tblgen::DagLeaf::getAsConstraint() const { 658f5fa566SLei Zhang assert((isOperandMatcher() || isAttrMatcher()) && 668f5fa566SLei Zhang "the DAG leaf must be operand or attribute"); 678f5fa566SLei Zhang return Constraint(cast<llvm::DefInit>(def)->getDef()); 68e0774c00SLei Zhang } 69e0774c00SLei Zhang 70e0774c00SLei Zhang tblgen::ConstantAttr tblgen::DagLeaf::getAsConstantAttr() const { 71e0774c00SLei Zhang assert(isConstantAttr() && "the DAG leaf must be constant attribute"); 72e0774c00SLei Zhang return ConstantAttr(cast<llvm::DefInit>(def)); 73e0774c00SLei Zhang } 74e0774c00SLei Zhang 75b9e38a79SLei Zhang tblgen::EnumAttrCase tblgen::DagLeaf::getAsEnumAttrCase() const { 76b9e38a79SLei Zhang assert(isEnumAttrCase() && "the DAG leaf must be an enum attribute case"); 77b9e38a79SLei Zhang return EnumAttrCase(cast<llvm::DefInit>(def)); 78b9e38a79SLei Zhang } 79b9e38a79SLei Zhang 80e0774c00SLei Zhang std::string tblgen::DagLeaf::getConditionTemplate() const { 818f5fa566SLei Zhang return getAsConstraint().getConditionTemplate(); 82e0774c00SLei Zhang } 83e0774c00SLei Zhang 84d0e2019dSLei Zhang llvm::StringRef tblgen::DagLeaf::getNativeCodeTemplate() const { 85d0e2019dSLei Zhang assert(isNativeCodeCall() && "the DAG leaf must be NativeCodeCall"); 86d0e2019dSLei Zhang return cast<llvm::DefInit>(def)->getDef()->getValueAsString("expression"); 87eb753f4aSLei Zhang } 88eb753f4aSLei Zhang 89b9e38a79SLei Zhang bool tblgen::DagLeaf::isSubClassOf(StringRef superclass) const { 90b9e38a79SLei Zhang if (auto *defInit = dyn_cast_or_null<llvm::DefInit>(def)) 91b9e38a79SLei Zhang return defInit->getDef()->isSubClassOf(superclass); 92b9e38a79SLei Zhang return false; 93b9e38a79SLei Zhang } 94b9e38a79SLei Zhang 95ac68637bSLei Zhang //===----------------------------------------------------------------------===// 96ac68637bSLei Zhang // DagNode 97ac68637bSLei Zhang //===----------------------------------------------------------------------===// 98ac68637bSLei Zhang 99d0e2019dSLei Zhang bool tblgen::DagNode::isNativeCodeCall() const { 100d0e2019dSLei Zhang if (auto *defInit = dyn_cast_or_null<llvm::DefInit>(node->getOperator())) 101d0e2019dSLei Zhang return defInit->getDef()->isSubClassOf("NativeCodeCall"); 102c52a8127SFeng Liu return false; 103c52a8127SFeng Liu } 104c52a8127SFeng Liu 105647f8cabSRiver Riddle bool tblgen::DagNode::isOperation() const { 106c72d849eSLei Zhang return !(isNativeCodeCall() || isReplaceWithValue()); 107647f8cabSRiver Riddle } 108647f8cabSRiver Riddle 109d0e2019dSLei Zhang llvm::StringRef tblgen::DagNode::getNativeCodeTemplate() const { 110d0e2019dSLei Zhang assert(isNativeCodeCall() && "the DAG leaf must be NativeCodeCall"); 111c52a8127SFeng Liu return cast<llvm::DefInit>(node->getOperator()) 112c52a8127SFeng Liu ->getDef() 113d0e2019dSLei Zhang ->getValueAsString("expression"); 114c52a8127SFeng Liu } 115c52a8127SFeng Liu 116e032d0dcSLei Zhang llvm::StringRef tblgen::DagNode::getSymbol() const { 117388fb375SJacques Pienaar return node->getNameStr(); 118388fb375SJacques Pienaar } 119388fb375SJacques Pienaar 120eb753f4aSLei Zhang Operator &tblgen::DagNode::getDialectOp(RecordOperatorMap *mapper) const { 121eb753f4aSLei Zhang llvm::Record *opDef = cast<llvm::DefInit>(node->getOperator())->getDef(); 1222dc6d205SLei Zhang auto it = mapper->find(opDef); 1232dc6d205SLei Zhang if (it != mapper->end()) 1242dc6d205SLei Zhang return *it->second; 1252dc6d205SLei Zhang return *mapper->try_emplace(opDef, llvm::make_unique<Operator>(opDef)) 1262dc6d205SLei Zhang .first->second; 127eb753f4aSLei Zhang } 128eb753f4aSLei Zhang 1292fe8ae4fSJacques Pienaar int tblgen::DagNode::getNumOps() const { 1302fe8ae4fSJacques Pienaar int count = isReplaceWithValue() ? 0 : 1; 1312fe8ae4fSJacques Pienaar for (int i = 0, e = getNumArgs(); i != e; ++i) { 132eb753f4aSLei Zhang if (auto child = getArgAsNestedDag(i)) 133eb753f4aSLei Zhang count += child.getNumOps(); 134eb753f4aSLei Zhang } 135eb753f4aSLei Zhang return count; 136eb753f4aSLei Zhang } 137eb753f4aSLei Zhang 1382fe8ae4fSJacques Pienaar int tblgen::DagNode::getNumArgs() const { return node->getNumArgs(); } 139eb753f4aSLei Zhang 140eb753f4aSLei Zhang bool tblgen::DagNode::isNestedDagArg(unsigned index) const { 141eb753f4aSLei Zhang return isa<llvm::DagInit>(node->getArg(index)); 142eb753f4aSLei Zhang } 143eb753f4aSLei Zhang 144eb753f4aSLei Zhang tblgen::DagNode tblgen::DagNode::getArgAsNestedDag(unsigned index) const { 145eb753f4aSLei Zhang return DagNode(dyn_cast_or_null<llvm::DagInit>(node->getArg(index))); 146eb753f4aSLei Zhang } 147eb753f4aSLei Zhang 148e0774c00SLei Zhang tblgen::DagLeaf tblgen::DagNode::getArgAsLeaf(unsigned index) const { 149e0774c00SLei Zhang assert(!isNestedDagArg(index)); 150e0774c00SLei Zhang return DagLeaf(node->getArg(index)); 151eb753f4aSLei Zhang } 152eb753f4aSLei Zhang 153eb753f4aSLei Zhang StringRef tblgen::DagNode::getArgName(unsigned index) const { 154eb753f4aSLei Zhang return node->getArgNameStr(index); 155eb753f4aSLei Zhang } 156eb753f4aSLei Zhang 157eb753f4aSLei Zhang bool tblgen::DagNode::isReplaceWithValue() const { 158eb753f4aSLei Zhang auto *dagOpDef = cast<llvm::DefInit>(node->getOperator())->getDef(); 159eb753f4aSLei Zhang return dagOpDef->getName() == "replaceWithValue"; 160eb753f4aSLei Zhang } 161eb753f4aSLei Zhang 162ac68637bSLei Zhang //===----------------------------------------------------------------------===// 163ac68637bSLei Zhang // SymbolInfoMap 164ac68637bSLei Zhang //===----------------------------------------------------------------------===// 165ac68637bSLei Zhang 166ac68637bSLei Zhang StringRef tblgen::SymbolInfoMap::getValuePackName(StringRef symbol, 167ac68637bSLei Zhang int *index) { 168ac68637bSLei Zhang StringRef name, indexStr; 169ac68637bSLei Zhang int idx = -1; 170ac68637bSLei Zhang std::tie(name, indexStr) = symbol.rsplit("__"); 171ac68637bSLei Zhang 172ac68637bSLei Zhang if (indexStr.consumeInteger(10, idx)) { 173ac68637bSLei Zhang // The second part is not an index; we return the whole symbol as-is. 174ac68637bSLei Zhang return symbol; 175eb753f4aSLei Zhang } 176ac68637bSLei Zhang if (index) { 177ac68637bSLei Zhang *index = idx; 178ac68637bSLei Zhang } 179ac68637bSLei Zhang return name; 180ac68637bSLei Zhang } 181ac68637bSLei Zhang 182ac68637bSLei Zhang tblgen::SymbolInfoMap::SymbolInfo::SymbolInfo(const Operator *op, 183ac68637bSLei Zhang SymbolInfo::Kind kind, 184ac68637bSLei Zhang Optional<int> index) 185ac68637bSLei Zhang : op(op), kind(kind), argIndex(index) {} 186ac68637bSLei Zhang 187ac68637bSLei Zhang int tblgen::SymbolInfoMap::SymbolInfo::getStaticValueCount() const { 188ac68637bSLei Zhang switch (kind) { 189ac68637bSLei Zhang case Kind::Attr: 190ac68637bSLei Zhang case Kind::Operand: 191ac68637bSLei Zhang case Kind::Value: 192ac68637bSLei Zhang return 1; 193ac68637bSLei Zhang case Kind::Result: 194ac68637bSLei Zhang return op->getNumResults(); 195ac68637bSLei Zhang } 196*12ff145eSjpienaar llvm_unreachable("unknown kind"); 197ac68637bSLei Zhang } 198ac68637bSLei Zhang 199ac68637bSLei Zhang std::string 200ac68637bSLei Zhang tblgen::SymbolInfoMap::SymbolInfo::getVarDecl(StringRef name) const { 201ac68637bSLei Zhang switch (kind) { 202ac68637bSLei Zhang case Kind::Attr: { 203ac68637bSLei Zhang auto type = 204ac68637bSLei Zhang op->getArg(*argIndex).get<NamedAttribute *>()->attr.getStorageType(); 205ac68637bSLei Zhang return formatv("{0} {1};\n", type, name); 206ac68637bSLei Zhang } 207ac68637bSLei Zhang case Kind::Operand: 208ac68637bSLei Zhang case Kind::Value: { 209ac68637bSLei Zhang return formatv("Value *{0};\n", name); 210ac68637bSLei Zhang } 211ac68637bSLei Zhang case Kind::Result: { 212ac68637bSLei Zhang // Use the op itself for the results. 213ac68637bSLei Zhang return formatv("{0} {1};\n", op->getQualCppClassName(), name); 214ac68637bSLei Zhang } 215ac68637bSLei Zhang } 216*12ff145eSjpienaar llvm_unreachable("unknown kind"); 217ac68637bSLei Zhang } 218ac68637bSLei Zhang 219ac68637bSLei Zhang std::string 220ac68637bSLei Zhang tblgen::SymbolInfoMap::SymbolInfo::getValueAndRangeUse(StringRef name, 221ac68637bSLei Zhang int index) const { 222ac68637bSLei Zhang switch (kind) { 223ac68637bSLei Zhang case Kind::Attr: 224ac68637bSLei Zhang case Kind::Operand: { 225ac68637bSLei Zhang assert(index < 0 && "only allowed for symbol bound to result"); 226ac68637bSLei Zhang return name; 227ac68637bSLei Zhang } 228ac68637bSLei Zhang case Kind::Result: { 229ac68637bSLei Zhang // TODO(b/133341698): The following is incorrect for variadic results. We 230ac68637bSLei Zhang // should use getODSResults(). 231ac68637bSLei Zhang if (index >= 0) { 232ac68637bSLei Zhang return formatv("{0}.getOperation()->getResult({1})", name, index); 233ac68637bSLei Zhang } 234ac68637bSLei Zhang 235ac68637bSLei Zhang // If referencing multiple results, compose a comma-separated list. 236ac68637bSLei Zhang SmallVector<std::string, 4> values; 237ac68637bSLei Zhang for (int i = 0, e = op->getNumResults(); i < e; ++i) { 238ac68637bSLei Zhang values.push_back(formatv("{0}.getOperation()->getResult({1})", name, i)); 239ac68637bSLei Zhang } 240ac68637bSLei Zhang return llvm::join(values, ", "); 241ac68637bSLei Zhang } 242ac68637bSLei Zhang case Kind::Value: { 243ac68637bSLei Zhang assert(index < 0 && "only allowed for symbol bound to result"); 244ac68637bSLei Zhang assert(op == nullptr); 245ac68637bSLei Zhang return name; 246ac68637bSLei Zhang } 247ac68637bSLei Zhang } 248*12ff145eSjpienaar llvm_unreachable("unknown kind"); 249ac68637bSLei Zhang } 250ac68637bSLei Zhang 251ac68637bSLei Zhang bool tblgen::SymbolInfoMap::bindOpArgument(StringRef symbol, const Operator &op, 252ac68637bSLei Zhang int argIndex) { 253ac68637bSLei Zhang StringRef name = getValuePackName(symbol); 254ac68637bSLei Zhang if (name != symbol) { 255ac68637bSLei Zhang auto error = formatv( 256ac68637bSLei Zhang "symbol '{0}' with trailing index cannot bind to op argument", symbol); 257ac68637bSLei Zhang PrintFatalError(loc, error); 258ac68637bSLei Zhang } 259ac68637bSLei Zhang 260ac68637bSLei Zhang auto symInfo = op.getArg(argIndex).is<NamedAttribute *>() 261ac68637bSLei Zhang ? SymbolInfo::getAttr(&op, argIndex) 262ac68637bSLei Zhang : SymbolInfo::getOperand(&op, argIndex); 263ac68637bSLei Zhang 264ac68637bSLei Zhang return symbolInfoMap.insert({symbol, symInfo}).second; 265ac68637bSLei Zhang } 266ac68637bSLei Zhang 267ac68637bSLei Zhang bool tblgen::SymbolInfoMap::bindOpResult(StringRef symbol, const Operator &op) { 268ac68637bSLei Zhang StringRef name = getValuePackName(symbol); 269ac68637bSLei Zhang return symbolInfoMap.insert({name, SymbolInfo::getResult(&op)}).second; 270ac68637bSLei Zhang } 271ac68637bSLei Zhang 272ac68637bSLei Zhang bool tblgen::SymbolInfoMap::bindValue(StringRef symbol) { 273ac68637bSLei Zhang return symbolInfoMap.insert({symbol, SymbolInfo::getValue()}).second; 274ac68637bSLei Zhang } 275ac68637bSLei Zhang 276ac68637bSLei Zhang bool tblgen::SymbolInfoMap::contains(StringRef symbol) const { 277ac68637bSLei Zhang return find(symbol) != symbolInfoMap.end(); 278ac68637bSLei Zhang } 279ac68637bSLei Zhang 280ac68637bSLei Zhang tblgen::SymbolInfoMap::const_iterator 281ac68637bSLei Zhang tblgen::SymbolInfoMap::find(StringRef key) const { 282ac68637bSLei Zhang StringRef name = getValuePackName(key); 283ac68637bSLei Zhang return symbolInfoMap.find(name); 284ac68637bSLei Zhang } 285ac68637bSLei Zhang 286ac68637bSLei Zhang int tblgen::SymbolInfoMap::getStaticValueCount(StringRef symbol) const { 287ac68637bSLei Zhang StringRef name = getValuePackName(symbol); 288ac68637bSLei Zhang if (name != symbol) { 289ac68637bSLei Zhang // If there is a trailing index inside symbol, it references just one 290ac68637bSLei Zhang // static value. 291ac68637bSLei Zhang return 1; 292ac68637bSLei Zhang } 293ac68637bSLei Zhang // Otherwise, find how many it represents by querying the symbol's info. 294ac68637bSLei Zhang return find(name)->getValue().getStaticValueCount(); 295ac68637bSLei Zhang } 296ac68637bSLei Zhang 297ac68637bSLei Zhang std::string tblgen::SymbolInfoMap::getValueAndRangeUse(StringRef symbol) const { 298ac68637bSLei Zhang int index = -1; 299ac68637bSLei Zhang StringRef name = getValuePackName(symbol, &index); 300ac68637bSLei Zhang 301ac68637bSLei Zhang auto it = symbolInfoMap.find(name); 302ac68637bSLei Zhang if (it == symbolInfoMap.end()) { 303ac68637bSLei Zhang auto error = formatv("referencing unbound symbol '{0}'", symbol); 304ac68637bSLei Zhang PrintFatalError(loc, error); 305ac68637bSLei Zhang } 306ac68637bSLei Zhang 307ac68637bSLei Zhang return it->getValue().getValueAndRangeUse(name, index); 308ac68637bSLei Zhang } 309ac68637bSLei Zhang 310ac68637bSLei Zhang //===----------------------------------------------------------------------===// 311ac68637bSLei Zhang // Pattern 312ac68637bSLei Zhang //==----------------------------------------------------------------------===// 313ac68637bSLei Zhang 314ac68637bSLei Zhang tblgen::Pattern::Pattern(const llvm::Record *def, RecordOperatorMap *mapper) 315ac68637bSLei Zhang : def(*def), recordOpMap(mapper) {} 316eb753f4aSLei Zhang 317eb753f4aSLei Zhang tblgen::DagNode tblgen::Pattern::getSourcePattern() const { 3188f5fa566SLei Zhang return tblgen::DagNode(def.getValueAsDag("sourcePattern")); 319eb753f4aSLei Zhang } 320eb753f4aSLei Zhang 321e032d0dcSLei Zhang int tblgen::Pattern::getNumResultPatterns() const { 3228f5fa566SLei Zhang auto *results = def.getValueAsListInit("resultPatterns"); 323eb753f4aSLei Zhang return results->size(); 324eb753f4aSLei Zhang } 325eb753f4aSLei Zhang 326eb753f4aSLei Zhang tblgen::DagNode tblgen::Pattern::getResultPattern(unsigned index) const { 3278f5fa566SLei Zhang auto *results = def.getValueAsListInit("resultPatterns"); 328eb753f4aSLei Zhang return tblgen::DagNode(cast<llvm::DagInit>(results->getElement(index))); 329eb753f4aSLei Zhang } 330eb753f4aSLei Zhang 331ac68637bSLei Zhang void tblgen::Pattern::collectSourcePatternBoundSymbols( 332ac68637bSLei Zhang tblgen::SymbolInfoMap &infoMap) { 333ac68637bSLei Zhang collectBoundSymbols(getSourcePattern(), infoMap, /*isSrcPattern=*/true); 334eb753f4aSLei Zhang } 335eb753f4aSLei Zhang 336ac68637bSLei Zhang void tblgen::Pattern::collectResultPatternBoundSymbols( 337ac68637bSLei Zhang tblgen::SymbolInfoMap &infoMap) { 338ac68637bSLei Zhang for (int i = 0, e = getNumResultPatterns(); i < e; ++i) { 339ac68637bSLei Zhang auto pattern = getResultPattern(i); 340ac68637bSLei Zhang collectBoundSymbols(pattern, infoMap, /*isSrcPattern=*/false); 341eb753f4aSLei Zhang } 342388fb375SJacques Pienaar } 343388fb375SJacques Pienaar 344eb753f4aSLei Zhang const tblgen::Operator &tblgen::Pattern::getSourceRootOp() { 345eb753f4aSLei Zhang return getSourcePattern().getDialectOp(recordOpMap); 346eb753f4aSLei Zhang } 347eb753f4aSLei Zhang 348eb753f4aSLei Zhang tblgen::Operator &tblgen::Pattern::getDialectOp(DagNode node) { 349eb753f4aSLei Zhang return node.getDialectOp(recordOpMap); 350eb753f4aSLei Zhang } 351388fb375SJacques Pienaar 3528f5fa566SLei Zhang std::vector<tblgen::AppliedConstraint> tblgen::Pattern::getConstraints() const { 353388fb375SJacques Pienaar auto *listInit = def.getValueAsListInit("constraints"); 3548f5fa566SLei Zhang std::vector<tblgen::AppliedConstraint> ret; 355388fb375SJacques Pienaar ret.reserve(listInit->size()); 3568f5fa566SLei Zhang 357388fb375SJacques Pienaar for (auto it : *listInit) { 3588f5fa566SLei Zhang auto *dagInit = dyn_cast<llvm::DagInit>(it); 3598f5fa566SLei Zhang if (!dagInit) 3608f5fa566SLei Zhang PrintFatalError(def.getLoc(), "all elemements in Pattern multi-entity " 3618f5fa566SLei Zhang "constraints should be DAG nodes"); 3628f5fa566SLei Zhang 3638f5fa566SLei Zhang std::vector<std::string> entities; 3648f5fa566SLei Zhang entities.reserve(dagInit->arg_size()); 3658f5fa566SLei Zhang for (auto *argName : dagInit->getArgNames()) 3668f5fa566SLei Zhang entities.push_back(argName->getValue()); 3678f5fa566SLei Zhang 3688f5fa566SLei Zhang ret.emplace_back(cast<llvm::DefInit>(dagInit->getOperator())->getDef(), 369c72d849eSLei Zhang dagInit->getNameStr(), std::move(entities)); 370388fb375SJacques Pienaar } 371388fb375SJacques Pienaar return ret; 372388fb375SJacques Pienaar } 37353035874SFeng Liu 37453035874SFeng Liu int tblgen::Pattern::getBenefit() const { 375a0606ca7SFeng Liu // The initial benefit value is a heuristic with number of ops in the source 37653035874SFeng Liu // pattern. 377a0606ca7SFeng Liu int initBenefit = getSourcePattern().getNumOps(); 37853035874SFeng Liu llvm::DagInit *delta = def.getValueAsDag("benefitDelta"); 379a0606ca7SFeng Liu if (delta->getNumArgs() != 1 || !isa<llvm::IntInit>(delta->getArg(0))) { 380a0606ca7SFeng Liu PrintFatalError(def.getLoc(), 381a0606ca7SFeng Liu "The 'addBenefit' takes and only takes one integer value"); 382a0606ca7SFeng Liu } 383a0606ca7SFeng Liu return initBenefit + dyn_cast<llvm::IntInit>(delta->getArg(0))->getValue(); 38453035874SFeng Liu } 38504b6d2f3SLei Zhang 3864165885aSJacques Pienaar std::vector<tblgen::Pattern::IdentifierLine> 3874165885aSJacques Pienaar tblgen::Pattern::getLocation() const { 3884165885aSJacques Pienaar std::vector<std::pair<StringRef, unsigned>> result; 3894165885aSJacques Pienaar result.reserve(def.getLoc().size()); 3904165885aSJacques Pienaar for (auto loc : def.getLoc()) { 3914165885aSJacques Pienaar unsigned buf = llvm::SrcMgr.FindBufferContainingLoc(loc); 3924165885aSJacques Pienaar assert(buf && "invalid source location"); 3934165885aSJacques Pienaar result.emplace_back( 3944165885aSJacques Pienaar llvm::SrcMgr.getBufferInfo(buf).Buffer->getBufferIdentifier(), 3954165885aSJacques Pienaar llvm::SrcMgr.getLineAndColumn(loc, buf).first); 3964165885aSJacques Pienaar } 3974165885aSJacques Pienaar return result; 3984165885aSJacques Pienaar } 3994165885aSJacques Pienaar 400ac68637bSLei Zhang void tblgen::Pattern::collectBoundSymbols(DagNode tree, SymbolInfoMap &infoMap, 401e032d0dcSLei Zhang bool isSrcPattern) { 402e032d0dcSLei Zhang auto treeName = tree.getSymbol(); 403e032d0dcSLei Zhang if (!tree.isOperation()) { 404e032d0dcSLei Zhang if (!treeName.empty()) { 405e032d0dcSLei Zhang PrintFatalError( 406e032d0dcSLei Zhang def.getLoc(), 407e032d0dcSLei Zhang formatv("binding symbol '{0}' to non-operation unsupported right now", 408e032d0dcSLei Zhang treeName)); 409e032d0dcSLei Zhang } 410e032d0dcSLei Zhang return; 411e032d0dcSLei Zhang } 412e032d0dcSLei Zhang 41304b6d2f3SLei Zhang auto &op = getDialectOp(tree); 41404b6d2f3SLei Zhang auto numOpArgs = op.getNumArgs(); 41504b6d2f3SLei Zhang auto numTreeArgs = tree.getNumArgs(); 41604b6d2f3SLei Zhang 41704b6d2f3SLei Zhang if (numOpArgs != numTreeArgs) { 418ac68637bSLei Zhang auto err = formatv("op '{0}' argument number mismatch: " 41904b6d2f3SLei Zhang "{1} in pattern vs. {2} in definition", 420ac68637bSLei Zhang op.getOperationName(), numTreeArgs, numOpArgs); 421ac68637bSLei Zhang PrintFatalError(def.getLoc(), err); 42204b6d2f3SLei Zhang } 42304b6d2f3SLei Zhang 42404b6d2f3SLei Zhang // The name attached to the DAG node's operator is for representing the 42504b6d2f3SLei Zhang // results generated from this op. It should be remembered as bound results. 426ac68637bSLei Zhang if (!treeName.empty()) { 427ac68637bSLei Zhang if (!infoMap.bindOpResult(treeName, op)) 428ac68637bSLei Zhang PrintFatalError(def.getLoc(), 429ac68637bSLei Zhang formatv("symbol '{0}' bound more than once", treeName)); 430ac68637bSLei Zhang } 43104b6d2f3SLei Zhang 4322fe8ae4fSJacques Pienaar for (int i = 0; i != numTreeArgs; ++i) { 43304b6d2f3SLei Zhang if (auto treeArg = tree.getArgAsNestedDag(i)) { 43404b6d2f3SLei Zhang // This DAG node argument is a DAG node itself. Go inside recursively. 435ac68637bSLei Zhang collectBoundSymbols(treeArg, infoMap, isSrcPattern); 436e032d0dcSLei Zhang } else if (isSrcPattern) { 437e032d0dcSLei Zhang // We can only bind symbols to op arguments in source pattern. Those 438e032d0dcSLei Zhang // symbols are referenced in result patterns. 43904b6d2f3SLei Zhang auto treeArgName = tree.getArgName(i); 440ac68637bSLei Zhang if (!treeArgName.empty()) { 441ac68637bSLei Zhang if (!infoMap.bindOpArgument(treeArgName, op, i)) { 442ac68637bSLei Zhang auto err = formatv("symbol '{0}' bound more than once", treeArgName); 443ac68637bSLei Zhang PrintFatalError(def.getLoc(), err); 444ac68637bSLei Zhang } 445ac68637bSLei Zhang } 44604b6d2f3SLei Zhang } 44704b6d2f3SLei Zhang } 44804b6d2f3SLei Zhang } 449