23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/SmallVector.h"
27 using namespace nb::literals;
32 using llvm::StringRef;
40 R
"(Parses the assembly form of a type.
42 Returns a Type object or raises an MLIRError if the type cannot be parsed.
44 See also: https://mlir.llvm.org/docs/LangRef/#type-system
48 R
"(Gets a Location representing a caller and callsite)";
51 R
"(Gets a Location representing a file, line and column)";
54 R
"(Gets a Location representing a fused location with optional metadata)";
57 R
"(Gets a Location representing a named location with optional child location)";
60 R
"(Parses a module's assembly format from a string.
62 Returns a new MlirModule or raises an MLIRError if the parsing fails.
64 See also: https://mlir.llvm.org/docs/LangRef/
68 R
"(Creates a new operation.
71 name: Operation name (e.g. "dialect.operation").
72 results: Sequence of Type representing op result types.
73 attributes: Dict of str:Attribute.
74 successors: List of Block for the operation's successors.
75 regions: Number of regions to create.
76 location: A Location object (defaults to resolve from context manager).
77 ip: An InsertionPoint (defaults to resolve from context manager or set to
78 False to disable insertion, even with an insertion point set in the
80 infer_type: Whether to infer result types.
82 A new "detached" Operation object. Detached operations can be added
83 to blocks, which causes them to become "attached."
87 R
"(Prints the assembly form of the operation to a file like object.
90 file: The file like object to write to. Defaults to sys.stdout.
91 binary: Whether to write bytes (True) or str (False). Defaults to False.
92 large_elements_limit: Whether to elide elements attributes above this
93 number of elements. Defaults to None (no limit).
94 enable_debug_info: Whether to print debug/location information. Defaults
96 pretty_debug_info: Whether to format debug information for easier reading
97 by a human (warning: the result is unparseable).
98 print_generic_op_form: Whether to print the generic assembly forms of all
99 ops. Defaults to False.
100 use_local_Scope: Whether to print in a way that is more optimized for
101 multi-threaded access but may not be consistent with how the overall
103 assume_verified: By default, if not printing generic form, the verifier
104 will be run and if it fails, generic form will be printed with a comment
105 about failed verification. While a reasonable default for interactive use,
106 for systematic use, it is often better for the caller to verify explicitly
107 and report failures in a more robust fashion. Set this to True if doing this
108 in order to avoid running a redundant verification. If the IR is actually
109 invalid, behavior is undefined.
110 skip_regions: Whether to skip printing regions. Defaults to False.
114 R
"(Prints the assembly form of the operation to a file like object.
117 file: The file like object to write to. Defaults to sys.stdout.
118 binary: Whether to write bytes (True) or str (False). Defaults to False.
119 state: AsmState capturing the operation numbering and flags.
123 R
"(Gets the assembly form of the operation with all options available.
126 binary: Whether to return a bytes (True) or str (False) object. Defaults to
128 ... others ...: See the print() method for common keyword arguments for
129 configuring the printout.
131 Either a bytes or str object, depending on the setting of the 'binary'
136 R
"(Write the bytecode form of the operation to a file like object.
139 file: The file like object to write to.
140 desired_version: The version of bytecode to emit.
142 The bytecode writer status.
146 R
"(Gets the assembly form of the operation with default options.
148 If more advanced control over the assembly formatting or I/O options is needed,
149 use the dedicated print or get_asm method, which supports keyword arguments to
154 R
"(Dumps a debug representation of the object to stderr.)";
157 R
"(Appends a new block, with argument types as positional args.
164 R
"(Returns the string form of the value.
166 If the value is a block argument, this is the assembly form of its type and the
167 position in the argument list. If the value is an operation result, this is
168 equivalent to printing the operation that produced it.
172 R
"(Returns the string form of value as an operand (i.e., the ValueID).
176 R
"(Replace all uses of value with the new value, updating anything in
177 the IR that uses 'self' to use the other value instead.
181 R
"("Replace all uses of this value with the 'with' value, except for those
182 in 'exceptions'. 'exceptions' can be either a single operation or a list of
191 template <
class Func,
typename... Args>
193 nb::object cf = nb::cpp_function(f, args...);
194 return nb::borrow<nb::object>((PyClassMethod_New(cf.ptr())));
199 nb::object dialectDescriptor) {
200 auto dialectClass =
PyGlobals::get().lookupDialectClass(dialectNamespace);
203 return nb::cast(
PyDialect(std::move(dialectDescriptor)));
207 return (*dialectClass)(std::move(dialectDescriptor));
221 const std::optional<nb::sequence> &pyArgLocs) {
223 argTypes.reserve(nb::len(pyArgTypes));
224 for (
const auto &pyType : pyArgTypes)
225 argTypes.push_back(nb::cast<PyType &>(pyType));
229 argLocs.reserve(nb::len(*pyArgLocs));
230 for (
const auto &pyLoc : *pyArgLocs)
231 argLocs.push_back(nb::cast<PyLocation &>(pyLoc));
232 }
else if (!argTypes.empty()) {
233 argLocs.assign(argTypes.size(), DefaultingPyLocation::resolve());
236 if (argTypes.size() != argLocs.size())
237 throw nb::value_error((
"Expected " + Twine(argTypes.size()) +
238 " locations, got: " + Twine(argLocs.size()))
241 return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
250 static void bind(nb::module_ &m) {
252 nb::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug")
257 [](
const std::string &type) {
260 "types"_a,
"Sets specific debug types to be produced by LLVM")
261 .def_static(
"set_types", [](
const std::vector<std::string> &types) {
262 std::vector<const char *> pointers;
263 pointers.reserve(types.size());
264 for (
const std::string &str : types)
265 pointers.push_back(str.c_str());
273 return PyGlobals::get().lookupAttributeBuilder(attributeKind).has_value();
276 auto builder =
PyGlobals::get().lookupAttributeBuilder(attributeKind);
278 throw nb::key_error(attributeKind.c_str());
282 nb::callable func,
bool replace) {
283 PyGlobals::get().registerAttributeBuilder(attributeKind, std::move(func),
287 static void bind(nb::module_ &m) {
288 nb::class_<PyAttrBuilderMap>(m,
"AttrBuilder")
292 "attribute_kind"_a,
"attr_builder"_a,
"replace"_a =
false,
293 "Register an attribute builder for building MLIR "
294 "attributes from python values.");
302 nb::object PyBlock::getCapsule() {
312 class PyRegionIterator {
315 : operation(std::move(operation)) {}
317 PyRegionIterator &dunderIter() {
return *
this; }
322 throw nb::stop_iteration();
328 static void bind(nb::module_ &m) {
329 nb::class_<PyRegionIterator>(m,
"RegionIterator")
330 .def(
"__iter__", &PyRegionIterator::dunderIter)
331 .def(
"__next__", &PyRegionIterator::dunderNext);
343 PyRegionList(
PyOperationRef operation) : operation(std::move(operation)) {}
345 PyRegionIterator dunderIter() {
347 return PyRegionIterator(operation);
350 intptr_t dunderLen() {
351 operation->checkValid();
355 PyRegion dunderGetItem(intptr_t index) {
357 if (index < 0 || index >= dunderLen()) {
358 throw nb::index_error(
"attempt to access out of bounds region");
364 static void bind(nb::module_ &m) {
365 nb::class_<PyRegionList>(m,
"RegionSequence")
366 .def(
"__len__", &PyRegionList::dunderLen)
367 .def(
"__iter__", &PyRegionList::dunderIter)
368 .def(
"__getitem__", &PyRegionList::dunderGetItem);
375 class PyBlockIterator {
378 : operation(std::move(operation)), next(next) {}
380 PyBlockIterator &dunderIter() {
return *
this; }
385 throw nb::stop_iteration();
388 PyBlock returnBlock(operation, next);
393 static void bind(nb::module_ &m) {
394 nb::class_<PyBlockIterator>(m,
"BlockIterator")
395 .def(
"__iter__", &PyBlockIterator::dunderIter)
396 .def(
"__next__", &PyBlockIterator::dunderNext);
410 : operation(std::move(operation)), region(region) {}
412 PyBlockIterator dunderIter() {
417 intptr_t dunderLen() {
418 operation->checkValid();
428 PyBlock dunderGetItem(intptr_t index) {
431 throw nb::index_error(
"attempt to access out of bounds block");
436 return PyBlock(operation, block);
441 throw nb::index_error(
"attempt to access out of bounds block");
444 PyBlock appendBlock(
const nb::args &pyArgTypes,
445 const std::optional<nb::sequence> &pyArgLocs) {
448 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
450 return PyBlock(operation, block);
453 static void bind(nb::module_ &m) {
454 nb::class_<PyBlockList>(m,
"BlockList")
455 .def(
"__getitem__", &PyBlockList::dunderGetItem)
456 .def(
"__iter__", &PyBlockList::dunderIter)
457 .def(
"__len__", &PyBlockList::dunderLen)
459 nb::arg(
"args"), nb::kw_only(),
460 nb::arg(
"arg_locs") = std::nullopt);
468 class PyOperationIterator {
470 PyOperationIterator(
PyOperationRef parentOperation, MlirOperation next)
471 : parentOperation(std::move(parentOperation)), next(next) {}
473 PyOperationIterator &dunderIter() {
return *
this; }
475 nb::object dunderNext() {
478 throw nb::stop_iteration();
482 PyOperation::forOperation(parentOperation->getContext(), next);
487 static void bind(nb::module_ &m) {
488 nb::class_<PyOperationIterator>(m,
"OperationIterator")
489 .def(
"__iter__", &PyOperationIterator::dunderIter)
490 .def(
"__next__", &PyOperationIterator::dunderNext);
502 class PyOperationList {
505 : parentOperation(std::move(parentOperation)), block(block) {}
507 PyOperationIterator dunderIter() {
509 return PyOperationIterator(parentOperation,
513 intptr_t dunderLen() {
514 parentOperation->checkValid();
524 nb::object dunderGetItem(intptr_t index) {
525 parentOperation->checkValid();
527 throw nb::index_error(
"attempt to access out of bounds operation");
532 return PyOperation::forOperation(parentOperation->getContext(), childOp)
538 throw nb::index_error(
"attempt to access out of bounds operation");
541 static void bind(nb::module_ &m) {
542 nb::class_<PyOperationList>(m,
"OperationList")
543 .def(
"__getitem__", &PyOperationList::dunderGetItem)
544 .def(
"__iter__", &PyOperationList::dunderIter)
545 .def(
"__len__", &PyOperationList::dunderLen);
555 PyOpOperand(MlirOpOperand opOperand) : opOperand(opOperand) {}
557 nb::object getOwner() {
561 return PyOperation::forOperation(context, owner)->createOpView();
566 static void bind(nb::module_ &m) {
567 nb::class_<PyOpOperand>(m,
"OpOperand")
568 .def_prop_ro(
"owner", &PyOpOperand::getOwner)
569 .def_prop_ro(
"operand_number", &PyOpOperand::getOperandNumber);
573 MlirOpOperand opOperand;
576 class PyOpOperandIterator {
578 PyOpOperandIterator(MlirOpOperand opOperand) : opOperand(opOperand) {}
580 PyOpOperandIterator &dunderIter() {
return *
this; }
582 PyOpOperand dunderNext() {
584 throw nb::stop_iteration();
586 PyOpOperand returnOpOperand(opOperand);
588 return returnOpOperand;
591 static void bind(nb::module_ &m) {
592 nb::class_<PyOpOperandIterator>(m,
"OpOperandIterator")
593 .def(
"__iter__", &PyOpOperandIterator::dunderIter)
594 .def(
"__next__", &PyOpOperandIterator::dunderNext);
598 MlirOpOperand opOperand;
607 PyMlirContext::PyMlirContext(MlirContext context) : context(context) {
608 nb::gil_scoped_acquire acquire;
609 auto &liveContexts = getLiveContexts();
610 liveContexts[context.ptr] =
this;
617 nb::gil_scoped_acquire acquire;
618 getLiveContexts().erase(context.ptr);
629 throw nb::python_error();
634 nb::gil_scoped_acquire acquire;
635 auto &liveContexts = getLiveContexts();
636 auto it = liveContexts.find(context.ptr);
637 if (it == liveContexts.end()) {
640 nb::object pyRef = nb::cast(unownedContextWrapper);
641 assert(pyRef &&
"cast to nb::object failed");
642 liveContexts[context.ptr] = unownedContextWrapper;
646 nb::object pyRef = nb::cast(it->second);
651 static LiveContextMap liveContexts;
660 std::vector<PyOperation *> liveObjects;
661 for (
auto &entry : liveOperations)
662 liveObjects.push_back(entry.second.second);
667 for (
auto &op : liveOperations)
668 op.second.second->setInvalid();
669 size_t numInvalidated = liveOperations.size();
670 liveOperations.clear();
671 return numInvalidated;
675 auto it = liveOperations.find(op.ptr);
676 if (it != liveOperations.end()) {
677 it->second.second->setInvalid();
678 liveOperations.erase(it);
692 callBackData *data =
static_cast<callBackData *
>(userData);
693 if (LLVM_LIKELY(data->rootSeen))
694 data->rootOp.getOperation().getContext()->clearOperation(op);
696 data->rootSeen =
true;
725 const nb::object &excVal,
726 const nb::object &excTb) {
735 nb::object pyHandlerObject =
736 nb::cast(pyHandler, nb::rv_policy::take_ownership);
737 pyHandlerObject.inc_ref();
741 auto handlerCallback =
744 nb::object pyDiagnosticObject =
745 nb::cast(pyDiagnostic, nb::rv_policy::take_ownership);
752 nb::gil_scoped_acquire gil;
754 result = nb::cast<bool>(pyHandler->callback(pyDiagnostic));
755 }
catch (std::exception &e) {
756 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
758 pyHandler->hadError =
true;
765 auto deleteCallback = +[](
void *userData) {
767 assert(pyHandler->registeredID &&
"handler is not registered");
768 pyHandler->registeredID.reset();
771 nb::object pyHandlerObject = nb::cast(pyHandler, nb::rv_policy::reference);
772 pyHandlerObject.dec_ref();
776 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
777 return pyHandlerObject;
784 if (self->ctx->emitErrorDiagnostics)
797 throw std::runtime_error(
798 "An MLIR function requires a Context but none was provided in the call "
799 "or from the surrounding environment. Either pass to the function with "
800 "a 'context=' argument or establish a default using 'with Context():'");
810 static thread_local std::vector<PyThreadContextEntry> stack;
815 auto &stack = getStack();
818 return &stack.back();
821 void PyThreadContextEntry::push(FrameKind frameKind, nb::object context,
822 nb::object insertionPoint,
823 nb::object location) {
824 auto &stack = getStack();
825 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
826 std::move(location));
830 if (stack.size() > 1) {
831 auto &prev = *(stack.rbegin() + 1);
832 auto ¤t = stack.back();
833 if (current.context.is(prev.context)) {
835 if (!current.insertionPoint)
836 current.insertionPoint = prev.insertionPoint;
837 if (!current.location)
838 current.location = prev.location;
846 return nb::cast<PyMlirContext *>(context);
852 return nb::cast<PyInsertionPoint *>(insertionPoint);
858 return nb::cast<PyLocation *>(location);
862 auto *tos = getTopOfStack();
863 return tos ? tos->getContext() :
nullptr;
867 auto *tos = getTopOfStack();
868 return tos ? tos->getInsertionPoint() :
nullptr;
872 auto *tos = getTopOfStack();
873 return tos ? tos->getLocation() :
nullptr;
877 push(FrameKind::Context, context,
884 auto &stack = getStack();
886 throw std::runtime_error(
"Unbalanced Context enter/exit");
887 auto &tos = stack.back();
888 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
889 throw std::runtime_error(
"Unbalanced Context enter/exit");
896 nb::cast<PyInsertionPoint &>(insertionPointObj);
897 nb::object contextObj =
899 push(FrameKind::InsertionPoint,
903 return insertionPointObj;
907 auto &stack = getStack();
909 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
910 auto &tos = stack.back();
911 if (tos.frameKind != FrameKind::InsertionPoint &&
912 tos.getInsertionPoint() != &insertionPoint)
913 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
918 PyLocation &location = nb::cast<PyLocation &>(locationObj);
920 push(FrameKind::Location, contextObj,
927 auto &stack = getStack();
929 throw std::runtime_error(
"Unbalanced Location enter/exit");
930 auto &tos = stack.back();
931 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
932 throw std::runtime_error(
"Unbalanced Location enter/exit");
942 if (materializedNotes) {
943 for (nb::handle noteObject : *materializedNotes) {
944 PyDiagnostic *note = nb::cast<PyDiagnostic *>(noteObject);
952 : context(context), callback(std::move(callback)) {}
961 assert(!registeredID &&
"should have unregistered");
967 void PyDiagnostic::checkValid() {
969 throw std::invalid_argument(
970 "Diagnostic is invalid (used outside of callback)");
988 nb::object fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
991 return nb::cast<nb::str>(fileObject.attr(
"getvalue")());
996 if (materializedNotes)
997 return *materializedNotes;
999 nb::tuple notes = nb::steal<nb::tuple>(PyTuple_New(numNotes));
1000 for (intptr_t i = 0; i < numNotes; ++i) {
1002 nb::object diagnostic = nb::cast(
PyDiagnostic(noteDiag));
1003 PyTuple_SET_ITEM(notes.ptr(), i, diagnostic.release().ptr());
1005 materializedNotes = std::move(notes);
1007 return *materializedNotes;
1011 std::vector<DiagnosticInfo> notes;
1013 notes.emplace_back(nb::cast<PyDiagnostic>(n).
getInfo());
1025 {key.data(), key.size()});
1027 std::string msg = (Twine(
"Dialect '") + key +
"' not found").str();
1029 throw nb::attribute_error(msg.c_str());
1030 throw nb::index_error(msg.c_str());
1040 MlirDialectRegistry rawRegistry =
1043 throw nb::python_error();
1058 throw nb::python_error();
1068 const nb::object &excVal,
1069 const nb::object &excTb) {
1076 throw std::runtime_error(
1077 "An MLIR function requires a Location but none was provided in the "
1078 "call or from the surrounding environment. Either pass to the function "
1079 "with a 'loc=' argument or establish a default using 'with loc:'");
1092 nb::gil_scoped_acquire acquire;
1093 auto &liveModules =
getContext()->liveModules;
1094 assert(liveModules.count(module.ptr) == 1 &&
1095 "destroying module not in live map");
1096 liveModules.erase(module.ptr);
1104 nb::gil_scoped_acquire acquire;
1105 auto &liveModules = contextRef->liveModules;
1106 auto it = liveModules.find(module.ptr);
1107 if (it == liveModules.end()) {
1113 nb::object pyRef = nb::cast(unownedModule, nb::rv_policy::take_ownership);
1114 unownedModule->handle = pyRef;
1115 liveModules[module.ptr] =
1116 std::make_pair(unownedModule->handle, unownedModule);
1117 return PyModuleRef(unownedModule, std::move(pyRef));
1120 PyModule *existing = it->second.second;
1121 nb::object pyRef = nb::borrow<nb::object>(it->second.first);
1128 throw nb::python_error();
1140 PyOperation::PyOperation(
PyMlirContextRef contextRef, MlirOperation operation)
1161 MlirOperation operation,
1162 nb::object parentKeepAlive) {
1163 auto &liveOperations = contextRef->liveOperations;
1166 new PyOperation(std::move(contextRef), operation);
1170 nb::object pyRef = nb::cast(unownedOperation, nb::rv_policy::take_ownership);
1171 unownedOperation->handle = pyRef;
1172 if (parentKeepAlive) {
1173 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
1175 liveOperations[operation.ptr] = std::make_pair(pyRef, unownedOperation);
1180 MlirOperation operation,
1181 nb::object parentKeepAlive) {
1182 auto &liveOperations = contextRef->liveOperations;
1183 auto it = liveOperations.find(operation.ptr);
1184 if (it == liveOperations.end()) {
1186 return createInstance(std::move(contextRef), operation,
1187 std::move(parentKeepAlive));
1191 nb::object pyRef = nb::borrow<nb::object>(it->second.first);
1196 MlirOperation operation,
1197 nb::object parentKeepAlive) {
1198 auto &liveOperations = contextRef->liveOperations;
1199 assert(liveOperations.count(operation.ptr) == 0 &&
1200 "cannot create detached operation that already exists");
1201 (void)liveOperations;
1203 PyOperationRef created = createInstance(std::move(contextRef), operation,
1204 std::move(parentKeepAlive));
1205 created->attached =
false;
1210 const std::string &sourceStr,
1211 const std::string &sourceName) {
1217 throw MLIRError(
"Unable to parse operation assembly", errors.
take());
1223 throw std::runtime_error(
"the operation has been invalidated");
1228 bool enableDebugInfo,
bool prettyDebugInfo,
1229 bool printGenericOpForm,
bool useLocalScope,
1230 bool assumeVerified, nb::object fileObject,
1231 bool binary,
bool skipRegions) {
1234 if (fileObject.is_none())
1235 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1238 if (largeElementsLimit)
1240 if (enableDebugInfo)
1243 if (printGenericOpForm)
1254 accum.getUserData());
1262 if (fileObject.is_none())
1263 fileObject = nb::module_::import_(
"sys").attr(
"stdout");
1266 accum.getUserData());
1270 std::optional<int64_t> bytecodeVersion) {
1275 if (!bytecodeVersion.has_value())
1285 throw nb::value_error((Twine(
"Unable to honor desired bytecode version ") +
1286 Twine(*bytecodeVersion))
1299 std::string exceptionWhat;
1300 nb::object exceptionType;
1302 UserData userData{callback,
false, {}, {}};
1305 UserData *calleeUserData =
static_cast<UserData *
>(userData);
1307 return (calleeUserData->callback)(op);
1308 }
catch (nb::python_error &e) {
1309 calleeUserData->gotException =
true;
1310 calleeUserData->exceptionWhat = std::string(e.what());
1311 calleeUserData->exceptionType = nb::borrow(e.type());
1316 if (userData.gotException) {
1317 std::string message(
"Exception raised in callback: ");
1318 message.append(userData.exceptionWhat);
1319 throw std::runtime_error(message);
1324 std::optional<int64_t> largeElementsLimit,
1325 bool enableDebugInfo,
bool prettyDebugInfo,
1326 bool printGenericOpForm,
bool useLocalScope,
1327 bool assumeVerified,
bool skipRegions) {
1328 nb::object fileObject;
1330 fileObject = nb::module_::import_(
"io").attr(
"BytesIO")();
1332 fileObject = nb::module_::import_(
"io").attr(
"StringIO")();
1334 print(largeElementsLimit,
1344 return fileObject.attr(
"getvalue")();
1353 operation.parentKeepAlive = otherOp.parentKeepAlive;
1362 operation.parentKeepAlive = otherOp.parentKeepAlive;
1376 throw nb::value_error(
"Detached operations have no parent");
1387 assert(!
mlirBlockIsNull(block) &&
"Attached operation has null parent");
1388 assert(parentOperation &&
"Operation has no parent");
1389 return PyBlock{std::move(*parentOperation), block};
1400 throw nb::python_error();
1407 const nb::object &maybeIp) {
1409 if (!maybeIp.is(nb::cast(
false))) {
1411 if (maybeIp.is_none()) {
1414 ip = nb::cast<PyInsertionPoint *>(maybeIp);
1422 std::optional<std::vector<PyType *>> results,
1423 std::optional<std::vector<PyValue *>> operands,
1424 std::optional<nb::dict> attributes,
1425 std::optional<std::vector<PyBlock *>> successors,
1427 const nb::object &maybeIp,
bool inferType) {
1435 throw nb::value_error(
"number of regions must be >= 0");
1439 mlirOperands.reserve(operands->size());
1440 for (
PyValue *operand : *operands) {
1442 throw nb::value_error(
"operand value cannot be None");
1443 mlirOperands.push_back(operand->get());
1449 mlirResults.reserve(results->size());
1450 for (
PyType *result : *results) {
1453 throw nb::value_error(
"result type cannot be None");
1454 mlirResults.push_back(*result);
1459 mlirAttributes.reserve(attributes->size());
1460 for (std::pair<nb::handle, nb::handle> it : *attributes) {
1463 key = nb::cast<std::string>(it.first);
1464 }
catch (nb::cast_error &err) {
1465 std::string msg =
"Invalid attribute key (not a string) when "
1466 "attempting to create the operation \"" +
1467 name +
"\" (" + err.what() +
")";
1468 throw nb::type_error(msg.c_str());
1471 auto &attribute = nb::cast<PyAttribute &>(it.second);
1473 mlirAttributes.emplace_back(std::move(key), attribute);
1474 }
catch (nb::cast_error &err) {
1475 std::string msg =
"Invalid attribute value for the key \"" + key +
1476 "\" when attempting to create the operation \"" +
1477 name +
"\" (" + err.what() +
")";
1478 throw nb::type_error(msg.c_str());
1479 }
catch (std::runtime_error &) {
1482 "Found an invalid (`None`?) attribute value for the key \"" + key +
1483 "\" when attempting to create the operation \"" + name +
"\"";
1484 throw std::runtime_error(msg);
1490 mlirSuccessors.reserve(successors->size());
1491 for (
auto *successor : *successors) {
1494 throw nb::value_error(
"successor block cannot be None");
1495 mlirSuccessors.push_back(successor->get());
1503 if (!mlirOperands.empty())
1505 mlirOperands.data());
1506 state.enableResultTypeInference = inferType;
1507 if (!mlirResults.empty())
1509 mlirResults.data());
1510 if (!mlirAttributes.empty()) {
1515 mlirNamedAttributes.reserve(mlirAttributes.size());
1516 for (
auto &it : mlirAttributes)
1522 mlirNamedAttributes.data());
1524 if (!mlirSuccessors.empty())
1526 mlirSuccessors.data());
1529 mlirRegions.resize(regions);
1530 for (
int i = 0; i < regions; ++i)
1533 mlirRegions.data());
1539 throw nb::value_error(
"Operation creation failed");
1578 const nb::object &resultSegmentSpecObj,
1579 std::vector<int32_t> &resultSegmentLengths,
1580 std::vector<PyType *> &resultTypes) {
1581 resultTypes.reserve(resultTypeList.size());
1582 if (resultSegmentSpecObj.is_none()) {
1586 resultTypes.push_back(nb::cast<PyType *>(it.value()));
1587 if (!resultTypes.back())
1588 throw nb::cast_error();
1589 }
catch (nb::cast_error &err) {
1590 throw nb::value_error((llvm::Twine(
"Result ") +
1591 llvm::Twine(it.index()) +
" of operation \"" +
1592 name +
"\" must be a Type (" + err.what() +
")")
1599 auto resultSegmentSpec = nb::cast<std::vector<int>>(resultSegmentSpecObj);
1600 if (resultSegmentSpec.size() != resultTypeList.size()) {
1601 throw nb::value_error((llvm::Twine(
"Operation \"") + name +
1603 llvm::Twine(resultSegmentSpec.size()) +
1604 " result segments but was provided " +
1605 llvm::Twine(resultTypeList.size()))
1609 resultSegmentLengths.reserve(resultTypeList.size());
1610 for (
const auto &it :
1612 int segmentSpec = std::get<1>(it.value());
1613 if (segmentSpec == 1 || segmentSpec == 0) {
1616 auto *resultType = nb::cast<PyType *>(std::get<0>(it.value()));
1618 resultTypes.push_back(resultType);
1619 resultSegmentLengths.push_back(1);
1620 }
else if (segmentSpec == 0) {
1622 resultSegmentLengths.push_back(0);
1624 throw nb::value_error(
1625 (llvm::Twine(
"Result ") + llvm::Twine(it.index()) +
1626 " of operation \"" + name +
1627 "\" must be a Type (was None and result is not optional)")
1631 }
catch (nb::cast_error &err) {
1632 throw nb::value_error((llvm::Twine(
"Result ") +
1633 llvm::Twine(it.index()) +
" of operation \"" +
1634 name +
"\" must be a Type (" + err.what() +
1639 }
else if (segmentSpec == -1) {
1642 if (std::get<0>(it.value()).is_none()) {
1644 resultSegmentLengths.push_back(0);
1647 auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
1648 for (nb::handle segmentItem : segment) {
1649 resultTypes.push_back(nb::cast<PyType *>(segmentItem));
1650 if (!resultTypes.back()) {
1651 throw nb::type_error(
"contained a None item");
1654 resultSegmentLengths.push_back(nb::len(segment));
1656 }
catch (std::exception &err) {
1660 throw nb::value_error((llvm::Twine(
"Result ") +
1661 llvm::Twine(it.index()) +
" of operation \"" +
1662 name +
"\" must be a Sequence of Types (" +
1668 throw nb::value_error(
"Unexpected segment spec");
1675 const nb::object &cls, std::optional<nb::list> resultTypeList,
1676 nb::list operandList, std::optional<nb::dict> attributes,
1677 std::optional<std::vector<PyBlock *>> successors,
1679 const nb::object &maybeIp) {
1682 std::string name = nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
1688 nb::object operandSegmentSpecObj = cls.attr(
"_ODS_OPERAND_SEGMENTS");
1689 nb::object resultSegmentSpecObj = cls.attr(
"_ODS_RESULT_SEGMENTS");
1691 std::vector<int32_t> operandSegmentLengths;
1692 std::vector<int32_t> resultSegmentLengths;
1695 auto opRegionSpec = nb::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
1696 int opMinRegionCount = std::get<0>(opRegionSpec);
1697 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1699 regions = opMinRegionCount;
1701 if (*regions < opMinRegionCount) {
1702 throw nb::value_error(
1703 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1704 llvm::Twine(opMinRegionCount) +
1705 " regions but was built with regions=" + llvm::Twine(*regions))
1709 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1710 throw nb::value_error(
1711 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1712 llvm::Twine(opMinRegionCount) +
1713 " regions but was built with regions=" + llvm::Twine(*regions))
1719 std::vector<PyType *> resultTypes;
1720 if (resultTypeList.has_value()) {
1722 resultSegmentLengths, resultTypes);
1726 std::vector<PyValue *> operands;
1727 operands.reserve(operands.size());
1728 if (operandSegmentSpecObj.is_none()) {
1732 operands.push_back(nb::cast<PyValue *>(it.value()));
1733 if (!operands.back())
1734 throw nb::cast_error();
1735 }
catch (nb::cast_error &err) {
1736 throw nb::value_error((llvm::Twine(
"Operand ") +
1737 llvm::Twine(it.index()) +
" of operation \"" +
1738 name +
"\" must be a Value (" + err.what() +
")")
1745 auto operandSegmentSpec = nb::cast<std::vector<int>>(operandSegmentSpecObj);
1746 if (operandSegmentSpec.size() != operandList.size()) {
1747 throw nb::value_error((llvm::Twine(
"Operation \"") + name +
1749 llvm::Twine(operandSegmentSpec.size()) +
1750 "operand segments but was provided " +
1751 llvm::Twine(operandList.size()))
1755 operandSegmentLengths.reserve(operandList.size());
1756 for (
const auto &it :
1758 int segmentSpec = std::get<1>(it.value());
1759 if (segmentSpec == 1 || segmentSpec == 0) {
1762 auto *operandValue = nb::cast<PyValue *>(std::get<0>(it.value()));
1764 operands.push_back(operandValue);
1765 operandSegmentLengths.push_back(1);
1766 }
else if (segmentSpec == 0) {
1768 operandSegmentLengths.push_back(0);
1770 throw nb::value_error(
1771 (llvm::Twine(
"Operand ") + llvm::Twine(it.index()) +
1772 " of operation \"" + name +
1773 "\" must be a Value (was None and operand is not optional)")
1777 }
catch (nb::cast_error &err) {
1778 throw nb::value_error((llvm::Twine(
"Operand ") +
1779 llvm::Twine(it.index()) +
" of operation \"" +
1780 name +
"\" must be a Value (" + err.what() +
1785 }
else if (segmentSpec == -1) {
1788 if (std::get<0>(it.value()).is_none()) {
1790 operandSegmentLengths.push_back(0);
1793 auto segment = nb::cast<nb::sequence>(std::get<0>(it.value()));
1794 for (nb::handle segmentItem : segment) {
1795 operands.push_back(nb::cast<PyValue *>(segmentItem));
1796 if (!operands.back()) {
1797 throw nb::type_error(
"contained a None item");
1800 operandSegmentLengths.push_back(nb::len(segment));
1802 }
catch (std::exception &err) {
1806 throw nb::value_error((llvm::Twine(
"Operand ") +
1807 llvm::Twine(it.index()) +
" of operation \"" +
1808 name +
"\" must be a Sequence of Values (" +
1814 throw nb::value_error(
"Unexpected segment spec");
1820 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1823 attributes = nb::dict(*attributes);
1825 attributes = nb::dict();
1827 if (attributes->contains(
"resultSegmentSizes") ||
1828 attributes->contains(
"operandSegmentSizes")) {
1829 throw nb::value_error(
"Manually setting a 'resultSegmentSizes' or "
1830 "'operandSegmentSizes' attribute is unsupported. "
1831 "Use Operation.create for such low-level access.");
1835 if (!resultSegmentLengths.empty()) {
1836 MlirAttribute segmentLengthAttr =
1838 resultSegmentLengths.data());
1839 (*attributes)[
"resultSegmentSizes"] =
1844 if (!operandSegmentLengths.empty()) {
1845 MlirAttribute segmentLengthAttr =
1847 operandSegmentLengths.data());
1848 (*attributes)[
"operandSegmentSizes"] =
1855 std::move(resultTypes),
1856 std::move(operands),
1857 std::move(attributes),
1858 std::move(successors),
1859 *regions, location, maybeIp,
1864 const nb::object &operation) {
1865 nb::handle opViewType = nb::type<PyOpView>();
1866 nb::object instance = cls.attr(
"__new__")(cls);
1867 opViewType.attr(
"__init__")(instance, operation);
1875 operationObject(operation.getRef().getObject()) {}
1884 : refOperation(beforeOperationBase.getOperation().getRef()),
1885 block((*refOperation)->getBlock()) {}
1890 throw nb::value_error(
1891 "Attempt to insert operation that is already attached");
1892 block.getParentOperation()->checkValid();
1893 MlirOperation beforeOp = {
nullptr};
1896 (*refOperation)->checkValid();
1897 beforeOp = (*refOperation)->get();
1903 throw nb::index_error(
"Cannot insert operation at the end of a block "
1904 "that already has a terminator. Did you mean to "
1905 "use 'InsertionPoint.at_block_terminator(block)' "
1906 "versus 'InsertionPoint(block)'?");
1929 throw nb::value_error(
"Block has no terminator");
1940 const nb::object &excVal,
1941 const nb::object &excTb) {
1960 throw nb::python_error();
1970 : ownedName(new std::string(std::move(ownedName))) {
1992 throw nb::python_error();
2008 throw nb::python_error();
2027 "mlirTypeID was expected to be non-null.");
2028 std::optional<nb::callable> valueCaster =
2032 nb::object thisObj = nb::cast(
this, nb::rv_policy::move);
2035 return valueCaster.value()(thisObj);
2041 throw nb::python_error();
2042 MlirOperation owner;
2048 throw nb::python_error();
2052 return PyValue(ownerRef, value);
2060 : operation(operation.getOperation().getRef()) {
2063 throw nb::type_error(
"Operation is not a Symbol Table.");
2072 throw nb::key_error(
2073 (
"Symbol '" + name +
"' not in the symbol table.").c_str());
2076 operation.getObject())
2092 erase(nb::cast<PyOperationBase &>(operation));
2101 throw nb::value_error(
"Expected operation to have a symbol name.");
2110 MlirAttribute existingNameAttr =
2113 throw nb::value_error(
"Expected operation to have a symbol name.");
2114 return existingNameAttr;
2118 const std::string &name) {
2123 MlirAttribute existingNameAttr =
2126 throw nb::value_error(
"Expected operation to have a symbol name.");
2127 MlirAttribute newNameAttr =
2136 MlirAttribute existingVisAttr =
2139 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2140 return existingVisAttr;
2144 const std::string &visibility) {
2145 if (visibility !=
"public" && visibility !=
"private" &&
2146 visibility !=
"nested")
2147 throw nb::value_error(
2148 "Expected visibility to be 'public', 'private' or 'nested'");
2152 MlirAttribute existingVisAttr =
2155 throw nb::value_error(
"Expected operation to have a symbol visibility.");
2162 const std::string &newSymbol,
2170 throw nb::value_error(
"Symbol rename failed");
2174 bool allSymUsesVisible,
2175 nb::object callback) {
2180 nb::object callback;
2182 std::string exceptionWhat;
2183 nb::object exceptionType;
2186 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
2188 fromOperation.
get(), allSymUsesVisible,
2189 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
2190 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
2192 PyOperation::forOperation(calleeUserData->context, foundOp);
2193 if (calleeUserData->gotException)
2196 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
2197 } catch (nb::python_error &e) {
2198 calleeUserData->gotException =
true;
2199 calleeUserData->exceptionWhat = e.what();
2200 calleeUserData->exceptionType = nb::borrow(e.type());
2203 static_cast<void *
>(&userData));
2204 if (userData.gotException) {
2205 std::string message(
"Exception raised in callback: ");
2206 message.append(userData.exceptionWhat);
2207 throw std::runtime_error(message);
2215 template <
typename DerivedTy>
2216 class PyConcreteValue :
public PyValue {
2222 using ClassTy = nb::class_<DerivedTy, PyValue>;
2223 using IsAFunctionTy = bool (*)(MlirValue);
2225 PyConcreteValue() =
default;
2227 :
PyValue(operationRef, value) {}
2228 PyConcreteValue(
PyValue &orig)
2229 : PyConcreteValue(orig.getParentOperation(), castFrom(orig)) {}
2233 static MlirValue castFrom(
PyValue &orig) {
2234 if (!DerivedTy::isaFunction(orig.
get())) {
2235 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(orig)));
2236 throw nb::value_error((Twine(
"Cannot cast value to ") +
2237 DerivedTy::pyClassName +
" (from " + origRepr +
2246 static void bind(nb::module_ &m) {
2247 auto cls = ClassTy(m, DerivedTy::pyClassName);
2248 cls.def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg(
"value"));
2251 [](
PyValue &otherValue) ->
bool {
2252 return DerivedTy::isaFunction(otherValue);
2254 nb::arg(
"other_value"));
2256 [](
DerivedTy &
self) {
return self.maybeDownCast(); });
2257 DerivedTy::bindDerived(cls);
2261 static void bindDerived(ClassTy &m) {}
2265 class PyBlockArgument :
public PyConcreteValue<PyBlockArgument> {
2268 static constexpr
const char *pyClassName =
"BlockArgument";
2269 using PyConcreteValue::PyConcreteValue;
2271 static void bindDerived(ClassTy &c) {
2272 c.def_prop_ro(
"owner", [](PyBlockArgument &
self) {
2273 return PyBlock(
self.getParentOperation(),
2276 c.def_prop_ro(
"arg_number", [](PyBlockArgument &
self) {
2281 [](PyBlockArgument &
self,
PyType type) {
2289 class PyOpResult :
public PyConcreteValue<PyOpResult> {
2292 static constexpr
const char *pyClassName =
"OpResult";
2293 using PyConcreteValue::PyConcreteValue;
2295 static void bindDerived(ClassTy &c) {
2296 c.def_prop_ro(
"owner", [](PyOpResult &
self) {
2300 "expected the owner of the value in Python to match that in the IR");
2301 return self.getParentOperation().getObject();
2303 c.def_prop_ro(
"result_number", [](PyOpResult &
self) {
2310 template <
typename Container>
2311 static std::vector<MlirType> getValueTypes(Container &container,
2313 std::vector<MlirType> result;
2314 result.reserve(container.size());
2315 for (
int i = 0, e = container.size(); i < e; ++i) {
2325 class PyBlockArgumentList
2326 :
public Sliceable<PyBlockArgumentList, PyBlockArgument> {
2328 static constexpr
const char *pyClassName =
"BlockArgumentList";
2332 intptr_t startIndex = 0, intptr_t length = -1,
2337 operation(std::move(operation)), block(block) {}
2339 static void bindDerived(ClassTy &c) {
2340 c.def_prop_ro(
"types", [](PyBlockArgumentList &
self) {
2341 return getValueTypes(
self,
self.operation->
getContext());
2347 friend class Sliceable<PyBlockArgumentList, PyBlockArgument>;
2350 intptr_t getRawNumElements() {
2356 PyBlockArgument getRawElement(intptr_t pos) {
2358 return PyBlockArgument(operation, argument);
2362 PyBlockArgumentList slice(intptr_t startIndex, intptr_t length,
2364 return PyBlockArgumentList(operation, block, startIndex, length, step);
2375 class PyOpOperandList :
public Sliceable<PyOpOperandList, PyValue> {
2377 static constexpr
const char *pyClassName =
"OpOperandList";
2380 PyOpOperandList(
PyOperationRef operation, intptr_t startIndex = 0,
2381 intptr_t length = -1, intptr_t step = 1)
2386 operation(operation) {}
2388 void dunderSetItem(intptr_t index,
PyValue value) {
2389 index = wrapIndex(index);
2393 static void bindDerived(ClassTy &c) {
2394 c.def(
"__setitem__", &PyOpOperandList::dunderSetItem);
2401 intptr_t getRawNumElements() {
2406 PyValue getRawElement(intptr_t pos) {
2408 MlirOperation owner;
2414 assert(
false &&
"Value must be an block arg or op result.");
2416 PyOperation::forOperation(operation->
getContext(), owner);
2417 return PyValue(pyOwner, operand);
2420 PyOpOperandList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2421 return PyOpOperandList(operation, startIndex, length, step);
2431 class PyOpResultList :
public Sliceable<PyOpResultList, PyOpResult> {
2433 static constexpr
const char *pyClassName =
"OpResultList";
2436 PyOpResultList(
PyOperationRef operation, intptr_t startIndex = 0,
2437 intptr_t length = -1, intptr_t step = 1)
2442 operation(std::move(operation)) {}
2444 static void bindDerived(ClassTy &c) {
2445 c.def_prop_ro(
"types", [](PyOpResultList &
self) {
2446 return getValueTypes(
self,
self.operation->
getContext());
2448 c.def_prop_ro(
"owner", [](PyOpResultList &
self) {
2449 return self.operation->createOpView();
2455 friend class Sliceable<PyOpResultList, PyOpResult>;
2457 intptr_t getRawNumElements() {
2462 PyOpResult getRawElement(intptr_t index) {
2464 return PyOpResult(value);
2467 PyOpResultList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2468 return PyOpResultList(operation, startIndex, length, step);
2478 class PyOpSuccessors :
public Sliceable<PyOpSuccessors, PyBlock> {
2480 static constexpr
const char *pyClassName =
"OpSuccessors";
2482 PyOpSuccessors(
PyOperationRef operation, intptr_t startIndex = 0,
2483 intptr_t length = -1, intptr_t step = 1)
2488 operation(operation) {}
2490 void dunderSetItem(intptr_t index,
PyBlock block) {
2491 index = wrapIndex(index);
2495 static void bindDerived(ClassTy &c) {
2496 c.def(
"__setitem__", &PyOpSuccessors::dunderSetItem);
2503 intptr_t getRawNumElements() {
2508 PyBlock getRawElement(intptr_t pos) {
2510 return PyBlock(operation, block);
2513 PyOpSuccessors slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2514 return PyOpSuccessors(operation, startIndex, length, step);
2522 class PyOpAttributeMap {
2525 : operation(std::move(operation)) {}
2527 MlirAttribute dunderGetItemNamed(
const std::string &name) {
2531 throw nb::key_error(
"attempt to access a non-existent attribute");
2537 if (index < 0 || index >= dunderLen()) {
2538 throw nb::index_error(
"attempt to access out of bounds attribute");
2548 void dunderSetItem(
const std::string &name,
const PyAttribute &attr) {
2553 void dunderDelItem(
const std::string &name) {
2557 throw nb::key_error(
"attempt to delete a non-existent attribute");
2560 intptr_t dunderLen() {
2564 bool dunderContains(
const std::string &name) {
2569 static void bind(nb::module_ &m) {
2570 nb::class_<PyOpAttributeMap>(m,
"OpAttributeMap")
2571 .def(
"__contains__", &PyOpAttributeMap::dunderContains)
2572 .def(
"__len__", &PyOpAttributeMap::dunderLen)
2573 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
2574 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
2575 .def(
"__setitem__", &PyOpAttributeMap::dunderSetItem)
2576 .def(
"__delitem__", &PyOpAttributeMap::dunderDelItem);
2591 nb::set_leak_warnings(
false);
2595 nb::enum_<MlirDiagnosticSeverity>(m,
"DiagnosticSeverity")
2601 nb::enum_<MlirWalkOrder>(m,
"WalkOrder")
2605 nb::enum_<MlirWalkResult>(m,
"WalkResult")
2613 nb::class_<PyDiagnostic>(m,
"Diagnostic")
2614 .def_prop_ro(
"severity", &PyDiagnostic::getSeverity)
2615 .def_prop_ro(
"location", &PyDiagnostic::getLocation)
2616 .def_prop_ro(
"message", &PyDiagnostic::getMessage)
2617 .def_prop_ro(
"notes", &PyDiagnostic::getNotes)
2619 if (!
self.isValid())
2620 return nb::str(
"<Invalid Diagnostic>");
2621 return self.getMessage();
2624 nb::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo")
2629 .def_ro(
"severity", &PyDiagnostic::DiagnosticInfo::severity)
2630 .def_ro(
"location", &PyDiagnostic::DiagnosticInfo::location)
2631 .def_ro(
"message", &PyDiagnostic::DiagnosticInfo::message)
2632 .def_ro(
"notes", &PyDiagnostic::DiagnosticInfo::notes)
2636 nb::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler")
2637 .def(
"detach", &PyDiagnosticHandler::detach)
2638 .def_prop_ro(
"attached", &PyDiagnosticHandler::isAttached)
2639 .def_prop_ro(
"had_error", &PyDiagnosticHandler::getHadError)
2640 .def(
"__enter__", &PyDiagnosticHandler::contextEnter)
2641 .def(
"__exit__", &PyDiagnosticHandler::contextExit,
2642 nb::arg(
"exc_type").none(), nb::arg(
"exc_value").none(),
2643 nb::arg(
"traceback").none());
2651 nb::class_<PyMlirContext>(m,
"_BaseContext")
2657 .def_static(
"_get_live_count", &PyMlirContext::getLiveCount)
2658 .def(
"_get_context_again",
2663 .def(
"_get_live_operation_count", &PyMlirContext::getLiveOperationCount)
2664 .def(
"_get_live_operation_objects",
2665 &PyMlirContext::getLiveOperationObjects)
2666 .def(
"_clear_live_operations", &PyMlirContext::clearLiveOperations)
2667 .def(
"_clear_live_operations_inside",
2668 nb::overload_cast<MlirOperation>(
2669 &PyMlirContext::clearOperationsInside))
2670 .def(
"_get_live_module_count", &PyMlirContext::getLiveModuleCount)
2673 .def(
"__enter__", &PyMlirContext::contextEnter)
2674 .def(
"__exit__", &PyMlirContext::contextExit, nb::arg(
"exc_type").none(),
2675 nb::arg(
"exc_value").none(), nb::arg(
"traceback").none())
2676 .def_prop_ro_static(
2682 return nb::cast(context);
2684 "Gets the Context bound to the current thread or raises ValueError")
2688 "Gets a container for accessing dialects by name")
2691 "Alias for 'dialect'")
2693 "get_dialect_descriptor",
2696 self.
get(), {name.data(), name.size()});
2698 throw nb::value_error(
2699 (Twine(
"Dialect '") + name +
"' not found").str().c_str());
2703 nb::arg(
"dialect_name"),
2704 "Gets or loads a dialect by name, returning its descriptor object")
2706 "allow_unregistered_dialects",
2713 .def(
"attach_diagnostic_handler", &PyMlirContext::attachDiagnosticHandler,
2714 nb::arg(
"callback"),
2715 "Attaches a diagnostic handler that will receive callbacks")
2717 "enable_multithreading",
2723 "is_registered_operation",
2728 nb::arg(
"operation_name"))
2730 "append_dialect_registry",
2734 nb::arg(
"registry"))
2735 .def_prop_rw(
"emit_error_diagnostics",
nullptr,
2736 &PyMlirContext::setEmitErrorDiagnostics,
2737 "Emit error diagnostics to diagnostic handlers. By default "
2738 "error diagnostics are captured and reported through "
2739 "MLIRError exceptions.")
2740 .def(
"load_all_available_dialects", [](
PyMlirContext &
self) {
2747 nb::class_<PyDialectDescriptor>(m,
"DialectDescriptor")
2748 .def_prop_ro(
"namespace",
2755 std::string repr(
"<DialectDescriptor ");
2764 nb::class_<PyDialects>(m,
"Dialects")
2767 MlirDialect dialect =
2768 self.getDialectForKey(keyName,
false);
2769 nb::object descriptor =
2773 .def(
"__getattr__", [=](
PyDialects &
self, std::string attrName) {
2774 MlirDialect dialect =
2775 self.getDialectForKey(attrName,
true);
2776 nb::object descriptor =
2784 nb::class_<PyDialect>(m,
"Dialect")
2785 .def(nb::init<nb::object>(), nb::arg(
"descriptor"))
2786 .def_prop_ro(
"descriptor",
2787 [](
PyDialect &
self) {
return self.getDescriptor(); })
2788 .def(
"__repr__", [](nb::object
self) {
2789 auto clazz =
self.attr(
"__class__");
2790 return nb::str(
"<Dialect ") +
2791 self.attr(
"descriptor").attr(
"namespace") + nb::str(
" (class ") +
2792 clazz.attr(
"__module__") + nb::str(
".") +
2793 clazz.attr(
"__name__") + nb::str(
")>");
2799 nb::class_<PyDialectRegistry>(m,
"DialectRegistry")
2807 nb::class_<PyLocation>(m,
"Location")
2810 .def(
"__enter__", &PyLocation::contextEnter)
2811 .def(
"__exit__", &PyLocation::contextExit, nb::arg(
"exc_type").none(),
2812 nb::arg(
"exc_value").none(), nb::arg(
"traceback").none())
2817 .def(
"__eq__", [](
PyLocation &
self, nb::object other) {
return false; })
2818 .def_prop_ro_static(
2821 auto *loc = PyThreadContextEntry::getDefaultLocation();
2823 throw nb::value_error(
"No current Location");
2826 "Gets the Location bound to the current thread or raises ValueError")
2833 nb::arg(
"context").none() = nb::none(),
2834 "Gets a Location representing an unknown location")
2837 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
2840 throw nb::value_error(
"No caller frames provided");
2841 MlirLocation caller = frames.back().get();
2848 nb::arg(
"callee"), nb::arg(
"frames"),
2849 nb::arg(
"context").none() = nb::none(),
2853 [](std::string filename,
int line,
int col,
2860 nb::arg(
"filename"), nb::arg(
"line"), nb::arg(
"col"),
2861 nb::arg(
"context").none() = nb::none(),
2865 [](
const std::vector<PyLocation> &pyLocations,
2866 std::optional<PyAttribute> metadata,
2869 locations.reserve(pyLocations.size());
2870 for (
auto &pyLocation : pyLocations)
2871 locations.push_back(pyLocation.get());
2873 context->
get(), locations.size(), locations.data(),
2874 metadata ? metadata->get() : MlirAttribute{0});
2875 return PyLocation(context->getRef(), location);
2877 nb::arg(
"locations"), nb::arg(
"metadata").none() = nb::none(),
2878 nb::arg(
"context").none() = nb::none(),
2882 [](std::string name, std::optional<PyLocation> childLoc,
2888 childLoc ? childLoc->get()
2891 nb::arg(
"name"), nb::arg(
"childLoc").none() = nb::none(),
2892 nb::arg(
"context").none() = nb::none(),
2900 nb::arg(
"attribute"), nb::arg(
"context").none() = nb::none(),
2901 "Gets a Location from a LocationAttr")
2904 [](
PyLocation &
self) {
return self.getContext().getObject(); },
2905 "Context that owns the Location")
2909 "Get the underlying LocationAttr")
2915 nb::arg(
"message"),
"Emits an error at this location")
2920 return printAccum.
join();
2926 nb::class_<PyModule>(m,
"Module", nb::is_weak_referenceable())
2936 throw MLIRError(
"Unable to parse module assembly", errors.take());
2937 return PyModule::forModule(module).releaseObject();
2939 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
2948 throw MLIRError(
"Unable to parse module assembly", errors.take());
2949 return PyModule::forModule(module).releaseObject();
2951 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
2957 return PyModule::forModule(module).releaseObject();
2959 nb::arg(
"loc").none() = nb::none(),
"Creates an empty module")
2962 [](
PyModule &
self) {
return self.getContext().getObject(); },
2963 "Context that created the Module")
2967 return PyOperation::forOperation(
self.
getContext(),
2969 self.getRef().releaseObject())
2972 "Accesses the module as an operation")
2978 self.getRef().releaseObject());
2982 "Return the block for this module")
2991 [](nb::object
self) {
2993 return self.attr(
"operation").attr(
"__str__")();
3000 nb::class_<PyOperationBase>(m,
"_OperationBase")
3003 return self.getOperation().getCapsule();
3015 .def_prop_ro(
"attributes",
3017 return PyOpAttributeMap(
self.getOperation().getRef());
3026 "Context that owns the Operation")
3027 .def_prop_ro(
"name",
3031 MlirOperation operation = concreteOperation.
get();
3036 .def_prop_ro(
"operands",
3038 return PyOpOperandList(
self.getOperation().getRef());
3040 .def_prop_ro(
"regions",
3042 return PyRegionList(
self.getOperation().getRef());
3047 return PyOpResultList(
self.getOperation().getRef());
3049 "Returns the list of Operation results.")
3053 auto &operation =
self.getOperation();
3055 if (numResults != 1) {
3057 throw nb::value_error(
3058 (Twine(
"Cannot call .result on operation ") +
3059 StringRef(name.
data, name.
length) +
" which has " +
3061 " results (it is only valid for operations with a "
3066 return PyOpResult(operation.getRef(),
3070 "Shortcut to get an op result if it has only one (throws an error "
3079 "Returns the source location the operation was defined or derived "
3081 .def_prop_ro(
"parent",
3083 auto parent =
self.getOperation().getParentOperation();
3085 return parent->getObject();
3091 return self.getAsm(
false,
3100 "Returns the assembly form of the operation.")
3102 nb::overload_cast<PyAsmState &, nb::object, bool>(
3104 nb::arg(
"state"), nb::arg(
"file").none() = nb::none(),
3107 nb::overload_cast<std::optional<int64_t>,
bool,
bool,
bool,
bool,
3108 bool, nb::object,
bool,
bool>(
3111 nb::arg(
"large_elements_limit").none() = nb::none(),
3112 nb::arg(
"enable_debug_info") =
false,
3113 nb::arg(
"pretty_debug_info") =
false,
3114 nb::arg(
"print_generic_op_form") =
false,
3115 nb::arg(
"use_local_scope") =
false,
3116 nb::arg(
"assume_verified") =
false,
3117 nb::arg(
"file").none() = nb::none(), nb::arg(
"binary") =
false,
3119 .def(
"write_bytecode", &PyOperationBase::writeBytecode, nb::arg(
"file"),
3120 nb::arg(
"desired_version").none() = nb::none(),
3122 .def(
"get_asm", &PyOperationBase::getAsm,
3124 nb::arg(
"binary") =
false,
3125 nb::arg(
"large_elements_limit").none() = nb::none(),
3126 nb::arg(
"enable_debug_info") =
false,
3127 nb::arg(
"pretty_debug_info") =
false,
3128 nb::arg(
"print_generic_op_form") =
false,
3129 nb::arg(
"use_local_scope") =
false,
3130 nb::arg(
"assume_verified") =
false, nb::arg(
"skip_regions") =
false,
3133 "Verify the operation. Raises MLIRError if verification fails, and "
3134 "returns true otherwise.")
3135 .def(
"move_after", &PyOperationBase::moveAfter, nb::arg(
"other"),
3136 "Puts self immediately after the other operation in its parent "
3138 .def(
"move_before", &PyOperationBase::moveBefore, nb::arg(
"other"),
3139 "Puts self immediately before the other operation in its parent "
3144 return self.getOperation().clone(ip);
3146 nb::arg(
"ip").none() = nb::none())
3148 "detach_from_parent",
3153 throw nb::value_error(
"Detached operation has no parent.");
3158 "Detaches the operation from its parent block.")
3159 .def(
"erase", [](
PyOperationBase &
self) {
self.getOperation().erase(); })
3163 nb::class_<PyOperation, PyOperationBase>(m,
"Operation")
3164 .def_static(
"create", &PyOperation::create, nb::arg(
"name"),
3165 nb::arg(
"results").none() = nb::none(),
3166 nb::arg(
"operands").none() = nb::none(),
3167 nb::arg(
"attributes").none() = nb::none(),
3168 nb::arg(
"successors").none() = nb::none(),
3169 nb::arg(
"regions") = 0, nb::arg(
"loc").none() = nb::none(),
3170 nb::arg(
"ip").none() = nb::none(),
3174 [](
const std::string &sourceStr,
const std::string &sourceName,
3179 nb::arg(
"source"), nb::kw_only(), nb::arg(
"source_name") =
"",
3180 nb::arg(
"context").none() = nb::none(),
3181 "Parses an operation. Supports both text assembly format and binary "
3185 .def_prop_ro(
"operation", [](nb::object
self) {
return self; })
3186 .def_prop_ro(
"opview", &PyOperation::createOpView)
3190 return PyOpSuccessors(
self.getOperation().getRef());
3192 "Returns the list of Operation successors.");
3195 nb::class_<PyOpView, PyOperationBase>(m,
"OpView")
3196 .def(nb::init<nb::object>(), nb::arg(
"operation"))
3197 .def_prop_ro(
"operation", &PyOpView::getOperationObject)
3198 .def_prop_ro(
"opview", [](nb::object
self) {
return self; })
3201 [](
PyOpView &
self) {
return nb::str(
self.getOperationObject()); })
3205 return PyOpSuccessors(
self.getOperation().getRef());
3207 "Returns the list of Operation successors.");
3208 opViewClass.attr(
"_ODS_REGIONS") = nb::make_tuple(0,
true);
3209 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = nb::none();
3210 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = nb::none();
3212 &PyOpView::buildGeneric, nb::arg(
"cls"),
3213 nb::arg(
"results").none() = nb::none(),
3214 nb::arg(
"operands").none() = nb::none(),
3215 nb::arg(
"attributes").none() = nb::none(),
3216 nb::arg(
"successors").none() = nb::none(),
3217 nb::arg(
"regions").none() = nb::none(),
3218 nb::arg(
"loc").none() = nb::none(), nb::arg(
"ip").none() = nb::none(),
3219 "Builds a specific, generated OpView based on class level attributes.");
3221 [](
const nb::object &cls,
const std::string &sourceStr,
3231 std::string clsOpName =
3232 nb::cast<std::string>(cls.attr(
"OPERATION_NAME"));
3235 std::string_view parsedOpName(identifier.
data, identifier.
length);
3236 if (clsOpName != parsedOpName)
3237 throw MLIRError(Twine(
"Expected a '") + clsOpName +
"' op, got: '" +
3238 parsedOpName +
"'");
3239 return PyOpView::constructDerived(cls, parsed.
getObject());
3241 nb::arg(
"cls"), nb::arg(
"source"), nb::kw_only(),
3242 nb::arg(
"source_name") =
"", nb::arg(
"context").none() = nb::none(),
3243 "Parses a specific, generated OpView based on class level attributes");
3248 nb::class_<PyRegion>(m,
"Region")
3252 return PyBlockList(
self.getParentOperation(),
self.
get());
3254 "Returns a forward-optimized sequence of blocks.")
3258 return self.getParentOperation()->createOpView();
3260 "Returns the operation owning this region.")
3266 return PyBlockIterator(
self.getParentOperation(), firstBlock);
3268 "Iterates over blocks in the region.")
3271 return self.get().ptr == other.
get().ptr;
3273 .def(
"__eq__", [](
PyRegion &
self, nb::object &other) {
return false; });
3278 nb::class_<PyBlock>(m,
"Block")
3283 return self.getParentOperation()->createOpView();
3285 "Returns the owning operation of this block.")
3290 return PyRegion(
self.getParentOperation(), region);
3292 "Returns the owning region of this block.")
3296 return PyBlockArgumentList(
self.getParentOperation(),
self.
get());
3298 "Returns a list of block arguments.")
3304 "Append an argument of the specified type to the block and returns "
3305 "the newly added argument.")
3308 [](
PyBlock &
self,
unsigned index) {
3311 "Erase the argument at 'index' and remove it from the argument list.")
3315 return PyOperationList(
self.getParentOperation(),
self.
get());
3317 "Returns a forward-optimized sequence of operations.")
3320 [](
PyRegion &parent,
const nb::sequence &pyArgTypes,
3321 const std::optional<nb::sequence> &pyArgLocs) {
3323 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3327 nb::arg(
"parent"), nb::arg(
"arg_types") = nb::list(),
3328 nb::arg(
"arg_locs") = std::nullopt,
3329 "Creates and returns a new Block at the beginning of the given "
3330 "region (with given argument types and locations).")
3334 MlirBlock b =
self.get();
3339 "Append this block to a region, transferring ownership if necessary")
3342 [](
PyBlock &
self,
const nb::args &pyArgTypes,
3343 const std::optional<nb::sequence> &pyArgLocs) {
3346 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
3349 return PyBlock(
self.getParentOperation(), block);
3351 nb::arg(
"arg_types"), nb::kw_only(),
3352 nb::arg(
"arg_locs") = std::nullopt,
3353 "Creates and returns a new Block before this block "
3354 "(with given argument types and locations).")
3357 [](
PyBlock &
self,
const nb::args &pyArgTypes,
3358 const std::optional<nb::sequence> &pyArgLocs) {
3361 createBlock(nb::cast<nb::sequence>(pyArgTypes), pyArgLocs);
3364 return PyBlock(
self.getParentOperation(), block);
3366 nb::arg(
"arg_types"), nb::kw_only(),
3367 nb::arg(
"arg_locs") = std::nullopt,
3368 "Creates and returns a new Block after this block "
3369 "(with given argument types and locations).")
3374 MlirOperation firstOperation =
3376 return PyOperationIterator(
self.getParentOperation(),
3379 "Iterates over operations in the block.")
3382 return self.get().ptr == other.
get().ptr;
3384 .def(
"__eq__", [](
PyBlock &
self, nb::object &other) {
return false; })
3396 return printAccum.
join();
3398 "Returns the assembly form of the block.")
3408 self.getParentOperation().getObject());
3410 nb::arg(
"operation"),
3411 "Appends an operation to this block. If the operation is currently "
3412 "in another block, it will be moved.");
3418 nb::class_<PyInsertionPoint>(m,
"InsertionPoint")
3419 .def(nb::init<PyBlock &>(), nb::arg(
"block"),
3420 "Inserts after the last operation but still inside the block.")
3421 .def(
"__enter__", &PyInsertionPoint::contextEnter)
3422 .def(
"__exit__", &PyInsertionPoint::contextExit,
3423 nb::arg(
"exc_type").none(), nb::arg(
"exc_value").none(),
3424 nb::arg(
"traceback").none())
3425 .def_prop_ro_static(
3428 auto *ip = PyThreadContextEntry::getDefaultInsertionPoint();
3430 throw nb::value_error(
"No current InsertionPoint");
3433 "Gets the InsertionPoint bound to the current thread or raises "
3434 "ValueError if none has been set")
3435 .def(nb::init<PyOperationBase &>(), nb::arg(
"beforeOperation"),
3436 "Inserts before a referenced operation.")
3437 .def_static(
"at_block_begin", &PyInsertionPoint::atBlockBegin,
3438 nb::arg(
"block"),
"Inserts at the beginning of the block.")
3439 .def_static(
"at_block_terminator", &PyInsertionPoint::atBlockTerminator,
3440 nb::arg(
"block"),
"Inserts before the block terminator.")
3441 .def(
"insert", &PyInsertionPoint::insert, nb::arg(
"operation"),
3442 "Inserts an operation.")
3445 "Returns the block that this InsertionPoint points to.")
3449 auto refOperation =
self.getRefOperation();
3451 return refOperation->getObject();
3454 "The reference operation before which new operations are "
3455 "inserted, or None if the insertion point is at the end of "
3461 nb::class_<PyAttribute>(m,
"Attribute")
3464 .def(nb::init<PyAttribute &>(), nb::arg(
"cast_from_type"),
3465 "Casts the passed attribute to the generic Attribute")
3475 throw MLIRError(
"Unable to parse attribute", errors.take());
3478 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
3479 "Parses an attribute from an assembly form. Raises an MLIRError on "
3483 [](
PyAttribute &
self) {
return self.getContext().getObject(); },
3484 "Context that owns the Attribute")
3485 .def_prop_ro(
"type",
3492 nb::keep_alive<0, 1>(),
"Binds a name to the attribute")
3495 .def(
"__eq__", [](
PyAttribute &
self, nb::object &other) {
return false; })
3509 return printAccum.
join();
3511 "Returns the assembly form of the Attribute.")
3520 printAccum.
parts.append(
"Attribute(");
3523 printAccum.
parts.append(
")");
3524 return printAccum.
join();
3526 .def_prop_ro(
"typeid",
3530 "mlirTypeID was expected to be non-null.");
3536 "mlirTypeID was expected to be non-null.");
3537 std::optional<nb::callable> typeCaster =
3541 return nb::cast(
self);
3542 return typeCaster.value()(
self);
3548 nb::class_<PyNamedAttribute>(m,
"NamedAttribute")
3552 printAccum.
parts.append(
"NamedAttribute(");
3553 printAccum.
parts.append(
3556 printAccum.
parts.append(
"=");
3560 printAccum.
parts.append(
")");
3561 return printAccum.
join();
3569 "The name of the NamedAttribute binding")
3573 nb::keep_alive<0, 1>(),
3574 "The underlying generic attribute of the NamedAttribute binding");
3579 nb::class_<PyType>(m,
"Type")
3582 .def(nb::init<PyType &>(), nb::arg(
"cast_from_type"),
3583 "Casts the passed type to the generic Type")
3593 throw MLIRError(
"Unable to parse type", errors.take());
3596 nb::arg(
"asm"), nb::arg(
"context").none() = nb::none(),
3599 "context", [](
PyType &
self) {
return self.getContext().getObject(); },
3600 "Context that owns the Type")
3601 .def(
"__eq__", [](
PyType &
self,
PyType &other) {
return self == other; })
3603 "__eq__", [](
PyType &
self, nb::object &other) {
return false; },
3604 nb::arg(
"other").none())
3617 return printAccum.
join();
3619 "Returns the assembly form of the type.")
3627 printAccum.
parts.append(
"Type(");
3630 printAccum.
parts.append(
")");
3631 return printAccum.
join();
3637 "mlirTypeID was expected to be non-null.");
3638 std::optional<nb::callable> typeCaster =
3642 return nb::cast(
self);
3643 return typeCaster.value()(
self);
3645 .def_prop_ro(
"typeid", [](
PyType &
self) -> MlirTypeID {
3649 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(
self)));
3650 throw nb::value_error(
3651 (origRepr + llvm::Twine(
" has no typeid.")).str().c_str());
3657 nb::class_<PyTypeID>(m,
"TypeID")
3666 [](
PyTypeID &
self,
const nb::object &other) {
return false; })
3670 .def(
"__hash__", [](
PyTypeID &
self) {
3677 nb::class_<PyValue>(m,
"Value")
3678 .def(nb::init<PyValue &>(), nb::keep_alive<0, 1>(), nb::arg(
"value"))
3684 "Context in which the value lives.")
3690 [](
PyValue &
self) -> nb::object {
3691 MlirValue v =
self.get();
3696 "expected the owner of the value in Python to match that in "
3698 return self.getParentOperation().getObject();
3703 return nb::cast(
PyBlock(
self.getParentOperation(), block));
3706 assert(
false &&
"Value must be a block argument or an op result");
3709 .def_prop_ro(
"uses",
3711 return PyOpOperandIterator(
3716 return self.get().ptr == other.
get().ptr;
3718 .def(
"__eq__", [](
PyValue &
self, nb::object other) {
return false; })
3727 printAccum.
parts.append(
"Value(");
3730 printAccum.
parts.append(
")");
3731 return printAccum.
join();
3736 [](
PyValue &
self,
bool useLocalScope) {
3741 MlirAsmState valueState =
3748 return printAccum.
join();
3750 nb::arg(
"use_local_scope") =
false)
3755 MlirAsmState valueState = state.get();
3759 return printAccum.
join();
3762 .def_prop_ro(
"type",
3771 "replace_all_uses_with",
3777 "replace_all_uses_except",
3778 [](MlirValue
self, MlirValue with,
PyOperation &exception) {
3779 MlirOperation exceptedUser = exception.
get();
3782 nb::arg(
"with"), nb::arg(
"exceptions"),
3785 "replace_all_uses_except",
3786 [](MlirValue
self, MlirValue with, nb::list exceptions) {
3789 for (nb::handle exception : exceptions) {
3790 exceptionOps.push_back(nb::cast<PyOperation &>(exception).
get());
3794 self, with,
static_cast<intptr_t
>(exceptionOps.size()),
3795 exceptionOps.data());
3797 nb::arg(
"with"), nb::arg(
"exceptions"),
3800 [](
PyValue &
self) {
return self.maybeDownCast(); });
3801 PyBlockArgument::bind(m);
3802 PyOpResult::bind(m);
3803 PyOpOperand::bind(m);
3805 nb::class_<PyAsmState>(m,
"AsmState")
3806 .def(nb::init<PyValue &, bool>(), nb::arg(
"value"),
3807 nb::arg(
"use_local_scope") =
false)
3808 .def(nb::init<PyOperationBase &, bool>(), nb::arg(
"op"),
3809 nb::arg(
"use_local_scope") =
false);
3814 nb::class_<PySymbolTable>(m,
"SymbolTable")
3815 .def(nb::init<PyOperationBase &>())
3816 .def(
"__getitem__", &PySymbolTable::dunderGetItem)
3817 .def(
"insert", &PySymbolTable::insert, nb::arg(
"operation"))
3818 .def(
"erase", &PySymbolTable::erase, nb::arg(
"operation"))
3819 .def(
"__delitem__", &PySymbolTable::dunderDel)
3820 .def(
"__contains__",
3826 .def_static(
"set_symbol_name", &PySymbolTable::setSymbolName,
3827 nb::arg(
"symbol"), nb::arg(
"name"))
3828 .def_static(
"get_symbol_name", &PySymbolTable::getSymbolName,
3830 .def_static(
"get_visibility", &PySymbolTable::getVisibility,
3832 .def_static(
"set_visibility", &PySymbolTable::setVisibility,
3833 nb::arg(
"symbol"), nb::arg(
"visibility"))
3834 .def_static(
"replace_all_symbol_uses",
3835 &PySymbolTable::replaceAllSymbolUses, nb::arg(
"old_symbol"),
3836 nb::arg(
"new_symbol"), nb::arg(
"from_op"))
3837 .def_static(
"walk_symbol_tables", &PySymbolTable::walkSymbolTables,
3838 nb::arg(
"from_op"), nb::arg(
"all_sym_uses_visible"),
3839 nb::arg(
"callback"));
3842 PyBlockArgumentList::bind(m);
3843 PyBlockIterator::bind(m);
3844 PyBlockList::bind(m);
3845 PyOperationIterator::bind(m);
3846 PyOperationList::bind(m);
3847 PyOpAttributeMap::bind(m);
3848 PyOpOperandIterator::bind(m);
3849 PyOpOperandList::bind(m);
3850 PyOpResultList::bind(m);
3851 PyOpSuccessors::bind(m);
3852 PyRegionIterator::bind(m);
3853 PyRegionList::bind(m);
3861 nb::register_exception_translator([](
const std::exception_ptr &p,
3867 std::rethrow_exception(p);
3871 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 const char kContextGetFileLocationDocstring[]
static const char kDumpDocstring[]
static const char kAppendBlockDocstring[]
static const char kContextGetFusedLocationDocstring[]
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 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()
Accumulates int a python file-like object, 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...
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.
PyOpView(const nanobind::object &operationObject)
static nanobind::object buildGeneric(const nanobind::object &cls, 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)
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 assumeVerified, nanobind::object fileObject, bool binary, bool skipRegions)
Implements the bound 'print' method and helps with others.
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
nanobind::object getAsm(bool binary, std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified, bool skipRegions)
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.
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 create(const std::string &name, std::optional< std::vector< PyType * >> results, std::optional< std::vector< PyValue * >> 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 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 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.
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()
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 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 MlirAttribute mlirSymbolTableInsert(MlirSymbolTable symbolTable, MlirOperation operation)
Inserts the given operation into the given symbol table.
MlirWalkOrder
Traversal order for operation walk.
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 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 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 MlirDialect mlirAttributeGetDialect(MlirAttribute attribute)
Gets the dialect of the attribute.
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 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 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 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 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 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 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 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 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 MlirBlock mlirModuleGetBody(MlirModule module)
Gets the body of the module, i.e. the only block it contains.
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 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 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 nb::callable dundeGetItemNamed(const std::string &attributeKind)
static void dundeSetItemNamed(const std::string &attributeKind, nb::callable func, bool replace)
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)