133 lines · cpp
1//===- PDLPatternMatch.cpp - Base classes for PDL pattern match2//------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#include "mlir/IR/PatternMatch.h"11#include "llvm/Support/InterleavedRange.h"12 13using namespace mlir;14 15//===----------------------------------------------------------------------===//16// PDLValue17//===----------------------------------------------------------------------===//18 19void PDLValue::print(raw_ostream &os) const {20 if (!value) {21 os << "<NULL-PDLValue>";22 return;23 }24 switch (kind) {25 case Kind::Attribute:26 os << cast<Attribute>();27 break;28 case Kind::Operation:29 os << *cast<Operation *>();30 break;31 case Kind::Type:32 os << cast<Type>();33 break;34 case Kind::TypeRange:35 os << llvm::interleaved(cast<TypeRange>());36 break;37 case Kind::Value:38 os << cast<Value>();39 break;40 case Kind::ValueRange:41 os << llvm::interleaved(cast<ValueRange>());42 break;43 }44}45 46void PDLValue::print(raw_ostream &os, Kind kind) {47 switch (kind) {48 case Kind::Attribute:49 os << "Attribute";50 break;51 case Kind::Operation:52 os << "Operation";53 break;54 case Kind::Type:55 os << "Type";56 break;57 case Kind::TypeRange:58 os << "TypeRange";59 break;60 case Kind::Value:61 os << "Value";62 break;63 case Kind::ValueRange:64 os << "ValueRange";65 break;66 }67}68 69//===----------------------------------------------------------------------===//70// PDLPatternModule71//===----------------------------------------------------------------------===//72 73void PDLPatternModule::mergeIn(PDLPatternModule &&other) {74 // Ignore the other module if it has no patterns.75 if (!other.pdlModule)76 return;77 78 // Steal the functions and config of the other module.79 for (auto &it : other.constraintFunctions)80 registerConstraintFunction(it.first(), std::move(it.second));81 for (auto &it : other.rewriteFunctions)82 registerRewriteFunction(it.first(), std::move(it.second));83 for (auto &it : other.configs)84 configs.emplace_back(std::move(it));85 for (auto &it : other.configMap)86 configMap.insert(it);87 88 // Steal the other state if we have no patterns.89 if (!pdlModule) {90 pdlModule = std::move(other.pdlModule);91 return;92 }93 94 // Merge the pattern operations from the other module into this one.95 Block *block = pdlModule->getBody();96 block->getOperations().splice(block->end(),97 other.pdlModule->getBody()->getOperations());98}99 100void PDLPatternModule::attachConfigToPatterns(ModuleOp module,101 PDLPatternConfigSet &configSet) {102 // Attach the configuration to the symbols within the module. We only add103 // to symbols to avoid hardcoding any specific operation names here (given104 // that we don't depend on any PDL dialect). We can't use105 // cast<SymbolOpInterface> here because patterns may be optional symbols.106 module->walk([&](Operation *op) {107 if (op->hasTrait<SymbolOpInterface::Trait>())108 configMap[op] = &configSet;109 });110}111 112//===----------------------------------------------------------------------===//113// Function Registry114//===----------------------------------------------------------------------===//115 116void PDLPatternModule::registerConstraintFunction(117 StringRef name, PDLConstraintFunction constraintFn) {118 // TODO: Is it possible to diagnose when `name` is already registered to119 // a function that is not equivalent to `constraintFn`?120 // Allow existing mappings in the case multiple patterns depend on the same121 // constraint.122 constraintFunctions.try_emplace(name, std::move(constraintFn));123}124 125void PDLPatternModule::registerRewriteFunction(StringRef name,126 PDLRewriteFunction rewriteFn) {127 // TODO: Is it possible to diagnose when `name` is already registered to128 // a function that is not equivalent to `rewriteFn`?129 // Allow existing mappings in the case multiple patterns depend on the same130 // rewrite.131 rewriteFunctions.try_emplace(name, std::move(rewriteFn));132}133