xref: /llvm-project/mlir/lib/Bindings/Python/DialectLLVM.cpp (revision 5cd427477218d8bdb659c6c53a7758f741c3990a)
1bd8fcf75SOleksandr "Alex" Zinenko //===- DialectLLVM.cpp - Pybind module for LLVM dialect API support -------===//
2bd8fcf75SOleksandr "Alex" Zinenko //
3bd8fcf75SOleksandr "Alex" Zinenko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bd8fcf75SOleksandr "Alex" Zinenko // See https://llvm.org/LICENSE.txt for license information.
5bd8fcf75SOleksandr "Alex" Zinenko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bd8fcf75SOleksandr "Alex" Zinenko //
7bd8fcf75SOleksandr "Alex" Zinenko //===----------------------------------------------------------------------===//
8bd8fcf75SOleksandr "Alex" Zinenko 
9392622d0SMaksim Levental #include <string>
10392622d0SMaksim Levental 
11bd8fcf75SOleksandr "Alex" Zinenko #include "mlir-c/Dialect/LLVM.h"
12bd8fcf75SOleksandr "Alex" Zinenko #include "mlir-c/IR.h"
13bd8fcf75SOleksandr "Alex" Zinenko #include "mlir-c/Support.h"
14392622d0SMaksim Levental #include "mlir/Bindings/Python/Diagnostics.h"
15*5cd42747SPeter Hawkins #include "mlir/Bindings/Python/NanobindAdaptors.h"
16*5cd42747SPeter Hawkins #include "mlir/Bindings/Python/Nanobind.h"
17bd8fcf75SOleksandr "Alex" Zinenko 
18*5cd42747SPeter Hawkins namespace nb = nanobind;
19*5cd42747SPeter Hawkins 
20*5cd42747SPeter Hawkins using namespace nanobind::literals;
21*5cd42747SPeter Hawkins 
22bd8fcf75SOleksandr "Alex" Zinenko using namespace llvm;
23bd8fcf75SOleksandr "Alex" Zinenko using namespace mlir;
24bd8fcf75SOleksandr "Alex" Zinenko using namespace mlir::python;
25*5cd42747SPeter Hawkins using namespace mlir::python::nanobind_adaptors;
26bd8fcf75SOleksandr "Alex" Zinenko 
27*5cd42747SPeter Hawkins void populateDialectLLVMSubmodule(const nanobind::module_ &m) {
2879d4d165SMaksim Levental 
2979d4d165SMaksim Levental   //===--------------------------------------------------------------------===//
3079d4d165SMaksim Levental   // StructType
3179d4d165SMaksim Levental   //===--------------------------------------------------------------------===//
3279d4d165SMaksim Levental 
33bd8fcf75SOleksandr "Alex" Zinenko   auto llvmStructType =
34bd8fcf75SOleksandr "Alex" Zinenko       mlir_type_subclass(m, "StructType", mlirTypeIsALLVMStructType);
35bd8fcf75SOleksandr "Alex" Zinenko 
36bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_classmethod(
37bd8fcf75SOleksandr "Alex" Zinenko       "get_literal",
38*5cd42747SPeter Hawkins       [](nb::object cls, const std::vector<MlirType> &elements, bool packed,
39bd8fcf75SOleksandr "Alex" Zinenko          MlirLocation loc) {
40bd8fcf75SOleksandr "Alex" Zinenko         CollectDiagnosticsToStringScope scope(mlirLocationGetContext(loc));
41bd8fcf75SOleksandr "Alex" Zinenko 
42bd8fcf75SOleksandr "Alex" Zinenko         MlirType type = mlirLLVMStructTypeLiteralGetChecked(
43bd8fcf75SOleksandr "Alex" Zinenko             loc, elements.size(), elements.data(), packed);
44bd8fcf75SOleksandr "Alex" Zinenko         if (mlirTypeIsNull(type)) {
45*5cd42747SPeter Hawkins           throw nb::value_error(scope.takeMessage().c_str());
46bd8fcf75SOleksandr "Alex" Zinenko         }
47bd8fcf75SOleksandr "Alex" Zinenko         return cls(type);
48bd8fcf75SOleksandr "Alex" Zinenko       },
49*5cd42747SPeter Hawkins       "cls"_a, "elements"_a, nb::kw_only(), "packed"_a = false,
50*5cd42747SPeter Hawkins       "loc"_a.none() = nb::none());
51bd8fcf75SOleksandr "Alex" Zinenko 
52bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_classmethod(
53bd8fcf75SOleksandr "Alex" Zinenko       "get_identified",
54*5cd42747SPeter Hawkins       [](nb::object cls, const std::string &name, MlirContext context) {
55bd8fcf75SOleksandr "Alex" Zinenko         return cls(mlirLLVMStructTypeIdentifiedGet(
56bd8fcf75SOleksandr "Alex" Zinenko             context, mlirStringRefCreate(name.data(), name.size())));
57bd8fcf75SOleksandr "Alex" Zinenko       },
58*5cd42747SPeter Hawkins       "cls"_a, "name"_a, nb::kw_only(), "context"_a.none() = nb::none());
59bd8fcf75SOleksandr "Alex" Zinenko 
60bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_classmethod(
61bd8fcf75SOleksandr "Alex" Zinenko       "get_opaque",
62*5cd42747SPeter Hawkins       [](nb::object cls, const std::string &name, MlirContext context) {
63bd8fcf75SOleksandr "Alex" Zinenko         return cls(mlirLLVMStructTypeOpaqueGet(
64bd8fcf75SOleksandr "Alex" Zinenko             context, mlirStringRefCreate(name.data(), name.size())));
65bd8fcf75SOleksandr "Alex" Zinenko       },
66*5cd42747SPeter Hawkins       "cls"_a, "name"_a, "context"_a.none() = nb::none());
67bd8fcf75SOleksandr "Alex" Zinenko 
68bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def(
69bd8fcf75SOleksandr "Alex" Zinenko       "set_body",
70bd8fcf75SOleksandr "Alex" Zinenko       [](MlirType self, const std::vector<MlirType> &elements, bool packed) {
71bd8fcf75SOleksandr "Alex" Zinenko         MlirLogicalResult result = mlirLLVMStructTypeSetBody(
72bd8fcf75SOleksandr "Alex" Zinenko             self, elements.size(), elements.data(), packed);
73bd8fcf75SOleksandr "Alex" Zinenko         if (!mlirLogicalResultIsSuccess(result)) {
74*5cd42747SPeter Hawkins           throw nb::value_error(
75bd8fcf75SOleksandr "Alex" Zinenko               "Struct body already set to different content.");
76bd8fcf75SOleksandr "Alex" Zinenko         }
77bd8fcf75SOleksandr "Alex" Zinenko       },
78*5cd42747SPeter Hawkins       "elements"_a, nb::kw_only(), "packed"_a = false);
79bd8fcf75SOleksandr "Alex" Zinenko 
80bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_classmethod(
81bd8fcf75SOleksandr "Alex" Zinenko       "new_identified",
82*5cd42747SPeter Hawkins       [](nb::object cls, const std::string &name,
83bd8fcf75SOleksandr "Alex" Zinenko          const std::vector<MlirType> &elements, bool packed, MlirContext ctx) {
84bd8fcf75SOleksandr "Alex" Zinenko         return cls(mlirLLVMStructTypeIdentifiedNewGet(
85bd8fcf75SOleksandr "Alex" Zinenko             ctx, mlirStringRefCreate(name.data(), name.length()),
86bd8fcf75SOleksandr "Alex" Zinenko             elements.size(), elements.data(), packed));
87bd8fcf75SOleksandr "Alex" Zinenko       },
88*5cd42747SPeter Hawkins       "cls"_a, "name"_a, "elements"_a, nb::kw_only(), "packed"_a = false,
89*5cd42747SPeter Hawkins       "context"_a.none() = nb::none());
90bd8fcf75SOleksandr "Alex" Zinenko 
91bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_property_readonly(
92bd8fcf75SOleksandr "Alex" Zinenko       "name", [](MlirType type) -> std::optional<std::string> {
93bd8fcf75SOleksandr "Alex" Zinenko         if (mlirLLVMStructTypeIsLiteral(type))
94bd8fcf75SOleksandr "Alex" Zinenko           return std::nullopt;
95bd8fcf75SOleksandr "Alex" Zinenko 
96bd8fcf75SOleksandr "Alex" Zinenko         MlirStringRef stringRef = mlirLLVMStructTypeGetIdentifier(type);
97bd8fcf75SOleksandr "Alex" Zinenko         return StringRef(stringRef.data, stringRef.length).str();
98bd8fcf75SOleksandr "Alex" Zinenko       });
99bd8fcf75SOleksandr "Alex" Zinenko 
100*5cd42747SPeter Hawkins   llvmStructType.def_property_readonly("body", [](MlirType type) -> nb::object {
101bd8fcf75SOleksandr "Alex" Zinenko     // Don't crash in absence of a body.
102bd8fcf75SOleksandr "Alex" Zinenko     if (mlirLLVMStructTypeIsOpaque(type))
103*5cd42747SPeter Hawkins       return nb::none();
104bd8fcf75SOleksandr "Alex" Zinenko 
105*5cd42747SPeter Hawkins     nb::list body;
106bd8fcf75SOleksandr "Alex" Zinenko     for (intptr_t i = 0, e = mlirLLVMStructTypeGetNumElementTypes(type); i < e;
107bd8fcf75SOleksandr "Alex" Zinenko          ++i) {
108bd8fcf75SOleksandr "Alex" Zinenko       body.append(mlirLLVMStructTypeGetElementType(type, i));
109bd8fcf75SOleksandr "Alex" Zinenko     }
110bd8fcf75SOleksandr "Alex" Zinenko     return body;
111bd8fcf75SOleksandr "Alex" Zinenko   });
112bd8fcf75SOleksandr "Alex" Zinenko 
113bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_property_readonly(
114bd8fcf75SOleksandr "Alex" Zinenko       "packed", [](MlirType type) { return mlirLLVMStructTypeIsPacked(type); });
115bd8fcf75SOleksandr "Alex" Zinenko 
116bd8fcf75SOleksandr "Alex" Zinenko   llvmStructType.def_property_readonly(
117bd8fcf75SOleksandr "Alex" Zinenko       "opaque", [](MlirType type) { return mlirLLVMStructTypeIsOpaque(type); });
11879d4d165SMaksim Levental 
11979d4d165SMaksim Levental   //===--------------------------------------------------------------------===//
12079d4d165SMaksim Levental   // PointerType
12179d4d165SMaksim Levental   //===--------------------------------------------------------------------===//
12279d4d165SMaksim Levental 
12379d4d165SMaksim Levental   mlir_type_subclass(m, "PointerType", mlirTypeIsALLVMPointerType)
12479d4d165SMaksim Levental       .def_classmethod(
12579d4d165SMaksim Levental           "get",
126*5cd42747SPeter Hawkins           [](nb::object cls, std::optional<unsigned> addressSpace,
12779d4d165SMaksim Levental              MlirContext context) {
12879d4d165SMaksim Levental             CollectDiagnosticsToStringScope scope(context);
12979d4d165SMaksim Levental             MlirType type = mlirLLVMPointerTypeGet(
13079d4d165SMaksim Levental                 context, addressSpace.has_value() ? *addressSpace : 0);
13179d4d165SMaksim Levental             if (mlirTypeIsNull(type)) {
132*5cd42747SPeter Hawkins               throw nb::value_error(scope.takeMessage().c_str());
13379d4d165SMaksim Levental             }
13479d4d165SMaksim Levental             return cls(type);
13579d4d165SMaksim Levental           },
136*5cd42747SPeter Hawkins           "cls"_a, "address_space"_a.none() = nb::none(), nb::kw_only(),
137*5cd42747SPeter Hawkins           "context"_a.none() = nb::none())
13879d4d165SMaksim Levental       .def_property_readonly("address_space", [](MlirType type) {
13979d4d165SMaksim Levental         return mlirLLVMPointerTypeGetAddressSpace(type);
14079d4d165SMaksim Levental       });
141bd8fcf75SOleksandr "Alex" Zinenko }
142bd8fcf75SOleksandr "Alex" Zinenko 
143*5cd42747SPeter Hawkins NB_MODULE(_mlirDialectsLLVM, m) {
144bd8fcf75SOleksandr "Alex" Zinenko   m.doc() = "MLIR LLVM Dialect";
145bd8fcf75SOleksandr "Alex" Zinenko 
146bd8fcf75SOleksandr "Alex" Zinenko   populateDialectLLVMSubmodule(m);
147bd8fcf75SOleksandr "Alex" Zinenko }
148