1eb753f4aSLei Zhang //===- Pattern.cpp - Pattern wrapper class ----------------------*- C++ -*-===// 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" 25eb753f4aSLei Zhang #include "llvm/TableGen/Record.h" 26eb753f4aSLei Zhang 27eb753f4aSLei Zhang using namespace mlir; 28eb753f4aSLei Zhang 29eb753f4aSLei Zhang using mlir::tblgen::Operator; 30eb753f4aSLei Zhang 31eb753f4aSLei Zhang bool tblgen::DagArg::isAttr() const { 32eb753f4aSLei Zhang return arg.is<tblgen::NamedAttribute *>(); 33eb753f4aSLei Zhang } 34eb753f4aSLei Zhang 35eb753f4aSLei Zhang Operator &tblgen::DagNode::getDialectOp(RecordOperatorMap *mapper) const { 36eb753f4aSLei Zhang llvm::Record *opDef = cast<llvm::DefInit>(node->getOperator())->getDef(); 37eb753f4aSLei Zhang return mapper->try_emplace(opDef, opDef).first->second; 38eb753f4aSLei Zhang } 39eb753f4aSLei Zhang 40eb753f4aSLei Zhang unsigned tblgen::DagNode::getNumOps() const { 41eb753f4aSLei Zhang unsigned count = isReplaceWithValue() ? 0 : 1; 42eb753f4aSLei Zhang for (unsigned i = 0, e = getNumArgs(); i != e; ++i) { 43eb753f4aSLei Zhang if (auto child = getArgAsNestedDag(i)) 44eb753f4aSLei Zhang count += child.getNumOps(); 45eb753f4aSLei Zhang } 46eb753f4aSLei Zhang return count; 47eb753f4aSLei Zhang } 48eb753f4aSLei Zhang 49eb753f4aSLei Zhang unsigned tblgen::DagNode::getNumArgs() const { return node->getNumArgs(); } 50eb753f4aSLei Zhang 51eb753f4aSLei Zhang bool tblgen::DagNode::isNestedDagArg(unsigned index) const { 52eb753f4aSLei Zhang return isa<llvm::DagInit>(node->getArg(index)); 53eb753f4aSLei Zhang } 54eb753f4aSLei Zhang 55eb753f4aSLei Zhang tblgen::DagNode tblgen::DagNode::getArgAsNestedDag(unsigned index) const { 56eb753f4aSLei Zhang return DagNode(dyn_cast_or_null<llvm::DagInit>(node->getArg(index))); 57eb753f4aSLei Zhang } 58eb753f4aSLei Zhang 59eb753f4aSLei Zhang llvm::DefInit *tblgen::DagNode::getArgAsDefInit(unsigned index) const { 60eb753f4aSLei Zhang return dyn_cast<llvm::DefInit>(node->getArg(index)); 61eb753f4aSLei Zhang } 62eb753f4aSLei Zhang 63eb753f4aSLei Zhang StringRef tblgen::DagNode::getArgName(unsigned index) const { 64eb753f4aSLei Zhang return node->getArgNameStr(index); 65eb753f4aSLei Zhang } 66eb753f4aSLei Zhang 67eb753f4aSLei Zhang static void collectBoundArguments(const llvm::DagInit *tree, 68eb753f4aSLei Zhang tblgen::Pattern *pattern) { 69eb753f4aSLei Zhang auto &op = pattern->getDialectOp(tblgen::DagNode(tree)); 70eb753f4aSLei Zhang 71eb753f4aSLei Zhang // TODO(jpienaar): Expand to multiple matches. 72eb753f4aSLei Zhang for (unsigned i = 0, e = tree->getNumArgs(); i != e; ++i) { 73eb753f4aSLei Zhang auto *arg = tree->getArg(i); 74eb753f4aSLei Zhang 75eb753f4aSLei Zhang if (auto *argTree = dyn_cast<llvm::DagInit>(arg)) { 76eb753f4aSLei Zhang collectBoundArguments(argTree, pattern); 77eb753f4aSLei Zhang continue; 78eb753f4aSLei Zhang } 79eb753f4aSLei Zhang 80eb753f4aSLei Zhang StringRef name = tree->getArgNameStr(i); 81eb753f4aSLei Zhang if (name.empty()) 82eb753f4aSLei Zhang continue; 83eb753f4aSLei Zhang 84eb753f4aSLei Zhang pattern->getSourcePatternBoundArgs().try_emplace(name, op.getArg(i), arg); 85eb753f4aSLei Zhang } 86eb753f4aSLei Zhang } 87eb753f4aSLei Zhang 88eb753f4aSLei Zhang void tblgen::DagNode::collectBoundArguments(tblgen::Pattern *pattern) const { 89eb753f4aSLei Zhang ::collectBoundArguments(node, pattern); 90eb753f4aSLei Zhang } 91eb753f4aSLei Zhang 92eb753f4aSLei Zhang bool tblgen::DagNode::isReplaceWithValue() const { 93eb753f4aSLei Zhang auto *dagOpDef = cast<llvm::DefInit>(node->getOperator())->getDef(); 94eb753f4aSLei Zhang return dagOpDef->getName() == "replaceWithValue"; 95eb753f4aSLei Zhang } 96eb753f4aSLei Zhang 97*82dc6a87SJacques Pienaar bool tblgen::DagNode::isNativeCodeBuilder() const { 98*82dc6a87SJacques Pienaar auto *dagOpDef = cast<llvm::DefInit>(node->getOperator())->getDef(); 99*82dc6a87SJacques Pienaar return dagOpDef->isSubClassOf("cOp"); 100*82dc6a87SJacques Pienaar } 101*82dc6a87SJacques Pienaar 102*82dc6a87SJacques Pienaar llvm::StringRef tblgen::DagNode::getNativeCodeBuilder() const { 103*82dc6a87SJacques Pienaar assert(isNativeCodeBuilder()); 104*82dc6a87SJacques Pienaar auto *dagOpDef = cast<llvm::DefInit>(node->getOperator())->getDef(); 105*82dc6a87SJacques Pienaar return dagOpDef->getValueAsString("function"); 106*82dc6a87SJacques Pienaar } 107*82dc6a87SJacques Pienaar 108eb753f4aSLei Zhang tblgen::Pattern::Pattern(const llvm::Record *def, RecordOperatorMap *mapper) 109eb753f4aSLei Zhang : def(*def), recordOpMap(mapper) { 110eb753f4aSLei Zhang getSourcePattern().collectBoundArguments(this); 111eb753f4aSLei Zhang } 112eb753f4aSLei Zhang 113eb753f4aSLei Zhang tblgen::DagNode tblgen::Pattern::getSourcePattern() const { 114eb753f4aSLei Zhang return tblgen::DagNode(def.getValueAsDag("PatternToMatch")); 115eb753f4aSLei Zhang } 116eb753f4aSLei Zhang 117eb753f4aSLei Zhang unsigned tblgen::Pattern::getNumResults() const { 118eb753f4aSLei Zhang auto *results = def.getValueAsListInit("ResultOps"); 119eb753f4aSLei Zhang return results->size(); 120eb753f4aSLei Zhang } 121eb753f4aSLei Zhang 122eb753f4aSLei Zhang tblgen::DagNode tblgen::Pattern::getResultPattern(unsigned index) const { 123eb753f4aSLei Zhang auto *results = def.getValueAsListInit("ResultOps"); 124eb753f4aSLei Zhang return tblgen::DagNode(cast<llvm::DagInit>(results->getElement(index))); 125eb753f4aSLei Zhang } 126eb753f4aSLei Zhang 127eb753f4aSLei Zhang void tblgen::Pattern::ensureArgBoundInSourcePattern( 128eb753f4aSLei Zhang llvm::StringRef name) const { 129eb753f4aSLei Zhang if (boundArguments.find(name) == boundArguments.end()) 130eb753f4aSLei Zhang PrintFatalError(def.getLoc(), 131eb753f4aSLei Zhang Twine("referencing unbound variable '") + name + "'"); 132eb753f4aSLei Zhang } 133eb753f4aSLei Zhang 134eb753f4aSLei Zhang llvm::StringMap<tblgen::DagArg> &tblgen::Pattern::getSourcePatternBoundArgs() { 135eb753f4aSLei Zhang return boundArguments; 136eb753f4aSLei Zhang } 137eb753f4aSLei Zhang 138eb753f4aSLei Zhang const tblgen::Operator &tblgen::Pattern::getSourceRootOp() { 139eb753f4aSLei Zhang return getSourcePattern().getDialectOp(recordOpMap); 140eb753f4aSLei Zhang } 141eb753f4aSLei Zhang 142eb753f4aSLei Zhang tblgen::Operator &tblgen::Pattern::getDialectOp(DagNode node) { 143eb753f4aSLei Zhang return node.getDialectOp(recordOpMap); 144eb753f4aSLei Zhang } 145