21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/SmallVector.h"
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
81 A new "detached" Operation object. Detached operations can be added
82 to blocks, which causes them to become "attached."
86 R
"(Prints the assembly form of the operation to a file like object.
89 file: The file like object to write to. Defaults to sys.stdout.
90 binary: Whether to write bytes (True) or str (False). Defaults to False.
91 large_elements_limit: Whether to elide elements attributes above this
92 number of elements. Defaults to None (no limit).
93 enable_debug_info: Whether to print debug/location information. Defaults
95 pretty_debug_info: Whether to format debug information for easier reading
96 by a human (warning: the result is unparseable).
97 print_generic_op_form: Whether to print the generic assembly forms of all
98 ops. Defaults to False.
99 use_local_Scope: Whether to print in a way that is more optimized for
100 multi-threaded access but may not be consistent with how the overall
102 assume_verified: By default, if not printing generic form, the verifier
103 will be run and if it fails, generic form will be printed with a comment
104 about failed verification. While a reasonable default for interactive use,
105 for systematic use, it is often better for the caller to verify explicitly
106 and report failures in a more robust fashion. Set this to True if doing this
107 in order to avoid running a redundant verification. If the IR is actually
108 invalid, behavior is undefined.
112 R
"(Gets the assembly form of the operation with all options available.
115 binary: Whether to return a bytes (True) or str (False) object. Defaults to
117 ... others ...: See the print() method for common keyword arguments for
118 configuring the printout.
120 Either a bytes or str object, depending on the setting of the 'binary'
125 R
"(Write the bytecode form of the operation to a file like object.
128 file: The file like object to write to.
132 R
"(Gets the assembly form of the operation with default options.
134 If more advanced control over the assembly formatting or I/O options is needed,
135 use the dedicated print or get_asm method, which supports keyword arguments to
140 R
"(Dumps a debug representation of the object to stderr.)";
143 R
"(Appends a new block, with argument types as positional args.
150 R
"(Returns the string form of the value.
152 If the value is a block argument, this is the assembly form of its type and the
153 position in the argument list. If the value is an operation result, this is
154 equivalent to printing the operation that produced it.
162 template <
class Func,
typename... Args>
164 py::object cf = py::cpp_function(f, args...);
165 return py::reinterpret_borrow<py::object>((PyClassMethod_New(cf.ptr())));
170 py::object dialectDescriptor) {
174 return py::cast(
PyDialect(std::move(dialectDescriptor)));
178 return (*dialectClass)(std::move(dialectDescriptor));
191 static void bind(py::module &m) {
193 py::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug", py::module_local())
206 throw py::key_error();
214 static void bind(py::module &m) {
215 py::class_<PyAttrBuilderMap>(m,
"AttrBuilder", py::module_local())
228 class PyRegionIterator {
231 : operation(std::move(operation)) {}
233 PyRegionIterator &dunderIter() {
return *
this; }
238 throw py::stop_iteration();
244 static void bind(py::module &m) {
245 py::class_<PyRegionIterator>(m,
"RegionIterator", py::module_local())
246 .def(
"__iter__", &PyRegionIterator::dunderIter)
247 .def(
"__next__", &PyRegionIterator::dunderNext);
259 PyRegionList(
PyOperationRef operation) : operation(std::move(operation)) {}
261 intptr_t dunderLen() {
266 PyRegion dunderGetItem(intptr_t index) {
268 if (index < 0 || index >= dunderLen()) {
270 "attempt to access out of bounds region");
276 static void bind(py::module &m) {
277 py::class_<PyRegionList>(m,
"RegionSequence", py::module_local())
278 .def(
"__len__", &PyRegionList::dunderLen)
279 .def(
"__getitem__", &PyRegionList::dunderGetItem);
286 class PyBlockIterator {
289 : operation(std::move(operation)), next(next) {}
291 PyBlockIterator &dunderIter() {
return *
this; }
296 throw py::stop_iteration();
299 PyBlock returnBlock(operation, next);
304 static void bind(py::module &m) {
305 py::class_<PyBlockIterator>(m,
"BlockIterator", py::module_local())
306 .def(
"__iter__", &PyBlockIterator::dunderIter)
307 .def(
"__next__", &PyBlockIterator::dunderNext);
321 : operation(std::move(operation)), region(region) {}
323 PyBlockIterator dunderIter() {
328 intptr_t dunderLen() {
329 operation->checkValid();
339 PyBlock dunderGetItem(intptr_t index) {
343 "attempt to access out of bounds block");
348 return PyBlock(operation, block);
353 throw SetPyError(PyExc_IndexError,
"attempt to access out of bounds block");
356 PyBlock appendBlock(
const py::args &pyArgTypes) {
360 argTypes.reserve(pyArgTypes.size());
361 argLocs.reserve(pyArgTypes.size());
362 for (
auto &pyArg : pyArgTypes) {
363 argTypes.push_back(pyArg.cast<
PyType &>());
372 return PyBlock(operation, block);
375 static void bind(py::module &m) {
376 py::class_<PyBlockList>(m,
"BlockList", py::module_local())
377 .def(
"__getitem__", &PyBlockList::dunderGetItem)
378 .def(
"__iter__", &PyBlockList::dunderIter)
379 .def(
"__len__", &PyBlockList::dunderLen)
388 class PyOperationIterator {
390 PyOperationIterator(
PyOperationRef parentOperation, MlirOperation next)
391 : parentOperation(std::move(parentOperation)), next(next) {}
393 PyOperationIterator &dunderIter() {
return *
this; }
395 py::object dunderNext() {
398 throw py::stop_iteration();
407 static void bind(py::module &m) {
408 py::class_<PyOperationIterator>(m,
"OperationIterator", py::module_local())
409 .def(
"__iter__", &PyOperationIterator::dunderIter)
410 .def(
"__next__", &PyOperationIterator::dunderNext);
422 class PyOperationList {
425 : parentOperation(std::move(parentOperation)), block(block) {}
427 PyOperationIterator dunderIter() {
429 return PyOperationIterator(parentOperation,
433 intptr_t dunderLen() {
434 parentOperation->checkValid();
444 py::object dunderGetItem(intptr_t index) {
445 parentOperation->checkValid();
448 "attempt to access out of bounds operation");
460 "attempt to access out of bounds operation");
463 static void bind(py::module &m) {
464 py::class_<PyOperationList>(m,
"OperationList", py::module_local())
465 .def(
"__getitem__", &PyOperationList::dunderGetItem)
466 .def(
"__iter__", &PyOperationList::dunderIter)
467 .def(
"__len__", &PyOperationList::dunderLen);
477 PyOpOperand(MlirOpOperand opOperand) : opOperand(opOperand) {}
479 py::object getOwner() {
488 static void bind(py::module &m) {
489 py::class_<PyOpOperand>(m,
"OpOperand", py::module_local())
490 .def_property_readonly(
"owner", &PyOpOperand::getOwner)
491 .def_property_readonly(
"operand_number",
492 &PyOpOperand::getOperandNumber);
496 MlirOpOperand opOperand;
499 class PyOpOperandIterator {
501 PyOpOperandIterator(MlirOpOperand opOperand) : opOperand(opOperand) {}
503 PyOpOperandIterator &dunderIter() {
return *
this; }
505 PyOpOperand dunderNext() {
507 throw py::stop_iteration();
509 PyOpOperand returnOpOperand(opOperand);
511 return returnOpOperand;
514 static void bind(py::module &m) {
515 py::class_<PyOpOperandIterator>(m,
"OpOperandIterator", py::module_local())
516 .def(
"__iter__", &PyOpOperandIterator::dunderIter)
517 .def(
"__next__", &PyOpOperandIterator::dunderNext);
521 MlirOpOperand opOperand;
531 py::gil_scoped_acquire acquire;
532 auto &liveContexts = getLiveContexts();
533 liveContexts[context.ptr] =
this;
536 PyMlirContext::~PyMlirContext() {
540 py::gil_scoped_acquire acquire;
541 getLiveContexts().erase(context.ptr);
552 throw py::error_already_set();
562 py::gil_scoped_acquire acquire;
563 auto &liveContexts = getLiveContexts();
564 auto it = liveContexts.find(context.ptr);
565 if (it == liveContexts.end()) {
568 py::object pyRef = py::cast(unownedContextWrapper);
569 assert(pyRef &&
"cast to py::object failed");
570 liveContexts[context.ptr] = unownedContextWrapper;
574 py::object pyRef = py::cast(it->second);
579 static LiveContextMap liveContexts;
588 for (
auto &op : liveOperations)
589 op.second.second->setInvalid();
590 size_t numInvalidated = liveOperations.size();
591 liveOperations.clear();
592 return numInvalidated;
602 const pybind11::object &excVal,
603 const pybind11::object &excTb) {
612 py::object pyHandlerObject =
613 py::cast(pyHandler, py::return_value_policy::take_ownership);
614 pyHandlerObject.inc_ref();
618 auto handlerCallback =
621 py::object pyDiagnosticObject =
622 py::cast(pyDiagnostic, py::return_value_policy::take_ownership);
629 py::gil_scoped_acquire gil;
631 result = py::cast<bool>(pyHandler->callback(pyDiagnostic));
632 }
catch (std::exception &e) {
633 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
635 pyHandler->hadError =
true;
642 auto deleteCallback = +[](
void *userData) {
644 assert(pyHandler->registeredID &&
"handler is not registered");
645 pyHandler->registeredID.reset();
648 py::object pyHandlerObject =
649 py::cast(pyHandler, py::return_value_policy::reference);
650 pyHandlerObject.dec_ref();
654 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
655 return pyHandlerObject;
662 if (self->ctx->emitErrorDiagnostics)
677 "An MLIR function requires a Context but none was provided in the call "
678 "or from the surrounding environment. Either pass to the function with "
679 "a 'context=' argument or establish a default using 'with Context():'");
689 static thread_local std::vector<PyThreadContextEntry> stack;
694 auto &stack = getStack();
697 return &stack.back();
700 void PyThreadContextEntry::push(FrameKind frameKind, py::object context,
701 py::object insertionPoint,
702 py::object location) {
703 auto &stack = getStack();
704 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
705 std::move(location));
709 if (stack.size() > 1) {
710 auto &prev = *(stack.rbegin() + 1);
711 auto ¤t = stack.back();
712 if (current.context.is(prev.context)) {
714 if (!current.insertionPoint)
715 current.insertionPoint = prev.insertionPoint;
716 if (!current.location)
717 current.location = prev.location;
725 return py::cast<PyMlirContext *>(context);
731 return py::cast<PyInsertionPoint *>(insertionPoint);
737 return py::cast<PyLocation *>(location);
741 auto *tos = getTopOfStack();
742 return tos ? tos->getContext() :
nullptr;
746 auto *tos = getTopOfStack();
747 return tos ? tos->getInsertionPoint() :
nullptr;
751 auto *tos = getTopOfStack();
752 return tos ? tos->getLocation() :
nullptr;
756 py::object contextObj = py::cast(context);
757 push(FrameKind::Context, contextObj,
764 auto &stack = getStack();
766 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Context enter/exit");
767 auto &tos = stack.back();
768 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
769 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Context enter/exit");
775 py::object contextObj =
777 py::object insertionPointObj = py::cast(insertionPoint);
778 push(FrameKind::InsertionPoint,
782 return insertionPointObj;
786 auto &stack = getStack();
789 "Unbalanced InsertionPoint enter/exit");
790 auto &tos = stack.back();
791 if (tos.frameKind != FrameKind::InsertionPoint &&
792 tos.getInsertionPoint() != &insertionPoint)
794 "Unbalanced InsertionPoint enter/exit");
800 py::object locationObj = py::cast(location);
801 push(FrameKind::Location, contextObj,
808 auto &stack = getStack();
810 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Location enter/exit");
811 auto &tos = stack.back();
812 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
813 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Location enter/exit");
823 if (materializedNotes) {
824 for (
auto ¬eObject : *materializedNotes) {
825 PyDiagnostic *note = py::cast<PyDiagnostic *>(noteObject);
833 : context(context), callback(std::move(callback)) {}
842 assert(!registeredID &&
"should have unregistered");
848 void PyDiagnostic::checkValid() {
850 throw std::invalid_argument(
851 "Diagnostic is invalid (used outside of callback)");
869 py::object fileObject = py::module::import(
"io").attr(
"StringIO")();
872 return fileObject.attr(
"getvalue")();
877 if (materializedNotes)
878 return *materializedNotes;
880 materializedNotes = py::tuple(numNotes);
881 for (intptr_t i = 0; i < numNotes; ++i) {
885 return *materializedNotes;
889 std::vector<DiagnosticInfo> notes;
902 {key.data(), key.size()});
904 throw SetPyError(attrError ? PyExc_AttributeError : PyExc_IndexError,
905 Twine(
"Dialect '") + key +
"' not found");
911 return py::reinterpret_steal<py::object>(
916 MlirDialectRegistry rawRegistry =
919 throw py::error_already_set();
934 throw py::error_already_set();
944 const pybind11::object &excVal,
945 const pybind11::object &excTb) {
954 "An MLIR function requires a Location but none was provided in the "
955 "call or from the surrounding environment. Either pass to the function "
956 "with a 'loc=' argument or establish a default using 'with loc:'");
969 py::gil_scoped_acquire acquire;
970 auto &liveModules =
getContext()->liveModules;
971 assert(liveModules.count(module.ptr) == 1 &&
972 "destroying module not in live map");
973 liveModules.erase(module.ptr);
981 py::gil_scoped_acquire acquire;
982 auto &liveModules = contextRef->liveModules;
983 auto it = liveModules.find(module.ptr);
984 if (it == liveModules.end()) {
991 py::cast(unownedModule, py::return_value_policy::take_ownership);
992 unownedModule->handle = pyRef;
993 liveModules[module.ptr] =
994 std::make_pair(unownedModule->handle, unownedModule);
995 return PyModuleRef(unownedModule, std::move(pyRef));
998 PyModule *existing = it->second.second;
999 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
1006 throw py::error_already_set();
1018 PyOperation::PyOperation(
PyMlirContextRef contextRef, MlirOperation operation)
1025 auto &liveOperations =
getContext()->liveOperations;
1026 assert(liveOperations.count(operation.ptr) == 1 &&
1027 "destroying operation not in live map");
1028 liveOperations.erase(operation.ptr);
1035 MlirOperation operation,
1036 py::object parentKeepAlive) {
1037 auto &liveOperations = contextRef->liveOperations;
1040 new PyOperation(std::move(contextRef), operation);
1045 py::cast(unownedOperation, py::return_value_policy::take_ownership);
1046 unownedOperation->handle = pyRef;
1047 if (parentKeepAlive) {
1048 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
1050 liveOperations[operation.ptr] = std::make_pair(pyRef, unownedOperation);
1055 MlirOperation operation,
1056 py::object parentKeepAlive) {
1057 auto &liveOperations = contextRef->liveOperations;
1058 auto it = liveOperations.find(operation.ptr);
1059 if (it == liveOperations.end()) {
1061 return createInstance(std::move(contextRef), operation,
1062 std::move(parentKeepAlive));
1066 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
1071 MlirOperation operation,
1072 py::object parentKeepAlive) {
1073 auto &liveOperations = contextRef->liveOperations;
1074 assert(liveOperations.count(operation.ptr) == 0 &&
1075 "cannot create detached operation that already exists");
1076 (void)liveOperations;
1078 PyOperationRef created = createInstance(std::move(contextRef), operation,
1079 std::move(parentKeepAlive));
1080 created->attached =
false;
1085 const std::string &sourceStr,
1086 const std::string &sourceName) {
1092 throw MLIRError(
"Unable to parse operation assembly", errors.
take());
1098 throw SetPyError(PyExc_RuntimeError,
"the operation has been invalidated");
1103 std::optional<int64_t> largeElementsLimit,
1104 bool enableDebugInfo,
bool prettyDebugInfo,
1105 bool printGenericOpForm,
bool useLocalScope,
1106 bool assumeVerified) {
1109 if (fileObject.is_none())
1110 fileObject = py::module::import(
"sys").attr(
"stdout");
1113 if (largeElementsLimit)
1115 if (enableDebugInfo)
1118 if (printGenericOpForm)
1140 std::optional<int64_t> largeElementsLimit,
1141 bool enableDebugInfo,
bool prettyDebugInfo,
1142 bool printGenericOpForm,
bool useLocalScope,
1143 bool assumeVerified) {
1144 py::object fileObject;
1146 fileObject = py::module::import(
"io").attr(
"BytesIO")();
1148 fileObject = py::module::import(
"io").attr(
"StringIO")();
1150 print(fileObject, binary,
1158 return fileObject.attr(
"getvalue")();
1167 operation.parentKeepAlive = otherOp.parentKeepAlive;
1176 operation.parentKeepAlive = otherOp.parentKeepAlive;
1190 throw SetPyError(PyExc_ValueError,
"Detached operations have no parent");
1201 assert(!
mlirBlockIsNull(block) &&
"Attached operation has null parent");
1202 assert(parentOperation &&
"Operation has no parent");
1203 return PyBlock{std::move(*parentOperation), block};
1214 throw py::error_already_set();
1221 const py::object &maybeIp) {
1223 if (!maybeIp.is(py::cast(
false))) {
1225 if (maybeIp.is_none()) {
1228 ip = py::cast<PyInsertionPoint *>(maybeIp);
1236 std::optional<std::vector<PyType *>> results,
1237 std::optional<std::vector<PyValue *>> operands,
1238 std::optional<py::dict> attributes,
1239 std::optional<std::vector<PyBlock *>> successors,
1241 const py::object &maybeIp) {
1249 throw SetPyError(PyExc_ValueError,
"number of regions must be >= 0");
1253 mlirOperands.reserve(operands->size());
1254 for (
PyValue *operand : *operands) {
1256 throw SetPyError(PyExc_ValueError,
"operand value cannot be None");
1257 mlirOperands.push_back(operand->get());
1263 mlirResults.reserve(results->size());
1264 for (
PyType *result : *results) {
1267 throw SetPyError(PyExc_ValueError,
"result type cannot be None");
1268 mlirResults.push_back(*result);
1273 mlirAttributes.reserve(attributes->size());
1274 for (
auto &it : *attributes) {
1277 key = it.first.cast<std::string>();
1278 }
catch (py::cast_error &err) {
1279 std::string msg =
"Invalid attribute key (not a string) when "
1280 "attempting to create the operation \"" +
1281 name +
"\" (" + err.what() +
")";
1282 throw py::cast_error(msg);
1285 auto &attribute = it.second.cast<
PyAttribute &>();
1287 mlirAttributes.emplace_back(std::move(key), attribute);
1288 }
catch (py::reference_cast_error &) {
1291 "Found an invalid (`None`?) attribute value for the key \"" + key +
1292 "\" when attempting to create the operation \"" + name +
"\"";
1293 throw py::cast_error(msg);
1294 }
catch (py::cast_error &err) {
1295 std::string msg =
"Invalid attribute value for the key \"" + key +
1296 "\" when attempting to create the operation \"" +
1297 name +
"\" (" + err.what() +
")";
1298 throw py::cast_error(msg);
1304 mlirSuccessors.reserve(successors->size());
1305 for (
auto *successor : *successors) {
1308 throw SetPyError(PyExc_ValueError,
"successor block cannot be None");
1309 mlirSuccessors.push_back(successor->get());
1317 if (!mlirOperands.empty())
1319 mlirOperands.data());
1320 if (!mlirResults.empty())
1322 mlirResults.data());
1323 if (!mlirAttributes.empty()) {
1328 mlirNamedAttributes.reserve(mlirAttributes.size());
1329 for (
auto &it : mlirAttributes)
1335 mlirNamedAttributes.data());
1337 if (!mlirSuccessors.empty())
1339 mlirSuccessors.data());
1342 mlirRegions.resize(regions);
1343 for (
int i = 0; i < regions; ++i)
1346 mlirRegions.data());
1383 auto &liveOperations =
getContext()->liveOperations;
1384 if (liveOperations.count(operation.ptr))
1385 liveOperations.erase(operation.ptr);
1396 py::list operandList, std::optional<py::dict> attributes,
1397 std::optional<std::vector<PyBlock *>> successors,
1398 std::optional<int> regions,
1400 const py::object &maybeIp) {
1403 std::string name = py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
1409 py::object operandSegmentSpecObj = cls.attr(
"_ODS_OPERAND_SEGMENTS");
1410 py::object resultSegmentSpecObj = cls.attr(
"_ODS_RESULT_SEGMENTS");
1412 std::vector<int32_t> operandSegmentLengths;
1413 std::vector<int32_t> resultSegmentLengths;
1416 auto opRegionSpec = py::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
1417 int opMinRegionCount = std::get<0>(opRegionSpec);
1418 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1420 regions = opMinRegionCount;
1422 if (*regions < opMinRegionCount) {
1423 throw py::value_error(
1424 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1425 llvm::Twine(opMinRegionCount) +
1426 " regions but was built with regions=" + llvm::Twine(*regions))
1429 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1430 throw py::value_error(
1431 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1432 llvm::Twine(opMinRegionCount) +
1433 " regions but was built with regions=" + llvm::Twine(*regions))
1438 std::vector<PyType *> resultTypes;
1439 resultTypes.reserve(resultTypeList.size());
1440 if (resultSegmentSpecObj.is_none()) {
1444 resultTypes.push_back(py::cast<PyType *>(it.value()));
1445 if (!resultTypes.back())
1446 throw py::cast_error();
1447 }
catch (py::cast_error &err) {
1448 throw py::value_error((llvm::Twine(
"Result ") +
1449 llvm::Twine(it.index()) +
" of operation \"" +
1450 name +
"\" must be a Type (" + err.what() +
")")
1456 auto resultSegmentSpec = py::cast<std::vector<int>>(resultSegmentSpecObj);
1457 if (resultSegmentSpec.size() != resultTypeList.size()) {
1458 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1460 llvm::Twine(resultSegmentSpec.size()) +
1461 " result segments but was provided " +
1462 llvm::Twine(resultTypeList.size()))
1465 resultSegmentLengths.reserve(resultTypeList.size());
1466 for (
const auto &it :
1468 int segmentSpec = std::get<1>(it.value());
1469 if (segmentSpec == 1 || segmentSpec == 0) {
1472 auto *resultType = py::cast<PyType *>(std::get<0>(it.value()));
1474 resultTypes.push_back(resultType);
1475 resultSegmentLengths.push_back(1);
1476 }
else if (segmentSpec == 0) {
1478 resultSegmentLengths.push_back(0);
1480 throw py::cast_error(
"was None and result is not optional");
1482 }
catch (py::cast_error &err) {
1483 throw py::value_error((llvm::Twine(
"Result ") +
1484 llvm::Twine(it.index()) +
" of operation \"" +
1485 name +
"\" must be a Type (" + err.what() +
1489 }
else if (segmentSpec == -1) {
1492 if (std::get<0>(it.value()).is_none()) {
1494 resultSegmentLengths.push_back(0);
1497 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1498 for (py::object segmentItem : segment) {
1499 resultTypes.push_back(py::cast<PyType *>(segmentItem));
1500 if (!resultTypes.back()) {
1501 throw py::cast_error(
"contained a None item");
1504 resultSegmentLengths.push_back(segment.size());
1506 }
catch (std::exception &err) {
1510 throw py::value_error((llvm::Twine(
"Result ") +
1511 llvm::Twine(it.index()) +
" of operation \"" +
1512 name +
"\" must be a Sequence of Types (" +
1517 throw py::value_error(
"Unexpected segment spec");
1523 std::vector<PyValue *> operands;
1524 operands.reserve(operands.size());
1525 if (operandSegmentSpecObj.is_none()) {
1529 operands.push_back(py::cast<PyValue *>(it.value()));
1530 if (!operands.back())
1531 throw py::cast_error();
1532 }
catch (py::cast_error &err) {
1533 throw py::value_error((llvm::Twine(
"Operand ") +
1534 llvm::Twine(it.index()) +
" of operation \"" +
1535 name +
"\" must be a Value (" + err.what() +
")")
1541 auto operandSegmentSpec = py::cast<std::vector<int>>(operandSegmentSpecObj);
1542 if (operandSegmentSpec.size() != operandList.size()) {
1543 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1545 llvm::Twine(operandSegmentSpec.size()) +
1546 "operand segments but was provided " +
1547 llvm::Twine(operandList.size()))
1550 operandSegmentLengths.reserve(operandList.size());
1551 for (
const auto &it :
1553 int segmentSpec = std::get<1>(it.value());
1554 if (segmentSpec == 1 || segmentSpec == 0) {
1557 auto *operandValue = py::cast<PyValue *>(std::get<0>(it.value()));
1559 operands.push_back(operandValue);
1560 operandSegmentLengths.push_back(1);
1561 }
else if (segmentSpec == 0) {
1563 operandSegmentLengths.push_back(0);
1565 throw py::cast_error(
"was None and operand is not optional");
1567 }
catch (py::cast_error &err) {
1568 throw py::value_error((llvm::Twine(
"Operand ") +
1569 llvm::Twine(it.index()) +
" of operation \"" +
1570 name +
"\" must be a Value (" + err.what() +
1574 }
else if (segmentSpec == -1) {
1577 if (std::get<0>(it.value()).is_none()) {
1579 operandSegmentLengths.push_back(0);
1582 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1583 for (py::object segmentItem : segment) {
1584 operands.push_back(py::cast<PyValue *>(segmentItem));
1585 if (!operands.back()) {
1586 throw py::cast_error(
"contained a None item");
1589 operandSegmentLengths.push_back(segment.size());
1591 }
catch (std::exception &err) {
1595 throw py::value_error((llvm::Twine(
"Operand ") +
1596 llvm::Twine(it.index()) +
" of operation \"" +
1597 name +
"\" must be a Sequence of Values (" +
1602 throw py::value_error(
"Unexpected segment spec");
1608 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1611 attributes = py::dict(*attributes);
1613 attributes = py::dict();
1615 if (attributes->contains(
"result_segment_sizes") ||
1616 attributes->contains(
"operand_segment_sizes")) {
1617 throw py::value_error(
"Manually setting a 'result_segment_sizes' or "
1618 "'operand_segment_sizes' attribute is unsupported. "
1619 "Use Operation.create for such low-level access.");
1623 if (!resultSegmentLengths.empty()) {
1624 MlirAttribute segmentLengthAttr =
1626 resultSegmentLengths.data());
1627 (*attributes)[
"result_segment_sizes"] =
1632 if (!operandSegmentLengths.empty()) {
1633 MlirAttribute segmentLengthAttr =
1635 operandSegmentLengths.data());
1636 (*attributes)[
"operand_segment_sizes"] =
1643 std::move(resultTypes),
1644 std::move(operands),
1645 std::move(attributes),
1646 std::move(successors),
1647 *regions, location, maybeIp);
1655 py::handle opViewType = py::detail::get_type_handle(
typeid(
PyOpView),
true);
1656 py::object instance = cls.attr(
"__new__")(cls);
1657 opViewType.attr(
"__init__")(instance, operation);
1665 operationObject(operation.getRef().getObject()) {}
1674 : refOperation(beforeOperationBase.getOperation().getRef()),
1675 block((*refOperation)->getBlock()) {}
1681 "Attempt to insert operation that is already attached");
1682 block.getParentOperation()->checkValid();
1683 MlirOperation beforeOp = {
nullptr};
1686 (*refOperation)->checkValid();
1687 beforeOp = (*refOperation)->get();
1693 throw py::index_error(
"Cannot insert operation at the end of a block "
1694 "that already has a terminator. Did you mean to "
1695 "use 'InsertionPoint.at_block_terminator(block)' "
1696 "versus 'InsertionPoint(block)'?");
1719 throw SetPyError(PyExc_ValueError,
"Block has no terminator");
1730 const pybind11::object &excVal,
1731 const pybind11::object &excTb) {
1750 throw py::error_already_set();
1760 : ownedName(new std::string(std::move(ownedName))) {
1782 throw py::error_already_set();
1798 throw py::error_already_set();
1799 MlirOperation owner;
1805 throw py::error_already_set();
1809 return PyValue(ownerRef, value);
1817 : operation(operation.getOperation().getRef()) {
1820 throw py::cast_error(
"Operation is not a Symbol Table.");
1825 operation->checkValid();
1829 throw py::key_error(
"Symbol '" + name +
"' not in the symbol table.");
1832 operation.getObject())
1837 operation->checkValid();
1848 erase(py::cast<PyOperationBase &>(operation));
1852 operation->checkValid();
1857 throw py::value_error(
"Expected operation to have a symbol name.");
1868 MlirAttribute existingNameAttr =
1871 throw py::value_error(
"Expected operation to have a symbol name.");
1876 const std::string &name) {
1881 MlirAttribute existingNameAttr =
1884 throw py::value_error(
"Expected operation to have a symbol name.");
1885 MlirAttribute newNameAttr =
1894 MlirAttribute existingVisAttr =
1897 throw py::value_error(
"Expected operation to have a symbol visibility.");
1902 const std::string &visibility) {
1903 if (visibility !=
"public" && visibility !=
"private" &&
1904 visibility !=
"nested")
1905 throw py::value_error(
1906 "Expected visibility to be 'public', 'private' or 'nested'");
1910 MlirAttribute existingVisAttr =
1913 throw py::value_error(
"Expected operation to have a symbol visibility.");
1920 const std::string &newSymbol,
1928 throw py::value_error(
"Symbol rename failed");
1932 bool allSymUsesVisible,
1933 py::object callback) {
1938 py::object callback;
1940 std::string exceptionWhat;
1941 py::object exceptionType;
1944 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
1946 fromOperation.
get(), allSymUsesVisible,
1947 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
1948 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
1950 PyOperation::forOperation(calleeUserData->context, foundOp);
1951 if (calleeUserData->gotException)
1954 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
1955 } catch (py::error_already_set &e) {
1956 calleeUserData->gotException =
true;
1957 calleeUserData->exceptionWhat = e.what();
1958 calleeUserData->exceptionType = e.type();
1961 static_cast<void *
>(&userData));
1962 if (userData.gotException) {
1963 std::string message(
"Exception raised in callback: ");
1964 message.append(userData.exceptionWhat);
1965 throw std::runtime_error(message);
1973 template <
typename DerivedTy>
1974 class PyConcreteValue :
public PyValue {
1980 using ClassTy = py::class_<DerivedTy, PyValue>;
1981 using IsAFunctionTy = bool (*)(MlirValue);
1983 PyConcreteValue() =
default;
1985 :
PyValue(operationRef, value) {}
1986 PyConcreteValue(
PyValue &orig)
1987 : PyConcreteValue(orig.getParentOperation(), castFrom(orig)) {}
1991 static MlirValue castFrom(
PyValue &orig) {
1992 if (!DerivedTy::isaFunction(orig.
get())) {
1993 auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
1994 throw SetPyError(PyExc_ValueError, Twine(
"Cannot cast value to ") +
1995 DerivedTy::pyClassName +
1996 " (from " + origRepr +
")");
2002 static void bind(py::module &m) {
2003 auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
2004 cls.def(py::init<PyValue &>(), py::keep_alive<0, 1>(), py::arg(
"value"));
2007 [](
PyValue &otherValue) ->
bool {
2008 return DerivedTy::isaFunction(otherValue);
2010 py::arg(
"other_value"));
2011 DerivedTy::bindDerived(cls);
2015 static void bindDerived(ClassTy &m) {}
2019 class PyBlockArgument :
public PyConcreteValue<PyBlockArgument> {
2022 static constexpr
const char *pyClassName =
"BlockArgument";
2023 using PyConcreteValue::PyConcreteValue;
2025 static void bindDerived(ClassTy &c) {
2026 c.def_property_readonly(
"owner", [](PyBlockArgument &
self) {
2027 return PyBlock(
self.getParentOperation(),
2030 c.def_property_readonly(
"arg_number", [](PyBlockArgument &
self) {
2035 [](PyBlockArgument &
self,
PyType type) {
2043 class PyOpResult :
public PyConcreteValue<PyOpResult> {
2046 static constexpr
const char *pyClassName =
"OpResult";
2047 using PyConcreteValue::PyConcreteValue;
2049 static void bindDerived(ClassTy &c) {
2050 c.def_property_readonly(
"owner", [](PyOpResult &
self) {
2054 "expected the owner of the value in Python to match that in the IR");
2055 return self.getParentOperation().getObject();
2057 c.def_property_readonly(
"result_number", [](PyOpResult &
self) {
2064 template <
typename Container>
2065 static std::vector<PyType> getValueTypes(Container &container,
2067 std::vector<PyType> result;
2068 result.reserve(container.size());
2069 for (
int i = 0, e = container.size(); i < e; ++i) {
2080 class PyBlockArgumentList
2081 :
public Sliceable<PyBlockArgumentList, PyBlockArgument> {
2083 static constexpr
const char *pyClassName =
"BlockArgumentList";
2086 intptr_t startIndex = 0, intptr_t length = -1,
2091 operation(std::move(operation)), block(block) {}
2093 static void bindDerived(ClassTy &c) {
2094 c.def_property_readonly(
"types", [](PyBlockArgumentList &
self) {
2095 return getValueTypes(
self,
self.operation->getContext());
2101 friend class Sliceable<PyBlockArgumentList, PyBlockArgument>;
2104 intptr_t getRawNumElements() {
2105 operation->checkValid();
2110 PyBlockArgument getRawElement(intptr_t pos) {
2112 return PyBlockArgument(operation, argument);
2116 PyBlockArgumentList slice(intptr_t startIndex, intptr_t length,
2118 return PyBlockArgumentList(operation, block, startIndex, length, step);
2129 class PyOpOperandList :
public Sliceable<PyOpOperandList, PyValue> {
2131 static constexpr
const char *pyClassName =
"OpOperandList";
2133 PyOpOperandList(
PyOperationRef operation, intptr_t startIndex = 0,
2134 intptr_t length = -1, intptr_t step = 1)
2139 operation(operation) {}
2141 void dunderSetItem(intptr_t index,
PyValue value) {
2142 index = wrapIndex(index);
2146 static void bindDerived(ClassTy &c) {
2147 c.def(
"__setitem__", &PyOpOperandList::dunderSetItem);
2154 intptr_t getRawNumElements() {
2159 PyValue getRawElement(intptr_t pos) {
2161 MlirOperation owner;
2167 assert(
false &&
"Value must be an block arg or op result.");
2169 PyOperation::forOperation(operation->getContext(), owner);
2170 return PyValue(pyOwner, operand);
2173 PyOpOperandList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2174 return PyOpOperandList(operation, startIndex, length, step);
2184 class PyOpResultList :
public Sliceable<PyOpResultList, PyOpResult> {
2186 static constexpr
const char *pyClassName =
"OpResultList";
2188 PyOpResultList(
PyOperationRef operation, intptr_t startIndex = 0,
2189 intptr_t length = -1, intptr_t step = 1)
2194 operation(operation) {}
2196 static void bindDerived(ClassTy &c) {
2197 c.def_property_readonly(
"types", [](PyOpResultList &
self) {
2198 return getValueTypes(
self,
self.operation->getContext());
2204 friend class Sliceable<PyOpResultList, PyOpResult>;
2206 intptr_t getRawNumElements() {
2207 operation->checkValid();
2211 PyOpResult getRawElement(intptr_t index) {
2213 return PyOpResult(value);
2216 PyOpResultList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2217 return PyOpResultList(operation, startIndex, length, step);
2225 class PyOpAttributeMap {
2228 : operation(std::move(operation)) {}
2230 PyAttribute dunderGetItemNamed(
const std::string &name) {
2235 "attempt to access a non-existent attribute");
2237 return PyAttribute(operation->getContext(), attr);
2241 if (index < 0 || index >= dunderLen()) {
2243 "attempt to access out of bounds attribute");
2253 void dunderSetItem(
const std::string &name,
const PyAttribute &attr) {
2258 void dunderDelItem(
const std::string &name) {
2263 "attempt to delete a non-existent attribute");
2266 intptr_t dunderLen() {
2270 bool dunderContains(
const std::string &name) {
2275 static void bind(py::module &m) {
2276 py::class_<PyOpAttributeMap>(m,
"OpAttributeMap", py::module_local())
2277 .def(
"__contains__", &PyOpAttributeMap::dunderContains)
2278 .def(
"__len__", &PyOpAttributeMap::dunderLen)
2279 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
2280 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
2281 .def(
"__setitem__", &PyOpAttributeMap::dunderSetItem)
2282 .def(
"__delitem__", &PyOpAttributeMap::dunderDelItem);
2299 py::enum_<MlirDiagnosticSeverity>(m,
"DiagnosticSeverity", py::module_local())
2308 py::class_<PyDiagnostic>(m,
"Diagnostic", py::module_local())
2309 .def_property_readonly(
"severity", &PyDiagnostic::getSeverity)
2310 .def_property_readonly(
"location", &PyDiagnostic::getLocation)
2311 .def_property_readonly(
"message", &PyDiagnostic::getMessage)
2312 .def_property_readonly(
"notes", &PyDiagnostic::getNotes)
2314 if (!
self.isValid())
2315 return "<Invalid Diagnostic>";
2316 return self.getMessage();
2319 py::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo",
2322 .def_readonly(
"severity", &PyDiagnostic::DiagnosticInfo::severity)
2323 .def_readonly(
"location", &PyDiagnostic::DiagnosticInfo::location)
2324 .def_readonly(
"message", &PyDiagnostic::DiagnosticInfo::message)
2325 .def_readonly(
"notes", &PyDiagnostic::DiagnosticInfo::notes)
2329 py::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler", py::module_local())
2330 .def(
"detach", &PyDiagnosticHandler::detach)
2331 .def_property_readonly(
"attached", &PyDiagnosticHandler::isAttached)
2332 .def_property_readonly(
"had_error", &PyDiagnosticHandler::getHadError)
2333 .def(
"__enter__", &PyDiagnosticHandler::contextEnter)
2334 .def(
"__exit__", &PyDiagnosticHandler::contextExit);
2342 py::class_<PyMlirContext>(m,
"_BaseContext", py::module_local())
2343 .def(py::init<>(&PyMlirContext::createNewContextForInit))
2344 .def_static(
"_get_live_count", &PyMlirContext::getLiveCount)
2345 .def(
"_get_context_again",
2350 .def(
"_get_live_operation_count", &PyMlirContext::getLiveOperationCount)
2351 .def(
"_clear_live_operations", &PyMlirContext::clearLiveOperations)
2352 .def(
"_get_live_module_count", &PyMlirContext::getLiveModuleCount)
2354 &PyMlirContext::getCapsule)
2356 .def(
"__enter__", &PyMlirContext::contextEnter)
2357 .def(
"__exit__", &PyMlirContext::contextExit)
2358 .def_property_readonly_static(
2361 auto *context = PyThreadContextEntry::getDefaultContext();
2363 throw SetPyError(PyExc_ValueError,
"No current Context");
2366 "Gets the Context bound to the current thread or raises ValueError")
2367 .def_property_readonly(
2370 "Gets a container for accessing dialects by name")
2371 .def_property_readonly(
2373 "Alias for 'dialect'")
2375 "get_dialect_descriptor",
2378 self.get(), {name.data(), name.size()});
2381 Twine(
"Dialect '") + name +
"' not found");
2385 py::arg(
"dialect_name"),
2386 "Gets or loads a dialect by name, returning its descriptor object")
2388 "allow_unregistered_dialects",
2395 .def(
"attach_diagnostic_handler", &PyMlirContext::attachDiagnosticHandler,
2396 py::arg(
"callback"),
2397 "Attaches a diagnostic handler that will receive callbacks")
2399 "enable_multithreading",
2405 "is_registered_operation",
2410 py::arg(
"operation_name"))
2412 "append_dialect_registry",
2416 py::arg(
"registry"))
2417 .def_property(
"emit_error_diagnostics",
nullptr,
2418 &PyMlirContext::setEmitErrorDiagnostics,
2419 "Emit error diagnostics to diagnostic handlers. By default "
2420 "error diagnostics are captured and reported through "
2421 "MLIRError exceptions.")
2422 .def(
"load_all_available_dialects", [](
PyMlirContext &
self) {
2429 py::class_<PyDialectDescriptor>(m,
"DialectDescriptor", py::module_local())
2430 .def_property_readonly(
"namespace",
2438 std::string repr(
"<DialectDescriptor ");
2447 py::class_<PyDialects>(m,
"Dialects", py::module_local())
2450 MlirDialect dialect =
2451 self.getDialectForKey(keyName,
false);
2452 py::object descriptor =
2456 .def(
"__getattr__", [=](
PyDialects &
self, std::string attrName) {
2457 MlirDialect dialect =
2458 self.getDialectForKey(attrName,
true);
2459 py::object descriptor =
2467 py::class_<PyDialect>(m,
"Dialect", py::module_local())
2468 .def(py::init<py::object>(), py::arg(
"descriptor"))
2469 .def_property_readonly(
2470 "descriptor", [](
PyDialect &
self) {
return self.getDescriptor(); })
2471 .def(
"__repr__", [](py::object
self) {
2472 auto clazz =
self.attr(
"__class__");
2473 return py::str(
"<Dialect ") +
2474 self.attr(
"descriptor").attr(
"namespace") + py::str(
" (class ") +
2475 clazz.attr(
"__module__") + py::str(
".") +
2476 clazz.attr(
"__name__") + py::str(
")>");
2482 py::class_<PyDialectRegistry>(m,
"DialectRegistry", py::module_local())
2484 &PyDialectRegistry::getCapsule)
2491 py::class_<PyLocation>(m,
"Location", py::module_local())
2494 .def(
"__enter__", &PyLocation::contextEnter)
2495 .def(
"__exit__", &PyLocation::contextExit)
2500 .def(
"__eq__", [](
PyLocation &
self, py::object other) {
return false; })
2501 .def_property_readonly_static(
2504 auto *loc = PyThreadContextEntry::getDefaultLocation();
2506 throw SetPyError(PyExc_ValueError,
"No current Location");
2509 "Gets the Location bound to the current thread or raises ValueError")
2516 py::arg(
"context") = py::none(),
2517 "Gets a Location representing an unknown location")
2520 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
2523 throw py::value_error(
"No caller frames provided");
2524 MlirLocation caller = frames.back().get();
2531 py::arg(
"callee"), py::arg(
"frames"), py::arg(
"context") = py::none(),
2535 [](std::string filename,
int line,
int col,
2542 py::arg(
"filename"), py::arg(
"line"), py::arg(
"col"),
2546 [](
const std::vector<PyLocation> &pyLocations,
2547 std::optional<PyAttribute> metadata,
2550 locations.reserve(pyLocations.size());
2551 for (
auto &pyLocation : pyLocations)
2552 locations.push_back(pyLocation.get());
2554 context->
get(), locations.size(), locations.data(),
2555 metadata ? metadata->get() : MlirAttribute{0});
2556 return PyLocation(context->getRef(), location);
2558 py::arg(
"locations"), py::arg(
"metadata") = py::none(),
2562 [](std::string name, std::optional<PyLocation> childLoc,
2568 childLoc ? childLoc->get()
2571 py::arg(
"name"), py::arg(
"childLoc") = py::none(),
2579 py::arg(
"attribute"), py::arg(
"context") = py::none(),
2580 "Gets a Location from a LocationAttr")
2581 .def_property_readonly(
2583 [](
PyLocation &
self) {
return self.getContext().getObject(); },
2584 "Context that owns the Location")
2585 .def_property_readonly(
2591 "Get the underlying LocationAttr")
2597 py::arg(
"message"),
"Emits an error at this location")
2602 return printAccum.
join();
2608 py::class_<PyModule>(m,
"Module", py::module_local())
2618 throw MLIRError(
"Unable to parse module assembly", errors.take());
2619 return PyModule::forModule(module).releaseObject();
2621 py::arg(
"asm"), py::arg(
"context") = py::none(),
2627 return PyModule::forModule(module).releaseObject();
2629 py::arg(
"loc") = py::none(),
"Creates an empty module")
2630 .def_property_readonly(
2632 [](
PyModule &
self) {
return self.getContext().getObject(); },
2633 "Context that created the Module")
2634 .def_property_readonly(
2637 return PyOperation::forOperation(
self.getContext(),
2639 self.getRef().releaseObject())
2642 "Accesses the module as an operation")
2643 .def_property_readonly(
2648 self.getRef().releaseObject());
2652 "Return the block for this module")
2661 [](py::object
self) {
2663 return self.attr(
"operation").attr(
"__str__")();
2670 py::class_<PyOperationBase>(m,
"_OperationBase", py::module_local())
2673 return self.getOperation().getCapsule();
2685 .def_property_readonly(
"attributes",
2687 return PyOpAttributeMap(
2688 self.getOperation().getRef());
2690 .def_property_readonly(
"operands",
2692 return PyOpOperandList(
2693 self.getOperation().getRef());
2695 .def_property_readonly(
"regions",
2697 return PyRegionList(
2698 self.getOperation().getRef());
2700 .def_property_readonly(
2703 return PyOpResultList(
self.getOperation().getRef());
2705 "Returns the list of Operation results.")
2706 .def_property_readonly(
2709 auto &operation =
self.getOperation();
2711 if (numResults != 1) {
2715 Twine(
"Cannot call .result on operation ") +
2716 StringRef(name.data, name.length) +
" which has " +
2718 " results (it is only valid for operations with a "
2721 return PyOpResult(operation.getRef(),
2724 "Shortcut to get an op result if it has only one (throws an error "
2726 .def_property_readonly(
2733 "Returns the source location the operation was defined or derived "
2738 return self.getAsm(
false,
2746 "Returns the assembly form of the operation.")
2749 py::arg(
"file") = py::none(), py::arg(
"binary") =
false,
2750 py::arg(
"large_elements_limit") = py::none(),
2751 py::arg(
"enable_debug_info") =
false,
2752 py::arg(
"pretty_debug_info") =
false,
2753 py::arg(
"print_generic_op_form") =
false,
2754 py::arg(
"use_local_scope") =
false,
2756 .def(
"write_bytecode", &PyOperationBase::writeBytecode, py::arg(
"file"),
2758 .def(
"get_asm", &PyOperationBase::getAsm,
2760 py::arg(
"binary") =
false,
2761 py::arg(
"large_elements_limit") = py::none(),
2762 py::arg(
"enable_debug_info") =
false,
2763 py::arg(
"pretty_debug_info") =
false,
2764 py::arg(
"print_generic_op_form") =
false,
2765 py::arg(
"use_local_scope") =
false,
2768 "Verify the operation. Raises MLIRError if verification fails, and "
2769 "returns true otherwise.")
2770 .def(
"move_after", &PyOperationBase::moveAfter, py::arg(
"other"),
2771 "Puts self immediately after the other operation in its parent "
2773 .def(
"move_before", &PyOperationBase::moveBefore, py::arg(
"other"),
2774 "Puts self immediately before the other operation in its parent "
2777 "detach_from_parent",
2782 throw py::value_error(
"Detached operation has no parent.");
2787 "Detaches the operation from its parent block.");
2789 py::class_<PyOperation, PyOperationBase>(m,
"Operation", py::module_local())
2790 .def_static(
"create", &PyOperation::create, py::arg(
"name"),
2791 py::arg(
"results") = py::none(),
2792 py::arg(
"operands") = py::none(),
2793 py::arg(
"attributes") = py::none(),
2794 py::arg(
"successors") = py::none(), py::arg(
"regions") = 0,
2795 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
2799 [](
const std::string &sourceStr,
const std::string &sourceName,
2801 return PyOperation::parse(context->getRef(), sourceStr, sourceName)
2804 py::arg(
"source"), py::kw_only(), py::arg(
"source_name") =
"",
2805 py::arg(
"context") = py::none(),
2806 "Parses an operation. Supports both text assembly format and binary "
2808 .def_property_readonly(
"parent",
2810 auto parent =
self.getParentOperation();
2812 return parent->getObject();
2815 .def(
"erase", &PyOperation::erase)
2818 &PyOperation::getCapsule)
2820 .def_property_readonly(
"name",
2823 MlirOperation operation =
self.
get();
2828 .def_property_readonly(
2832 return self.getContext().getObject();
2834 "Context that owns the Operation")
2835 .def_property_readonly(
"opview", &PyOperation::createOpView);
2838 py::class_<PyOpView, PyOperationBase>(m,
"OpView", py::module_local())
2839 .def(py::init<py::object>(), py::arg(
"operation"))
2840 .def_property_readonly(
"operation", &PyOpView::getOperationObject)
2841 .def_property_readonly(
2844 return self.getOperation().getContext().getObject();
2846 "Context that owns the Operation")
2847 .def(
"__str__", [](
PyOpView &
self) {
2848 return py::str(
self.getOperationObject());
2850 opViewClass.attr(
"_ODS_REGIONS") = py::make_tuple(0,
true);
2851 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = py::none();
2852 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = py::none();
2854 &PyOpView::buildGeneric, py::arg(
"cls"), py::arg(
"results") = py::none(),
2855 py::arg(
"operands") = py::none(), py::arg(
"attributes") = py::none(),
2856 py::arg(
"successors") = py::none(), py::arg(
"regions") = py::none(),
2857 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
2858 "Builds a specific, generated OpView based on class level attributes.");
2860 [](
const py::object &cls,
const std::string &sourceStr,
2863 PyOperation::parse(context->getRef(), sourceStr, sourceName);
2870 std::string clsOpName =
2871 py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
2874 std::string_view parsedOpName(identifier.
data, identifier.
length);
2875 if (clsOpName != parsedOpName)
2876 throw MLIRError(Twine(
"Expected a '") + clsOpName +
"' op, got: '" +
2877 parsedOpName +
"'");
2878 return PyOpView::constructDerived(cls, *parsed.
get());
2880 py::arg(
"cls"), py::arg(
"source"), py::kw_only(),
2881 py::arg(
"source_name") =
"", py::arg(
"context") = py::none(),
2882 "Parses a specific, generated OpView based on class level attributes");
2887 py::class_<PyRegion>(m,
"Region", py::module_local())
2888 .def_property_readonly(
2891 return PyBlockList(
self.getParentOperation(),
self.get());
2893 "Returns a forward-optimized sequence of blocks.")
2894 .def_property_readonly(
2897 return self.getParentOperation()->createOpView();
2899 "Returns the operation owning this region.")
2905 return PyBlockIterator(
self.getParentOperation(), firstBlock);
2907 "Iterates over blocks in the region.")
2910 return self.get().ptr == other.
get().ptr;
2912 .def(
"__eq__", [](
PyRegion &
self, py::object &other) {
return false; });
2917 py::class_<PyBlock>(m,
"Block", py::module_local())
2918 .def_property_readonly(
2921 return self.getParentOperation()->createOpView();
2923 "Returns the owning operation of this block.")
2924 .def_property_readonly(
2928 return PyRegion(
self.getParentOperation(), region);
2930 "Returns the owning region of this block.")
2931 .def_property_readonly(
2934 return PyBlockArgumentList(
self.getParentOperation(),
self.get());
2936 "Returns a list of block arguments.")
2937 .def_property_readonly(
2940 return PyOperationList(
self.getParentOperation(),
self.get());
2942 "Returns a forward-optimized sequence of operations.")
2945 [](
PyRegion &parent, py::list pyArgTypes) {
2949 argTypes.reserve(pyArgTypes.size());
2950 argLocs.reserve(pyArgTypes.size());
2951 for (
auto &pyArg : pyArgTypes) {
2952 argTypes.push_back(pyArg.cast<
PyType &>());
2963 py::arg(
"parent"), py::arg(
"arg_types") = py::list(),
2964 "Creates and returns a new Block at the beginning of the given "
2965 "region (with given argument types).")
2969 MlirBlock b =
self.get();
2974 "Append this block to a region, transferring ownership if necessary")
2977 [](
PyBlock &
self, py::args pyArgTypes) {
2981 argTypes.reserve(pyArgTypes.size());
2982 argLocs.reserve(pyArgTypes.size());
2983 for (
auto &pyArg : pyArgTypes) {
2984 argTypes.push_back(pyArg.cast<
PyType &>());
2994 return PyBlock(
self.getParentOperation(), block);
2996 "Creates and returns a new Block before this block "
2997 "(with given argument types).")
3000 [](
PyBlock &
self, py::args pyArgTypes) {
3004 argTypes.reserve(pyArgTypes.size());
3005 argLocs.reserve(pyArgTypes.size());
3006 for (
auto &pyArg : pyArgTypes) {
3007 argTypes.push_back(pyArg.cast<
PyType &>());
3017 return PyBlock(
self.getParentOperation(), block);
3019 "Creates and returns a new Block after this block "
3020 "(with given argument types).")
3025 MlirOperation firstOperation =
3027 return PyOperationIterator(
self.getParentOperation(),
3030 "Iterates over operations in the block.")
3033 return self.get().ptr == other.
get().ptr;
3035 .def(
"__eq__", [](
PyBlock &
self, py::object &other) {
return false; })
3047 return printAccum.
join();
3049 "Returns the assembly form of the block.")
3059 self.getParentOperation().getObject());
3061 py::arg(
"operation"),
3062 "Appends an operation to this block. If the operation is currently "
3063 "in another block, it will be moved.");
3069 py::class_<PyInsertionPoint>(m,
"InsertionPoint", py::module_local())
3070 .def(py::init<PyBlock &>(), py::arg(
"block"),
3071 "Inserts after the last operation but still inside the block.")
3072 .def(
"__enter__", &PyInsertionPoint::contextEnter)
3073 .def(
"__exit__", &PyInsertionPoint::contextExit)
3074 .def_property_readonly_static(
3077 auto *ip = PyThreadContextEntry::getDefaultInsertionPoint();
3079 throw SetPyError(PyExc_ValueError,
"No current InsertionPoint");
3082 "Gets the InsertionPoint bound to the current thread or raises "
3083 "ValueError if none has been set")
3084 .def(py::init<PyOperationBase &>(), py::arg(
"beforeOperation"),
3085 "Inserts before a referenced operation.")
3086 .def_static(
"at_block_begin", &PyInsertionPoint::atBlockBegin,
3087 py::arg(
"block"),
"Inserts at the beginning of the block.")
3088 .def_static(
"at_block_terminator", &PyInsertionPoint::atBlockTerminator,
3089 py::arg(
"block"),
"Inserts before the block terminator.")
3090 .def(
"insert", &PyInsertionPoint::insert, py::arg(
"operation"),
3091 "Inserts an operation.")
3092 .def_property_readonly(
3094 "Returns the block that this InsertionPoint points to.");
3099 py::class_<PyAttribute>(m,
"Attribute", py::module_local())
3102 .def(py::init<PyAttribute &>(), py::arg(
"cast_from_type"),
3103 "Casts the passed attribute to the generic Attribute")
3105 &PyAttribute::getCapsule)
3114 throw MLIRError(
"Unable to parse attribute", errors.take());
3117 py::arg(
"asm"), py::arg(
"context") = py::none(),
3118 "Parses an attribute from an assembly form. Raises an MLIRError on "
3120 .def_property_readonly(
3122 [](
PyAttribute &
self) {
return self.getContext().getObject(); },
3123 "Context that owns the Attribute")
3124 .def_property_readonly(
"type",
3126 return PyType(
self.getContext()->getRef(),
3134 py::keep_alive<0, 1>(),
"Binds a name to the attribute")
3137 .def(
"__eq__", [](
PyAttribute &
self, py::object &other) {
return false; })
3151 return printAccum.
join();
3153 "Returns the assembly form of the Attribute.")
3161 printAccum.
parts.append(
"Attribute(");
3164 printAccum.
parts.append(
")");
3165 return printAccum.
join();
3171 py::class_<PyNamedAttribute>(m,
"NamedAttribute", py::module_local())
3175 printAccum.
parts.append(
"NamedAttribute(");
3176 printAccum.
parts.append(
3179 printAccum.
parts.append(
"=");
3183 printAccum.
parts.append(
")");
3184 return printAccum.
join();
3186 .def_property_readonly(
3192 "The name of the NamedAttribute binding")
3193 .def_property_readonly(
3198 auto contextRef = PyMlirContext::forContext(
3202 py::keep_alive<0, 1>(),
3203 "The underlying generic attribute of the NamedAttribute binding");
3208 py::class_<PyType>(m,
"Type", py::module_local())
3211 .def(py::init<PyType &>(), py::arg(
"cast_from_type"),
3212 "Casts the passed type to the generic Type")
3222 throw MLIRError(
"Unable to parse type", errors.take());
3223 return PyType(context->getRef(), type);
3225 py::arg(
"asm"), py::arg(
"context") = py::none(),
3227 .def_property_readonly(
3228 "context", [](
PyType &
self) {
return self.getContext().getObject(); },
3229 "Context that owns the Type")
3230 .def(
"__eq__", [](
PyType &
self,
PyType &other) {
return self == other; })
3231 .def(
"__eq__", [](
PyType &
self, py::object &other) {
return false; })
3244 return printAccum.
join();
3246 "Returns the assembly form of the type.")
3247 .def(
"__repr__", [](
PyType &
self) {
3253 printAccum.
parts.append(
"Type(");
3255 printAccum.
parts.append(
")");
3256 return printAccum.
join();
3262 py::class_<PyValue>(m,
"Value", py::module_local())
3265 .def_property_readonly(
3267 [](
PyValue &
self) {
return self.getParentOperation()->getContext(); },
3268 "Context in which the value lives.")
3272 .def_property_readonly(
3274 [](
PyValue &
self) -> py::object {
3275 MlirValue v =
self.get();
3280 "expected the owner of the value in Python to match that in "
3282 return self.getParentOperation().getObject();
3287 return py::cast(
PyBlock(
self.getParentOperation(), block));
3290 assert(
false &&
"Value must be a block argument or an op result");
3293 .def_property_readonly(
"uses",
3295 return PyOpOperandIterator(
3300 return self.get().ptr == other.
get().ptr;
3302 .def(
"__eq__", [](
PyValue &
self, py::object other) {
return false; })
3311 printAccum.
parts.append(
"Value(");
3314 printAccum.
parts.append(
")");
3315 return printAccum.
join();
3318 .def_property_readonly(
"type", [](
PyValue &
self) {
3319 return PyType(
self.getParentOperation()->getContext(),
3322 PyBlockArgument::bind(m);
3323 PyOpResult::bind(m);
3324 PyOpOperand::bind(m);
3329 py::class_<PySymbolTable>(m,
"SymbolTable", py::module_local())
3330 .def(py::init<PyOperationBase &>())
3331 .def(
"__getitem__", &PySymbolTable::dunderGetItem)
3332 .def(
"insert", &PySymbolTable::insert, py::arg(
"operation"))
3333 .def(
"erase", &PySymbolTable::erase, py::arg(
"operation"))
3334 .def(
"__delitem__", &PySymbolTable::dunderDel)
3335 .def(
"__contains__",
3341 .def_static(
"set_symbol_name", &PySymbolTable::setSymbolName,
3342 py::arg(
"symbol"), py::arg(
"name"))
3343 .def_static(
"get_symbol_name", &PySymbolTable::getSymbolName,
3345 .def_static(
"get_visibility", &PySymbolTable::getVisibility,
3347 .def_static(
"set_visibility", &PySymbolTable::setVisibility,
3348 py::arg(
"symbol"), py::arg(
"visibility"))
3349 .def_static(
"replace_all_symbol_uses",
3350 &PySymbolTable::replaceAllSymbolUses, py::arg(
"old_symbol"),
3351 py::arg(
"new_symbol"), py::arg(
"from_op"))
3352 .def_static(
"walk_symbol_tables", &PySymbolTable::walkSymbolTables,
3353 py::arg(
"from_op"), py::arg(
"all_sym_uses_visible"),
3354 py::arg(
"callback"));
3357 PyBlockArgumentList::bind(m);
3358 PyBlockIterator::bind(m);
3359 PyBlockList::bind(m);
3360 PyOperationIterator::bind(m);
3361 PyOperationList::bind(m);
3362 PyOpAttributeMap::bind(m);
3363 PyOpOperandIterator::bind(m);
3364 PyOpOperandList::bind(m);
3365 PyOpResultList::bind(m);
3366 PyRegionIterator::bind(m);
3367 PyRegionList::bind(m);
3375 py::register_local_exception_translator([](std::exception_ptr p) {
3380 std::rethrow_exception(p);
3384 PyErr_SetObject(PyExc_Exception, obj.ptr());
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 py::object createCustomDialectWrapper(const std::string &dialectNamespace, py::object dialectDescriptor)
static const char kContextGetNameLocationDocString[]
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 py::object &maybeIp)
static const char kOperationPrintBytecodeDocstring[]
static const char kOperationGetAsmDocstring[]
static const char kOperationCreateDocstring[]
static const char kContextParseTypeDocstring[]
static const char kContextGetCallSiteLocationDocstring[]
static const char kValueDunderStrDocstring[]
py::object classmethod(Func f, Args... args)
Helper for creating an @classmethod.
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
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 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 * 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 std::string diag(const llvm::Value &value)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
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 the generic MlirAttribute.
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
static PyAttribute createFromCapsule(pybind11::object capsule)
Creates a PyAttribute from the MlirAttribute wrapped by a capsule.
bool operator==(const PyAttribute &other)
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAttribute.
Wrapper around an MlirBlock.
PyOperationRef & getParentOperation()
Represents a diagnostic handler attached to the context.
void detach()
Detaches the handler. Does nothing if not attached.
PyDiagnosticHandler(MlirContext context, pybind11::object callback)
Python class mirroring the C MlirDiagnostic struct.
pybind11::str getMessage()
PyDiagnostic(MlirDiagnostic diagnostic)
MlirDiagnosticSeverity getSeverity()
pybind11::tuple getNotes()
Wrapper around an MlirDialect.
Wrapper around an MlirDialectRegistry.
static PyDialectRegistry createFromCapsule(pybind11::object capsule)
pybind11::object getCapsule()
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< pybind11::function > lookupAttributeBuilder(const std::string &attributeKind)
Returns the custom Attribute builder for Attribute kind.
std::optional< pybind11::object > lookupDialectClass(const std::string &dialectNamespace)
Looks up a registered dialect class by namespace.
static PyGlobals & get()
Most code should get the globals via this static accessor.
void registerAttributeBuilder(const std::string &attributeKind, pybind11::function pyFunc)
Adds a user-friendly Attribute builder.
std::optional< pybind11::object > lookupOperationClass(llvm::StringRef operationName)
Looks up a registered operation class (deriving from OpView) by operation name.
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 insert(PyOperationBase &operationBase)
Inserts an operation.
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
pybind11::object contextEnter()
Enter and exit the context manager.
Wrapper around an MlirLocation.
PyLocation(PyMlirContextRef contextRef, MlirLocation loc)
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirLocation.
static PyLocation createFromCapsule(pybind11::object capsule)
Creates a PyLocation from the MlirLocation wrapped by a capsule.
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
pybind11::object contextEnter()
Enter and exit the context manager.
pybind11::object attachDiagnosticHandler(pybind11::object callback)
Attaches a Python callback as a diagnostic handler, returning a registration object (internally a PyD...
MlirContext get()
Accesses the underlying MlirContext.
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyMlirContext from the MlirContext wrapped by a capsule.
static size_t getLiveCount()
Gets the count of live context objects. Used for testing.
static PyMlirContext * createNewContextForInit()
For the case of a python init (py::init) method, pybind11 is quite strict about needing to return a p...
size_t getLiveModuleCount()
Gets the count of live modules associated with this context.
pybind11::object contextEnter()
Enter and exit the context manager.
size_t clearLiveOperations()
Clears the live operations map, returning the number of entries which were invalidated.
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
size_t getLiveOperationCount()
Gets the count of live operations associated with this context.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirContext.
MlirModule get()
Gets the backing MlirModule.
static PyModuleRef forModule(MlirModule module)
Returns a PyModule reference for the given MlirModule.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirModule.
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyModule from the MlirModule wrapped by a capsule.
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
pybind11::object getObject()
pybind11::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...
PyOpView(const pybind11::object &operationObject)
static pybind11::object constructDerived(const pybind11::object &cls, const PyOperation &operation)
Construct an instance of a class deriving from OpView, bypassing its __init__ method.
static pybind11::object buildGeneric(const pybind11::object &cls, pybind11::list resultTypeList, pybind11::list operandList, std::optional< pybind11::dict > attributes, std::optional< std::vector< PyBlock * >> successors, std::optional< int > regions, DefaultingPyLocation location, const pybind11::object &maybeIp)
Base class for PyOperation and PyOpView which exposes the primary, user visible methods for manipulat...
virtual PyOperation & getOperation()=0
Each must provide access to the raw Operation.
pybind11::object getAsm(bool binary, std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified)
void print(pybind11::object fileObject, bool binary, std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified)
Implements the bound 'print' method and helps with others.
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
void moveBefore(PyOperationBase &other)
bool verify()
Verify the operation.
void writeBytecode(const pybind11::object &fileObject)
pybind11::object clone(const pybind11::object &ip)
Clones this 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...
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirOperation.
PyOperation & getOperation() override
Each must provide access to the raw Operation.
static pybind11::object create(const std::string &name, std::optional< std::vector< PyType * >> results, std::optional< std::vector< PyValue * >> operands, std::optional< pybind11::dict > attributes, std::optional< std::vector< PyBlock * >> successors, int regions, DefaultingPyLocation location, const pybind11::object &ip)
Creates an operation. See corresponding python docstring.
MlirOperation get() const
void setAttached(const pybind11::object &parent=pybind11::object())
pybind11::object createOpView()
Creates an OpView suitable for this operation.
static PyOperationRef forOperation(PyMlirContextRef contextRef, MlirOperation operation, pybind11::object parentKeepAlive=pybind11::object())
Returns a PyOperation for the given MlirOperation, optionally associating it with a parentKeepAlive.
std::optional< PyOperationRef > getParentOperation()
Gets the parent operation or raises an exception if the operation has no parent.
PyBlock getBlock()
Gets the owning block or raises an exception if the operation has no owning block.
static PyOperationRef createDetached(PyMlirContextRef contextRef, MlirOperation operation, pybind11::object parentKeepAlive=pybind11::object())
Creates a detached operation.
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.
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyOperation from the MlirOperation wrapped by a capsule.
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 ...
PyAttribute insert(PyOperationBase &symbol)
Inserts the given operation into the symbol table.
static PyAttribute getSymbolName(PyOperationBase &symbol)
Gets and sets the name of a symbol op.
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)
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.
pybind11::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 void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible, pybind11::object callback)
Walks all symbol tables under and including 'from'.
static PyAttribute 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)
PyLocation * getLocation()
static pybind11::object pushContext(PyMlirContext &context)
static PyLocation * getDefaultLocation()
Gets the top of stack location and returns nullptr if not defined.
static void popInsertionPoint(PyInsertionPoint &insertionPoint)
static void popContext(PyMlirContext &context)
static PyInsertionPoint * getDefaultInsertionPoint()
Gets the top of stack insertion point and return nullptr if not defined.
static pybind11::object pushInsertionPoint(PyInsertionPoint &insertionPoint)
static pybind11::object pushLocation(PyLocation &location)
PyMlirContext * getContext()
static PyMlirContext * getDefaultContext()
Gets the top of stack context and return nullptr if not defined.
static std::vector< PyThreadContextEntry > & getStack()
Gets the thread local stack.
PyInsertionPoint * getInsertionPoint()
Wrapper around the generic MlirType.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirType.
static PyType createFromCapsule(pybind11::object capsule)
Creates a PyType from the MlirType wrapped by a capsule.
bool operator==(const PyType &other)
PyType(PyMlirContextRef contextRef, MlirType type)
Wrapper around the generic MlirValue.
static PyValue createFromCapsule(pybind11::object capsule)
Creates a PyValue from the MlirValue wrapped by a capsule.
PyValue(PyOperationRef parentOperation, MlirValue value)
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirValue.
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 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 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.
MLIR_CAPI_EXPORTED void mlirOperationWriteBytecode(MlirOperation op, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but writing the bytecode format out.
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.
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 MlirLocation mlirLocationUnknownGet(MlirContext context)
Creates a location with unknown position owned by the given context.
MLIR_CAPI_EXPORTED void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, MlirAttribute attr)
Sets an attribute by name, replacing the existing if it exists or adding a new one otherwise.
MLIR_CAPI_EXPORTED MlirOperation mlirOpOperandGetOwner(MlirOpOperand opOperand)
Returns the owner operation of an op operand.
MLIR_CAPI_EXPORTED void 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 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 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...
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 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 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 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 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 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 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 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 MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
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 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 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 MlirContext mlirContextCreate(void)
Creates an MLIR context and transfers its ownership to the caller.
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 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.
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.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
llvm::hash_code hash_value(const MPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
PyObjectRef< PyModule > PyModuleRef
pybind11::error_already_set SetPyError(PyObject *excClass, const llvm::Twine &message)
void populateIRCore(pybind11::module &m)
PyObjectRef< PyOperation > PyOperationRef
Include the generated interface declarations.
Operation * clone(OpBuilder &b, Operation *op, TypeRange newResultTypes, ValueRange newOperands)
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 py::function dundeGetItemNamed(const std::string &attributeKind)
static void bind(py::module &m)
static void dundeSetItemNamed(const std::string &attributeKind, py::function func)
Wrapper for the global LLVM debugging flag.
static void bind(py::module &m)
static bool get(const py::object &)
static void set(py::object &o, bool enable)
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)