1//===- DialectLLVM.cpp - Pybind module for LLVM dialect API support -------===//
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-c/Dialect/LLVM.h"
10#include "mlir-c/IR.h"
11#include "mlir-c/Support.h"
12#include "mlir/Bindings/Python/PybindAdaptors.h"
13#include <string>
14
15namespace py = pybind11;
16using namespace llvm;
17using namespace mlir;
18using namespace mlir::python;
19using namespace mlir::python::adaptors;
20
21void populateDialectLLVMSubmodule(const pybind11::module &m) {
22
23 //===--------------------------------------------------------------------===//
24 // StructType
25 //===--------------------------------------------------------------------===//
26
27 auto llvmStructType =
28 mlir_type_subclass(m, "StructType", mlirTypeIsALLVMStructType);
29
30 llvmStructType.def_classmethod(
31 "get_literal",
32 [](py::object cls, const std::vector<MlirType> &elements, bool packed,
33 MlirLocation loc) {
34 CollectDiagnosticsToStringScope scope(mlirLocationGetContext(loc));
35
36 MlirType type = mlirLLVMStructTypeLiteralGetChecked(
37 loc, elements.size(), elements.data(), packed);
38 if (mlirTypeIsNull(type)) {
39 throw py::value_error(scope.takeMessage());
40 }
41 return cls(type);
42 },
43 "cls"_a, "elements"_a, py::kw_only(), "packed"_a = false,
44 "loc"_a = py::none());
45
46 llvmStructType.def_classmethod(
47 "get_identified",
48 [](py::object cls, const std::string &name, MlirContext context) {
49 return cls(mlirLLVMStructTypeIdentifiedGet(
50 context, mlirStringRefCreate(name.data(), name.size())));
51 },
52 "cls"_a, "name"_a, py::kw_only(), "context"_a = py::none());
53
54 llvmStructType.def_classmethod(
55 "get_opaque",
56 [](py::object cls, const std::string &name, MlirContext context) {
57 return cls(mlirLLVMStructTypeOpaqueGet(
58 context, mlirStringRefCreate(name.data(), name.size())));
59 },
60 "cls"_a, "name"_a, "context"_a = py::none());
61
62 llvmStructType.def(
63 "set_body",
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.");
70 }
71 },
72 "elements"_a, py::kw_only(), "packed"_a = false);
73
74 llvmStructType.def_classmethod(
75 "new_identified",
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));
81 },
82 "cls"_a, "name"_a, "elements"_a, py::kw_only(), "packed"_a = false,
83 "context"_a = py::none());
84
85 llvmStructType.def_property_readonly(
86 "name", [](MlirType type) -> std::optional<std::string> {
87 if (mlirLLVMStructTypeIsLiteral(type))
88 return std::nullopt;
89
90 MlirStringRef stringRef = mlirLLVMStructTypeGetIdentifier(type);
91 return StringRef(stringRef.data, stringRef.length).str();
92 });
93
94 llvmStructType.def_property_readonly("body", [](MlirType type) -> py::object {
95 // Don't crash in absence of a body.
96 if (mlirLLVMStructTypeIsOpaque(type))
97 return py::none();
98
99 py::list body;
100 for (intptr_t i = 0, e = mlirLLVMStructTypeGetNumElementTypes(type); i < e;
101 ++i) {
102 body.append(mlirLLVMStructTypeGetElementType(type, i));
103 }
104 return body;
105 });
106
107 llvmStructType.def_property_readonly(
108 "packed", [](MlirType type) { return mlirLLVMStructTypeIsPacked(type); });
109
110 llvmStructType.def_property_readonly(
111 "opaque", [](MlirType type) { return mlirLLVMStructTypeIsOpaque(type); });
112
113 //===--------------------------------------------------------------------===//
114 // PointerType
115 //===--------------------------------------------------------------------===//
116
117 mlir_type_subclass(m, "PointerType", mlirTypeIsALLVMPointerType)
118 .def_classmethod(
119 "get",
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());
127 }
128 return cls(type);
129 },
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);
134 });
135}
136
137PYBIND11_MODULE(_mlirDialectsLLVM, m) {
138 m.doc() = "MLIR LLVM Dialect";
139
140 populateDialectLLVMSubmodule(m);
141}
142

source code of mlir/lib/Bindings/Python/DialectLLVM.cpp