1 //===- IRTypes.cpp - Exports builtin and standard types -------------------===//
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 "IRModule.h"
10
11 #include "PybindUtils.h"
12
13 #include "mlir-c/BuiltinAttributes.h"
14 #include "mlir-c/BuiltinTypes.h"
15
16 namespace py = pybind11;
17 using namespace mlir;
18 using namespace mlir::python;
19
20 using llvm::SmallVector;
21 using llvm::Twine;
22
23 namespace {
24
25 /// Checks whether the given type is an integer or float type.
mlirTypeIsAIntegerOrFloat(MlirType type)26 static int mlirTypeIsAIntegerOrFloat(MlirType type) {
27 return mlirTypeIsAInteger(type) || mlirTypeIsABF16(type) ||
28 mlirTypeIsAF16(type) || mlirTypeIsAF32(type) || mlirTypeIsAF64(type);
29 }
30
31 class PyIntegerType : public PyConcreteType<PyIntegerType> {
32 public:
33 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAInteger;
34 static constexpr const char *pyClassName = "IntegerType";
35 using PyConcreteType::PyConcreteType;
36
bindDerived(ClassTy & c)37 static void bindDerived(ClassTy &c) {
38 c.def_static(
39 "get_signless",
40 [](unsigned width, DefaultingPyMlirContext context) {
41 MlirType t = mlirIntegerTypeGet(context->get(), width);
42 return PyIntegerType(context->getRef(), t);
43 },
44 py::arg("width"), py::arg("context") = py::none(),
45 "Create a signless integer type");
46 c.def_static(
47 "get_signed",
48 [](unsigned width, DefaultingPyMlirContext context) {
49 MlirType t = mlirIntegerTypeSignedGet(context->get(), width);
50 return PyIntegerType(context->getRef(), t);
51 },
52 py::arg("width"), py::arg("context") = py::none(),
53 "Create a signed integer type");
54 c.def_static(
55 "get_unsigned",
56 [](unsigned width, DefaultingPyMlirContext context) {
57 MlirType t = mlirIntegerTypeUnsignedGet(context->get(), width);
58 return PyIntegerType(context->getRef(), t);
59 },
60 py::arg("width"), py::arg("context") = py::none(),
61 "Create an unsigned integer type");
62 c.def_property_readonly(
63 "width",
64 [](PyIntegerType &self) { return mlirIntegerTypeGetWidth(self); },
65 "Returns the width of the integer type");
66 c.def_property_readonly(
67 "is_signless",
68 [](PyIntegerType &self) -> bool {
69 return mlirIntegerTypeIsSignless(self);
70 },
71 "Returns whether this is a signless integer");
72 c.def_property_readonly(
73 "is_signed",
74 [](PyIntegerType &self) -> bool {
75 return mlirIntegerTypeIsSigned(self);
76 },
77 "Returns whether this is a signed integer");
78 c.def_property_readonly(
79 "is_unsigned",
80 [](PyIntegerType &self) -> bool {
81 return mlirIntegerTypeIsUnsigned(self);
82 },
83 "Returns whether this is an unsigned integer");
84 }
85 };
86
87 /// Index Type subclass - IndexType.
88 class PyIndexType : public PyConcreteType<PyIndexType> {
89 public:
90 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAIndex;
91 static constexpr const char *pyClassName = "IndexType";
92 using PyConcreteType::PyConcreteType;
93
bindDerived(ClassTy & c)94 static void bindDerived(ClassTy &c) {
95 c.def_static(
96 "get",
97 [](DefaultingPyMlirContext context) {
98 MlirType t = mlirIndexTypeGet(context->get());
99 return PyIndexType(context->getRef(), t);
100 },
101 py::arg("context") = py::none(), "Create a index type.");
102 }
103 };
104
105 /// Floating Point Type subclass - BF16Type.
106 class PyBF16Type : public PyConcreteType<PyBF16Type> {
107 public:
108 static constexpr IsAFunctionTy isaFunction = mlirTypeIsABF16;
109 static constexpr const char *pyClassName = "BF16Type";
110 using PyConcreteType::PyConcreteType;
111
bindDerived(ClassTy & c)112 static void bindDerived(ClassTy &c) {
113 c.def_static(
114 "get",
115 [](DefaultingPyMlirContext context) {
116 MlirType t = mlirBF16TypeGet(context->get());
117 return PyBF16Type(context->getRef(), t);
118 },
119 py::arg("context") = py::none(), "Create a bf16 type.");
120 }
121 };
122
123 /// Floating Point Type subclass - F16Type.
124 class PyF16Type : public PyConcreteType<PyF16Type> {
125 public:
126 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAF16;
127 static constexpr const char *pyClassName = "F16Type";
128 using PyConcreteType::PyConcreteType;
129
bindDerived(ClassTy & c)130 static void bindDerived(ClassTy &c) {
131 c.def_static(
132 "get",
133 [](DefaultingPyMlirContext context) {
134 MlirType t = mlirF16TypeGet(context->get());
135 return PyF16Type(context->getRef(), t);
136 },
137 py::arg("context") = py::none(), "Create a f16 type.");
138 }
139 };
140
141 /// Floating Point Type subclass - F32Type.
142 class PyF32Type : public PyConcreteType<PyF32Type> {
143 public:
144 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAF32;
145 static constexpr const char *pyClassName = "F32Type";
146 using PyConcreteType::PyConcreteType;
147
bindDerived(ClassTy & c)148 static void bindDerived(ClassTy &c) {
149 c.def_static(
150 "get",
151 [](DefaultingPyMlirContext context) {
152 MlirType t = mlirF32TypeGet(context->get());
153 return PyF32Type(context->getRef(), t);
154 },
155 py::arg("context") = py::none(), "Create a f32 type.");
156 }
157 };
158
159 /// Floating Point Type subclass - F64Type.
160 class PyF64Type : public PyConcreteType<PyF64Type> {
161 public:
162 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAF64;
163 static constexpr const char *pyClassName = "F64Type";
164 using PyConcreteType::PyConcreteType;
165
bindDerived(ClassTy & c)166 static void bindDerived(ClassTy &c) {
167 c.def_static(
168 "get",
169 [](DefaultingPyMlirContext context) {
170 MlirType t = mlirF64TypeGet(context->get());
171 return PyF64Type(context->getRef(), t);
172 },
173 py::arg("context") = py::none(), "Create a f64 type.");
174 }
175 };
176
177 /// None Type subclass - NoneType.
178 class PyNoneType : public PyConcreteType<PyNoneType> {
179 public:
180 static constexpr IsAFunctionTy isaFunction = mlirTypeIsANone;
181 static constexpr const char *pyClassName = "NoneType";
182 using PyConcreteType::PyConcreteType;
183
bindDerived(ClassTy & c)184 static void bindDerived(ClassTy &c) {
185 c.def_static(
186 "get",
187 [](DefaultingPyMlirContext context) {
188 MlirType t = mlirNoneTypeGet(context->get());
189 return PyNoneType(context->getRef(), t);
190 },
191 py::arg("context") = py::none(), "Create a none type.");
192 }
193 };
194
195 /// Complex Type subclass - ComplexType.
196 class PyComplexType : public PyConcreteType<PyComplexType> {
197 public:
198 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAComplex;
199 static constexpr const char *pyClassName = "ComplexType";
200 using PyConcreteType::PyConcreteType;
201
bindDerived(ClassTy & c)202 static void bindDerived(ClassTy &c) {
203 c.def_static(
204 "get",
205 [](PyType &elementType) {
206 // The element must be a floating point or integer scalar type.
207 if (mlirTypeIsAIntegerOrFloat(elementType)) {
208 MlirType t = mlirComplexTypeGet(elementType);
209 return PyComplexType(elementType.getContext(), t);
210 }
211 throw SetPyError(
212 PyExc_ValueError,
213 Twine("invalid '") +
214 py::repr(py::cast(elementType)).cast<std::string>() +
215 "' and expected floating point or integer type.");
216 },
217 "Create a complex type");
218 c.def_property_readonly(
219 "element_type",
220 [](PyComplexType &self) -> PyType {
221 MlirType t = mlirComplexTypeGetElementType(self);
222 return PyType(self.getContext(), t);
223 },
224 "Returns element type.");
225 }
226 };
227
228 class PyShapedType : public PyConcreteType<PyShapedType> {
229 public:
230 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAShaped;
231 static constexpr const char *pyClassName = "ShapedType";
232 using PyConcreteType::PyConcreteType;
233
bindDerived(ClassTy & c)234 static void bindDerived(ClassTy &c) {
235 c.def_property_readonly(
236 "element_type",
237 [](PyShapedType &self) {
238 MlirType t = mlirShapedTypeGetElementType(self);
239 return PyType(self.getContext(), t);
240 },
241 "Returns the element type of the shaped type.");
242 c.def_property_readonly(
243 "has_rank",
244 [](PyShapedType &self) -> bool { return mlirShapedTypeHasRank(self); },
245 "Returns whether the given shaped type is ranked.");
246 c.def_property_readonly(
247 "rank",
248 [](PyShapedType &self) {
249 self.requireHasRank();
250 return mlirShapedTypeGetRank(self);
251 },
252 "Returns the rank of the given ranked shaped type.");
253 c.def_property_readonly(
254 "has_static_shape",
255 [](PyShapedType &self) -> bool {
256 return mlirShapedTypeHasStaticShape(self);
257 },
258 "Returns whether the given shaped type has a static shape.");
259 c.def(
260 "is_dynamic_dim",
261 [](PyShapedType &self, intptr_t dim) -> bool {
262 self.requireHasRank();
263 return mlirShapedTypeIsDynamicDim(self, dim);
264 },
265 "Returns whether the dim-th dimension of the given shaped type is "
266 "dynamic.");
267 c.def(
268 "get_dim_size",
269 [](PyShapedType &self, intptr_t dim) {
270 self.requireHasRank();
271 return mlirShapedTypeGetDimSize(self, dim);
272 },
273 "Returns the dim-th dimension of the given ranked shaped type.");
274 c.def_static(
275 "is_dynamic_size",
276 [](int64_t size) -> bool { return mlirShapedTypeIsDynamicSize(size); },
277 "Returns whether the given dimension size indicates a dynamic "
278 "dimension.");
279 c.def(
280 "is_dynamic_stride_or_offset",
281 [](PyShapedType &self, int64_t val) -> bool {
282 self.requireHasRank();
283 return mlirShapedTypeIsDynamicStrideOrOffset(val);
284 },
285 "Returns whether the given value is used as a placeholder for dynamic "
286 "strides and offsets in shaped types.");
287 }
288
289 private:
requireHasRank()290 void requireHasRank() {
291 if (!mlirShapedTypeHasRank(*this)) {
292 throw SetPyError(
293 PyExc_ValueError,
294 "calling this method requires that the type has a rank.");
295 }
296 }
297 };
298
299 /// Vector Type subclass - VectorType.
300 class PyVectorType : public PyConcreteType<PyVectorType, PyShapedType> {
301 public:
302 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAVector;
303 static constexpr const char *pyClassName = "VectorType";
304 using PyConcreteType::PyConcreteType;
305
bindDerived(ClassTy & c)306 static void bindDerived(ClassTy &c) {
307 c.def_static(
308 "get",
309 [](std::vector<int64_t> shape, PyType &elementType,
310 DefaultingPyLocation loc) {
311 MlirType t = mlirVectorTypeGetChecked(loc, shape.size(), shape.data(),
312 elementType);
313 // TODO: Rework error reporting once diagnostic engine is exposed
314 // in C API.
315 if (mlirTypeIsNull(t)) {
316 throw SetPyError(
317 PyExc_ValueError,
318 Twine("invalid '") +
319 py::repr(py::cast(elementType)).cast<std::string>() +
320 "' and expected floating point or integer type.");
321 }
322 return PyVectorType(elementType.getContext(), t);
323 },
324 py::arg("shape"), py::arg("elementType"), py::arg("loc") = py::none(),
325 "Create a vector type");
326 }
327 };
328
329 /// Ranked Tensor Type subclass - RankedTensorType.
330 class PyRankedTensorType
331 : public PyConcreteType<PyRankedTensorType, PyShapedType> {
332 public:
333 static constexpr IsAFunctionTy isaFunction = mlirTypeIsARankedTensor;
334 static constexpr const char *pyClassName = "RankedTensorType";
335 using PyConcreteType::PyConcreteType;
336
bindDerived(ClassTy & c)337 static void bindDerived(ClassTy &c) {
338 c.def_static(
339 "get",
340 [](std::vector<int64_t> shape, PyType &elementType,
341 llvm::Optional<PyAttribute> &encodingAttr,
342 DefaultingPyLocation loc) {
343 MlirType t = mlirRankedTensorTypeGetChecked(
344 loc, shape.size(), shape.data(), elementType,
345 encodingAttr ? encodingAttr->get() : mlirAttributeGetNull());
346 // TODO: Rework error reporting once diagnostic engine is exposed
347 // in C API.
348 if (mlirTypeIsNull(t)) {
349 throw SetPyError(
350 PyExc_ValueError,
351 Twine("invalid '") +
352 py::repr(py::cast(elementType)).cast<std::string>() +
353 "' and expected floating point, integer, vector or "
354 "complex "
355 "type.");
356 }
357 return PyRankedTensorType(elementType.getContext(), t);
358 },
359 py::arg("shape"), py::arg("element_type"),
360 py::arg("encoding") = py::none(), py::arg("loc") = py::none(),
361 "Create a ranked tensor type");
362 c.def_property_readonly(
363 "encoding",
364 [](PyRankedTensorType &self) -> llvm::Optional<PyAttribute> {
365 MlirAttribute encoding = mlirRankedTensorTypeGetEncoding(self.get());
366 if (mlirAttributeIsNull(encoding))
367 return llvm::None;
368 return PyAttribute(self.getContext(), encoding);
369 });
370 }
371 };
372
373 /// Unranked Tensor Type subclass - UnrankedTensorType.
374 class PyUnrankedTensorType
375 : public PyConcreteType<PyUnrankedTensorType, PyShapedType> {
376 public:
377 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAUnrankedTensor;
378 static constexpr const char *pyClassName = "UnrankedTensorType";
379 using PyConcreteType::PyConcreteType;
380
bindDerived(ClassTy & c)381 static void bindDerived(ClassTy &c) {
382 c.def_static(
383 "get",
384 [](PyType &elementType, DefaultingPyLocation loc) {
385 MlirType t = mlirUnrankedTensorTypeGetChecked(loc, elementType);
386 // TODO: Rework error reporting once diagnostic engine is exposed
387 // in C API.
388 if (mlirTypeIsNull(t)) {
389 throw SetPyError(
390 PyExc_ValueError,
391 Twine("invalid '") +
392 py::repr(py::cast(elementType)).cast<std::string>() +
393 "' and expected floating point, integer, vector or "
394 "complex "
395 "type.");
396 }
397 return PyUnrankedTensorType(elementType.getContext(), t);
398 },
399 py::arg("element_type"), py::arg("loc") = py::none(),
400 "Create a unranked tensor type");
401 }
402 };
403
404 class PyMemRefLayoutMapList;
405
406 /// Ranked MemRef Type subclass - MemRefType.
407 class PyMemRefType : public PyConcreteType<PyMemRefType, PyShapedType> {
408 public:
409 static constexpr IsAFunctionTy isaFunction = mlirTypeIsARankedTensor;
410 static constexpr const char *pyClassName = "MemRefType";
411 using PyConcreteType::PyConcreteType;
412
413 PyMemRefLayoutMapList getLayout();
414
bindDerived(ClassTy & c)415 static void bindDerived(ClassTy &c) {
416 c.def_static(
417 "get",
418 [](std::vector<int64_t> shape, PyType &elementType,
419 std::vector<PyAffineMap> layout, PyAttribute *memorySpace,
420 DefaultingPyLocation loc) {
421 SmallVector<MlirAffineMap> maps;
422 maps.reserve(layout.size());
423 for (PyAffineMap &map : layout)
424 maps.push_back(map);
425
426 MlirAttribute memSpaceAttr = {};
427 if (memorySpace)
428 memSpaceAttr = *memorySpace;
429
430 MlirType t = mlirMemRefTypeGetChecked(loc, elementType, shape.size(),
431 shape.data(), maps.size(),
432 maps.data(), memSpaceAttr);
433 // TODO: Rework error reporting once diagnostic engine is exposed
434 // in C API.
435 if (mlirTypeIsNull(t)) {
436 throw SetPyError(
437 PyExc_ValueError,
438 Twine("invalid '") +
439 py::repr(py::cast(elementType)).cast<std::string>() +
440 "' and expected floating point, integer, vector or "
441 "complex "
442 "type.");
443 }
444 return PyMemRefType(elementType.getContext(), t);
445 },
446 py::arg("shape"), py::arg("element_type"),
447 py::arg("layout") = py::list(), py::arg("memory_space") = py::none(),
448 py::arg("loc") = py::none(), "Create a memref type")
449 .def_property_readonly("layout", &PyMemRefType::getLayout,
450 "The list of layout maps of the MemRef type.")
451 .def_property_readonly(
452 "memory_space",
453 [](PyMemRefType &self) -> PyAttribute {
454 MlirAttribute a = mlirMemRefTypeGetMemorySpace(self);
455 return PyAttribute(self.getContext(), a);
456 },
457 "Returns the memory space of the given MemRef type.");
458 }
459 };
460
461 /// A list of affine layout maps in a memref type. Internally, these are stored
462 /// as consecutive elements, random access is cheap. Both the type and the maps
463 /// are owned by the context, no need to worry about lifetime extension.
464 class PyMemRefLayoutMapList
465 : public Sliceable<PyMemRefLayoutMapList, PyAffineMap> {
466 public:
467 static constexpr const char *pyClassName = "MemRefLayoutMapList";
468
PyMemRefLayoutMapList(PyMemRefType type,intptr_t startIndex=0,intptr_t length=-1,intptr_t step=1)469 PyMemRefLayoutMapList(PyMemRefType type, intptr_t startIndex = 0,
470 intptr_t length = -1, intptr_t step = 1)
471 : Sliceable(startIndex,
472 length == -1 ? mlirMemRefTypeGetNumAffineMaps(type) : length,
473 step),
474 memref(type) {}
475
getNumElements()476 intptr_t getNumElements() { return mlirMemRefTypeGetNumAffineMaps(memref); }
477
getElement(intptr_t index)478 PyAffineMap getElement(intptr_t index) {
479 return PyAffineMap(memref.getContext(),
480 mlirMemRefTypeGetAffineMap(memref, index));
481 }
482
slice(intptr_t startIndex,intptr_t length,intptr_t step)483 PyMemRefLayoutMapList slice(intptr_t startIndex, intptr_t length,
484 intptr_t step) {
485 return PyMemRefLayoutMapList(memref, startIndex, length, step);
486 }
487
488 private:
489 PyMemRefType memref;
490 };
491
getLayout()492 PyMemRefLayoutMapList PyMemRefType::getLayout() {
493 return PyMemRefLayoutMapList(*this);
494 }
495
496 /// Unranked MemRef Type subclass - UnrankedMemRefType.
497 class PyUnrankedMemRefType
498 : public PyConcreteType<PyUnrankedMemRefType, PyShapedType> {
499 public:
500 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAUnrankedMemRef;
501 static constexpr const char *pyClassName = "UnrankedMemRefType";
502 using PyConcreteType::PyConcreteType;
503
bindDerived(ClassTy & c)504 static void bindDerived(ClassTy &c) {
505 c.def_static(
506 "get",
507 [](PyType &elementType, PyAttribute *memorySpace,
508 DefaultingPyLocation loc) {
509 MlirAttribute memSpaceAttr = {};
510 if (memorySpace)
511 memSpaceAttr = *memorySpace;
512
513 MlirType t =
514 mlirUnrankedMemRefTypeGetChecked(loc, elementType, memSpaceAttr);
515 // TODO: Rework error reporting once diagnostic engine is exposed
516 // in C API.
517 if (mlirTypeIsNull(t)) {
518 throw SetPyError(
519 PyExc_ValueError,
520 Twine("invalid '") +
521 py::repr(py::cast(elementType)).cast<std::string>() +
522 "' and expected floating point, integer, vector or "
523 "complex "
524 "type.");
525 }
526 return PyUnrankedMemRefType(elementType.getContext(), t);
527 },
528 py::arg("element_type"), py::arg("memory_space"),
529 py::arg("loc") = py::none(), "Create a unranked memref type")
530 .def_property_readonly(
531 "memory_space",
532 [](PyUnrankedMemRefType &self) -> PyAttribute {
533 MlirAttribute a = mlirMemRefTypeGetMemorySpace(self);
534 return PyAttribute(self.getContext(), a);
535 },
536 "Returns the memory space of the given Unranked MemRef type.");
537 }
538 };
539
540 /// Tuple Type subclass - TupleType.
541 class PyTupleType : public PyConcreteType<PyTupleType> {
542 public:
543 static constexpr IsAFunctionTy isaFunction = mlirTypeIsATuple;
544 static constexpr const char *pyClassName = "TupleType";
545 using PyConcreteType::PyConcreteType;
546
bindDerived(ClassTy & c)547 static void bindDerived(ClassTy &c) {
548 c.def_static(
549 "get_tuple",
550 [](py::list elementList, DefaultingPyMlirContext context) {
551 intptr_t num = py::len(elementList);
552 // Mapping py::list to SmallVector.
553 SmallVector<MlirType, 4> elements;
554 for (auto element : elementList)
555 elements.push_back(element.cast<PyType>());
556 MlirType t = mlirTupleTypeGet(context->get(), num, elements.data());
557 return PyTupleType(context->getRef(), t);
558 },
559 py::arg("elements"), py::arg("context") = py::none(),
560 "Create a tuple type");
561 c.def(
562 "get_type",
563 [](PyTupleType &self, intptr_t pos) -> PyType {
564 MlirType t = mlirTupleTypeGetType(self, pos);
565 return PyType(self.getContext(), t);
566 },
567 "Returns the pos-th type in the tuple type.");
568 c.def_property_readonly(
569 "num_types",
570 [](PyTupleType &self) -> intptr_t {
571 return mlirTupleTypeGetNumTypes(self);
572 },
573 "Returns the number of types contained in a tuple.");
574 }
575 };
576
577 /// Function type.
578 class PyFunctionType : public PyConcreteType<PyFunctionType> {
579 public:
580 static constexpr IsAFunctionTy isaFunction = mlirTypeIsAFunction;
581 static constexpr const char *pyClassName = "FunctionType";
582 using PyConcreteType::PyConcreteType;
583
bindDerived(ClassTy & c)584 static void bindDerived(ClassTy &c) {
585 c.def_static(
586 "get",
587 [](std::vector<PyType> inputs, std::vector<PyType> results,
588 DefaultingPyMlirContext context) {
589 SmallVector<MlirType, 4> inputsRaw(inputs.begin(), inputs.end());
590 SmallVector<MlirType, 4> resultsRaw(results.begin(), results.end());
591 MlirType t = mlirFunctionTypeGet(context->get(), inputsRaw.size(),
592 inputsRaw.data(), resultsRaw.size(),
593 resultsRaw.data());
594 return PyFunctionType(context->getRef(), t);
595 },
596 py::arg("inputs"), py::arg("results"), py::arg("context") = py::none(),
597 "Gets a FunctionType from a list of input and result types");
598 c.def_property_readonly(
599 "inputs",
600 [](PyFunctionType &self) {
601 MlirType t = self;
602 auto contextRef = self.getContext();
603 py::list types;
604 for (intptr_t i = 0, e = mlirFunctionTypeGetNumInputs(self); i < e;
605 ++i) {
606 types.append(PyType(contextRef, mlirFunctionTypeGetInput(t, i)));
607 }
608 return types;
609 },
610 "Returns the list of input types in the FunctionType.");
611 c.def_property_readonly(
612 "results",
613 [](PyFunctionType &self) {
614 auto contextRef = self.getContext();
615 py::list types;
616 for (intptr_t i = 0, e = mlirFunctionTypeGetNumResults(self); i < e;
617 ++i) {
618 types.append(
619 PyType(contextRef, mlirFunctionTypeGetResult(self, i)));
620 }
621 return types;
622 },
623 "Returns the list of result types in the FunctionType.");
624 }
625 };
626
627 } // namespace
628
populateIRTypes(py::module & m)629 void mlir::python::populateIRTypes(py::module &m) {
630 PyIntegerType::bind(m);
631 PyIndexType::bind(m);
632 PyBF16Type::bind(m);
633 PyF16Type::bind(m);
634 PyF32Type::bind(m);
635 PyF64Type::bind(m);
636 PyNoneType::bind(m);
637 PyComplexType::bind(m);
638 PyShapedType::bind(m);
639 PyVectorType::bind(m);
640 PyRankedTensorType::bind(m);
641 PyUnrankedTensorType::bind(m);
642 PyMemRefType::bind(m);
643 PyMemRefLayoutMapList::bind(m);
644 PyUnrankedMemRefType::bind(m);
645 PyTupleType::bind(m);
646 PyFunctionType::bind(m);
647 }
648