1 //===- DialectLLVM.cpp - Pybind module for LLVM dialect API support -------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "mlir-c/Dialect/LLVM.h"
10 #include "mlir-c/IR.h"
11 #include "mlir-c/Support.h"
12 #include "mlir/Bindings/Python/PybindAdaptors.h"
15 namespace py
= pybind11
;
18 using namespace mlir::python
;
19 using namespace mlir::python::adaptors
;
21 void populateDialectLLVMSubmodule(const pybind11::module
&m
) {
23 //===--------------------------------------------------------------------===//
25 //===--------------------------------------------------------------------===//
28 mlir_type_subclass(m
, "StructType", mlirTypeIsALLVMStructType
);
30 llvmStructType
.def_classmethod(
32 [](py::object cls
, const std::vector
<MlirType
> &elements
, bool packed
,
34 CollectDiagnosticsToStringScope
scope(mlirLocationGetContext(loc
));
36 MlirType type
= mlirLLVMStructTypeLiteralGetChecked(
37 loc
, elements
.size(), elements
.data(), packed
);
38 if (mlirTypeIsNull(type
)) {
39 throw py::value_error(scope
.takeMessage());
43 "cls"_a
, "elements"_a
, py::kw_only(), "packed"_a
= false,
44 "loc"_a
= py::none());
46 llvmStructType
.def_classmethod(
48 [](py::object cls
, const std::string
&name
, MlirContext context
) {
49 return cls(mlirLLVMStructTypeIdentifiedGet(
50 context
, mlirStringRefCreate(name
.data(), name
.size())));
52 "cls"_a
, "name"_a
, py::kw_only(), "context"_a
= py::none());
54 llvmStructType
.def_classmethod(
56 [](py::object cls
, const std::string
&name
, MlirContext context
) {
57 return cls(mlirLLVMStructTypeOpaqueGet(
58 context
, mlirStringRefCreate(name
.data(), name
.size())));
60 "cls"_a
, "name"_a
, "context"_a
= py::none());
64 [](MlirType self
, const std::vector
<MlirType
> &elements
, bool packed
) {
65 MlirLogicalResult result
= mlirLLVMStructTypeSetBody(
66 self
, elements
.size(), elements
.data(), packed
);
67 if (!mlirLogicalResultIsSuccess(result
)) {
68 throw py::value_error(
69 "Struct body already set to different content.");
72 "elements"_a
, py::kw_only(), "packed"_a
= false);
74 llvmStructType
.def_classmethod(
76 [](py::object cls
, const std::string
&name
,
77 const std::vector
<MlirType
> &elements
, bool packed
, MlirContext ctx
) {
78 return cls(mlirLLVMStructTypeIdentifiedNewGet(
79 ctx
, mlirStringRefCreate(name
.data(), name
.length()),
80 elements
.size(), elements
.data(), packed
));
82 "cls"_a
, "name"_a
, "elements"_a
, py::kw_only(), "packed"_a
= false,
83 "context"_a
= py::none());
85 llvmStructType
.def_property_readonly(
86 "name", [](MlirType type
) -> std::optional
<std::string
> {
87 if (mlirLLVMStructTypeIsLiteral(type
))
90 MlirStringRef stringRef
= mlirLLVMStructTypeGetIdentifier(type
);
91 return StringRef(stringRef
.data
, stringRef
.length
).str();
94 llvmStructType
.def_property_readonly("body", [](MlirType type
) -> py::object
{
95 // Don't crash in absence of a body.
96 if (mlirLLVMStructTypeIsOpaque(type
))
100 for (intptr_t i
= 0, e
= mlirLLVMStructTypeGetNumElementTypes(type
); i
< e
;
102 body
.append(mlirLLVMStructTypeGetElementType(type
, i
));
107 llvmStructType
.def_property_readonly(
108 "packed", [](MlirType type
) { return mlirLLVMStructTypeIsPacked(type
); });
110 llvmStructType
.def_property_readonly(
111 "opaque", [](MlirType type
) { return mlirLLVMStructTypeIsOpaque(type
); });
113 //===--------------------------------------------------------------------===//
115 //===--------------------------------------------------------------------===//
117 mlir_type_subclass(m
, "PointerType", mlirTypeIsALLVMPointerType
)
120 [](py::object cls
, std::optional
<unsigned> addressSpace
,
121 MlirContext context
) {
122 CollectDiagnosticsToStringScope
scope(context
);
123 MlirType type
= mlirLLVMPointerTypeGet(
124 context
, addressSpace
.has_value() ? *addressSpace
: 0);
125 if (mlirTypeIsNull(type
)) {
126 throw py::value_error(scope
.takeMessage());
130 "cls"_a
, "address_space"_a
= py::none(), py::kw_only(),
131 "context"_a
= py::none())
132 .def_property_readonly("address_space", [](MlirType type
) {
133 return mlirLLVMPointerTypeGetAddressSpace(type
);
137 PYBIND11_MODULE(_mlirDialectsLLVM
, m
) {
138 m
.doc() = "MLIR LLVM Dialect";
140 populateDialectLLVMSubmodule(m
);