MLIR 24.0.0git
PDLPatternMatch.cpp
Go to the documentation of this file.
1//===- PDLPatternMatch.cpp - Base classes for PDL pattern match
2//------------===//
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-exception
7//
8//===----------------------------------------------------------------------===//
9
11#include "llvm/Support/InterleavedRange.h"
12
13using namespace mlir;
14
15//===----------------------------------------------------------------------===//
16// PDLValue
17//===----------------------------------------------------------------------===//
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// PDLPatternModule
71//===----------------------------------------------------------------------===//
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 configMap.insert_range(other.configMap);
86
87 // Steal the other state if we have no patterns.
88 if (!pdlModule) {
89 pdlModule = std::move(other.pdlModule);
90 return;
91 }
92
93 // Merge the pattern operations from the other module into this one.
94 Block *block = pdlModule->getBody();
95 block->getOperations().splice(block->end(),
96 other.pdlModule->getBody()->getOperations());
97}
98
99void PDLPatternModule::attachConfigToPatterns(ModuleOp module,
100 PDLPatternConfigSet &configSet) {
101 // Attach the configuration to the symbols within the module. We only add
102 // to symbols to avoid hardcoding any specific operation names here (given
103 // that we don't depend on any PDL dialect). We can't use
104 // cast<SymbolOpInterface> here because patterns may be optional symbols.
105 module->walk([&](Operation *op) {
106 if (op->hasTrait<SymbolOpInterface::Trait>())
107 configMap[op] = &configSet;
108 });
109}
110
111//===----------------------------------------------------------------------===//
112// Function Registry
113//===----------------------------------------------------------------------===//
114
115void PDLPatternModule::registerConstraintFunction(
116 StringRef name, PDLConstraintFunction constraintFn) {
117 // TODO: Is it possible to diagnose when `name` is already registered to
118 // a function that is not equivalent to `constraintFn`?
119 // Allow existing mappings in the case multiple patterns depend on the same
120 // constraint.
121 constraintFunctions.try_emplace(name, std::move(constraintFn));
122}
123
124void PDLPatternModule::registerRewriteFunction(StringRef name,
125 PDLRewriteFunction rewriteFn) {
126 // TODO: Is it possible to diagnose when `name` is already registered to
127 // a function that is not equivalent to `rewriteFn`?
128 // Allow existing mappings in the case multiple patterns depend on the same
129 // rewrite.
130 rewriteFunctions.try_emplace(name, std::move(rewriteFn));
131}
OpListType & getOperations()
Definition Block.h:161
iterator end()
Definition Block.h:168
Include the generated interface declarations.