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 <string>
10
11#include "mlir-c/Dialect/LLVM.h"
12#include "mlir-c/IR.h"
13#include "mlir-c/Support.h"
14#include "mlir/Bindings/Python/Diagnostics.h"
15#include "mlir/Bindings/Python/NanobindAdaptors.h"
16#include "mlir/Bindings/Python/Nanobind.h"
17
18namespace nb = nanobind;
19
20using namespace nanobind::literals;
21
22using namespace llvm;
23using namespace mlir;
24using namespace mlir::python;
25using namespace mlir::python::nanobind_adaptors;
26
27void populateDialectLLVMSubmodule(const nanobind::module_ &m) {
28
29 //===--------------------------------------------------------------------===//
30 // StructType
31 //===--------------------------------------------------------------------===//
32
33 auto llvmStructType =
34 mlir_type_subclass(m, "StructType", mlirTypeIsALLVMStructType);
35
36 llvmStructType.def_classmethod(
37 "get_literal",
38 [](nb::object cls, const std::vector<MlirType> &elements, bool packed,
39 MlirLocation loc) {
40 CollectDiagnosticsToStringScope scope(mlirLocationGetContext(loc));
41
42 MlirType type = mlirLLVMStructTypeLiteralGetChecked(
43 loc, elements.size(), elements.data(), packed);
44 if (mlirTypeIsNull(type)) {
45 throw nb::value_error(scope.takeMessage().c_str());
46 }
47 return cls(type);
48 },
49 "cls"_a, "elements"_a, nb::kw_only(), "packed"_a = false,
50 "loc"_a.none() = nb::none());
51
52 llvmStructType.def_classmethod(
53 "get_identified",
54 [](nb::object cls, const std::string &name, MlirContext context) {
55 return cls(mlirLLVMStructTypeIdentifiedGet(
56 context, mlirStringRefCreate(name.data(), name.size())));
57 },
58 "cls"_a, "name"_a, nb::kw_only(), "context"_a.none() = nb::none());
59
60 llvmStructType.def_classmethod(
61 "get_opaque",
62 [](nb::object cls, const std::string &name, MlirContext context) {
63 return cls(mlirLLVMStructTypeOpaqueGet(
64 context, mlirStringRefCreate(name.data(), name.size())));
65 },
66 "cls"_a, "name"_a, "context"_a.none() = nb::none());
67
68 llvmStructType.def(
69 "set_body",
70 [](MlirType self, const std::vector<MlirType> &elements, bool packed) {
71 MlirLogicalResult result = mlirLLVMStructTypeSetBody(
72 self, elements.size(), elements.data(), packed);
73 if (!mlirLogicalResultIsSuccess(result)) {
74 throw nb::value_error(
75 "Struct body already set to different content.");
76 }
77 },
78 "elements"_a, nb::kw_only(), "packed"_a = false);
79
80 llvmStructType.def_classmethod(
81 "new_identified",
82 [](nb::object cls, const std::string &name,
83 const std::vector<MlirType> &elements, bool packed, MlirContext ctx) {
84 return cls(mlirLLVMStructTypeIdentifiedNewGet(
85 ctx, mlirStringRefCreate(name.data(), name.length()),
86 elements.size(), elements.data(), packed));
87 },
88 "cls"_a, "name"_a, "elements"_a, nb::kw_only(), "packed"_a = false,
89 "context"_a.none() = nb::none());
90
91 llvmStructType.def_property_readonly(
92 "name", [](MlirType type) -> std::optional<std::string> {
93 if (mlirLLVMStructTypeIsLiteral(type))
94 return std::nullopt;
95
96 MlirStringRef stringRef = mlirLLVMStructTypeGetIdentifier(type);
97 return StringRef(stringRef.data, stringRef.length).str();
98 });
99
100 llvmStructType.def_property_readonly("body", [](MlirType type) -> nb::object {
101 // Don't crash in absence of a body.
102 if (mlirLLVMStructTypeIsOpaque(type))
103 return nb::none();
104
105 nb::list body;
106 for (intptr_t i = 0, e = mlirLLVMStructTypeGetNumElementTypes(type); i < e;
107 ++i) {
108 body.append(mlirLLVMStructTypeGetElementType(type, i));
109 }
110 return body;
111 });
112
113 llvmStructType.def_property_readonly(
114 "packed", [](MlirType type) { return mlirLLVMStructTypeIsPacked(type); });
115
116 llvmStructType.def_property_readonly(
117 "opaque", [](MlirType type) { return mlirLLVMStructTypeIsOpaque(type); });
118
119 //===--------------------------------------------------------------------===//
120 // PointerType
121 //===--------------------------------------------------------------------===//
122
123 mlir_type_subclass(m, "PointerType", mlirTypeIsALLVMPointerType)
124 .def_classmethod(
125 "get",
126 [](nb::object cls, std::optional<unsigned> addressSpace,
127 MlirContext context) {
128 CollectDiagnosticsToStringScope scope(context);
129 MlirType type = mlirLLVMPointerTypeGet(
130 context, addressSpace.has_value() ? *addressSpace : 0);
131 if (mlirTypeIsNull(type)) {
132 throw nb::value_error(scope.takeMessage().c_str());
133 }
134 return cls(type);
135 },
136 "cls"_a, "address_space"_a.none() = nb::none(), nb::kw_only(),
137 "context"_a.none() = nb::none())
138 .def_property_readonly("address_space", [](MlirType type) {
139 return mlirLLVMPointerTypeGetAddressSpace(type);
140 });
141}
142
143NB_MODULE(_mlirDialectsLLVM, m) {
144 m.doc() = "MLIR LLVM Dialect";
145
146 populateDialectLLVMSubmodule(m);
147}
148

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

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