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