1 | //===- Types.cpp ----------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "mlir/Tools/PDLL/AST/Types.h" |
10 | #include "TypeDetail.h" |
11 | #include "mlir/Tools/PDLL/AST/Context.h" |
12 | #include <optional> |
13 | |
14 | using namespace mlir; |
15 | using namespace mlir::pdll; |
16 | using namespace mlir::pdll::ast; |
17 | |
18 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::AttributeTypeStorage) |
19 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::ConstraintTypeStorage) |
20 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::OperationTypeStorage) |
21 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::RangeTypeStorage) |
22 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::RewriteTypeStorage) |
23 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::TupleTypeStorage) |
24 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::TypeTypeStorage) |
25 | MLIR_DEFINE_EXPLICIT_TYPE_ID(mlir::pdll::ast::detail::ValueTypeStorage) |
26 | |
27 | //===----------------------------------------------------------------------===// |
28 | // Type |
29 | //===----------------------------------------------------------------------===// |
30 | |
31 | TypeID Type::getTypeID() const { return impl->typeID; } |
32 | |
33 | Type Type::refineWith(Type other) const { |
34 | if (*this == other) |
35 | return *this; |
36 | |
37 | // Operation types are compatible if the operation names don't conflict. |
38 | if (auto opTy = dyn_cast<OperationType>()) { |
39 | auto otherOpTy = other.dyn_cast<ast::OperationType>(); |
40 | if (!otherOpTy) |
41 | return nullptr; |
42 | if (!otherOpTy.getName()) |
43 | return *this; |
44 | if (!opTy.getName()) |
45 | return other; |
46 | |
47 | return nullptr; |
48 | } |
49 | |
50 | return nullptr; |
51 | } |
52 | |
53 | //===----------------------------------------------------------------------===// |
54 | // AttributeType |
55 | //===----------------------------------------------------------------------===// |
56 | |
57 | AttributeType AttributeType::get(Context &context) { |
58 | return context.getTypeUniquer().get<ImplTy>(); |
59 | } |
60 | |
61 | //===----------------------------------------------------------------------===// |
62 | // ConstraintType |
63 | //===----------------------------------------------------------------------===// |
64 | |
65 | ConstraintType ConstraintType::get(Context &context) { |
66 | return context.getTypeUniquer().get<ImplTy>(); |
67 | } |
68 | |
69 | //===----------------------------------------------------------------------===// |
70 | // OperationType |
71 | //===----------------------------------------------------------------------===// |
72 | |
73 | OperationType OperationType::get(Context &context, |
74 | std::optional<StringRef> name, |
75 | const ods::Operation *odsOp) { |
76 | return context.getTypeUniquer().get<ImplTy>( |
77 | /*initFn=*/function_ref<void(ImplTy *)>(), |
78 | args: std::make_pair(x: name.value_or(u: "" ), y&: odsOp)); |
79 | } |
80 | |
81 | std::optional<StringRef> OperationType::getName() const { |
82 | StringRef name = getImplAs<ImplTy>()->getValue().first; |
83 | return name.empty() ? std::optional<StringRef>() |
84 | : std::optional<StringRef>(name); |
85 | } |
86 | |
87 | const ods::Operation *OperationType::getODSOperation() const { |
88 | return getImplAs<ImplTy>()->getValue().second; |
89 | } |
90 | |
91 | //===----------------------------------------------------------------------===// |
92 | // RangeType |
93 | //===----------------------------------------------------------------------===// |
94 | |
95 | RangeType RangeType::get(Context &context, Type elementType) { |
96 | return context.getTypeUniquer().get<ImplTy>( |
97 | /*initFn=*/function_ref<void(ImplTy *)>(), args&: elementType); |
98 | } |
99 | |
100 | Type RangeType::getElementType() const { |
101 | return getImplAs<ImplTy>()->getValue(); |
102 | } |
103 | |
104 | //===----------------------------------------------------------------------===// |
105 | // TypeRangeType |
106 | |
107 | bool TypeRangeType::classof(Type type) { |
108 | RangeType range = type.dyn_cast<RangeType>(); |
109 | return range && range.getElementType().isa<TypeType>(); |
110 | } |
111 | |
112 | TypeRangeType TypeRangeType::get(Context &context) { |
113 | return RangeType::get(context, elementType: TypeType::get(context)).cast<TypeRangeType>(); |
114 | } |
115 | |
116 | //===----------------------------------------------------------------------===// |
117 | // ValueRangeType |
118 | |
119 | bool ValueRangeType::classof(Type type) { |
120 | RangeType range = type.dyn_cast<RangeType>(); |
121 | return range && range.getElementType().isa<ValueType>(); |
122 | } |
123 | |
124 | ValueRangeType ValueRangeType::get(Context &context) { |
125 | return RangeType::get(context, elementType: ValueType::get(context)) |
126 | .cast<ValueRangeType>(); |
127 | } |
128 | |
129 | //===----------------------------------------------------------------------===// |
130 | // RewriteType |
131 | //===----------------------------------------------------------------------===// |
132 | |
133 | RewriteType RewriteType::get(Context &context) { |
134 | return context.getTypeUniquer().get<ImplTy>(); |
135 | } |
136 | |
137 | //===----------------------------------------------------------------------===// |
138 | // TupleType |
139 | //===----------------------------------------------------------------------===// |
140 | |
141 | TupleType TupleType::get(Context &context, ArrayRef<Type> elementTypes, |
142 | ArrayRef<StringRef> elementNames) { |
143 | assert(elementTypes.size() == elementNames.size()); |
144 | return context.getTypeUniquer().get<ImplTy>( |
145 | /*initFn=*/function_ref<void(ImplTy *)>(), args&: elementTypes, args&: elementNames); |
146 | } |
147 | TupleType TupleType::get(Context &context, ArrayRef<Type> elementTypes) { |
148 | SmallVector<StringRef> elementNames(elementTypes.size()); |
149 | return get(context, elementTypes, elementNames); |
150 | } |
151 | |
152 | ArrayRef<Type> TupleType::getElementTypes() const { |
153 | return getImplAs<ImplTy>()->getValue().first; |
154 | } |
155 | |
156 | ArrayRef<StringRef> TupleType::getElementNames() const { |
157 | return getImplAs<ImplTy>()->getValue().second; |
158 | } |
159 | |
160 | //===----------------------------------------------------------------------===// |
161 | // TypeType |
162 | //===----------------------------------------------------------------------===// |
163 | |
164 | TypeType TypeType::get(Context &context) { |
165 | return context.getTypeUniquer().get<ImplTy>(); |
166 | } |
167 | |
168 | //===----------------------------------------------------------------------===// |
169 | // ValueType |
170 | //===----------------------------------------------------------------------===// |
171 | |
172 | ValueType ValueType::get(Context &context) { |
173 | return context.getTypeUniquer().get<ImplTy>(); |
174 | } |
175 | |