20 #include "nanobind/nanobind.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/Support/raw_ostream.h"
26 #include <system_error>
30 using namespace nb::literals;
35 using llvm::StringRef;
43 R
"(Parses the assembly form of a type.
45 Returns a Type object or raises an MLIRError if the type cannot be parsed.
47 See also: https://mlir.llvm.org/docs/LangRef/#type-system
51 R
"(Gets a Location representing a caller and callsite)";
54 R
"(Gets a Location representing a file, line and column)";
57 R
"(Gets a Location representing a file, line and column range)";
60 R
"(Gets a Location representing a fused location with optional metadata)";
63 R
"(Gets a Location representing a named location with optional child location)";
66 R
"(Parses a module's assembly format from a string.
68 Returns a new MlirModule or raises an MLIRError if the parsing fails.
70 See also: https://mlir.llvm.org/docs/LangRef/
74 R
"(Creates a new operation.
77 name: Operation name (e.g. "dialect.operation").
78 results: Sequence of Type representing op result types.
79 attributes: Dict of str:Attribute.
80 successors: List of Block for the operation's successors.
81 regions: Number of regions to create.
82 location: A Location object (defaults to resolve from context manager).
83 ip: An InsertionPoint (defaults to resolve from context manager or set to
84 False to disable insertion, even with an insertion point set in the
86 infer_type: Whether to infer result types.
88 A new "detached" Operation object. Detached operations can be added
89 to blocks, which causes them to become "attached."
93 R
"(Prints the assembly form of the operation to a file like object.
96 file: The file like object to write to. Defaults to sys.stdout.
97 binary: Whether to write bytes (True) or str (False). Defaults to False.
98 large_elements_limit: Whether to elide elements attributes above this
99 number of elements. Defaults to None (no limit).
100 enable_debug_info: Whether to print debug/location information. Defaults
102 pretty_debug_info: Whether to format debug information for easier reading
103 by a human (warning: the result is unparseable).
104 print_generic_op_form: Whether to print the generic assembly forms of all
105 ops. Defaults to False.
106 use_local_Scope: Whether to print in a way that is more optimized for
107 multi-threaded access but may not be consistent with how the overall
109 assume_verified: By default, if not printing generic form, the verifier
110 will be run and if it fails, generic form will be printed with a comment
111 about failed verification. While a reasonable default for interactive use,
112 for systematic use, it is often better for the caller to verify explicitly
113 and report failures in a more robust fashion. Set this to True if doing this
114 in order to avoid running a redundant verification. If the IR is actually
115 invalid, behavior is undefined.
116 skip_regions: Whether to skip printing regions. Defaults to False.
120 R
"(Prints the assembly form of the operation to a file like object.
123 file: The file like object to write to. Defaults to sys.stdout.
124 binary: Whether to write bytes (True) or str (False). Defaults to False.
125 state: AsmState capturing the operation numbering and flags.
129 R
"(Gets the assembly form of the operation with all options available.
132 binary: Whether to return a bytes (True) or str (False) object. Defaults to
134 ... others ...: See the print() method for common keyword arguments for
135 configuring the printout.
137 Either a bytes or str object, depending on the setting of the 'binary'
142 R
"(Write the bytecode form of the operation to a file like object.
145 file: The file like object to write to.
146 desired_version: The version of bytecode to emit.
148 The bytecode writer status.
152 R
"(Gets the assembly form of the operation with default options.
154 If more advanced control over the assembly formatting or I/O options is needed,
155 use the dedicated print or get_asm method, which supports keyword arguments to
160 R
"(Dumps a debug representation of the object to stderr.)";
163 R
"(Appends a new block, with argument types as positional args.
170 R
"(Returns the string form of the value.
172 If the value is a block argument, this is the assembly form of its type and the
173 position in the argument list. If the value is an operation result, this is
174 equivalent to printing the operation that produced it.
178 R
"(Returns the string form of value as an operand (i.e., the ValueID).
182 R
"(Replace all uses of value with the new value, updating anything in
183 the IR that uses 'self' to use the other value instead.
187 R
"("Replace all uses of this value with the 'with' value, except for those
188 in 'exceptions'. 'exceptions' can be either a single operation or a list of
197 template <
class Func,
typename... Args>
199 nb::object cf = nb::cpp_function(f, args...);
200 return nb::borrow<nb::object>((PyClassMethod_New(cf.ptr())));
205 nb::object dialectDescriptor) {
206 auto dialectClass =
PyGlobals::get().lookupDialectClass(dialectNamespace);
209 return nb::cast(
PyDialect(std::move(dialectDescriptor)));
213 return (*dialectClass)(std::move(dialectDescriptor));
231 const std::optional<nb::sequence> &pyArgLocs) {
233 argTypes.reserve(nb::len(pyArgTypes));
234 for (
const auto &pyType : pyArgTypes)
235 argTypes.push_back(nb::cast<PyType &>(pyType));
239 argLocs.reserve(nb::len(*pyArgLocs));
240 for (
const auto &pyLoc : *pyArgLocs)
241 argLocs.push_back(nb::cast<PyLocation &>(pyLoc));
242 }
else if (!argTypes.empty()) {
243 argLocs.assign(argTypes.size(), DefaultingPyLocation::resolve());
246 if (argTypes.size() != argLocs.size())
247 throw nb::value_error((
"Expected " + Twine(argTypes.size()) +
248 " locations, got: " + Twine(argLocs.size()))
251 return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
256 static void set(nb::object &o,
bool enable) {
257 nb::ft_lock_guard lock(mutex);
261 static bool get(
const nb::object &) {
262 nb::ft_lock_guard lock(mutex);
266 static void bind(nb::module_ &m) {
268 nb::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug")
273 [](
const std::string &type) {
274 nb::ft_lock_guard lock(mutex);
277 "types"_a,
"Sets specific debug types to be produced by LLVM")
278 .def_static(
"set_types", [](
const std::vector<std::string> &types) {
279 std::vector<const char *> pointers;
280 pointers.reserve(types.size());
281 for (
const std::string &str : types)
282 pointers.push_back(str.c_str());
283 nb::ft_lock_guard lock(mutex);
289 static nb::ft_mutex mutex;
292 nb::ft_mutex PyGlobalDebugFlag::mutex;
296 return PyGlobals::get().lookupAttributeBuilder(attributeKind).has_value();
299 auto builder =
PyGlobals::get().lookupAttributeBuilder(attributeKind);
301 throw nb::key_error(attributeKind.c_str());
305 nb::callable func,
bool replace) {
306 PyGlobals::get().registerAttributeBuilder(attributeKind, std::move(func),
310 static void bind(nb::module_ &m) {
311 nb::class_<PyAttrBuilderMap>(m,
"AttrBuilder")
315 "attribute_kind"_a,
"attr_builder"_a,
"replace"_a =
false,
316 "Register an attribute builder for building MLIR "
317 "attributes from python values.");
325 nb::object PyBlock::getCapsule() {
335 class PyRegionIterator {
338 : operation(std::move(operation)) {}
340 PyRegionIterator &dunderIter() {
return *
this; }
345 throw nb::stop_iteration();
351 static void bind(nb::module_ &m) {
352 nb::class_<PyRegionIterator>(m,
"RegionIterator")
353 .def(
"__iter__", &PyRegionIterator::dunderIter)
354 .def(
"__next__", &PyRegionIterator::dunderNext);
364 class PyRegionList :
public Sliceable<PyRegionList, PyRegion> {
366 static constexpr
const char *pyClassName =
"RegionSequence";
369 intptr_t length = -1, intptr_t step = 1)
374 operation(std::move(operation)) {}
376 PyRegionIterator dunderIter() {
378 return PyRegionIterator(operation);
381 static void bindDerived(ClassTy &c) {
382 c.def(
"__iter__", &PyRegionList::dunderIter);
389 intptr_t getRawNumElements() {
394 PyRegion getRawElement(intptr_t pos) {
399 PyRegionList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
400 return PyRegionList(operation, startIndex, length, step);
406 class PyBlockIterator {
409 : operation(std::move(operation)), next(next) {}
411 PyBlockIterator &dunderIter() {
return *
this; }
416 throw nb::stop_iteration();
419 PyBlock returnBlock(operation, next);
424 static void bind(nb::module_ &m) {
425 nb::class_<PyBlockIterator>(m,
"BlockIterator")
426 .def(
"__iter__", &PyBlockIterator::dunderIter)
427 .def(
"__next__", &PyBlockIterator::dunderNext);
441 : operation(std::move(operation)), region(region) {}
443 PyBlockIterator dunderIter() {
448 intptr_t dunderLen() {
449 operation->checkValid();
459 PyBlock dunderGetItem(intptr_t index) {
462 index += dunderLen();
465 throw nb::index_error(
"attempt to access out of bounds block");
470 return PyBlock(operation, block);
475 throw nb::index_error(
"attempt to access out of bounds block");
478 PyBlock appendBlock(
const nb::args &pyArgTypes,
479 const std::optional<nb::sequence> &pyArgLocs) {
482 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
484 return PyBlock(operation, block);
487 static void bind(nb::module_ &m) {
488 nb::class_<PyBlockList>(m,
"BlockList")
489 .def(
"__getitem__", &PyBlockList::dunderGetItem)
490 .def(
"__iter__", &PyBlockList::dunderIter)
491 .def(
"__len__", &PyBlockList::dunderLen)
493 nb::arg(
"args"), nb::kw_only(),
494 nb::arg(
"arg_locs") = std::nullopt);
502 class PyOperationIterator {
504 PyOperationIterator(
PyOperationRef parentOperation, MlirOperation next)
505 : parentOperation(std::move(parentOperation)), next(next) {}
507 PyOperationIterator &dunderIter() {
return *
this; }
509 nb::object dunderNext() {
512 throw nb::stop_iteration();
516 PyOperation::forOperation(parentOperation->getContext(), next);
521 static void bind(nb::module_ &m) {
522 nb::class_<PyOperationIterator>(m,
"OperationIterator")
523 .def(
"__iter__", &PyOperationIterator::dunderIter)
524 .def(
"__next__", &PyOperationIterator::dunderNext);
536 class PyOperationList {
539 : parentOperation(std::move(parentOperation)), block(block) {}
541 PyOperationIterator dunderIter() {
543 return PyOperationIterator(parentOperation,
547 intptr_t dunderLen() {
548 parentOperation->checkValid();
558 nb::object dunderGetItem(intptr_t index) {
559 parentOperation->checkValid();
561 index += dunderLen();
564 throw nb::index_error(
"attempt to access out of bounds operation");
569 return PyOperation::forOperation(parentOperation->getContext(), childOp)
575 throw nb::index_error(
"attempt to access out of bounds operation");
578 static void bind(nb::module_ &m) {
579 nb::class_<PyOperationList>(m,
"OperationList")
580 .def(
"__getitem__", &PyOperationList::dunderGetItem)
581 .def(
"__iter__", &PyOperationList::dunderIter)
582 .def(
"__len__", &PyOperationList::dunderLen);
592 PyOpOperand(MlirOpOperand opOperand) : opOperand(opOperand) {}
594 nb::object getOwner() {
598 return PyOperation::forOperation(context, owner)->createOpView();
603 static void bind(nb::module_ &m) {
604 nb::class_<PyOpOperand>(m,
"OpOperand")
605 .def_prop_ro(
"owner", &PyOpOperand::getOwner)
606 .def_prop_ro(
"operand_number", &PyOpOperand::getOperandNumber);
610 MlirOpOperand opOperand;
613 class PyOpOperandIterator {
615 PyOpOperandIterator(MlirOpOperand opOperand) : opOperand(opOperand) {}
617 PyOpOperandIterator &dunderIter() {
return *
this; }
619 PyOpOperand dunderNext() {
621 throw nb::stop_iteration();
623 PyOpOperand returnOpOperand(opOperand);
625 return returnOpOperand;
628 static void bind(nb::module_ &m) {
629 nb::class_<PyOpOperandIterator>(m,
"OpOperandIterator")
630 .def(
"__iter__", &PyOpOperandIterator::dunderIter)
631 .def(
"__next__", &PyOpOperandIterator::dunderNext);
635 MlirOpOperand opOperand;
644 PyMlirContext::PyMlirContext(MlirContext context) : context(context) {
645 nb::gil_scoped_acquire acquire;
646 nb::ft_lock_guard lock(live_contexts_mutex);
647 auto &liveContexts = getLiveContexts();
648 liveContexts[context.ptr] =
this;
655 nb::gil_scoped_acquire acquire;
657 nb::ft_lock_guard lock(live_contexts_mutex);
658 getLiveContexts().erase(context.ptr);
670 throw nb::python_error();
675 nb::gil_scoped_acquire acquire;
676 nb::ft_lock_guard lock(live_contexts_mutex);
677 auto &liveContexts = getLiveContexts();
678 auto it = liveContexts.find(context.ptr);
679 if (it == liveContexts.end()) {
682 nb::object pyRef = nb::cast(unownedContextWrapper);
683 assert(pyRef &&
"cast to nb::object failed");
684 liveContexts[context.ptr] = unownedContextWrapper;
688 nb::object pyRef = nb::cast(it->second);
692 nb::ft_mutex PyMlirContext::live_contexts_mutex;
695 static LiveContextMap liveContexts;
700 nb::ft_lock_guard lock(live_contexts_mutex);
701 return getLiveContexts().size();
705 nb::ft_lock_guard lock(liveOperationsMutex);
706 return liveOperations.size();
710 std::vector<PyOperation *> liveObjects;
711 nb::ft_lock_guard lock(liveOperationsMutex);
712 for (
auto &entry : liveOperations)
713 liveObjects.push_back(entry.second.second);
721 nb::ft_lock_guard lock(liveOperationsMutex);
722 std::swap(operations, liveOperations);
724 for (
auto &op : operations)
725 op.second.second->setInvalid();
726 size_t numInvalidated = operations.size();
727 return numInvalidated;
733 nb::ft_lock_guard lock(liveOperationsMutex);
734 auto it = liveOperations.find(op.ptr);
735 if (it == liveOperations.end()) {
738 py_op = it->second.second;
739 liveOperations.erase(it);
754 callBackData *data =
static_cast<callBackData *
>(userData);
755 if (LLVM_LIKELY(data->rootSeen))
756 data->rootOp.getOperation().getContext()->clearOperation(op);
758 data->rootSeen =
true;
787 const nb::object &excVal,
788 const nb::object &excTb) {
797 nb::object pyHandlerObject =
798 nb::cast(pyHandler, nb::rv_policy::take_ownership);
799 pyHandlerObject.inc_ref();
803 auto handlerCallback =
806 nb::object pyDiagnosticObject =
807 nb::cast(pyDiagnostic, nb::rv_policy::take_ownership);
814 nb::gil_scoped_acquire gil;
816 result = nb::cast<bool>(pyHandler->callback(pyDiagnostic));
817 }
catch (std::exception &e) {
818 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
820 pyHandler->hadError =
true;
827 auto deleteCallback = +[](
void *userData) {
829 assert(pyHandler->registeredID &&
"handler is not registered");
830 pyHandler->registeredID.reset();
833 nb::object pyHandlerObject = nb::cast(pyHandler, nb::rv_policy::reference);
834 pyHandlerObject.dec_ref();
838 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
839 return pyHandlerObject;
846 if (self->ctx->emitErrorDiagnostics)
859 throw std::runtime_error(
860 "An MLIR function requires a Context but none was provided in the call "
861 "or from the surrounding environment. Either pass to the function with "
862 "a 'context=' argument or establish a default using 'with Context():'");
872 static thread_local std::vector<PyThreadContextEntry> stack;
877 auto &stack = getStack();
880 return &stack.back();
883 void PyThreadContextEntry::push(FrameKind frameKind, nb::object context,
884 nb::object insertionPoint,
885 nb::object location) {
886 auto &stack = getStack();
887 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
888 std::move(location));
892 if (stack.size() > 1) {
893 auto &prev = *(stack.rbegin() + 1);
894 auto ¤t = stack.back();
895 if (current.context.is(prev.context)) {
897 if (!current.insertionPoint)
898 current.insertionPoint = prev.insertionPoint;
899 if (!current.location)
900 current.location = prev.location;
908 return nb::cast<PyMlirContext *>(context);
914 return nb::cast<PyInsertionPoint *>(insertionPoint);
920 return nb::cast<PyLocation *>(location);
924 auto *tos = getTopOfStack();
925 return tos ? tos->getContext() :
nullptr;
929 auto *tos = getTopOfStack();
930 return tos ? tos->getInsertionPoint() :
nullptr;
934 auto *tos = getTopOfStack();
935 return tos ? tos->getLocation() :
nullptr;
939 push(FrameKind::Context, context,
946 auto &stack = getStack();
948 throw std::runtime_error(
"Unbalanced Context enter/exit");
949 auto &tos = stack.back();
950 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
951 throw std::runtime_error(
"Unbalanced Context enter/exit");
958 nb::cast<PyInsertionPoint &>(insertionPointObj);
959 nb::object contextObj =
961 push(FrameKind::InsertionPoint,
965 return insertionPointObj;
969 auto &stack = getStack();
971 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
972 auto &tos = stack.back();
973 if (tos.frameKind != FrameKind::InsertionPoint &&
974 tos.getInsertionPoint() != &insertionPoint)
975 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
980 PyLocation &location = nb::cast<PyLocation &>(locationObj);
982 push(FrameKind::Location, contextObj,
989 auto &stack = getStack();
991 throw std::runtime_error(
"Unbalanced Location enter/exit");
992 auto &tos = stack.back();
993 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
994 throw std::runtime_error(
"Unbalanced Location enter/exit");
1004 if (materializedNotes) {
1005 for (nb::handle noteObject : *materializedNotes) {
1006 PyDiagnostic *note = nb::cast<PyDiagnostic *>(noteObject);
1013 nb::object callback)
1014 : context(context), callback(std::move(callback)) {}
1023 assert(!registeredID &&
"should have unregistered");
1026 context = {
nullptr};
1029 void PyDiagnostic::checkValid() {
1031 throw std::invalid_argument(
1032 "Diagnostic is invalid (used outside of callback)");
1050 nb::object fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
1053 return nb::cast<nb::str>(fileObject.attr(
"getvalue")());
1058 if (materializedNotes)
1059 return *materializedNotes;
1061 nb::tuple notes = nb::steal<nb::tuple>(PyTuple_New(numNotes));
1062 for (intptr_t i = 0; i < numNotes; ++i) {
1064 nb::object diagnostic = nb::cast(
PyDiagnostic(noteDiag));
1065 PyTuple_SET_ITEM(notes.ptr(), i, diagnostic.release().ptr());
1067 materializedNotes = std::move(notes);
1069 return *materializedNotes;
1073 std::vector<DiagnosticInfo> notes;
1075 notes.emplace_back(nb::cast<PyDiagnostic>(n).
getInfo());
1087 {key.data(), key.size()});
1089 std::string msg = (Twine(
"Dialect '") + key +
"' not found").str();
1091 throw nb::attribute_error(msg.c_str());
1092 throw nb::index_error(msg.c_str());
1102 MlirDialectRegistry rawRegistry =
1105 throw nb::python_error();
1120 throw nb::python_error();
1130 const nb::object &excVal,
1131 const nb::object &excTb) {
1138 throw std::runtime_error(
1139 "An MLIR function requires a Location but none was provided in the "
1140 "call or from the surrounding environment. Either pass to the function "
1141 "with a 'loc=' argument or establish a default using 'with loc:'");
1154 nb::gil_scoped_acquire acquire;
1155 auto &liveModules =
getContext()->liveModules;
1156 assert(liveModules.count(module.ptr) == 1 &&
1157 "destroying module not in live map");
1158 liveModules.erase(module.ptr);
1166 nb::gil_scoped_acquire acquire;
1167 auto &liveModules = contextRef->liveModules;
1168 auto it = liveModules.find(module.ptr);
1169 if (it == liveModules.end()) {
1175 nb::object pyRef = nb::cast(unownedModule, nb::rv_policy::take_ownership);
1176 unownedModule->handle = pyRef;
1177 liveModules[module.ptr] =
1178 std::make_pair(unownedModule->handle, unownedModule);
1179 return PyModuleRef(unownedModule, std::move(pyRef));
1182 PyModule *existing = it->second.second;
1183 nb::object pyRef = nb::borrow<nb::object>(it->second.first);
1190 throw nb::python_error();
1226 template <
typename T,
class... Args>
1228 nb::handle type = nb::type<T>();
1229 nb::object instance = nb::inst_alloc(type);
1230 T *ptr = nb::inst_ptr<T>(instance);
1231 new (ptr) T(std::forward<Args>(args)...);
1232 nb::inst_mark_ready(instance);
1239 MlirOperation operation,
1240 nb::object parentKeepAlive) {
1243 makeObjectRef<PyOperation>(std::move(contextRef), operation);
1244 unownedOperation->handle = unownedOperation.
getObject();
1245 if (parentKeepAlive) {
1246 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
1248 return unownedOperation;
1252 MlirOperation operation,
1253 nb::object parentKeepAlive) {
1254 nb::ft_lock_guard lock(contextRef->liveOperationsMutex);
1255 auto &liveOperations = contextRef->liveOperations;
1256 auto it = liveOperations.find(operation.ptr);
1257 if (it == liveOperations.end()) {
1259 PyOperationRef result = createInstance(std::move(contextRef), operation,
1260 std::move(parentKeepAlive));
1261 liveOperations[operation.ptr] =
1267 nb::object pyRef = nb::borrow<nb::object>(it->second.first);
1272 MlirOperation operation,
1273 nb::object parentKeepAlive) {
1274 nb::ft_lock_guard lock(contextRef->liveOperationsMutex);
1275 auto &liveOperations = contextRef->liveOperations;
1276 assert(liveOperations.count(operation.ptr) == 0 &&
1277 "cannot create detached operation that already exists");
1278 (void)liveOperations;
1279 PyOperationRef created = createInstance(std::move(contextRef), operation,
1280 std::move(parentKeepAlive));
1281 liveOperations[operation.ptr] =
1283 created->attached =
false;
1288 const std::string &sourceStr,
1289 const std::string &sourceName) {
1295 throw MLIRError(
"Unable to parse operation assembly", errors.
take());
1301 throw std::runtime_error(
"the operation has been invalidated");
1306 bool enableDebugInfo,
bool prettyDebugInfo,
1307 bool printGenericOpForm,
bool useLocalScope,
1308 bool useNameLocAsPrefix,
bool assumeVerified,
1309 nb::object fileObject,
bool binary,
1313 if (fileObject.is_none())
1314 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1317 if (largeElementsLimit) {
1321 if (enableDebugInfo)
1324 if (printGenericOpForm)
1332 if (useNameLocAsPrefix)
1337 accum.getUserData());
1345 if (fileObject.is_none())
1346 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1349 accum.getUserData());
1353 std::optional<int64_t> bytecodeVersion) {
1358 if (!bytecodeVersion.has_value())
1368 throw nb::value_error((Twine(
"Unable to honor desired bytecode version ") +
1369 Twine(*bytecodeVersion))
1382 std::string exceptionWhat;
1383 nb::object exceptionType;
1385 UserData userData{callback,
false, {}, {}};
1388 UserData *calleeUserData =
static_cast<UserData *
>(userData);
1390 return (calleeUserData->callback)(op);
1391 }
catch (nb::python_error &e) {
1392 calleeUserData->gotException =
true;
1393 calleeUserData->exceptionWhat = std::string(e.what());
1394 calleeUserData->exceptionType = nb::borrow(e.type());
1399 if (userData.gotException) {
1400 std::string message(
"Exception raised in callback: ");
1401 message.append(userData.exceptionWhat);
1402 throw std::runtime_error(message);
1407 std::optional<int64_t> largeElementsLimit,
1408 bool enableDebugInfo,
bool prettyDebugInfo,
1409 bool printGenericOpForm,
bool useLocalScope,
1410 bool useNameLocAsPrefix,
bool assumeVerified,
1412 nb::object fileObject;
1414 fileObject = nb::module_::import_(
"io").attr(
"BytesIO")();
1416 fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
1418 print(largeElementsLimit,
1429 return fileObject.attr(
"getvalue")();
1438 operation.parentKeepAlive = otherOp.parentKeepAlive;
1447 operation.parentKeepAlive = otherOp.parentKeepAlive;
1461 throw nb::value_error(
"Detached operations have no parent");
1472 assert(!
mlirBlockIsNull(block) &&
"Attached operation has null parent");
1473 assert(parentOperation &&
"Operation has no parent");
1474 return PyBlock{std::move(*parentOperation), block};
1485 throw nb::python_error();
1492 const nb::object &maybeIp) {
1494 if (!maybeIp.is(nb::cast(
false))) {
1496 if (maybeIp.is_none()) {
1499 ip = nb::cast<PyInsertionPoint *>(maybeIp);
1507 std::optional<std::vector<PyType *>> results,
1509 std::optional<nb::dict> attributes,
1510 std::optional<std::vector<PyBlock *>> successors,
1512 const nb::object &maybeIp,
bool inferType) {
1519 throw nb::value_error(
"number of regions must be >= 0");
1523 mlirResults.reserve(results->size());
1524 for (
PyType *result : *results) {
1527 throw nb::value_error(
"result type cannot be None");
1528 mlirResults.push_back(*result);
1533 mlirAttributes.reserve(attributes->size());
1534 for (std::pair<nb::handle, nb::handle> it : *attributes) {
1537 key = nb::cast<std::string>(it.first);
1538 }
catch (nb::cast_error &err) {
1539 std::string msg =
"Invalid attribute key (not a string) when "
1540 "attempting to create the operation \"" +
1541 std::string(name) +
"\" (" + err.what() +
")";
1542 throw nb::type_error(msg.c_str());
1545 auto &attribute = nb::cast<PyAttribute &>(it.second);
1547 mlirAttributes.emplace_back(std::move(key), attribute);
1548 }
catch (nb::cast_error &err) {
1549 std::string msg =
"Invalid attribute value for the key \"" + key +
1550 "\" when attempting to create the operation \"" +
1551 std::string(name) +
"\" (" + err.what() +
")";
1552 throw nb::type_error(msg.c_str());
1553 }
catch (std::runtime_error &) {
1556 "Found an invalid (`None`?) attribute value for the key \"" + key +
1557 "\" when attempting to create the operation \"" +
1558 std::string(name) +
"\"";
1559 throw std::runtime_error(msg);
1565 mlirSuccessors.reserve(successors->size());
1566 for (
auto *successor : *successors) {
1569 throw nb::value_error(
"successor block cannot be None");
1570 mlirSuccessors.push_back(successor->get());
1578 if (!operands.empty())
1580 state.enableResultTypeInference = inferType;
1581 if (!mlirResults.empty())
1583 mlirResults.data());
1584 if (!mlirAttributes.empty()) {
1589 mlirNamedAttributes.reserve(mlirAttributes.size());
1590 for (
auto &it : mlirAttributes)
1596 mlirNamedAttributes.data());
1598 if (!mlirSuccessors.empty())
1600 mlirSuccessors.data());
1603 mlirRegions.resize(regions);
1604 for (
int i = 0; i < regions; ++i)
1607 mlirRegions.data());
1613 throw nb::value_error(
"Operation creation failed");
1651 template <
typename DerivedTy>
1652 class PyConcreteValue :
public PyValue {
1658 using ClassTy = nb::class_<DerivedTy, PyValue>;
1659 using IsAFunctionTy = bool (*)(MlirValue);
1661 PyConcreteValue() =
default;
1663 :
PyValue(operationRef, value) {}
1664 PyConcreteValue(
PyValue &orig)
1665 : PyConcreteValue(orig.getParentOperation(), castFrom(orig)) {}
1669 static MlirValue castFrom(
PyValue &orig) {
1670 if (!DerivedTy::isaFunction(orig.
get())) {
1671 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(orig)));
1672 throw nb::value_error((Twine(
"Cannot cast value to ") +
1673 DerivedTy::pyClassName +
" (from " + origRepr +
1682 static void bind(nb::module_ &m) {
1683 auto cls = ClassTy(m, DerivedTy::pyClassName);
1684 cls.def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg(
"value"));
1687 [](
PyValue &otherValue) ->
bool {
1688 return DerivedTy::isaFunction(otherValue);
1690 nb::arg(
"other_value"));
1692 [](
DerivedTy &
self) {
return self.maybeDownCast(); });
1693 DerivedTy::bindDerived(cls);
1697 static void bindDerived(ClassTy &m) {}
1706 static constexpr
const char *pyClassName =
"OpResult";
1707 using PyConcreteValue::PyConcreteValue;
1710 c.def_prop_ro(
"owner", [](
PyOpResult &
self) {
1714 "expected the owner of the value in Python to match that in the IR");
1715 return self.getParentOperation().getObject();
1717 c.def_prop_ro(
"result_number", [](
PyOpResult &
self) {
1724 template <
typename Container>
1727 std::vector<MlirType> result;
1728 result.reserve(container.size());
1729 for (
int i = 0, e = container.size(); i < e; ++i) {
1741 static constexpr
const char *pyClassName =
"OpResultList";
1745 intptr_t length = -1, intptr_t step = 1)
1750 operation(std::move(operation)) {}
1757 return self.operation->createOpView();
1767 intptr_t getRawNumElements() {
1777 PyOpResultList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
1789 const nb::object &resultSegmentSpecObj,
1790 std::vector<int32_t> &resultSegmentLengths,
1791 std::vector<PyType *> &resultTypes) {
1792 resultTypes.reserve(resultTypeList.size());
1793 if (resultSegmentSpecObj.is_none()) {
1797 resultTypes.push_back(nb::cast<PyType *>(it.value()));
1798 if (!resultTypes.back())
1799 throw nb::cast_error();
1800 }
catch (nb::cast_error &err) {
1801 throw nb::value_error((llvm::Twine(
"Result ") +
1802 llvm::Twine(it.index()) +
" of operation \"" +
1803 name +
"\" must be a Type (" + err.what() +
")")
1810 auto resultSegmentSpec = nb::cast<std::vector<int>>(resultSegmentSpecObj);
1811 if (resultSegmentSpec.size() != resultTypeList.size()) {
1812 throw nb::value_error((llvm::Twine(
"Operation \"") + name +
1814 llvm::Twine(resultSegmentSpec.size()) +
1815 " result segments but was provided " +
1816 llvm::Twine(resultTypeList.size()))
1820 resultSegmentLengths.reserve(resultTypeList.size());
1821 for (
const auto &it :
1823 int segmentSpec = std::get<1>(it.value());
1824 if (segmentSpec == 1 || segmentSpec == 0) {
1827 auto *resultType = nb::cast<PyType *>(std::get<0>(it.value()));
1829 resultTypes.push_back(resultType);
1830 resultSegmentLengths.push_back(1);
1831 }
else if (segmentSpec == 0) {
1833 resultSegmentLengths.push_back(0);
1835 throw nb::value_error(
1836 (llvm::Twine(
"Result ") + llvm::Twine(it.index()) +
1837 " of operation \"" + name +
1838 "\" must be a Type (was None and result is not optional)")
1842 }
catch (nb::cast_error &err) {
1843 throw nb::value_error((llvm::Twine(
"Result ") +
1844 llvm::Twine(it.index()) +
" of operation \"" +
1845 name +
"\" must be a Type (" + err.what() +
1850 }
else if (segmentSpec == -1) {
1853 if (std::get<0>(it.value()).is_none()) {
1855 resultSegmentLengths.push_back(0);
1858 auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
1859 for (nb::handle segmentItem : segment) {
1860 resultTypes.push_back(nb::cast<PyType *>(segmentItem));
1861 if (!resultTypes.back()) {
1862 throw nb::type_error(
"contained a None item");
1865 resultSegmentLengths.push_back(nb::len(segment));
1867 }
catch (std::exception &err) {
1871 throw nb::value_error((llvm::Twine(
"Result ") +
1872 llvm::Twine(it.index()) +
" of operation \"" +
1873 name +
"\" must be a Sequence of Types (" +
1879 throw nb::value_error(
"Unexpected segment spec");
1887 if (numResults != 1) {
1889 throw nb::value_error((Twine(
"Cannot call .result on operation ") +
1890 StringRef(name.data, name.length) +
" which has " +
1892 " results (it is only valid for operations with a "
1901 if (operand.is_none()) {
1902 throw nb::value_error(
"contained a None item");
1905 if (nb::try_cast<PyOperationBase *>(operand, op)) {
1909 if (nb::try_cast<PyOpResultList *>(operand, opResultList)) {
1913 if (nb::try_cast<PyValue *>(operand, value)) {
1914 return value->
get();
1916 throw nb::value_error(
"is not a Value");
1920 std::string_view name, std::tuple<int, bool> opRegionSpec,
1921 nb::object operandSegmentSpecObj, nb::object resultSegmentSpecObj,
1922 std::optional<nb::list> resultTypeList, nb::list operandList,
1923 std::optional<nb::dict> attributes,
1924 std::optional<std::vector<PyBlock *>> successors,
1926 const nb::object &maybeIp) {
1935 std::vector<int32_t> operandSegmentLengths;
1936 std::vector<int32_t> resultSegmentLengths;
1939 int opMinRegionCount = std::get<0>(opRegionSpec);
1940 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1942 regions = opMinRegionCount;
1944 if (*regions < opMinRegionCount) {
1945 throw nb::value_error(
1946 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1947 llvm::Twine(opMinRegionCount) +
1948 " regions but was built with regions=" + llvm::Twine(*regions))
1952 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1953 throw nb::value_error(
1954 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1955 llvm::Twine(opMinRegionCount) +
1956 " regions but was built with regions=" + llvm::Twine(*regions))
1962 std::vector<PyType *> resultTypes;
1963 if (resultTypeList.has_value()) {
1965 resultSegmentLengths, resultTypes);
1970 operands.reserve(operands.size());
1971 if (operandSegmentSpecObj.is_none()) {
1976 }
catch (nb::builtin_exception &err) {
1977 throw nb::value_error((llvm::Twine(
"Operand ") +
1978 llvm::Twine(it.index()) +
" of operation \"" +
1979 name +
"\" must be a Value (" + err.what() +
")")
1986 auto operandSegmentSpec = nb::cast<std::vector<int>>(operandSegmentSpecObj);
1987 if (operandSegmentSpec.size() != operandList.size()) {
1988 throw nb::value_error((llvm::Twine(
"Operation \"") + name +
1990 llvm::Twine(operandSegmentSpec.size()) +
1991 "operand segments but was provided " +
1992 llvm::Twine(operandList.size()))
1996 operandSegmentLengths.reserve(operandList.size());
1997 for (
const auto &it :
1999 int segmentSpec = std::get<1>(it.value());
2000 if (segmentSpec == 1 || segmentSpec == 0) {
2002 auto &operand = std::get<0>(it.value());
2003 if (!operand.is_none()) {
2007 }
catch (nb::builtin_exception &err) {
2008 throw nb::value_error((llvm::Twine(
"Operand ") +
2009 llvm::Twine(it.index()) +
2010 " of operation \"" + name +
2011 "\" must be a Value (" + err.what() +
")")
2016 operandSegmentLengths.push_back(1);
2017 }
else if (segmentSpec == 0) {
2019 operandSegmentLengths.push_back(0);
2021 throw nb::value_error(
2022 (llvm::Twine(
"Operand ") + llvm::Twine(it.index()) +
2023 " of operation \"" + name +
2024 "\" must be a Value (was None and operand is not optional)")
2028 }
else if (segmentSpec == -1) {
2031 if (std::get<0>(it.value()).is_none()) {
2033 operandSegmentLengths.push_back(0);
2036 auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
2037 for (nb::handle segmentItem : segment) {
2040 operandSegmentLengths.push_back(nb::len(segment));
2042 }
catch (std::exception &err) {
2046 throw nb::value_error((llvm::Twine(
"Operand ") +
2047 llvm::Twine(it.index()) +
" of operation \"" +
2048 name +
"\" must be a Sequence of Values (" +
2054 throw nb::value_error(
"Unexpected segment spec");
2060 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
2063 attributes = nb::dict(*attributes);
2065 attributes = nb::dict();
2067 if (attributes->contains(
"resultSegmentSizes") ||
2068 attributes->contains(
"operandSegmentSizes")) {
2069 throw nb::value_error(
"Manually setting a 'resultSegmentSizes' or "
2070 "'operandSegmentSizes' attribute is unsupported. "
2071 "Use Operation.create for such low-level access.");
2075 if (!resultSegmentLengths.empty()) {
2076 MlirAttribute segmentLengthAttr =
2078 resultSegmentLengths.data());
2079 (*attributes)[
"resultSegmentSizes"] =
2084 if (!operandSegmentLengths.empty()) {
2085 MlirAttribute segmentLengthAttr =
2087 operandSegmentLengths.data());
2088 (*attributes)[
"operandSegmentSizes"] =
2095 std::move(resultTypes),
2096 std::move(operands),
2097 std::move(attributes),
2098 std::move(successors),
2099 *regions, location, maybeIp,
2104 const nb::object &operation) {
2105 nb::handle opViewType = nb::type<PyOpView>();
2106 nb::object instance = cls.attr(
"__new__")(cls);
2107 opViewType.attr(
"__init__")(instance, operation);
2115 operationObject(operation.getRef().getObject()) {}
2124 : refOperation(beforeOperationBase.getOperation().getRef()),
2125 block((*refOperation)->getBlock()) {}
2130 throw nb::value_error(
2131 "Attempt to insert operation that is already attached");
2132 block.getParentOperation()->checkValid();
2133 MlirOperation beforeOp = {
nullptr};
2136 (*refOperation)->checkValid();
2137 beforeOp = (*refOperation)->get();
2143 throw nb::index_error(
"Cannot insert operation at the end of a block "
2144 "that already has a terminator. Did you mean to "
2145 "use 'InsertionPoint.at_block_terminator(block)' "
2146 "versus 'InsertionPoint(block)'?");
2169 throw nb::value_error(
"Block has no terminator");
2180 const nb::object &excVal,
2181 const nb::object &excTb) {
2200 throw nb::python_error();
2210 : ownedName(new std::string(std::move(ownedName))) {
2232 throw nb::python_error();
2248 throw nb::python_error();
2267 "mlirTypeID was expected to be non-null.");
2268 std::optional<nb::callable> valueCaster =
2272 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
2275 return valueCaster.value()(thisObj);
2281 throw nb::python_error();
2282 MlirOperation owner;
2288 throw nb::python_error();
2292 return PyValue(ownerRef, value);
2300 : operation(operation.getOperation().getRef()) {
2303 throw nb::type_error(
"Operation is not a Symbol Table.");
2312 throw nb::key_error(
2313 (
"Symbol '" + name +
"' not in the symbol table.").c_str());
2316 operation.getObject())
2332 erase(nb::cast<PyOperationBase &>(operation));
2341 throw nb::value_error(
"Expected operation to have a symbol name.");
2350 MlirAttribute existingNameAttr =
2353 throw nb::value_error(
"Expected operation to have a symbol name.");
2354 return existingNameAttr;
2358 const std::string &name) {
2363 MlirAttribute existingNameAttr =
2366 throw nb::value_error(
"Expected operation to have a symbol name.");
2367 MlirAttribute newNameAttr =
2376 MlirAttribute existingVisAttr =
2379 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2380 return existingVisAttr;
2384 const std::string &visibility) {
2385 if (visibility !=
"public" && visibility !=
"private" &&
2386 visibility !=
"nested")
2387 throw nb::value_error(
2388 "Expected visibility to be 'public', 'private' or 'nested'");
2392 MlirAttribute existingVisAttr =
2395 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2402 const std::string &newSymbol,
2410 throw nb::value_error(
"Symbol rename failed");
2414 bool allSymUsesVisible,
2415 nb::object callback) {
2420 nb::object callback;
2422 std::string exceptionWhat;
2423 nb::object exceptionType;
2426 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
2428 fromOperation.
get(), allSymUsesVisible,
2429 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
2430 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
2432 PyOperation::forOperation(calleeUserData->context, foundOp);
2433 if (calleeUserData->gotException)
2436 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
2437 } catch (nb::python_error &e) {
2438 calleeUserData->gotException =
true;
2439 calleeUserData->exceptionWhat = e.what();
2440 calleeUserData->exceptionType = nb::borrow(e.type());
2443 static_cast<void *
>(&userData));
2444 if (userData.gotException) {
2445 std::string message(
"Exception raised in callback: ");
2446 message.append(userData.exceptionWhat);
2447 throw std::runtime_error(message);
2454 class PyBlockArgument :
public PyConcreteValue<PyBlockArgument> {
2457 static constexpr
const char *pyClassName =
"BlockArgument";
2458 using PyConcreteValue::PyConcreteValue;
2460 static void bindDerived(ClassTy &c) {
2461 c.def_prop_ro(
"owner", [](PyBlockArgument &
self) {
2462 return PyBlock(
self.getParentOperation(),
2465 c.def_prop_ro(
"arg_number", [](PyBlockArgument &
self) {
2470 [](PyBlockArgument &
self,
PyType type) {
2481 class PyBlockArgumentList
2482 :
public Sliceable<PyBlockArgumentList, PyBlockArgument> {
2484 static constexpr
const char *pyClassName =
"BlockArgumentList";
2488 intptr_t startIndex = 0, intptr_t length = -1,
2493 operation(std::move(operation)), block(block) {}
2495 static void bindDerived(ClassTy &c) {
2496 c.def_prop_ro(
"types", [](PyBlockArgumentList &
self) {
2503 friend class Sliceable<PyBlockArgumentList, PyBlockArgument>;
2506 intptr_t getRawNumElements() {
2512 PyBlockArgument getRawElement(intptr_t pos) {
2514 return PyBlockArgument(operation, argument);
2518 PyBlockArgumentList slice(intptr_t startIndex, intptr_t length,
2520 return PyBlockArgumentList(operation, block, startIndex, length, step);
2531 class PyOpOperandList :
public Sliceable<PyOpOperandList, PyValue> {
2533 static constexpr
const char *pyClassName =
"OpOperandList";
2536 PyOpOperandList(
PyOperationRef operation, intptr_t startIndex = 0,
2537 intptr_t length = -1, intptr_t step = 1)
2542 operation(operation) {}
2544 void dunderSetItem(intptr_t index,
PyValue value) {
2545 index = wrapIndex(index);
2549 static void bindDerived(ClassTy &c) {
2550 c.def(
"__setitem__", &PyOpOperandList::dunderSetItem);
2557 intptr_t getRawNumElements() {
2562 PyValue getRawElement(intptr_t pos) {
2564 MlirOperation owner;
2570 assert(
false &&
"Value must be an block arg or op result.");
2572 PyOperation::forOperation(operation->
getContext(), owner);
2573 return PyValue(pyOwner, operand);
2576 PyOpOperandList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2577 return PyOpOperandList(operation, startIndex, length, step);
2587 class PyOpSuccessors :
public Sliceable<PyOpSuccessors, PyBlock> {
2589 static constexpr
const char *pyClassName =
"OpSuccessors";
2591 PyOpSuccessors(
PyOperationRef operation, intptr_t startIndex = 0,
2592 intptr_t length = -1, intptr_t step = 1)
2597 operation(operation) {}
2599 void dunderSetItem(intptr_t index,
PyBlock block) {
2600 index = wrapIndex(index);
2604 static void bindDerived(ClassTy &c) {
2605 c.def(
"__setitem__", &PyOpSuccessors::dunderSetItem);
2612 intptr_t getRawNumElements() {
2617 PyBlock getRawElement(intptr_t pos) {
2619 return PyBlock(operation, block);
2622 PyOpSuccessors slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2623 return PyOpSuccessors(operation, startIndex, length, step);
2631 class PyOpAttributeMap {
2634 : operation(std::move(operation)) {}
2636 MlirAttribute dunderGetItemNamed(
const std::string &name) {
2640 throw nb::key_error(
"attempt to access a non-existent attribute");
2647 index += dunderLen();
2649 if (index < 0 || index >= dunderLen()) {
2650 throw nb::index_error(
"attempt to access out of bounds attribute");
2660 void dunderSetItem(
const std::string &name,
const PyAttribute &attr) {
2665 void dunderDelItem(
const std::string &name) {
2669 throw nb::key_error(
"attempt to delete a non-existent attribute");
2672 intptr_t dunderLen() {
2676 bool dunderContains(
const std::string &name) {
2681 static void bind(nb::module_ &m) {
2682 nb::class_<PyOpAttributeMap>(m,
"OpAttributeMap")
2683 .def(
"__contains__", &PyOpAttributeMap::dunderContains)
2684 .def(
"__len__", &PyOpAttributeMap::dunderLen)
2685 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
2686 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
2687 .def(
"__setitem__", &PyOpAttributeMap::dunderSetItem)
2688 .def(
"__delitem__", &PyOpAttributeMap::dunderDelItem);
2703 nb::set_leak_warnings(
false);
2707 nb::enum_<MlirDiagnosticSeverity>(m,
"DiagnosticSeverity")
2713 nb::enum_<MlirWalkOrder>(m,
"WalkOrder")
2717 nb::enum_<MlirWalkResult>(m,
"WalkResult")
2725 nb::class_<PyDiagnostic>(m,
"Diagnostic")
2726 .def_prop_ro(
"severity", &PyDiagnostic::getSeverity)
2727 .def_prop_ro(
"location", &PyDiagnostic::getLocation)
2728 .def_prop_ro(
"message", &PyDiagnostic::getMessage)
2729 .def_prop_ro(
"notes", &PyDiagnostic::getNotes)
2731 if (!
self.isValid())
2732 return nb::str(
"<Invalid Diagnostic>");
2733 return self.getMessage();
2736 nb::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo")
2741 .def_ro(
"severity", &PyDiagnostic::DiagnosticInfo::severity)
2742 .def_ro(
"location", &PyDiagnostic::DiagnosticInfo::location)
2743 .def_ro(
"message", &PyDiagnostic::DiagnosticInfo::message)
2744 .def_ro(
"notes", &PyDiagnostic::DiagnosticInfo::notes)
2748 nb::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler")
2749 .def(
"detach", &PyDiagnosticHandler::detach)
2750 .def_prop_ro(
"attached", &PyDiagnosticHandler::isAttached)
2751 .def_prop_ro(
"had_error", &PyDiagnosticHandler::getHadError)
2752 .def(
"__enter__", &PyDiagnosticHandler::contextEnter)
2753 .def(
"__exit__", &PyDiagnosticHandler::contextExit,
2754 nb::arg(
"exc_type").none(), nb::arg(
"exc_value").none(),
2755 nb::arg(
"traceback").none());
2765 nb::class_<PyThreadPool>(m,
"ThreadPool")
2767 .def(
"get_max_concurrency", &PyThreadPool::getMaxConcurrency)
2768 .def(
"_mlir_thread_pool_ptr", &PyThreadPool::_mlir_thread_pool_ptr);
2770 nb::class_<PyMlirContext>(m,
"_BaseContext")
2776 .def_static(
"_get_live_count", &PyMlirContext::getLiveCount)
2777 .def(
"_get_context_again",
2782 .def(
"_get_live_operation_count", &PyMlirContext::getLiveOperationCount)
2783 .def(
"_get_live_operation_objects",
2784 &PyMlirContext::getLiveOperationObjects)
2785 .def(
"_clear_live_operations", &PyMlirContext::clearLiveOperations)
2786 .def(
"_clear_live_operations_inside",
2787 nb::overload_cast<MlirOperation>(
2788 &PyMlirContext::clearOperationsInside))
2789 .def(
"_get_live_module_count", &PyMlirContext::getLiveModuleCount)
2792 .def(
"__enter__", &PyMlirContext::contextEnter)
2793 .def(
"__exit__", &PyMlirContext::contextExit, nb::arg(
"exc_type").none(),
2794 nb::arg(
"exc_value").none(), nb::arg(
"traceback").none())
2795 .def_prop_ro_static(
2801 return nb::cast(context);
2803 "Gets the Context bound to the current thread or raises ValueError")
2807 "Gets a container for accessing dialects by name")
2810 "Alias for 'dialect'")
2812 "get_dialect_descriptor",
2815 self.
get(), {name.data(), name.size()});
2817 throw nb::value_error(
2818 (Twine(
"Dialect '") + name +
"' not found").str().c_str());
2822 nb::arg(
"dialect_name"),
2823 "Gets or loads a dialect by name, returning its descriptor object")
2825 "allow_unregistered_dialects",
2832 .def(
"attach_diagnostic_handler", &PyMlirContext::attachDiagnosticHandler,
2833 nb::arg(
"callback"),
2834 "Attaches a diagnostic handler that will receive callbacks")
2836 "enable_multithreading",
2841 .def(
"set_thread_pool",
2849 .def(
"get_num_threads",
2853 .def(
"_mlir_thread_pool_ptr",
2856 std::stringstream ss;
2861 "is_registered_operation",
2866 nb::arg(
"operation_name"))
2868 "append_dialect_registry",
2872 nb::arg(
"registry"))
2873 .def_prop_rw(
"emit_error_diagnostics",
nullptr,
2874 &PyMlirContext::setEmitErrorDiagnostics,
2875 "Emit error diagnostics to diagnostic handlers. By default "
2876 "error diagnostics are captured and reported through "
2877 "MLIRError exceptions.")
2878 .def(
"load_all_available_dialects", [](
PyMlirContext &
self) {
2885 nb::class_<PyDialectDescriptor>(m,
"DialectDescriptor")
2886 .def_prop_ro(
"namespace",
2893 std::string repr(
"<DialectDescriptor ");
2902 nb::class_<PyDialects>(m,
"Dialects")
2905 MlirDialect dialect =
2906 self.getDialectForKey(keyName,
false);
2907 nb::object descriptor =
2911 .def(
"__getattr__", [=](
PyDialects &
self, std::string attrName) {
2912 MlirDialect dialect =
2913 self.getDialectForKey(attrName,
true);
2914 nb::object descriptor =
2922 nb::class_<PyDialect>(m,
"Dialect")
2923 .def(nb::init<nb::object>(), nb::arg(
"descriptor"))
2924 .def_prop_ro(
"descriptor",
2925 [](
PyDialect &
self) {
return self.getDescriptor(); })
2926 .def(
"__repr__", [](nb::object
self) {
2927 auto clazz =
self.attr(
"__class__");
2928 return nb::str(
"<Dialect ") +
2929 self.attr(
"descriptor").attr(
"namespace") + nb::str(
" (class ") +
2930 clazz.attr(
"__module__") + nb::str(
".") +
2931 clazz.attr(
"__name__") + nb::str(
")>");
2937 nb::class_<PyDialectRegistry>(m,
"DialectRegistry")
2945 nb::class_<PyLocation>(m,
"Location")
2948 .def(
"__enter__", &PyLocation::contextEnter)
2949 .def(
"__exit__", &PyLocation::contextExit, nb::arg(
"exc_type").none(),
2950 nb::arg(
"exc_value").none(), nb::arg(
"traceback").none())
2955 .def(
"__eq__", [](
PyLocation &
self, nb::object other) {
return false; })
2956 .def_prop_ro_static(
2959 auto *loc = PyThreadContextEntry::getDefaultLocation();
2961 throw nb::value_error(
"No current Location");
2964 "Gets the Location bound to the current thread or raises ValueError")
2971 nb::arg(
"context").none() = nb::none(),
2972 "Gets a Location representing an unknown location")
2975 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
2978 throw nb::value_error(
"No caller frames provided");
2979 MlirLocation caller = frames.back().get();
2986 nb::arg(
"callee"), nb::arg(
"frames"),
2987 nb::arg(
"context").none() = nb::none(),
2994 [](std::string filename,
int line,
int col,
3001 nb::arg(
"filename"), nb::arg(
"line"), nb::arg(
"col"),
3002 nb::arg(
"context").none() = nb::none(),
3006 [](std::string filename,
int startLine,
int startCol,
int endLine,
3011 startLine, startCol, endLine, endCol));
3013 nb::arg(
"filename"), nb::arg(
"start_line"), nb::arg(
"start_col"),
3014 nb::arg(
"end_line"), nb::arg(
"end_col"),
3017 .def_prop_ro(
"filename",
3018 [](MlirLocation loc) {
3028 [](
const std::vector<PyLocation> &pyLocations,
3029 std::optional<PyAttribute> metadata,
3032 locations.reserve(pyLocations.size());
3033 for (
auto &pyLocation : pyLocations)
3034 locations.push_back(pyLocation.get());
3036 context->
get(), locations.size(), locations.data(),
3037 metadata ? metadata->get() : MlirAttribute{0});
3038 return PyLocation(context->getRef(), location);
3040 nb::arg(
"locations"), nb::arg(
"metadata").none() = nb::none(),
3041 nb::arg(
"context").none() = nb::none(),
3044 .def_prop_ro(
"locations",
3045 [](MlirLocation loc) {
3046 unsigned numLocations =
3048 std::vector<MlirLocation> locations(numLocations);
3055 [](std::string name, std::optional<PyLocation> childLoc,
3061 childLoc ? childLoc->get()
3064 nb::arg(
"name"), nb::arg(
"childLoc").none() = nb::none(),
3065 nb::arg(
"context").none() = nb::none(),
3068 .def_prop_ro(
"name_str",
3069 [](MlirLocation loc) {
3079 nb::arg(
"attribute"), nb::arg(
"context").none() = nb::none(),
3080 "Gets a Location from a LocationAttr")
3083 [](
PyLocation &
self) {
return self.getContext().getObject(); },
3084 "Context that owns the Location")
3088 "Get the underlying LocationAttr")
3094 nb::arg(
"message"),
"Emits an error at this location")
3099 return printAccum.
join();
3105 nb::class_<PyModule>(m,
"Module", nb::is_weak_referenceable())
3115 throw MLIRError(
"Unable to parse module assembly", errors.take());
3116 return PyModule::forModule(module).releaseObject();
3118 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
3127 throw MLIRError(
"Unable to parse module assembly", errors.take());
3128 return PyModule::forModule(module).releaseObject();
3130 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
3139 throw MLIRError(
"Unable to parse module assembly", errors.take());
3140 return PyModule::forModule(module).releaseObject();
3142 nb::arg(
"path"), nb::arg(
"context").none() = nb::none(),
3148 return PyModule::forModule(module).releaseObject();
3150 nb::arg(
"loc").none() = nb::none(),
"Creates an empty module")
3153 [](
PyModule &
self) {
return self.getContext().getObject(); },
3154 "Context that created the Module")
3158 return PyOperation::forOperation(
self.
getContext(),
3160 self.getRef().releaseObject())
3163 "Accesses the module as an operation")
3169 self.getRef().releaseObject());
3173 "Return the block for this module")
3182 [](nb::object
self) {
3184 return self.attr(
"operation").attr(
"__str__")();
3191 nb::class_<PyOperationBase>(m,
"_OperationBase")
3194 return self.getOperation().getCapsule();
3206 .def_prop_ro(
"attributes",
3208 return PyOpAttributeMap(
self.getOperation().getRef());
3217 "Context that owns the Operation")
3218 .def_prop_ro(
"name",
3222 MlirOperation operation = concreteOperation.
get();
3225 .def_prop_ro(
"operands",
3227 return PyOpOperandList(
self.getOperation().getRef());
3229 .def_prop_ro(
"regions",
3231 return PyRegionList(
self.getOperation().getRef());
3238 "Returns the list of Operation results.")
3242 auto &operation =
self.getOperation();
3246 "Shortcut to get an op result if it has only one (throws an error "
3255 "Returns the source location the operation was defined or derived "
3257 .def_prop_ro(
"parent",
3259 auto parent =
self.getOperation().getParentOperation();
3261 return parent->getObject();
3267 return self.getAsm(
false,
3277 "Returns the assembly form of the operation.")
3279 nb::overload_cast<PyAsmState &, nb::object, bool>(
3281 nb::arg(
"state"), nb::arg(
"file").none() = nb::none(),
3284 nb::overload_cast<std::optional<int64_t>,
bool,
bool,
bool,
bool,
3285 bool,
bool, nb::object,
bool,
bool>(
3288 nb::arg(
"large_elements_limit").none() = nb::none(),
3289 nb::arg(
"enable_debug_info") =
false,
3290 nb::arg(
"pretty_debug_info") =
false,
3291 nb::arg(
"print_generic_op_form") =
false,
3292 nb::arg(
"use_local_scope") =
false,
3293 nb::arg(
"use_name_loc_as_prefix") =
false,
3294 nb::arg(
"assume_verified") =
false,
3295 nb::arg(
"file").none() = nb::none(), nb::arg(
"binary") =
false,
3297 .def(
"write_bytecode", &PyOperationBase::writeBytecode, nb::arg(
"file"),
3298 nb::arg(
"desired_version").none() = nb::none(),
3300 .def(
"get_asm", &PyOperationBase::getAsm,
3302 nb::arg(
"binary") =
false,
3303 nb::arg(
"large_elements_limit").none() = nb::none(),
3304 nb::arg(
"enable_debug_info") =
false,
3305 nb::arg(
"pretty_debug_info") =
false,
3306 nb::arg(
"print_generic_op_form") =
false,
3307 nb::arg(
"use_local_scope") =
false,
3308 nb::arg(
"use_name_loc_as_prefix") =
false,
3309 nb::arg(
"assume_verified") =
false, nb::arg(
"skip_regions") =
false,
3312 "Verify the operation. Raises MLIRError if verification fails, and "
3313 "returns true otherwise.")
3314 .def(
"move_after", &PyOperationBase::moveAfter, nb::arg(
"other"),
3315 "Puts self immediately after the other operation in its parent "
3317 .def(
"move_before", &PyOperationBase::moveBefore, nb::arg(
"other"),
3318 "Puts self immediately before the other operation in its parent "
3323 return self.getOperation().clone(ip);
3325 nb::arg(
"ip").none() = nb::none())
3327 "detach_from_parent",
3332 throw nb::value_error(
"Detached operation has no parent.");
3337 "Detaches the operation from its parent block.")
3338 .def(
"erase", [](
PyOperationBase &
self) {
self.getOperation().erase(); })
3342 nb::class_<PyOperation, PyOperationBase>(m,
"Operation")
3345 [](std::string_view name,
3346 std::optional<std::vector<PyType *>> results,
3347 std::optional<std::vector<PyValue *>> operands,
3348 std::optional<nb::dict> attributes,
3349 std::optional<std::vector<PyBlock *>> successors,
int regions,
3355 mlirOperands.reserve(operands->size());
3356 for (
PyValue *operand : *operands) {
3358 throw nb::value_error(
"operand value cannot be None");
3359 mlirOperands.push_back(operand->get());
3363 return PyOperation::create(name, results, mlirOperands, attributes,
3364 successors, regions, location, maybeIp,
3367 nb::arg(
"name"), nb::arg(
"results").none() = nb::none(),
3368 nb::arg(
"operands").none() = nb::none(),
3369 nb::arg(
"attributes").none() = nb::none(),
3370 nb::arg(
"successors").none() = nb::none(), nb::arg(
"regions") = 0,
3371 nb::arg(
"loc").none() = nb::none(), nb::arg(
"ip").none() = nb::none(),
3375 [](
const std::string &sourceStr,
const std::string &sourceName,
3380 nb::arg(
"source"), nb::kw_only(), nb::arg(
"source_name") =
"",
3381 nb::arg(
"context").none() = nb::none(),
3382 "Parses an operation. Supports both text assembly format and binary "
3386 .def_prop_ro(
"operation", [](nb::object
self) {
return self; })
3387 .def_prop_ro(
"opview", &PyOperation::createOpView)
3391 return PyOpSuccessors(
self.getOperation().getRef());
3393 "Returns the list of Operation successors.");
3396 nb::class_<PyOpView, PyOperationBase>(m,
"OpView")
3397 .def(nb::init<nb::object>(), nb::arg(
"operation"))
3400 [](
PyOpView *
self, std::string_view name,
3401 std::tuple<int, bool> opRegionSpec,
3402 nb::object operandSegmentSpecObj,
3403 nb::object resultSegmentSpecObj,
3404 std::optional<nb::list> resultTypeList, nb::list operandList,
3405 std::optional<nb::dict> attributes,
3406 std::optional<std::vector<PyBlock *>> successors,
3408 const nb::object &maybeIp) {
3409 new (
self)
PyOpView(PyOpView::buildGeneric(
3410 name, opRegionSpec, operandSegmentSpecObj,
3411 resultSegmentSpecObj, resultTypeList, operandList,
3412 attributes, successors, regions, location, maybeIp));
3414 nb::arg(
"name"), nb::arg(
"opRegionSpec"),
3415 nb::arg(
"operandSegmentSpecObj").none() = nb::none(),
3416 nb::arg(
"resultSegmentSpecObj").none() = nb::none(),
3417 nb::arg(
"results").none() = nb::none(),
3418 nb::arg(
"operands").none() = nb::none(),
3419 nb::arg(
"attributes").none() = nb::none(),
3420 nb::arg(
"successors").none() = nb::none(),
3421 nb::arg(
"regions").none() = nb::none(),
3422 nb::arg(
"loc").none() = nb::none(),
3423 nb::arg(
"ip").none() = nb::none())
3425 .def_prop_ro(
"operation", &PyOpView::getOperationObject)
3426 .def_prop_ro(
"opview", [](nb::object
self) {
return self; })
3429 [](
PyOpView &
self) {
return nb::str(
self.getOperationObject()); })
3433 return PyOpSuccessors(
self.getOperation().getRef());
3435 "Returns the list of Operation successors.");
3436 opViewClass.attr(
"_ODS_REGIONS") = nb::make_tuple(0,
true);
3437 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = nb::none();
3438 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = nb::none();
3443 [](nb::handle cls, std::optional<nb::list> resultTypeList,
3444 nb::list operandList, std::optional<nb::dict> attributes,
3445 std::optional<std::vector<PyBlock *>> successors,
3447 const nb::object &maybeIp) {
3448 std::string name = nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
3449 std::tuple<int, bool> opRegionSpec =
3450 nb::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
3451 nb::object operandSegmentSpec = cls.attr(
"_ODS_OPERAND_SEGMENTS");
3452 nb::object resultSegmentSpec = cls.attr(
"_ODS_RESULT_SEGMENTS");
3453 return PyOpView::buildGeneric(name, opRegionSpec, operandSegmentSpec,
3454 resultSegmentSpec, resultTypeList,
3455 operandList, attributes, successors,
3456 regions, location, maybeIp);
3458 nb::arg(
"cls"), nb::arg(
"results").none() = nb::none(),
3459 nb::arg(
"operands").none() = nb::none(),
3460 nb::arg(
"attributes").none() = nb::none(),
3461 nb::arg(
"successors").none() = nb::none(),
3462 nb::arg(
"regions").none() = nb::none(),
3463 nb::arg(
"loc").none() = nb::none(), nb::arg(
"ip").none() = nb::none(),
3464 "Builds a specific, generated OpView based on class level attributes.");
3466 [](
const nb::object &cls,
const std::string &sourceStr,
3476 std::string clsOpName =
3477 nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
3480 std::string_view parsedOpName(identifier.
data, identifier.
length);
3481 if (clsOpName != parsedOpName)
3482 throw MLIRError(Twine(
"Expected a '") + clsOpName +
"' op, got: '" +
3483 parsedOpName +
"'");
3484 return PyOpView::constructDerived(cls, parsed.
getObject());
3486 nb::arg(
"cls"), nb::arg(
"source"), nb::kw_only(),
3487 nb::arg(
"source_name") =
"", nb::arg(
"context").none() = nb::none(),
3488 "Parses a specific, generated OpView based on class level attributes");
3493 nb::class_<PyRegion>(m,
"Region")
3497 return PyBlockList(
self.getParentOperation(),
self.
get());
3499 "Returns a forward-optimized sequence of blocks.")
3503 return self.getParentOperation()->createOpView();
3505 "Returns the operation owning this region.")
3511 return PyBlockIterator(
self.getParentOperation(), firstBlock);
3513 "Iterates over blocks in the region.")
3516 return self.get().ptr == other.
get().ptr;
3518 .def(
"__eq__", [](
PyRegion &
self, nb::object &other) {
return false; });
3523 nb::class_<PyBlock>(m,
"Block")
3528 return self.getParentOperation()->createOpView();
3530 "Returns the owning operation of this block.")
3535 return PyRegion(
self.getParentOperation(), region);
3537 "Returns the owning region of this block.")
3541 return PyBlockArgumentList(
self.getParentOperation(),
self.
get());
3543 "Returns a list of block arguments.")
3549 "Append an argument of the specified type to the block and returns "
3550 "the newly added argument.")
3553 [](
PyBlock &
self,
unsigned index) {
3556 "Erase the argument at 'index' and remove it from the argument list.")
3560 return PyOperationList(
self.getParentOperation(),
self.
get());
3562 "Returns a forward-optimized sequence of operations.")
3565 [](
PyRegion &parent,
const nb::sequence &pyArgTypes,
3566 const std::optional<nb::sequence> &pyArgLocs) {
3568 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3572 nb::arg(
"parent"), nb::arg(
"arg_types") = nb::list(),
3573 nb::arg(
"arg_locs") = std::nullopt,
3574 "Creates and returns a new Block at the beginning of the given "
3575 "region (with given argument types and locations).")
3579 MlirBlock b =
self.get();
3584 "Append this block to a region, transferring ownership if necessary")
3587 [](
PyBlock &
self,
const nb::args &pyArgTypes,
3588 const std::optional<nb::sequence> &pyArgLocs) {
3591 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
3594 return PyBlock(
self.getParentOperation(), block);
3596 nb::arg(
"arg_types"), nb::kw_only(),
3597 nb::arg(
"arg_locs") = std::nullopt,
3598 "Creates and returns a new Block before this block "
3599 "(with given argument types and locations).")
3602 [](
PyBlock &
self,
const nb::args &pyArgTypes,
3603 const std::optional<nb::sequence> &pyArgLocs) {
3606 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
3609 return PyBlock(
self.getParentOperation(), block);
3611 nb::arg(
"arg_types"), nb::kw_only(),
3612 nb::arg(
"arg_locs") = std::nullopt,
3613 "Creates and returns a new Block after this block "
3614 "(with given argument types and locations).")
3619 MlirOperation firstOperation =
3621 return PyOperationIterator(
self.getParentOperation(),
3624 "Iterates over operations in the block.")
3627 return self.get().ptr == other.
get().ptr;
3629 .def(
"__eq__", [](
PyBlock &
self, nb::object &other) {
return false; })
3641 return printAccum.
join();
3643 "Returns the assembly form of the block.")
3653 self.getParentOperation().getObject());
3655 nb::arg(
"operation"),
3656 "Appends an operation to this block. If the operation is currently "
3657 "in another block, it will be moved.");
3663 nb::class_<PyInsertionPoint>(m,
"InsertionPoint")
3664 .def(nb::init<PyBlock &>(), nb::arg(
"block"),
3665 "Inserts after the last operation but still inside the block.")
3666 .def(
"__enter__", &PyInsertionPoint::contextEnter)
3667 .def(
"__exit__", &PyInsertionPoint::contextExit,
3668 nb::arg(
"exc_type").none(), nb::arg(
"exc_value").none(),
3669 nb::arg(
"traceback").none())
3670 .def_prop_ro_static(
3673 auto *ip = PyThreadContextEntry::getDefaultInsertionPoint();
3675 throw nb::value_error(
"No current InsertionPoint");
3678 "Gets the InsertionPoint bound to the current thread or raises "
3679 "ValueError if none has been set")
3680 .def(nb::init<PyOperationBase &>(), nb::arg(
"beforeOperation"),
3681 "Inserts before a referenced operation.")
3682 .def_static(
"at_block_begin", &PyInsertionPoint::atBlockBegin,
3683 nb::arg(
"block"),
"Inserts at the beginning of the block.")
3684 .def_static(
"at_block_terminator", &PyInsertionPoint::atBlockTerminator,
3685 nb::arg(
"block"),
"Inserts before the block terminator.")
3686 .def(
"insert", &PyInsertionPoint::insert, nb::arg(
"operation"),
3687 "Inserts an operation.")
3690 "Returns the block that this InsertionPoint points to.")
3694 auto refOperation =
self.getRefOperation();
3696 return refOperation->getObject();
3699 "The reference operation before which new operations are "
3700 "inserted, or None if the insertion point is at the end of "
3706 nb::class_<PyAttribute>(m,
"Attribute")
3709 .def(nb::init<PyAttribute &>(), nb::arg(
"cast_from_type"),
3710 "Casts the passed attribute to the generic Attribute")
3720 throw MLIRError(
"Unable to parse attribute", errors.take());
3723 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
3724 "Parses an attribute from an assembly form. Raises an MLIRError on "
3728 [](
PyAttribute &
self) {
return self.getContext().getObject(); },
3729 "Context that owns the Attribute")
3730 .def_prop_ro(
"type",
3737 nb::keep_alive<0, 1>(),
"Binds a name to the attribute")
3740 .def(
"__eq__", [](
PyAttribute &
self, nb::object &other) {
return false; })
3754 return printAccum.
join();
3756 "Returns the assembly form of the Attribute.")
3765 printAccum.
parts.append(
"Attribute(");
3768 printAccum.
parts.append(
")");
3769 return printAccum.
join();
3771 .def_prop_ro(
"typeid",
3775 "mlirTypeID was expected to be non-null.");
3781 "mlirTypeID was expected to be non-null.");
3782 std::optional<nb::callable> typeCaster =
3786 return nb::cast(
self);
3787 return typeCaster.value()(
self);
3793 nb::class_<PyNamedAttribute>(m,
"NamedAttribute")
3797 printAccum.
parts.append(
"NamedAttribute(");
3798 printAccum.
parts.append(
3801 printAccum.
parts.append(
"=");
3805 printAccum.
parts.append(
")");
3806 return printAccum.
join();
3813 "The name of the NamedAttribute binding")
3817 nb::keep_alive<0, 1>(),
3818 "The underlying generic attribute of the NamedAttribute binding");
3823 nb::class_<PyType>(m,
"Type")
3826 .def(nb::init<PyType &>(), nb::arg(
"cast_from_type"),
3827 "Casts the passed type to the generic Type")
3837 throw MLIRError(
"Unable to parse type", errors.take());
3840 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
3843 "context", [](
PyType &
self) {
return self.getContext().getObject(); },
3844 "Context that owns the Type")
3845 .def(
"__eq__", [](
PyType &
self,
PyType &other) {
return self == other; })
3847 "__eq__", [](
PyType &
self, nb::object &other) {
return false; },
3848 nb::arg(
"other").none())
3861 return printAccum.
join();
3863 "Returns the assembly form of the type.")
3871 printAccum.
parts.append(
"Type(");
3874 printAccum.
parts.append(
")");
3875 return printAccum.
join();
3881 "mlirTypeID was expected to be non-null.");
3882 std::optional<nb::callable> typeCaster =
3886 return nb::cast(
self);
3887 return typeCaster.value()(
self);
3889 .def_prop_ro(
"typeid", [](
PyType &
self) -> MlirTypeID {
3893 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(
self)));
3894 throw nb::value_error(
3895 (origRepr + llvm::Twine(
" has no typeid.")).str().c_str());
3901 nb::class_<PyTypeID>(m,
"TypeID")
3910 [](
PyTypeID &
self,
const nb::object &other) {
return false; })
3914 .def(
"__hash__", [](
PyTypeID &
self) {
3921 nb::class_<PyValue>(m,
"Value")
3922 .def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg(
"value"))
3928 "Context in which the value lives.")
3934 [](
PyValue &
self) -> nb::object {
3935 MlirValue v =
self.get();
3940 "expected the owner of the value in Python to match that in "
3942 return self.getParentOperation().getObject();
3947 return nb::cast(
PyBlock(
self.getParentOperation(), block));
3950 assert(
false &&
"Value must be a block argument or an op result");
3953 .def_prop_ro(
"uses",
3955 return PyOpOperandIterator(
3960 return self.get().ptr == other.
get().ptr;
3962 .def(
"__eq__", [](
PyValue &
self, nb::object other) {
return false; })
3971 printAccum.
parts.append(
"Value(");
3974 printAccum.
parts.append(
")");
3975 return printAccum.
join();
3980 [](
PyValue &
self,
bool useLocalScope,
bool useNameLocAsPrefix) {
3985 if (useNameLocAsPrefix)
3987 MlirAsmState valueState =
3994 return printAccum.
join();
3996 nb::arg(
"use_local_scope") =
false,
3997 nb::arg(
"use_name_loc_as_prefix") =
false)
4002 MlirAsmState valueState = state.get();
4006 return printAccum.
join();
4009 .def_prop_ro(
"type",
4018 "replace_all_uses_with",
4024 "replace_all_uses_except",
4025 [](MlirValue
self, MlirValue with,
PyOperation &exception) {
4026 MlirOperation exceptedUser = exception.
get();
4029 nb::arg(
"with"), nb::arg(
"exceptions"),
4032 "replace_all_uses_except",
4033 [](MlirValue
self, MlirValue with, nb::list exceptions) {
4036 for (nb::handle exception : exceptions) {
4037 exceptionOps.push_back(nb::cast<PyOperation &>(exception).
get());
4041 self, with,
static_cast<intptr_t
>(exceptionOps.size()),
4042 exceptionOps.data());
4044 nb::arg(
"with"), nb::arg(
"exceptions"),
4047 [](
PyValue &
self) {
return self.maybeDownCast(); })
4050 [](MlirValue
self) {
4055 "Returns the source location the value");
4057 PyBlockArgument::bind(m);
4058 PyOpResult::bind(m);
4059 PyOpOperand::bind(m);
4061 nb::class_<PyAsmState>(m,
"AsmState")
4062 .def(nb::init<PyValue &, bool>(), nb::arg(
"value"),
4063 nb::arg(
"use_local_scope") =
false)
4064 .def(nb::init<PyOperationBase &, bool>(), nb::arg(
"op"),
4065 nb::arg(
"use_local_scope") =
false);
4070 nb::class_<PySymbolTable>(m,
"SymbolTable")
4071 .def(nb::init<PyOperationBase &>())
4072 .def(
"__getitem__", &PySymbolTable::dunderGetItem)
4073 .def(
"insert", &PySymbolTable::insert, nb::arg(
"operation"))
4074 .def(
"erase", &PySymbolTable::erase, nb::arg(
"operation"))
4075 .def(
"__delitem__", &PySymbolTable::dunderDel)
4076 .def(
"__contains__",
4082 .def_static(
"set_symbol_name", &PySymbolTable::setSymbolName,
4083 nb::arg(
"symbol"), nb::arg(
"name"))
4084 .def_static(
"get_symbol_name", &PySymbolTable::getSymbolName,
4086 .def_static(
"get_visibility", &PySymbolTable::getVisibility,
4088 .def_static(
"set_visibility", &PySymbolTable::setVisibility,
4089 nb::arg(
"symbol"), nb::arg(
"visibility"))
4090 .def_static(
"replace_all_symbol_uses",
4091 &PySymbolTable::replaceAllSymbolUses, nb::arg(
"old_symbol"),
4092 nb::arg(
"new_symbol"), nb::arg(
"from_op"))
4093 .def_static(
"walk_symbol_tables", &PySymbolTable::walkSymbolTables,
4094 nb::arg(
"from_op"), nb::arg(
"all_sym_uses_visible"),
4095 nb::arg(
"callback"));
4098 PyBlockArgumentList::bind(m);
4099 PyBlockIterator::bind(m);
4100 PyBlockList::bind(m);
4101 PyOperationIterator::bind(m);
4102 PyOperationList::bind(m);
4103 PyOpAttributeMap::bind(m);
4104 PyOpOperandIterator::bind(m);
4105 PyOpOperandList::bind(m);
4107 PyOpSuccessors::bind(m);
4108 PyRegionIterator::bind(m);
4109 PyRegionList::bind(m);
4117 nb::register_exception_translator([](
const std::exception_ptr &p,
4123 std::rethrow_exception(p);
4127 PyErr_SetObject(PyExc_Exception, obj.ptr());
MLIR_CAPI_EXPORTED void mlirSetGlobalDebugType(const char *type)
Sets the current debug type, similarly to -debug-only=type in the command-line tools.
MLIR_CAPI_EXPORTED void mlirSetGlobalDebugTypes(const char **types, intptr_t n)
Sets multiple current debug types, similarly to `-debug-only=type1,type2" in the command-line tools.
MLIR_CAPI_EXPORTED bool mlirIsGlobalDebugEnabled()
Retuns true if the global debugging flag is set, false otherwise.
MLIR_CAPI_EXPORTED void mlirEnableGlobalDebug(bool enable)
Sets the global debugging flag.
static const char kOperationPrintStateDocstring[]
static const char kValueReplaceAllUsesWithDocstring[]
static const char kContextGetNameLocationDocString[]
static const char kGetNameAsOperand[]
static MlirStringRef toMlirStringRef(const std::string &s)
static const char kModuleParseDocstring[]
static const char kOperationStrDunderDocstring[]
static const char kOperationPrintDocstring[]
static MlirValue getUniqueResult(MlirOperation operation)
static const char kContextGetFileLocationDocstring[]
static const char kDumpDocstring[]
static const char kAppendBlockDocstring[]
static MlirValue getOpResultOrValue(nb::handle operand)
static const char kContextGetFusedLocationDocstring[]
static const char kContextGetFileRangeDocstring[]
static void maybeInsertOperation(PyOperationRef &op, const nb::object &maybeIp)
static nb::object createCustomDialectWrapper(const std::string &dialectNamespace, nb::object dialectDescriptor)
nb::object classmethod(Func f, Args... args)
Helper for creating an @classmethod.
static const char kOperationPrintBytecodeDocstring[]
static const char kOperationGetAsmDocstring[]
static MlirBlock createBlock(const nb::sequence &pyArgTypes, const std::optional< nb::sequence > &pyArgLocs)
Create a block, using the current location context if no locations are specified.
static const char kOperationCreateDocstring[]
static std::vector< MlirType > getValueTypes(Container &container, PyMlirContextRef &context)
Returns the list of types of the values held by container.
static const char kContextParseTypeDocstring[]
static void populateResultTypes(StringRef name, nb::list resultTypeList, const nb::object &resultSegmentSpecObj, std::vector< int32_t > &resultSegmentLengths, std::vector< PyType * > &resultTypes)
static const char kContextGetCallSiteLocationDocstring[]
static const char kValueDunderStrDocstring[]
static const char kValueReplaceAllUsesExceptDocstring[]
static MLIRContext * getContext(OpFoldResult val)
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
#define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR
Attribute on MLIR Python objects that expose a function for downcasting the corresponding Python obje...
static PyObject * mlirPythonTypeIDToCapsule(MlirTypeID typeID)
Creates a capsule object encapsulating the raw C-API MlirTypeID.
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule.
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
static MlirTypeID mlirPythonCapsuleToTypeID(PyObject *capsule)
Extracts an MlirTypeID from a capsule as produced from mlirPythonTypeIDToCapsule.
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
#define MAKE_MLIR_PYTHON_QUALNAME(local)
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
static PyObject * mlirPythonBlockToCapsule(MlirBlock block)
Creates a capsule object encapsulating the raw C-API MlirBlock.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
static PyObject * mlirPythonContextToCapsule(MlirContext context)
Creates a capsule object encapsulating the raw C-API MlirContext.
static LogicalResult nextIndex(ArrayRef< int64_t > shape, MutableArrayRef< int64_t > index)
Walks over the indices of the elements of a tensor of a given shape by updating index in place to the...
static std::string diag(const llvm::Value &value)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
static sycl::context getDefaultContext()
A list of operation results.
PyOperationRef & getOperation()
static void bindDerived(ClassTy &c)
PyOpResultList(PyOperationRef operation, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Python wrapper for MlirOpResult.
static void bindDerived(ClassTy &c)
Accumulates into a file, either writing text (default) or binary.
MlirStringCallback getCallback()
A CRTP base class for pseudo-containers willing to support Python-type slicing access on top of index...
static void bind(nanobind::module_ &m)
Binds the indexing and length methods in the Python class.
nanobind::class_< PyOpResultList > ClassTy
Base class for all objects that directly or indirectly depend on an MlirContext.
PyMlirContextRef & getContext()
Accesses the context reference.
Used in function arguments when None should resolve to the current context manager set instance.
static PyLocation & resolve()
Used in function arguments when None should resolve to the current context manager set instance.
static PyMlirContext & resolve()
ReferrentTy * get() const
Wrapper around an MlirAsmState.
Wrapper around the generic MlirAttribute.
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAttribute.
static PyAttribute createFromCapsule(nanobind::object capsule)
Creates a PyAttribute from the MlirAttribute wrapped by a capsule.
bool operator==(const PyAttribute &other) const
Wrapper around an MlirBlock.
PyOperationRef & getParentOperation()
Represents a diagnostic handler attached to the context.
PyDiagnosticHandler(MlirContext context, nanobind::object callback)
void detach()
Detaches the handler. Does nothing if not attached.
Python class mirroring the C MlirDiagnostic struct.
nanobind::tuple getNotes()
nanobind::str getMessage()
PyDiagnostic(MlirDiagnostic diagnostic)
MlirDiagnosticSeverity getSeverity()
Wrapper around an MlirDialect.
Wrapper around an MlirDialectRegistry.
nanobind::object getCapsule()
static PyDialectRegistry createFromCapsule(nanobind::object capsule)
User-level dialect object.
User-level object for accessing dialects with dotted syntax such as: ctx.dialect.std.
MlirDialect getDialectForKey(const std::string &key, bool attrError)
std::optional< nanobind::callable > lookupValueCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom value caster for MlirTypeID mlirTypeID.
std::optional< nanobind::object > lookupOperationClass(llvm::StringRef operationName)
Looks up a registered operation class (deriving from OpView) by operation name.
static PyGlobals & get()
Most code should get the globals via this static accessor.
An insertion point maintains a pointer to a Block and a reference operation.
static PyInsertionPoint atBlockTerminator(PyBlock &block)
Shortcut to create an insertion point before the block terminator.
PyInsertionPoint(PyBlock &block)
Creates an insertion point positioned after the last operation in the block, but still inside the blo...
static PyInsertionPoint atBlockBegin(PyBlock &block)
Shortcut to create an insertion point at the beginning of the block.
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
void insert(PyOperationBase &operationBase)
Inserts an operation.
static nanobind::object contextEnter(nanobind::object insertionPoint)
Enter and exit the context manager.
Wrapper around an MlirLocation.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirLocation.
PyLocation(PyMlirContextRef contextRef, MlirLocation loc)
static PyLocation createFromCapsule(nanobind::object capsule)
Creates a PyLocation from the MlirLocation wrapped by a capsule.
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
static nanobind::object contextEnter(nanobind::object location)
Enter and exit the context manager.
MlirContext get()
Accesses the underlying MlirContext.
PyMlirContextRef getRef()
Gets a strong reference to this context, which will ensure it is kept alive for the life of the refer...
void clearOperationsInside(PyOperationBase &op)
Clears all operations nested inside the given op using clearOperation(MlirOperation).
static size_t getLiveCount()
Gets the count of live context objects. Used for testing.
void clearOperationAndInside(PyOperationBase &op)
Clears the operaiton and all operations inside using clearOperation(MlirOperation).
size_t getLiveModuleCount()
Gets the count of live modules associated with this context.
nanobind::object attachDiagnosticHandler(nanobind::object callback)
Attaches a Python callback as a diagnostic handler, returning a registration object (internally a PyD...
size_t clearLiveOperations()
Clears the live operations map, returning the number of entries which were invalidated.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirContext.
std::vector< PyOperation * > getLiveOperationObjects()
Get a list of Python objects which are still in the live context map.
void contextExit(const nanobind::object &excType, const nanobind::object &excVal, const nanobind::object &excTb)
void clearOperation(MlirOperation op)
Removes an operation from the live operations map and sets it invalid.
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
static nanobind::object createFromCapsule(nanobind::object capsule)
Creates a PyMlirContext from the MlirContext wrapped by a capsule.
size_t getLiveOperationCount()
Gets the count of live operations associated with this context.
static nanobind::object contextEnter(nanobind::object context)
Enter and exit the context manager.
MlirModule get()
Gets the backing MlirModule.
static PyModuleRef forModule(MlirModule module)
Returns a PyModule reference for the given MlirModule.
static nanobind::object createFromCapsule(nanobind::object capsule)
Creates a PyModule from the MlirModule wrapped by a capsule.
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirModule.
PyModule(PyModule &)=delete
Represents a Python MlirNamedAttr, carrying an optional owned name.
PyNamedAttribute(MlirAttribute attr, std::string ownedName)
Constructs a PyNamedAttr that retains an owned name.
MlirNamedAttribute namedAttr
nanobind::object getObject()
nanobind::object releaseObject()
Releases the object held by this instance, returning it.
A PyOpView is equivalent to the C++ "Op" wrappers: these are the basis for providing more instance-sp...
static nanobind::object constructDerived(const nanobind::object &cls, const nanobind::object &operation)
Construct an instance of a class deriving from OpView, bypassing its __init__ method.
static nanobind::object buildGeneric(std::string_view name, std::tuple< int, bool > opRegionSpec, nanobind::object operandSegmentSpecObj, nanobind::object resultSegmentSpecObj, std::optional< nanobind::list > resultTypeList, nanobind::list operandList, std::optional< nanobind::dict > attributes, std::optional< std::vector< PyBlock * >> successors, std::optional< int > regions, DefaultingPyLocation location, const nanobind::object &maybeIp)
PyOpView(const nanobind::object &operationObject)
Base class for PyOperation and PyOpView which exposes the primary, user visible methods for manipulat...
void walk(std::function< MlirWalkResult(MlirOperation)> callback, MlirWalkOrder walkOrder)
virtual PyOperation & getOperation()=0
Each must provide access to the raw Operation.
void print(std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool useNameLocAsPrefix, bool assumeVerified, nanobind::object fileObject, bool binary, bool skipRegions)
Implements the bound 'print' method and helps with others.
nanobind::object getAsm(bool binary, std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool useNameLocAsPrefix, bool assumeVerified, bool skipRegions)
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
void writeBytecode(const nanobind::object &fileObject, std::optional< int64_t > bytecodeVersion)
void moveBefore(PyOperationBase &other)
bool verify()
Verify the operation.
void detachFromParent()
Detaches the operation from its parent block and updates its state accordingly.
PyOperation(PyMlirContextRef contextRef, MlirOperation operation)
void erase()
Erases the underlying MlirOperation, removes its pointer from the parent context's live operations ma...
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirOperation.
static PyOperationRef createDetached(PyMlirContextRef contextRef, MlirOperation operation, nanobind::object parentKeepAlive=nanobind::object())
Creates a detached operation.
nanobind::object clone(const nanobind::object &ip)
Clones this operation.
PyOperation & getOperation() override
Each must provide access to the raw Operation.
static nanobind::object createFromCapsule(nanobind::object capsule)
Creates a PyOperation from the MlirOperation wrapped by a capsule.
MlirOperation get() const
static PyOperationRef forOperation(PyMlirContextRef contextRef, MlirOperation operation, nanobind::object parentKeepAlive=nanobind::object())
Returns a PyOperation for the given MlirOperation, optionally associating it with a parentKeepAlive.
void setAttached(const nanobind::object &parent=nanobind::object())
std::optional< PyOperationRef > getParentOperation()
Gets the parent operation or raises an exception if the operation has no parent.
nanobind::object createOpView()
Creates an OpView suitable for this operation.
PyBlock getBlock()
Gets the owning block or raises an exception if the operation has no owning block.
static nanobind::object create(std::string_view name, std::optional< std::vector< PyType * >> results, llvm::ArrayRef< MlirValue > operands, std::optional< nanobind::dict > attributes, std::optional< std::vector< PyBlock * >> successors, int regions, DefaultingPyLocation location, const nanobind::object &ip, bool inferType)
Creates an operation. See corresponding python docstring.
static PyOperationRef parse(PyMlirContextRef contextRef, const std::string &sourceStr, const std::string &sourceName)
Parses a source string (either text assembly or bytecode), creating a detached operation.
void setInvalid()
Invalidate the operation.
Wrapper around an MlirRegion.
PyOperationRef & getParentOperation()
Bindings for MLIR symbol tables.
void dunderDel(const std::string &name)
Removes the operation with the given name from the symbol table and erases it, throws if there is no ...
static void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible, nanobind::object callback)
Walks all symbol tables under and including 'from'.
static void replaceAllSymbolUses(const std::string &oldSymbol, const std::string &newSymbol, PyOperationBase &from)
Replaces all symbol uses within an operation.
static void setVisibility(PyOperationBase &symbol, const std::string &visibility)
static void setSymbolName(PyOperationBase &symbol, const std::string &name)
MlirAttribute insert(PyOperationBase &symbol)
Inserts the given operation into the symbol table.
void erase(PyOperationBase &symbol)
Removes the given operation from the symbol table and erases it.
PySymbolTable(PyOperationBase &operation)
Constructs a symbol table for the given operation.
static MlirAttribute getSymbolName(PyOperationBase &symbol)
Gets and sets the name of a symbol op.
nanobind::object dunderGetItem(const std::string &name)
Returns the symbol (opview) with the given name, throws if there is no such symbol in the table.
static MlirAttribute getVisibility(PyOperationBase &symbol)
Gets and sets the visibility of a symbol op.
Tracks an entry in the thread context stack.
static PyThreadContextEntry * getTopOfStack()
Stack management.
static void popLocation(PyLocation &location)
static nanobind::object pushLocation(nanobind::object location)
PyLocation * getLocation()
static nanobind::object pushContext(nanobind::object context)
static PyLocation * getDefaultLocation()
Gets the top of stack location and returns nullptr if not defined.
static void popInsertionPoint(PyInsertionPoint &insertionPoint)
static nanobind::object pushInsertionPoint(nanobind::object insertionPoint)
static void popContext(PyMlirContext &context)
static PyInsertionPoint * getDefaultInsertionPoint()
Gets the top of stack insertion point and return nullptr if not defined.
PyMlirContext * getContext()
static PyMlirContext * getDefaultContext()
Gets the top of stack context and return nullptr if not defined.
static std::vector< PyThreadContextEntry > & getStack()
Gets the thread local stack.
PyInsertionPoint * getInsertionPoint()
Wrapper around MlirLlvmThreadPool Python object owns the C++ thread pool.
A TypeID provides an efficient and unique identifier for a specific C++ type.
static PyTypeID createFromCapsule(nanobind::object capsule)
Creates a PyTypeID from the MlirTypeID wrapped by a capsule.
bool operator==(const PyTypeID &other) const
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirTypeID.
PyTypeID(MlirTypeID typeID)
Wrapper around the generic MlirType.
PyType(PyMlirContextRef contextRef, MlirType type)
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirType.
static PyType createFromCapsule(nanobind::object capsule)
Creates a PyType from the MlirType wrapped by a capsule.
bool operator==(const PyType &other) const
Wrapper around the generic MlirValue.
PyValue(PyOperationRef parentOperation, MlirValue value)
static PyValue createFromCapsule(nanobind::object capsule)
Creates a PyValue from the MlirValue wrapped by a capsule.
nanobind::object maybeDownCast()
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirValue.
MLIR_CAPI_EXPORTED intptr_t mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic)
Returns the number of notes attached to the diagnostic.
MLIR_CAPI_EXPORTED MlirDiagnosticSeverity mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic)
Returns the severity of the diagnostic.
MLIR_CAPI_EXPORTED void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback, void *userData)
Prints a diagnostic using the provided callback.
MlirDiagnosticSeverity
Severity of a diagnostic.
MLIR_CAPI_EXPORTED MlirDiagnostic mlirDiagnosticGetNote(MlirDiagnostic diagnostic, intptr_t pos)
Returns pos-th note attached to the diagnostic.
MLIR_CAPI_EXPORTED void mlirEmitError(MlirLocation location, const char *message)
Emits an error at the given location through the diagnostics engine.
MLIR_CAPI_EXPORTED MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(MlirContext context, MlirDiagnosticHandler handler, void *userData, void(*deleteUserData)(void *))
Attaches the diagnostic handler to the context.
MLIR_CAPI_EXPORTED void mlirContextDetachDiagnosticHandler(MlirContext context, MlirDiagnosticHandlerID id)
Detaches an attached diagnostic handler from the context given its identifier.
uint64_t MlirDiagnosticHandlerID
Opaque identifier of a diagnostic handler, useful to detach a handler.
MLIR_CAPI_EXPORTED MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic)
Returns the location at which the diagnostic is reported.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI32ArrayGet(MlirContext ctx, intptr_t size, int32_t const *values)
MLIR_CAPI_EXPORTED MlirAttribute mlirStringAttrGet(MlirContext ctx, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
MLIR_CAPI_EXPORTED MlirAttribute mlirLocationGetAttribute(MlirLocation location)
Returns the underlying location attribute of this location.
MLIR_CAPI_EXPORTED intptr_t mlirBlockArgumentGetArgNumber(MlirValue value)
Returns the position of the value in the argument list of its block.
static bool mlirAttributeIsNull(MlirAttribute attr)
Checks whether an attribute is null.
MlirWalkResult(* MlirOperationWalkCallback)(MlirOperation, void *userData)
Operation walker type.
MLIR_CAPI_EXPORTED MlirLocation mlirValueGetLocation(MlirValue v)
Gets the location of the value.
MLIR_CAPI_EXPORTED unsigned mlirContextGetNumThreads(MlirContext context)
Gets the number of threads of the thread pool of the context when multithreading is enabled.
MLIR_CAPI_EXPORTED void mlirOperationWriteBytecode(MlirOperation op, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but writing the bytecode format.
MLIR_CAPI_EXPORTED MlirIdentifier mlirOperationGetName(MlirOperation op)
Gets the name of the operation as an identifier.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFileLineColGet(MlirContext context, MlirStringRef filename, unsigned line, unsigned col)
Creates an File/Line/Column location owned by the given context.
MLIR_CAPI_EXPORTED void mlirSymbolTableWalkSymbolTables(MlirOperation from, bool allSymUsesVisible, void(*callback)(MlirOperation, bool, void *userData), void *userData)
Walks all symbol table operations nested within, and including, op.
MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect)
Returns the namespace of the given dialect.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumResults(MlirOperation op)
Returns the number of results of the operation.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetEndColumn(MlirLocation location)
Getter for end_column of FileLineColRange.
MLIR_CAPI_EXPORTED MlirAttribute mlirSymbolTableInsert(MlirSymbolTable symbolTable, MlirOperation operation)
Inserts the given operation into the given symbol table.
MlirWalkOrder
Traversal order for operation walk.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsPrintNameLocAsPrefix(MlirOpPrintingFlags flags)
Print the name and location, if NamedLoc, as a prefix to the SSA ID.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos)
Return pos-th attribute of the operation.
MLIR_CAPI_EXPORTED void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n, MlirValue const *operands)
MLIR_CAPI_EXPORTED void mlirModuleDestroy(MlirModule module)
Takes a module owned by the caller and deletes it.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, MlirAttribute attr)
Associates an attribute with the name. Takes ownership of neither.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGetChildLoc(MlirLocation location)
Getter for childLoc of Name.
MLIR_CAPI_EXPORTED void mlirSymbolTableErase(MlirSymbolTable symbolTable, MlirOperation operation)
Removes the given operation from the symbol table and erases it.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags)
Use local scope when printing the operation.
MLIR_CAPI_EXPORTED bool mlirValueIsABlockArgument(MlirValue value)
Returns 1 if the value is a block argument, 0 otherwise.
MLIR_CAPI_EXPORTED void mlirContextAppendDialectRegistry(MlirContext ctx, MlirDialectRegistry registry)
Append the contents of the given dialect registry to the registry associated with the context.
MLIR_CAPI_EXPORTED MlirStringRef mlirIdentifierStr(MlirIdentifier ident)
Gets the string value of the identifier.
static bool mlirModuleIsNull(MlirModule module)
Checks whether a module is null.
MLIR_CAPI_EXPORTED MlirType mlirTypeParseGet(MlirContext context, MlirStringRef type)
Parses a type. The type is owned by the context.
MLIR_CAPI_EXPORTED MlirOpOperand mlirOpOperandGetNextUse(MlirOpOperand opOperand)
Returns an op operand representing the next use of the value, or a null op operand if there is no nex...
MLIR_CAPI_EXPORTED MlirType mlirAttributeGetType(MlirAttribute attribute)
Gets the type of this attribute.
MLIR_CAPI_EXPORTED void mlirContextSetAllowUnregisteredDialects(MlirContext context, bool allow)
Sets whether unregistered dialects are allowed in this context.
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockBefore(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it before the (non-owned) reference block in the given ...
MLIR_CAPI_EXPORTED bool mlirLocationIsAFileLineColRange(MlirLocation location)
Checks whether the given location is an FileLineColRange.
MLIR_CAPI_EXPORTED unsigned mlirLocationFusedGetNumLocations(MlirLocation location)
Getter for number of locations fused together.
MLIR_CAPI_EXPORTED void mlirValueReplaceAllUsesOfWith(MlirValue of, MlirValue with)
Replace all uses of 'of' value with the 'with' value, updating anything in the IR that uses 'of' to u...
MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos)
Returns pos-th successor of the operation.
MLIR_CAPI_EXPORTED void mlirValuePrintAsOperand(MlirValue value, MlirAsmState state, MlirStringCallback callback, void *userData)
Prints a value as an operand (i.e., the ValueID).
MLIR_CAPI_EXPORTED MlirLocation mlirLocationUnknownGet(MlirContext context)
Creates a location with unknown position owned by the given context.
MLIR_CAPI_EXPORTED void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, MlirAttribute attr)
Sets an attribute by name, replacing the existing if it exists or adding a new one otherwise.
MLIR_CAPI_EXPORTED MlirOperation mlirOpOperandGetOwner(MlirOpOperand opOperand)
Returns the owner operation of an op operand.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsElideLargeResourceString(MlirOpPrintingFlags flags, intptr_t largeResourceLimit)
Enables the elision of large resources strings by omitting them from the dialect_resources section.
MLIR_CAPI_EXPORTED MlirIdentifier mlirLocationFileLineColRangeGetFilename(MlirLocation location)
Getter for filename of FileLineColRange.
MLIR_CAPI_EXPORTED MlirDialect mlirAttributeGetDialect(MlirAttribute attribute)
Gets the dialect of the attribute.
MLIR_CAPI_EXPORTED void mlirLocationFusedGetLocations(MlirLocation location, MlirLocation *locationsCPtr)
Getter for locations of Fused.
MLIR_CAPI_EXPORTED void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, void *userData)
Prints an attribute by sending chunks of the string representation and forwarding userData tocallback...
MLIR_CAPI_EXPORTED MlirRegion mlirBlockGetParentRegion(MlirBlock block)
Returns the region that contains this block.
MLIR_CAPI_EXPORTED void mlirOperationMoveBefore(MlirOperation op, MlirOperation other)
Moves the given operation immediately before the other operation in its parent block.
static bool mlirValueIsNull(MlirValue value)
Returns whether the value is null.
MLIR_CAPI_EXPORTED void mlirValueReplaceAllUsesExcept(MlirValue of, MlirValue with, intptr_t numExceptions, MlirOperation *exceptions)
Replace all uses of 'of' value with 'with' value, updating anything in the IR that uses 'of' to use '...
MLIR_CAPI_EXPORTED void mlirOperationPrintWithState(MlirOperation op, MlirAsmState state, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but accepts AsmState controlling the printing behavior as well as caching ...
MlirWalkResult
Operation walk result.
@ MlirWalkResultInterrupt
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, MlirBlock block)
Takes a block owned by the caller and inserts it at pos to the given region.
MLIR_CAPI_EXPORTED MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, MlirStringRef name)
Returns an attribute attached to the operation given its name.
static bool mlirTypeIsNull(MlirType type)
Checks whether a type is null.
MLIR_CAPI_EXPORTED bool mlirContextIsRegisteredOperation(MlirContext context, MlirStringRef name)
Returns whether the given fully-qualified operation (i.e.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumSuccessors(MlirOperation op)
Returns the number of successor blocks of the operation.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationClone(MlirOperation op)
Creates a deep copy of an operation.
MLIR_CAPI_EXPORTED intptr_t mlirBlockGetNumArguments(MlirBlock block)
Returns the number of arguments of the block.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetStartLine(MlirLocation location)
Getter for start_line of FileLineColRange.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsPrintGenericOpForm(MlirOpPrintingFlags flags)
Always print operations in the generic form.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFusedGet(MlirContext ctx, intptr_t nLocations, MlirLocation const *locations, MlirAttribute metadata)
Creates a fused location with an array of locations and metadata.
MLIR_CAPI_EXPORTED void mlirBlockInsertOwnedOperationBefore(MlirBlock block, MlirOperation reference, MlirOperation operation)
Takes an operation owned by the caller and inserts it before the (non-owned) reference operation in t...
MLIR_CAPI_EXPORTED void mlirAsmStateDestroy(MlirAsmState state)
Destroys printing flags created with mlirAsmStateCreate.
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
MLIR_CAPI_EXPORTED MlirDialect mlirContextGetOrLoadDialect(MlirContext context, MlirStringRef name)
Gets the dialect instance owned by the given context using the dialect namespace to identify it,...
MLIR_CAPI_EXPORTED bool mlirLocationIsACallSite(MlirLocation location)
Checks whether the given location is an CallSite.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsElideLargeElementsAttrs(MlirOpPrintingFlags flags, intptr_t largeElementLimit)
Enables the elision of large elements attributes by printing a lexically valid but otherwise meaningl...
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it after the (non-owned) reference block in the given r...
MLIR_CAPI_EXPORTED void mlirBlockArgumentSetType(MlirValue value, MlirType type)
Sets the type of the block argument to the given type.
MLIR_CAPI_EXPORTED MlirContext mlirOperationGetContext(MlirOperation op)
Gets the context this operation is associated with.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args, MlirLocation const *locs)
Creates a new empty block with the given argument types and transfers ownership to the caller.
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
MLIR_CAPI_EXPORTED void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation)
Takes an operation owned by the caller and appends it to the block.
MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos)
Returns pos-th argument of the block.
MLIR_CAPI_EXPORTED MlirOperation mlirSymbolTableLookup(MlirSymbolTable symbolTable, MlirStringRef name)
Looks up a symbol with the given name in the given symbol table and returns the operation that corres...
MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type)
Gets the context that a type was created with.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFileLineColRangeGet(MlirContext context, MlirStringRef filename, unsigned start_line, unsigned start_col, unsigned end_line, unsigned end_col)
Creates an File/Line/Column range location owned by the given context.
MLIR_CAPI_EXPORTED void mlirValueDump(MlirValue value)
Prints the value to the standard error stream.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateEmpty(MlirLocation location)
Creates a new, empty module and transfers ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirOpOperandIsNull(MlirOpOperand opOperand)
Returns whether the op operand is null.
MLIR_CAPI_EXPORTED MlirSymbolTable mlirSymbolTableCreate(MlirOperation operation)
Creates a symbol table for the given operation.
MLIR_CAPI_EXPORTED bool mlirLocationEqual(MlirLocation l1, MlirLocation l2)
Checks if two locations are equal.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetStartColumn(MlirLocation location)
Getter for start_column of FileLineColRange.
MLIR_CAPI_EXPORTED bool mlirLocationIsAFused(MlirLocation location)
Checks whether the given location is an Fused.
MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetBlock(MlirOperation op)
Gets the block that owns this operation, returning null if the operation is not owned.
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
MLIR_CAPI_EXPORTED bool mlirOperationEqual(MlirOperation op, MlirOperation other)
Checks whether two operation handles point to the same operation.
MLIR_CAPI_EXPORTED MlirValue mlirBlockAddArgument(MlirBlock block, MlirType type, MlirLocation loc)
Appends an argument of the specified type to the block.
MLIR_CAPI_EXPORTED void mlirOperationPrintWithFlags(MlirOperation op, MlirOpPrintingFlags flags, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but accepts flags controlling the printing behavior.
MLIR_CAPI_EXPORTED MlirOpOperand mlirValueGetFirstUse(MlirValue value)
Returns an op operand representing the first use of the value, or a null op operand if there are no u...
MLIR_CAPI_EXPORTED void mlirLocationPrint(MlirLocation location, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirContextSetThreadPool(MlirContext context, MlirLlvmThreadPool threadPool)
Sets the thread pool of the context explicitly, enabling multithreading in the process.
MLIR_CAPI_EXPORTED bool mlirOperationVerify(MlirOperation op)
Verify the operation and return true if it passes, false if it fails.
MLIR_CAPI_EXPORTED MlirOperation mlirModuleGetOperation(MlirModule module)
Views the module as a generic operation.
MLIR_CAPI_EXPORTED bool mlirTypeEqual(MlirType t1, MlirType t2)
Checks if two types are equal.
MLIR_CAPI_EXPORTED MlirOperationState mlirOperationStateGet(MlirStringRef name, MlirLocation loc)
Constructs an operation state from a name and a location.
MLIR_CAPI_EXPORTED unsigned mlirOpOperandGetOperandNumber(MlirOpOperand opOperand)
Returns the operand number of an op operand.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGetCaller(MlirLocation location)
Getter for caller of CallSite.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetTerminator(MlirBlock block)
Returns the terminator operation in the block or null if no terminator.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsSkipRegions(MlirOpPrintingFlags flags)
Skip printing regions.
MLIR_CAPI_EXPORTED MlirIdentifier mlirLocationNameGetName(MlirLocation location)
Getter for name of Name.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationGetNextInBlock(MlirOperation op)
Returns an operation immediately following the given operation it its enclosing block.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationGetParentOperation(MlirOperation op)
Gets the operation that owns this operation, returning null if the operation is not owned.
MLIR_CAPI_EXPORTED MlirContext mlirModuleGetContext(MlirModule module)
Gets the context that a module was created with.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFromAttribute(MlirAttribute attribute)
Creates a location from a location attribute.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsAssumeVerified(MlirOpPrintingFlags flags)
Do not verify the operation when using custom operation printers.
MLIR_CAPI_EXPORTED MlirTypeID mlirTypeGetTypeID(MlirType type)
Gets the type ID of the type.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetVisibilityAttributeName(void)
Returns the name of the attribute used to store symbol visibility.
static bool mlirDialectIsNull(MlirDialect dialect)
Checks if the dialect is null.
MLIR_CAPI_EXPORTED void mlirBytecodeWriterConfigDestroy(MlirBytecodeWriterConfig config)
Destroys printing flags created with mlirBytecodeWriterConfigCreate.
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos)
Returns pos-th operand of the operation.
MLIR_CAPI_EXPORTED void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, MlirNamedAttribute const *attributes)
MLIR_CAPI_EXPORTED MlirBlock mlirBlockGetNextInRegion(MlirBlock block)
Returns the block immediately following the given block in its parent region.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller)
Creates a call site location with a callee and a caller.
MLIR_CAPI_EXPORTED bool mlirLocationIsAName(MlirLocation location)
Checks whether the given location is an Name.
MLIR_CAPI_EXPORTED MlirOperation mlirOpResultGetOwner(MlirValue value)
Returns an operation that produced this value as its result.
MLIR_CAPI_EXPORTED bool mlirValueIsAOpResult(MlirValue value)
Returns 1 if the value is an operation result, 0 otherwise.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumOperands(MlirOperation op)
Returns the number of operands of the operation.
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
MLIR_CAPI_EXPORTED void mlirOperationWalk(MlirOperation op, MlirOperationWalkCallback callback, void *userData, MlirWalkOrder walkOrder)
Walks operation op in walkOrder and calls callback on that operation.
MLIR_CAPI_EXPORTED MlirContext mlirContextCreateWithThreading(bool threadingEnabled)
Creates an MLIR context with an explicit setting of the multithreading setting and transfers its owne...
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetParentOperation(MlirBlock)
Returns the closest surrounding operation that contains this block.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumRegions(MlirOperation op)
Returns the number of regions attached to the given operation.
MLIR_CAPI_EXPORTED MlirContext mlirLocationGetContext(MlirLocation location)
Gets the context that a location was created with.
MLIR_CAPI_EXPORTED void mlirBlockEraseArgument(MlirBlock block, unsigned index)
Erase the argument at 'index' and remove it from the argument list.
MLIR_CAPI_EXPORTED bool mlirOperationRemoveAttributeByName(MlirOperation op, MlirStringRef name)
Removes an attribute by name.
MLIR_CAPI_EXPORTED void mlirAttributeDump(MlirAttribute attr)
Prints the attribute to the standard error stream.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirSymbolTableReplaceAllSymbolUses(MlirStringRef oldSymbol, MlirStringRef newSymbol, MlirOperation from)
Attempt to replace all uses that are nested within the given operation of the given symbol 'oldSymbol...
MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeParseGet(MlirContext context, MlirStringRef attr)
Parses an attribute. The attribute is owned by the context.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateParse(MlirContext context, MlirStringRef module)
Parses a module from the string and transfers ownership to the caller.
MLIR_CAPI_EXPORTED void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block)
Takes a block owned by the caller and appends it to the given region.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetFirstOperation(MlirBlock block)
Returns the first operation in the block.
MLIR_CAPI_EXPORTED void mlirTypeDump(MlirType type)
Prints the type to the standard error stream.
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos)
Returns pos-th result of the operation.
MLIR_CAPI_EXPORTED MlirBytecodeWriterConfig mlirBytecodeWriterConfigCreate(void)
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED MlirContext mlirAttributeGetContext(MlirAttribute attribute)
Gets the context that an attribute was created with.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockArgumentGetOwner(MlirValue value)
Returns the block in which this value is defined as an argument.
static bool mlirRegionIsNull(MlirRegion region)
Checks whether a region is null.
MLIR_CAPI_EXPORTED void mlirOperationDestroy(MlirOperation op)
Takes an operation owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos)
Returns pos-th region attached to the operation.
MLIR_CAPI_EXPORTED MlirDialect mlirTypeGetDialect(MlirType type)
Gets the dialect a type belongs to.
MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
MLIR_CAPI_EXPORTED void mlirOperationSetSuccessor(MlirOperation op, intptr_t pos, MlirBlock block)
Set pos-th successor of the operation.
MLIR_CAPI_EXPORTED void mlirContextLoadAllAvailableDialects(MlirContext context)
Eagerly loads all available dialects registered with a context, making them available for use for IR ...
MLIR_CAPI_EXPORTED void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, MlirRegion const *regions)
MLIR_CAPI_EXPORTED void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, MlirBlock const *successors)
MLIR_CAPI_EXPORTED MlirLlvmThreadPool mlirContextGetThreadPool(MlirContext context)
Gets the thread pool of the context when enabled multithreading, otherwise an assertion is raised.
MLIR_CAPI_EXPORTED MlirBlock mlirModuleGetBody(MlirModule module)
Gets the body of the module, i.e. the only block it contains.
MLIR_CAPI_EXPORTED int mlirLocationFileLineColRangeGetEndLine(MlirLocation location)
Getter for end_line of FileLineColRange.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags)
Destroys printing flags created with mlirOpPrintingFlagsCreate.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGet(MlirContext context, MlirStringRef name, MlirLocation childLoc)
Creates a name location owned by the given context.
MLIR_CAPI_EXPORTED void mlirContextEnableMultithreading(MlirContext context, bool enable)
Set threading mode (must be set to false to mlir-print-ir-after-all).
MLIR_CAPI_EXPORTED void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, void *userData)
Prints a block by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGetCallee(MlirLocation location)
Getter for callee of CallSite.
MLIR_CAPI_EXPORTED MlirContext mlirValueGetContext(MlirValue v)
Gets the context that a value was created with.
MLIR_CAPI_EXPORTED void mlirBytecodeWriterConfigDesiredEmitVersion(MlirBytecodeWriterConfig flags, int64_t version)
Sets the version to emit in the writer config.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetSymbolAttributeName(void)
Returns the name of the attribute used to store symbol names compatible with symbol tables.
MLIR_CAPI_EXPORTED MlirRegion mlirRegionCreate(void)
Creates a new empty region and transfers ownership to the caller.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateParseFromFile(MlirContext context, MlirStringRef fileName)
Parses a module from file and transfers ownership to the caller.
MLIR_CAPI_EXPORTED void mlirBlockDetach(MlirBlock block)
Detach a block from the owning region and assume ownership.
MLIR_CAPI_EXPORTED void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, MlirType const *results)
Adds a list of components to the operation state.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, bool enable, bool prettyForm)
Enable or disable printing of debug information (based on enable).
MLIR_CAPI_EXPORTED MlirLocation mlirOperationGetLocation(MlirOperation op)
Gets the location of the operation.
MLIR_CAPI_EXPORTED MlirTypeID mlirAttributeGetTypeID(MlirAttribute attribute)
Gets the type id of the attribute.
MLIR_CAPI_EXPORTED void mlirOperationSetOperand(MlirOperation op, intptr_t pos, MlirValue newValue)
Sets the pos-th operand of the operation.
MLIR_CAPI_EXPORTED void mlirOperationDump(MlirOperation op)
Prints an operation to stderr.
MLIR_CAPI_EXPORTED intptr_t mlirOpResultGetResultNumber(MlirValue value)
Returns the position of the value in the list of results of the operation that produced it.
MLIR_CAPI_EXPORTED MlirOpPrintingFlags mlirOpPrintingFlagsCreate(void)
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED MlirAsmState mlirAsmStateCreateForValue(MlirValue value, MlirOpPrintingFlags flags)
Creates new AsmState from value.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreate(MlirOperationState *state)
Creates an operation and transfers ownership to the caller.
static bool mlirSymbolTableIsNull(MlirSymbolTable symbolTable)
Returns true if the symbol table is null.
MLIR_CAPI_EXPORTED bool mlirContextGetAllowUnregisteredDialects(MlirContext context)
Returns whether the context allows unregistered dialects.
MLIR_CAPI_EXPORTED void mlirOperationMoveAfter(MlirOperation op, MlirOperation other)
Moves the given operation immediately after the other operation in its parent block.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumAttributes(MlirOperation op)
Returns the number of attributes attached to the operation.
MLIR_CAPI_EXPORTED void mlirValuePrint(MlirValue value, MlirStringCallback callback, void *userData)
Prints a value by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirOperationWriteBytecodeWithConfig(MlirOperation op, MlirBytecodeWriterConfig config, MlirStringCallback callback, void *userData)
Same as mlirOperationWriteBytecode but with writer config and returns failure only if desired bytecod...
MLIR_CAPI_EXPORTED void mlirValueSetType(MlirValue value, MlirType type)
Set the type of the value.
MLIR_CAPI_EXPORTED MlirType mlirValueGetType(MlirValue value)
Returns the type of the value.
MLIR_CAPI_EXPORTED void mlirContextDestroy(MlirContext context)
Takes an MLIR context owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreateParse(MlirContext context, MlirStringRef sourceStr, MlirStringRef sourceName)
Parses an operation, giving ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2)
Checks if two attributes are equal.
static bool mlirOperationIsNull(MlirOperation op)
Checks whether the underlying operation is null.
MLIR_CAPI_EXPORTED MlirBlock mlirRegionGetFirstBlock(MlirRegion region)
Gets the first block in the region.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
static MlirLogicalResult mlirLogicalResultFailure(void)
Creates a logical result representing a failure.
MLIR_CAPI_EXPORTED size_t mlirTypeIDHashValue(MlirTypeID typeID)
Returns the hash value of the type id.
static MlirLogicalResult mlirLogicalResultSuccess(void)
Creates a logical result representing a success.
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
static bool mlirTypeIDIsNull(MlirTypeID typeID)
Checks whether a type id is null.
MLIR_CAPI_EXPORTED bool mlirTypeIDEqual(MlirTypeID typeID1, MlirTypeID typeID2)
Checks if two type ids are equal.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
inline ::llvm::hash_code hash_value(const PolynomialBase< D, T > &arg)
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
PyObjectRef< PyModule > PyModuleRef
void populateIRCore(nanobind::module_ &m)
PyObjectRef< PyOperation > PyOperationRef
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
const FrozenRewritePatternSet GreedyRewriteConfig config
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
A logical result value, essentially a boolean with named states.
An auxiliary class for constructing operations.
A pointer to a sized fragment of a string, not necessarily null-terminated.
const char * data
Pointer to the first symbol.
size_t length
Length of the fragment.
static bool dunderContains(const std::string &attributeKind)
static void dunderSetItemNamed(const std::string &attributeKind, nb::callable func, bool replace)
static nb::callable dunderGetItemNamed(const std::string &attributeKind)
static void bind(nb::module_ &m)
Wrapper for the global LLVM debugging flag.
static void bind(nb::module_ &m)
static void set(nb::object &o, bool enable)
static bool get(const nb::object &)
Accumulates into a python string from a method that accepts an MlirStringCallback.
MlirStringCallback getCallback()
Custom exception that allows access to error diagnostic information.
std::vector< PyDiagnostic::DiagnosticInfo > errorDiagnostics
Materialized diagnostic information.
RAII object that captures any error diagnostics emitted to the provided context.
std::vector< PyDiagnostic::DiagnosticInfo > take()
ErrorCapture(PyMlirContextRef ctx)