21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/SmallVector.h"
28 using namespace py::literals;
33 using llvm::StringRef;
41 R
"(Parses the assembly form of a type.
43 Returns a Type object or raises an MLIRError if the type cannot be parsed.
45 See also: https://mlir.llvm.org/docs/LangRef/#type-system
49 R
"(Gets a Location representing a caller and callsite)";
52 R
"(Gets a Location representing a file, line and column)";
55 R
"(Gets a Location representing a fused location with optional metadata)";
58 R
"(Gets a Location representing a named location with optional child location)";
61 R
"(Parses a module's assembly format from a string.
63 Returns a new MlirModule or raises an MLIRError if the parsing fails.
65 See also: https://mlir.llvm.org/docs/LangRef/
69 R
"(Creates a new operation.
72 name: Operation name (e.g. "dialect.operation").
73 results: Sequence of Type representing op result types.
74 attributes: Dict of str:Attribute.
75 successors: List of Block for the operation's successors.
76 regions: Number of regions to create.
77 location: A Location object (defaults to resolve from context manager).
78 ip: An InsertionPoint (defaults to resolve from context manager or set to
79 False to disable insertion, even with an insertion point set in the
81 infer_type: Whether to infer result types.
83 A new "detached" Operation object. Detached operations can be added
84 to blocks, which causes them to become "attached."
88 R
"(Prints the assembly form of the operation to a file like object.
91 file: The file like object to write to. Defaults to sys.stdout.
92 binary: Whether to write bytes (True) or str (False). Defaults to False.
93 large_elements_limit: Whether to elide elements attributes above this
94 number of elements. Defaults to None (no limit).
95 enable_debug_info: Whether to print debug/location information. Defaults
97 pretty_debug_info: Whether to format debug information for easier reading
98 by a human (warning: the result is unparseable).
99 print_generic_op_form: Whether to print the generic assembly forms of all
100 ops. Defaults to False.
101 use_local_Scope: Whether to print in a way that is more optimized for
102 multi-threaded access but may not be consistent with how the overall
104 assume_verified: By default, if not printing generic form, the verifier
105 will be run and if it fails, generic form will be printed with a comment
106 about failed verification. While a reasonable default for interactive use,
107 for systematic use, it is often better for the caller to verify explicitly
108 and report failures in a more robust fashion. Set this to True if doing this
109 in order to avoid running a redundant verification. If the IR is actually
110 invalid, behavior is undefined.
114 R
"(Gets the assembly form of the operation with all options available.
117 binary: Whether to return a bytes (True) or str (False) object. Defaults to
119 ... others ...: See the print() method for common keyword arguments for
120 configuring the printout.
122 Either a bytes or str object, depending on the setting of the 'binary'
127 R
"(Write the bytecode form of the operation to a file like object.
130 file: The file like object to write to.
131 desired_version: The version of bytecode to emit.
133 The bytecode writer status.
137 R
"(Gets the assembly form of the operation with default options.
139 If more advanced control over the assembly formatting or I/O options is needed,
140 use the dedicated print or get_asm method, which supports keyword arguments to
145 R
"(Dumps a debug representation of the object to stderr.)";
148 R
"(Appends a new block, with argument types as positional args.
155 R
"(Returns the string form of the value.
157 If the value is a block argument, this is the assembly form of its type and the
158 position in the argument list. If the value is an operation result, this is
159 equivalent to printing the operation that produced it.
163 R
"(Returns the string form of value as an operand (i.e., the ValueID).
167 R
"(Replace all uses of value with the new value, updating anything in
168 the IR that uses 'self' to use the other value instead.
176 template <
class Func,
typename... Args>
178 py::object cf = py::cpp_function(f, args...);
179 return py::reinterpret_borrow<py::object>((PyClassMethod_New(cf.ptr())));
184 py::object dialectDescriptor) {
185 auto dialectClass =
PyGlobals::get().lookupDialectClass(dialectNamespace);
188 return py::cast(
PyDialect(std::move(dialectDescriptor)));
192 return (*dialectClass)(std::move(dialectDescriptor));
202 const std::optional<py::sequence> &pyArgLocs) {
204 argTypes.reserve(pyArgTypes.size());
205 for (
const auto &pyType : pyArgTypes)
206 argTypes.push_back(pyType.cast<
PyType &>());
210 argLocs.reserve(pyArgLocs->size());
211 for (
const auto &pyLoc : *pyArgLocs)
212 argLocs.push_back(pyLoc.cast<
PyLocation &>());
213 }
else if (!argTypes.empty()) {
214 argLocs.assign(argTypes.size(), DefaultingPyLocation::resolve());
217 if (argTypes.size() != argLocs.size())
218 throw py::value_error((
"Expected " + Twine(argTypes.size()) +
219 " locations, got: " + Twine(argLocs.size()))
221 return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
230 static void bind(py::module &m) {
232 py::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug", py::module_local())
240 return PyGlobals::get().lookupAttributeBuilder(attributeKind).has_value();
243 auto builder =
PyGlobals::get().lookupAttributeBuilder(attributeKind);
245 throw py::key_error(attributeKind);
249 py::function func,
bool replace) {
250 PyGlobals::get().registerAttributeBuilder(attributeKind, std::move(func),
254 static void bind(py::module &m) {
255 py::class_<PyAttrBuilderMap>(m,
"AttrBuilder", py::module_local())
259 "attribute_kind"_a,
"attr_builder"_a,
"replace"_a =
false,
260 "Register an attribute builder for building MLIR "
261 "attributes from python values.");
269 py::object PyBlock::getCapsule() {
279 class PyRegionIterator {
282 : operation(std::move(operation)) {}
284 PyRegionIterator &dunderIter() {
return *
this; }
289 throw py::stop_iteration();
295 static void bind(py::module &m) {
296 py::class_<PyRegionIterator>(m,
"RegionIterator", py::module_local())
297 .def(
"__iter__", &PyRegionIterator::dunderIter)
298 .def(
"__next__", &PyRegionIterator::dunderNext);
310 PyRegionList(
PyOperationRef operation) : operation(std::move(operation)) {}
312 PyRegionIterator dunderIter() {
314 return PyRegionIterator(operation);
317 intptr_t dunderLen() {
318 operation->checkValid();
322 PyRegion dunderGetItem(intptr_t index) {
324 if (index < 0 || index >= dunderLen()) {
325 throw py::index_error(
"attempt to access out of bounds region");
331 static void bind(py::module &m) {
332 py::class_<PyRegionList>(m,
"RegionSequence", py::module_local())
333 .def(
"__len__", &PyRegionList::dunderLen)
334 .def(
"__iter__", &PyRegionList::dunderIter)
335 .def(
"__getitem__", &PyRegionList::dunderGetItem);
342 class PyBlockIterator {
345 : operation(std::move(operation)), next(next) {}
347 PyBlockIterator &dunderIter() {
return *
this; }
352 throw py::stop_iteration();
355 PyBlock returnBlock(operation, next);
360 static void bind(py::module &m) {
361 py::class_<PyBlockIterator>(m,
"BlockIterator", py::module_local())
362 .def(
"__iter__", &PyBlockIterator::dunderIter)
363 .def(
"__next__", &PyBlockIterator::dunderNext);
377 : operation(std::move(operation)), region(region) {}
379 PyBlockIterator dunderIter() {
384 intptr_t dunderLen() {
385 operation->checkValid();
395 PyBlock dunderGetItem(intptr_t index) {
398 throw py::index_error(
"attempt to access out of bounds block");
403 return PyBlock(operation, block);
408 throw py::index_error(
"attempt to access out of bounds block");
411 PyBlock appendBlock(
const py::args &pyArgTypes,
412 const std::optional<py::sequence> &pyArgLocs) {
414 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
416 return PyBlock(operation, block);
419 static void bind(py::module &m) {
420 py::class_<PyBlockList>(m,
"BlockList", py::module_local())
421 .def(
"__getitem__", &PyBlockList::dunderGetItem)
422 .def(
"__iter__", &PyBlockList::dunderIter)
423 .def(
"__len__", &PyBlockList::dunderLen)
425 py::arg(
"arg_locs") = std::nullopt);
433 class PyOperationIterator {
435 PyOperationIterator(
PyOperationRef parentOperation, MlirOperation next)
436 : parentOperation(std::move(parentOperation)), next(next) {}
438 PyOperationIterator &dunderIter() {
return *
this; }
440 py::object dunderNext() {
443 throw py::stop_iteration();
447 PyOperation::forOperation(parentOperation->getContext(), next);
452 static void bind(py::module &m) {
453 py::class_<PyOperationIterator>(m,
"OperationIterator", py::module_local())
454 .def(
"__iter__", &PyOperationIterator::dunderIter)
455 .def(
"__next__", &PyOperationIterator::dunderNext);
467 class PyOperationList {
470 : parentOperation(std::move(parentOperation)), block(block) {}
472 PyOperationIterator dunderIter() {
474 return PyOperationIterator(parentOperation,
478 intptr_t dunderLen() {
479 parentOperation->checkValid();
489 py::object dunderGetItem(intptr_t index) {
490 parentOperation->checkValid();
492 throw py::index_error(
"attempt to access out of bounds operation");
497 return PyOperation::forOperation(parentOperation->getContext(), childOp)
503 throw py::index_error(
"attempt to access out of bounds operation");
506 static void bind(py::module &m) {
507 py::class_<PyOperationList>(m,
"OperationList", py::module_local())
508 .def(
"__getitem__", &PyOperationList::dunderGetItem)
509 .def(
"__iter__", &PyOperationList::dunderIter)
510 .def(
"__len__", &PyOperationList::dunderLen);
520 PyOpOperand(MlirOpOperand opOperand) : opOperand(opOperand) {}
522 py::object getOwner() {
526 return PyOperation::forOperation(context, owner)->createOpView();
531 static void bind(py::module &m) {
532 py::class_<PyOpOperand>(m,
"OpOperand", py::module_local())
533 .def_property_readonly(
"owner", &PyOpOperand::getOwner)
534 .def_property_readonly(
"operand_number",
535 &PyOpOperand::getOperandNumber);
539 MlirOpOperand opOperand;
542 class PyOpOperandIterator {
544 PyOpOperandIterator(MlirOpOperand opOperand) : opOperand(opOperand) {}
546 PyOpOperandIterator &dunderIter() {
return *
this; }
548 PyOpOperand dunderNext() {
550 throw py::stop_iteration();
552 PyOpOperand returnOpOperand(opOperand);
554 return returnOpOperand;
557 static void bind(py::module &m) {
558 py::class_<PyOpOperandIterator>(m,
"OpOperandIterator", py::module_local())
559 .def(
"__iter__", &PyOpOperandIterator::dunderIter)
560 .def(
"__next__", &PyOpOperandIterator::dunderNext);
564 MlirOpOperand opOperand;
573 PyMlirContext::PyMlirContext(MlirContext context) : context(context) {
574 py::gil_scoped_acquire acquire;
575 auto &liveContexts = getLiveContexts();
576 liveContexts[context.ptr] =
this;
583 py::gil_scoped_acquire acquire;
584 getLiveContexts().erase(context.ptr);
595 throw py::error_already_set();
605 py::gil_scoped_acquire acquire;
606 auto &liveContexts = getLiveContexts();
607 auto it = liveContexts.find(context.ptr);
608 if (it == liveContexts.end()) {
611 py::object pyRef = py::cast(unownedContextWrapper);
612 assert(pyRef &&
"cast to py::object failed");
613 liveContexts[context.ptr] = unownedContextWrapper;
617 py::object pyRef = py::cast(it->second);
622 static LiveContextMap liveContexts;
631 for (
auto &op : liveOperations)
632 op.second.second->setInvalid();
633 size_t numInvalidated = liveOperations.size();
634 liveOperations.clear();
635 return numInvalidated;
645 const pybind11::object &excVal,
646 const pybind11::object &excTb) {
655 py::object pyHandlerObject =
656 py::cast(pyHandler, py::return_value_policy::take_ownership);
657 pyHandlerObject.inc_ref();
661 auto handlerCallback =
664 py::object pyDiagnosticObject =
665 py::cast(pyDiagnostic, py::return_value_policy::take_ownership);
672 py::gil_scoped_acquire gil;
674 result = py::cast<bool>(pyHandler->callback(pyDiagnostic));
675 }
catch (std::exception &e) {
676 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
678 pyHandler->hadError =
true;
685 auto deleteCallback = +[](
void *userData) {
687 assert(pyHandler->registeredID &&
"handler is not registered");
688 pyHandler->registeredID.reset();
691 py::object pyHandlerObject =
692 py::cast(pyHandler, py::return_value_policy::reference);
693 pyHandlerObject.dec_ref();
697 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
698 return pyHandlerObject;
705 if (self->ctx->emitErrorDiagnostics)
718 throw std::runtime_error(
719 "An MLIR function requires a Context but none was provided in the call "
720 "or from the surrounding environment. Either pass to the function with "
721 "a 'context=' argument or establish a default using 'with Context():'");
731 static thread_local std::vector<PyThreadContextEntry> stack;
736 auto &stack = getStack();
739 return &stack.back();
742 void PyThreadContextEntry::push(FrameKind frameKind, py::object context,
743 py::object insertionPoint,
744 py::object location) {
745 auto &stack = getStack();
746 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
747 std::move(location));
751 if (stack.size() > 1) {
752 auto &prev = *(stack.rbegin() + 1);
753 auto ¤t = stack.back();
754 if (current.context.is(prev.context)) {
756 if (!current.insertionPoint)
757 current.insertionPoint = prev.insertionPoint;
758 if (!current.location)
759 current.location = prev.location;
767 return py::cast<PyMlirContext *>(context);
773 return py::cast<PyInsertionPoint *>(insertionPoint);
779 return py::cast<PyLocation *>(location);
783 auto *tos = getTopOfStack();
784 return tos ? tos->getContext() :
nullptr;
788 auto *tos = getTopOfStack();
789 return tos ? tos->getInsertionPoint() :
nullptr;
793 auto *tos = getTopOfStack();
794 return tos ? tos->getLocation() :
nullptr;
798 py::object contextObj = py::cast(context);
799 push(FrameKind::Context, contextObj,
806 auto &stack = getStack();
808 throw std::runtime_error(
"Unbalanced Context enter/exit");
809 auto &tos = stack.back();
810 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
811 throw std::runtime_error(
"Unbalanced Context enter/exit");
817 py::object contextObj =
819 py::object insertionPointObj = py::cast(insertionPoint);
820 push(FrameKind::InsertionPoint,
824 return insertionPointObj;
828 auto &stack = getStack();
830 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
831 auto &tos = stack.back();
832 if (tos.frameKind != FrameKind::InsertionPoint &&
833 tos.getInsertionPoint() != &insertionPoint)
834 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
840 py::object locationObj = py::cast(location);
841 push(FrameKind::Location, contextObj,
848 auto &stack = getStack();
850 throw std::runtime_error(
"Unbalanced Location enter/exit");
851 auto &tos = stack.back();
852 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
853 throw std::runtime_error(
"Unbalanced Location enter/exit");
863 if (materializedNotes) {
864 for (
auto ¬eObject : *materializedNotes) {
865 PyDiagnostic *note = py::cast<PyDiagnostic *>(noteObject);
873 : context(context), callback(std::move(callback)) {}
882 assert(!registeredID &&
"should have unregistered");
888 void PyDiagnostic::checkValid() {
890 throw std::invalid_argument(
891 "Diagnostic is invalid (used outside of callback)");
909 py::object fileObject = py::module::import(
"io").attr(
"StringIO")();
912 return fileObject.attr(
"getvalue")();
917 if (materializedNotes)
918 return *materializedNotes;
920 materializedNotes = py::tuple(numNotes);
921 for (intptr_t i = 0; i < numNotes; ++i) {
925 return *materializedNotes;
929 std::vector<DiagnosticInfo> notes;
942 {key.data(), key.size()});
944 std::string msg = (Twine(
"Dialect '") + key +
"' not found").str();
946 throw py::attribute_error(msg);
948 throw py::index_error(msg);
954 return py::reinterpret_steal<py::object>(
959 MlirDialectRegistry rawRegistry =
962 throw py::error_already_set();
977 throw py::error_already_set();
987 const pybind11::object &excVal,
988 const pybind11::object &excTb) {
995 throw std::runtime_error(
996 "An MLIR function requires a Location but none was provided in the "
997 "call or from the surrounding environment. Either pass to the function "
998 "with a 'loc=' argument or establish a default using 'with loc:'");
1011 py::gil_scoped_acquire acquire;
1012 auto &liveModules =
getContext()->liveModules;
1013 assert(liveModules.count(module.ptr) == 1 &&
1014 "destroying module not in live map");
1015 liveModules.erase(module.ptr);
1023 py::gil_scoped_acquire acquire;
1024 auto &liveModules = contextRef->liveModules;
1025 auto it = liveModules.find(module.ptr);
1026 if (it == liveModules.end()) {
1033 py::cast(unownedModule, py::return_value_policy::take_ownership);
1034 unownedModule->handle = pyRef;
1035 liveModules[module.ptr] =
1036 std::make_pair(unownedModule->handle, unownedModule);
1037 return PyModuleRef(unownedModule, std::move(pyRef));
1040 PyModule *existing = it->second.second;
1041 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
1048 throw py::error_already_set();
1060 PyOperation::PyOperation(
PyMlirContextRef contextRef, MlirOperation operation)
1067 auto &liveOperations =
getContext()->liveOperations;
1068 assert(liveOperations.count(operation.ptr) == 1 &&
1069 "destroying operation not in live map");
1070 liveOperations.erase(operation.ptr);
1077 MlirOperation operation,
1078 py::object parentKeepAlive) {
1079 auto &liveOperations = contextRef->liveOperations;
1082 new PyOperation(std::move(contextRef), operation);
1087 py::cast(unownedOperation, py::return_value_policy::take_ownership);
1088 unownedOperation->handle = pyRef;
1089 if (parentKeepAlive) {
1090 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
1092 liveOperations[operation.ptr] = std::make_pair(pyRef, unownedOperation);
1097 MlirOperation operation,
1098 py::object parentKeepAlive) {
1099 auto &liveOperations = contextRef->liveOperations;
1100 auto it = liveOperations.find(operation.ptr);
1101 if (it == liveOperations.end()) {
1103 return createInstance(std::move(contextRef), operation,
1104 std::move(parentKeepAlive));
1108 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
1113 MlirOperation operation,
1114 py::object parentKeepAlive) {
1115 auto &liveOperations = contextRef->liveOperations;
1116 assert(liveOperations.count(operation.ptr) == 0 &&
1117 "cannot create detached operation that already exists");
1118 (void)liveOperations;
1120 PyOperationRef created = createInstance(std::move(contextRef), operation,
1121 std::move(parentKeepAlive));
1122 created->attached =
false;
1127 const std::string &sourceStr,
1128 const std::string &sourceName) {
1134 throw MLIRError(
"Unable to parse operation assembly", errors.
take());
1140 throw std::runtime_error(
"the operation has been invalidated");
1145 std::optional<int64_t> largeElementsLimit,
1146 bool enableDebugInfo,
bool prettyDebugInfo,
1147 bool printGenericOpForm,
bool useLocalScope,
1148 bool assumeVerified) {
1151 if (fileObject.is_none())
1152 fileObject = py::module::import(
"sys").attr(
"stdout");
1155 if (largeElementsLimit)
1157 if (enableDebugInfo)
1160 if (printGenericOpForm)
1174 std::optional<int64_t> bytecodeVersion) {
1179 if (!bytecodeVersion.has_value())
1189 throw py::value_error((Twine(
"Unable to honor desired bytecode version ") +
1190 Twine(*bytecodeVersion))
1195 std::optional<int64_t> largeElementsLimit,
1196 bool enableDebugInfo,
bool prettyDebugInfo,
1197 bool printGenericOpForm,
bool useLocalScope,
1198 bool assumeVerified) {
1199 py::object fileObject;
1201 fileObject = py::module::import(
"io").attr(
"BytesIO")();
1203 fileObject = py::module::import(
"io").attr(
"StringIO")();
1205 print(fileObject, binary,
1213 return fileObject.attr(
"getvalue")();
1222 operation.parentKeepAlive = otherOp.parentKeepAlive;
1231 operation.parentKeepAlive = otherOp.parentKeepAlive;
1245 throw py::value_error(
"Detached operations have no parent");
1256 assert(!
mlirBlockIsNull(block) &&
"Attached operation has null parent");
1257 assert(parentOperation &&
"Operation has no parent");
1258 return PyBlock{std::move(*parentOperation), block};
1269 throw py::error_already_set();
1276 const py::object &maybeIp) {
1278 if (!maybeIp.is(py::cast(
false))) {
1280 if (maybeIp.is_none()) {
1283 ip = py::cast<PyInsertionPoint *>(maybeIp);
1291 std::optional<std::vector<PyType *>> results,
1292 std::optional<std::vector<PyValue *>> operands,
1293 std::optional<py::dict> attributes,
1294 std::optional<std::vector<PyBlock *>> successors,
1296 const py::object &maybeIp,
bool inferType) {
1304 throw py::value_error(
"number of regions must be >= 0");
1308 mlirOperands.reserve(operands->size());
1309 for (
PyValue *operand : *operands) {
1311 throw py::value_error(
"operand value cannot be None");
1312 mlirOperands.push_back(operand->get());
1318 mlirResults.reserve(results->size());
1319 for (
PyType *result : *results) {
1322 throw py::value_error(
"result type cannot be None");
1323 mlirResults.push_back(*result);
1328 mlirAttributes.reserve(attributes->size());
1329 for (
auto &it : *attributes) {
1332 key = it.first.cast<std::string>();
1333 }
catch (py::cast_error &err) {
1334 std::string msg =
"Invalid attribute key (not a string) when "
1335 "attempting to create the operation \"" +
1336 name +
"\" (" + err.what() +
")";
1337 throw py::cast_error(msg);
1340 auto &attribute = it.second.cast<
PyAttribute &>();
1342 mlirAttributes.emplace_back(std::move(key), attribute);
1343 }
catch (py::reference_cast_error &) {
1346 "Found an invalid (`None`?) attribute value for the key \"" + key +
1347 "\" when attempting to create the operation \"" + name +
"\"";
1348 throw py::cast_error(msg);
1349 }
catch (py::cast_error &err) {
1350 std::string msg =
"Invalid attribute value for the key \"" + key +
1351 "\" when attempting to create the operation \"" +
1352 name +
"\" (" + err.what() +
")";
1353 throw py::cast_error(msg);
1359 mlirSuccessors.reserve(successors->size());
1360 for (
auto *successor : *successors) {
1363 throw py::value_error(
"successor block cannot be None");
1364 mlirSuccessors.push_back(successor->get());
1372 if (!mlirOperands.empty())
1374 mlirOperands.data());
1375 state.enableResultTypeInference = inferType;
1376 if (!mlirResults.empty())
1378 mlirResults.data());
1379 if (!mlirAttributes.empty()) {
1384 mlirNamedAttributes.reserve(mlirAttributes.size());
1385 for (
auto &it : mlirAttributes)
1391 mlirNamedAttributes.data());
1393 if (!mlirSuccessors.empty())
1395 mlirSuccessors.data());
1398 mlirRegions.resize(regions);
1399 for (
int i = 0; i < regions; ++i)
1402 mlirRegions.data());
1408 throw py::value_error(
"Operation creation failed");
1441 auto &liveOperations =
getContext()->liveOperations;
1442 if (liveOperations.count(operation.ptr))
1443 liveOperations.erase(operation.ptr);
1453 const py::object &resultSegmentSpecObj,
1454 std::vector<int32_t> &resultSegmentLengths,
1455 std::vector<PyType *> &resultTypes) {
1456 resultTypes.reserve(resultTypeList.size());
1457 if (resultSegmentSpecObj.is_none()) {
1461 resultTypes.push_back(py::cast<PyType *>(it.value()));
1462 if (!resultTypes.back())
1463 throw py::cast_error();
1464 }
catch (py::cast_error &err) {
1465 throw py::value_error((llvm::Twine(
"Result ") +
1466 llvm::Twine(it.index()) +
" of operation \"" +
1467 name +
"\" must be a Type (" + err.what() +
")")
1473 auto resultSegmentSpec = py::cast<std::vector<int>>(resultSegmentSpecObj);
1474 if (resultSegmentSpec.size() != resultTypeList.size()) {
1475 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1477 llvm::Twine(resultSegmentSpec.size()) +
1478 " result segments but was provided " +
1479 llvm::Twine(resultTypeList.size()))
1482 resultSegmentLengths.reserve(resultTypeList.size());
1483 for (
const auto &it :
1485 int segmentSpec = std::get<1>(it.value());
1486 if (segmentSpec == 1 || segmentSpec == 0) {
1489 auto *resultType = py::cast<PyType *>(std::get<0>(it.value()));
1491 resultTypes.push_back(resultType);
1492 resultSegmentLengths.push_back(1);
1493 }
else if (segmentSpec == 0) {
1495 resultSegmentLengths.push_back(0);
1497 throw py::cast_error(
"was None and result is not optional");
1499 }
catch (py::cast_error &err) {
1500 throw py::value_error((llvm::Twine(
"Result ") +
1501 llvm::Twine(it.index()) +
" of operation \"" +
1502 name +
"\" must be a Type (" + err.what() +
1506 }
else if (segmentSpec == -1) {
1509 if (std::get<0>(it.value()).is_none()) {
1511 resultSegmentLengths.push_back(0);
1514 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1515 for (py::object segmentItem : segment) {
1516 resultTypes.push_back(py::cast<PyType *>(segmentItem));
1517 if (!resultTypes.back()) {
1518 throw py::cast_error(
"contained a None item");
1521 resultSegmentLengths.push_back(segment.size());
1523 }
catch (std::exception &err) {
1527 throw py::value_error((llvm::Twine(
"Result ") +
1528 llvm::Twine(it.index()) +
" of operation \"" +
1529 name +
"\" must be a Sequence of Types (" +
1534 throw py::value_error(
"Unexpected segment spec");
1541 const py::object &cls, std::optional<py::list> resultTypeList,
1542 py::list operandList, std::optional<py::dict> attributes,
1543 std::optional<std::vector<PyBlock *>> successors,
1545 const py::object &maybeIp) {
1548 std::string name = py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
1554 py::object operandSegmentSpecObj = cls.attr(
"_ODS_OPERAND_SEGMENTS");
1555 py::object resultSegmentSpecObj = cls.attr(
"_ODS_RESULT_SEGMENTS");
1557 std::vector<int32_t> operandSegmentLengths;
1558 std::vector<int32_t> resultSegmentLengths;
1561 auto opRegionSpec = py::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
1562 int opMinRegionCount = std::get<0>(opRegionSpec);
1563 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1565 regions = opMinRegionCount;
1567 if (*regions < opMinRegionCount) {
1568 throw py::value_error(
1569 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1570 llvm::Twine(opMinRegionCount) +
1571 " regions but was built with regions=" + llvm::Twine(*regions))
1574 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1575 throw py::value_error(
1576 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1577 llvm::Twine(opMinRegionCount) +
1578 " regions but was built with regions=" + llvm::Twine(*regions))
1583 std::vector<PyType *> resultTypes;
1584 if (resultTypeList.has_value()) {
1586 resultSegmentLengths, resultTypes);
1590 std::vector<PyValue *> operands;
1591 operands.reserve(operands.size());
1592 if (operandSegmentSpecObj.is_none()) {
1596 operands.push_back(py::cast<PyValue *>(it.value()));
1597 if (!operands.back())
1598 throw py::cast_error();
1599 }
catch (py::cast_error &err) {
1600 throw py::value_error((llvm::Twine(
"Operand ") +
1601 llvm::Twine(it.index()) +
" of operation \"" +
1602 name +
"\" must be a Value (" + err.what() +
")")
1608 auto operandSegmentSpec = py::cast<std::vector<int>>(operandSegmentSpecObj);
1609 if (operandSegmentSpec.size() != operandList.size()) {
1610 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1612 llvm::Twine(operandSegmentSpec.size()) +
1613 "operand segments but was provided " +
1614 llvm::Twine(operandList.size()))
1617 operandSegmentLengths.reserve(operandList.size());
1618 for (
const auto &it :
1620 int segmentSpec = std::get<1>(it.value());
1621 if (segmentSpec == 1 || segmentSpec == 0) {
1624 auto *operandValue = py::cast<PyValue *>(std::get<0>(it.value()));
1626 operands.push_back(operandValue);
1627 operandSegmentLengths.push_back(1);
1628 }
else if (segmentSpec == 0) {
1630 operandSegmentLengths.push_back(0);
1632 throw py::cast_error(
"was None and operand is not optional");
1634 }
catch (py::cast_error &err) {
1635 throw py::value_error((llvm::Twine(
"Operand ") +
1636 llvm::Twine(it.index()) +
" of operation \"" +
1637 name +
"\" must be a Value (" + err.what() +
1641 }
else if (segmentSpec == -1) {
1644 if (std::get<0>(it.value()).is_none()) {
1646 operandSegmentLengths.push_back(0);
1649 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1650 for (py::object segmentItem : segment) {
1651 operands.push_back(py::cast<PyValue *>(segmentItem));
1652 if (!operands.back()) {
1653 throw py::cast_error(
"contained a None item");
1656 operandSegmentLengths.push_back(segment.size());
1658 }
catch (std::exception &err) {
1662 throw py::value_error((llvm::Twine(
"Operand ") +
1663 llvm::Twine(it.index()) +
" of operation \"" +
1664 name +
"\" must be a Sequence of Values (" +
1669 throw py::value_error(
"Unexpected segment spec");
1675 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1678 attributes = py::dict(*attributes);
1680 attributes = py::dict();
1682 if (attributes->contains(
"resultSegmentSizes") ||
1683 attributes->contains(
"operandSegmentSizes")) {
1684 throw py::value_error(
"Manually setting a 'resultSegmentSizes' or "
1685 "'operandSegmentSizes' attribute is unsupported. "
1686 "Use Operation.create for such low-level access.");
1690 if (!resultSegmentLengths.empty()) {
1691 MlirAttribute segmentLengthAttr =
1693 resultSegmentLengths.data());
1694 (*attributes)[
"resultSegmentSizes"] =
1699 if (!operandSegmentLengths.empty()) {
1700 MlirAttribute segmentLengthAttr =
1702 operandSegmentLengths.data());
1703 (*attributes)[
"operandSegmentSizes"] =
1710 std::move(resultTypes),
1711 std::move(operands),
1712 std::move(attributes),
1713 std::move(successors),
1714 *regions, location, maybeIp,
1723 py::handle opViewType = py::detail::get_type_handle(
typeid(
PyOpView),
true);
1724 py::object instance = cls.attr(
"__new__")(cls);
1725 opViewType.attr(
"__init__")(instance, operation);
1733 operationObject(operation.getRef().getObject()) {}
1742 : refOperation(beforeOperationBase.getOperation().getRef()),
1743 block((*refOperation)->getBlock()) {}
1748 throw py::value_error(
1749 "Attempt to insert operation that is already attached");
1750 block.getParentOperation()->checkValid();
1751 MlirOperation beforeOp = {
nullptr};
1754 (*refOperation)->checkValid();
1755 beforeOp = (*refOperation)->get();
1761 throw py::index_error(
"Cannot insert operation at the end of a block "
1762 "that already has a terminator. Did you mean to "
1763 "use 'InsertionPoint.at_block_terminator(block)' "
1764 "versus 'InsertionPoint(block)'?");
1787 throw py::value_error(
"Block has no terminator");
1798 const pybind11::object &excVal,
1799 const pybind11::object &excTb) {
1818 throw py::error_already_set();
1828 : ownedName(new std::string(std::move(ownedName))) {
1850 throw py::error_already_set();
1866 throw py::error_already_set();
1884 throw py::error_already_set();
1885 MlirOperation owner;
1891 throw py::error_already_set();
1895 return PyValue(ownerRef, value);
1903 : operation(operation.getOperation().getRef()) {
1906 throw py::cast_error(
"Operation is not a Symbol Table.");
1911 operation->checkValid();
1915 throw py::key_error(
"Symbol '" + name +
"' not in the symbol table.");
1918 operation.getObject())
1923 operation->checkValid();
1934 erase(py::cast<PyOperationBase &>(operation));
1938 operation->checkValid();
1943 throw py::value_error(
"Expected operation to have a symbol name.");
1952 MlirAttribute existingNameAttr =
1955 throw py::value_error(
"Expected operation to have a symbol name.");
1956 return existingNameAttr;
1960 const std::string &name) {
1965 MlirAttribute existingNameAttr =
1968 throw py::value_error(
"Expected operation to have a symbol name.");
1969 MlirAttribute newNameAttr =
1978 MlirAttribute existingVisAttr =
1981 throw py::value_error(
"Expected operation to have a symbol visibility.");
1982 return existingVisAttr;
1986 const std::string &visibility) {
1987 if (visibility !=
"public" && visibility !=
"private" &&
1988 visibility !=
"nested")
1989 throw py::value_error(
1990 "Expected visibility to be 'public', 'private' or 'nested'");
1994 MlirAttribute existingVisAttr =
1997 throw py::value_error(
"Expected operation to have a symbol visibility.");
2004 const std::string &newSymbol,
2012 throw py::value_error(
"Symbol rename failed");
2016 bool allSymUsesVisible,
2017 py::object callback) {
2022 py::object callback;
2024 std::string exceptionWhat;
2025 py::object exceptionType;
2028 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
2030 fromOperation.
get(), allSymUsesVisible,
2031 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
2032 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
2034 PyOperation::forOperation(calleeUserData->context, foundOp);
2035 if (calleeUserData->gotException)
2038 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
2039 } catch (py::error_already_set &e) {
2040 calleeUserData->gotException =
true;
2041 calleeUserData->exceptionWhat = e.what();
2042 calleeUserData->exceptionType = e.type();
2045 static_cast<void *
>(&userData));
2046 if (userData.gotException) {
2047 std::string message(
"Exception raised in callback: ");
2048 message.append(userData.exceptionWhat);
2049 throw std::runtime_error(message);
2057 template <
typename DerivedTy>
2058 class PyConcreteValue :
public PyValue {
2064 using ClassTy = py::class_<DerivedTy, PyValue>;
2065 using IsAFunctionTy = bool (*)(MlirValue);
2067 PyConcreteValue() =
default;
2069 :
PyValue(operationRef, value) {}
2070 PyConcreteValue(
PyValue &orig)
2071 : PyConcreteValue(orig.getParentOperation(), castFrom(orig)) {}
2075 static MlirValue castFrom(
PyValue &orig) {
2076 if (!DerivedTy::isaFunction(orig.
get())) {
2077 auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
2078 throw py::value_error((Twine(
"Cannot cast value to ") +
2079 DerivedTy::pyClassName +
" (from " + origRepr +
2087 static void bind(py::module &m) {
2088 auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
2089 cls.def(py::init<PyValue &>(), py::keep_alive<0, 1>(), py::arg(
"value"));
2092 [](
PyValue &otherValue) ->
bool {
2093 return DerivedTy::isaFunction(otherValue);
2095 py::arg(
"other_value"));
2096 DerivedTy::bindDerived(cls);
2100 static void bindDerived(ClassTy &m) {}
2104 class PyBlockArgument :
public PyConcreteValue<PyBlockArgument> {
2107 static constexpr
const char *pyClassName =
"BlockArgument";
2108 using PyConcreteValue::PyConcreteValue;
2110 static void bindDerived(ClassTy &c) {
2111 c.def_property_readonly(
"owner", [](PyBlockArgument &
self) {
2112 return PyBlock(
self.getParentOperation(),
2115 c.def_property_readonly(
"arg_number", [](PyBlockArgument &
self) {
2120 [](PyBlockArgument &
self,
PyType type) {
2128 class PyOpResult :
public PyConcreteValue<PyOpResult> {
2131 static constexpr
const char *pyClassName =
"OpResult";
2132 using PyConcreteValue::PyConcreteValue;
2134 static void bindDerived(ClassTy &c) {
2135 c.def_property_readonly(
"owner", [](PyOpResult &
self) {
2139 "expected the owner of the value in Python to match that in the IR");
2140 return self.getParentOperation().getObject();
2142 c.def_property_readonly(
"result_number", [](PyOpResult &
self) {
2149 template <
typename Container>
2150 static std::vector<MlirType> getValueTypes(Container &container,
2152 std::vector<MlirType> result;
2153 result.reserve(container.size());
2154 for (
int i = 0, e = container.size(); i < e; ++i) {
2164 class PyBlockArgumentList
2165 :
public Sliceable<PyBlockArgumentList, PyBlockArgument> {
2167 static constexpr
const char *pyClassName =
"BlockArgumentList";
2170 intptr_t startIndex = 0, intptr_t length = -1,
2175 operation(std::move(operation)), block(block) {}
2177 static void bindDerived(ClassTy &c) {
2178 c.def_property_readonly(
"types", [](PyBlockArgumentList &
self) {
2179 return getValueTypes(
self,
self.operation->getContext());
2185 friend class Sliceable<PyBlockArgumentList, PyBlockArgument>;
2188 intptr_t getRawNumElements() {
2189 operation->checkValid();
2194 PyBlockArgument getRawElement(intptr_t pos) {
2196 return PyBlockArgument(operation, argument);
2200 PyBlockArgumentList slice(intptr_t startIndex, intptr_t length,
2202 return PyBlockArgumentList(operation, block, startIndex, length, step);
2213 class PyOpOperandList :
public Sliceable<PyOpOperandList, PyValue> {
2215 static constexpr
const char *pyClassName =
"OpOperandList";
2217 PyOpOperandList(
PyOperationRef operation, intptr_t startIndex = 0,
2218 intptr_t length = -1, intptr_t step = 1)
2223 operation(operation) {}
2225 void dunderSetItem(intptr_t index,
PyValue value) {
2226 index = wrapIndex(index);
2230 static void bindDerived(ClassTy &c) {
2231 c.def(
"__setitem__", &PyOpOperandList::dunderSetItem);
2238 intptr_t getRawNumElements() {
2243 PyValue getRawElement(intptr_t pos) {
2245 MlirOperation owner;
2251 assert(
false &&
"Value must be an block arg or op result.");
2253 PyOperation::forOperation(operation->getContext(), owner);
2254 return PyValue(pyOwner, operand);
2257 PyOpOperandList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2258 return PyOpOperandList(operation, startIndex, length, step);
2268 class PyOpResultList :
public Sliceable<PyOpResultList, PyOpResult> {
2270 static constexpr
const char *pyClassName =
"OpResultList";
2272 PyOpResultList(
PyOperationRef operation, intptr_t startIndex = 0,
2273 intptr_t length = -1, intptr_t step = 1)
2278 operation(operation) {}
2280 static void bindDerived(ClassTy &c) {
2281 c.def_property_readonly(
"types", [](PyOpResultList &
self) {
2282 return getValueTypes(
self,
self.operation->getContext());
2284 c.def_property_readonly(
"owner", [](PyOpResultList &
self) {
2285 return self.operation->createOpView();
2291 friend class Sliceable<PyOpResultList, PyOpResult>;
2293 intptr_t getRawNumElements() {
2294 operation->checkValid();
2298 PyOpResult getRawElement(intptr_t index) {
2300 return PyOpResult(value);
2303 PyOpResultList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2304 return PyOpResultList(operation, startIndex, length, step);
2312 class PyOpAttributeMap {
2315 : operation(std::move(operation)) {}
2317 MlirAttribute dunderGetItemNamed(
const std::string &name) {
2321 throw py::key_error(
"attempt to access a non-existent attribute");
2327 if (index < 0 || index >= dunderLen()) {
2328 throw py::index_error(
"attempt to access out of bounds attribute");
2338 void dunderSetItem(
const std::string &name,
const PyAttribute &attr) {
2343 void dunderDelItem(
const std::string &name) {
2347 throw py::key_error(
"attempt to delete a non-existent attribute");
2350 intptr_t dunderLen() {
2354 bool dunderContains(
const std::string &name) {
2359 static void bind(py::module &m) {
2360 py::class_<PyOpAttributeMap>(m,
"OpAttributeMap", py::module_local())
2361 .def(
"__contains__", &PyOpAttributeMap::dunderContains)
2362 .def(
"__len__", &PyOpAttributeMap::dunderLen)
2363 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
2364 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
2365 .def(
"__setitem__", &PyOpAttributeMap::dunderSetItem)
2366 .def(
"__delitem__", &PyOpAttributeMap::dunderDelItem);
2383 py::enum_<MlirDiagnosticSeverity>(m,
"DiagnosticSeverity", py::module_local())
2392 py::class_<PyDiagnostic>(m,
"Diagnostic", py::module_local())
2393 .def_property_readonly(
"severity", &PyDiagnostic::getSeverity)
2394 .def_property_readonly(
"location", &PyDiagnostic::getLocation)
2395 .def_property_readonly(
"message", &PyDiagnostic::getMessage)
2396 .def_property_readonly(
"notes", &PyDiagnostic::getNotes)
2398 if (!
self.isValid())
2399 return "<Invalid Diagnostic>";
2400 return self.getMessage();
2403 py::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo",
2406 .def_readonly(
"severity", &PyDiagnostic::DiagnosticInfo::severity)
2407 .def_readonly(
"location", &PyDiagnostic::DiagnosticInfo::location)
2408 .def_readonly(
"message", &PyDiagnostic::DiagnosticInfo::message)
2409 .def_readonly(
"notes", &PyDiagnostic::DiagnosticInfo::notes)
2413 py::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler", py::module_local())
2414 .def(
"detach", &PyDiagnosticHandler::detach)
2415 .def_property_readonly(
"attached", &PyDiagnosticHandler::isAttached)
2416 .def_property_readonly(
"had_error", &PyDiagnosticHandler::getHadError)
2417 .def(
"__enter__", &PyDiagnosticHandler::contextEnter)
2418 .def(
"__exit__", &PyDiagnosticHandler::contextExit);
2426 py::class_<PyMlirContext>(m,
"_BaseContext", py::module_local())
2427 .def(py::init<>(&PyMlirContext::createNewContextForInit))
2428 .def_static(
"_get_live_count", &PyMlirContext::getLiveCount)
2429 .def(
"_get_context_again",
2434 .def(
"_get_live_operation_count", &PyMlirContext::getLiveOperationCount)
2435 .def(
"_clear_live_operations", &PyMlirContext::clearLiveOperations)
2436 .def(
"_get_live_module_count", &PyMlirContext::getLiveModuleCount)
2438 &PyMlirContext::getCapsule)
2440 .def(
"__enter__", &PyMlirContext::contextEnter)
2441 .def(
"__exit__", &PyMlirContext::contextExit)
2442 .def_property_readonly_static(
2445 auto *context = PyThreadContextEntry::getDefaultContext();
2447 throw py::value_error(
"No current Context");
2450 "Gets the Context bound to the current thread or raises ValueError")
2451 .def_property_readonly(
2454 "Gets a container for accessing dialects by name")
2455 .def_property_readonly(
2457 "Alias for 'dialect'")
2459 "get_dialect_descriptor",
2462 self.
get(), {name.data(), name.size()});
2464 throw py::value_error(
2465 (Twine(
"Dialect '") + name +
"' not found").str());
2469 py::arg(
"dialect_name"),
2470 "Gets or loads a dialect by name, returning its descriptor object")
2472 "allow_unregistered_dialects",
2479 .def(
"attach_diagnostic_handler", &PyMlirContext::attachDiagnosticHandler,
2480 py::arg(
"callback"),
2481 "Attaches a diagnostic handler that will receive callbacks")
2483 "enable_multithreading",
2489 "is_registered_operation",
2494 py::arg(
"operation_name"))
2496 "append_dialect_registry",
2500 py::arg(
"registry"))
2501 .def_property(
"emit_error_diagnostics",
nullptr,
2502 &PyMlirContext::setEmitErrorDiagnostics,
2503 "Emit error diagnostics to diagnostic handlers. By default "
2504 "error diagnostics are captured and reported through "
2505 "MLIRError exceptions.")
2506 .def(
"load_all_available_dialects", [](
PyMlirContext &
self) {
2513 py::class_<PyDialectDescriptor>(m,
"DialectDescriptor", py::module_local())
2514 .def_property_readonly(
"namespace",
2522 std::string repr(
"<DialectDescriptor ");
2531 py::class_<PyDialects>(m,
"Dialects", py::module_local())
2534 MlirDialect dialect =
2535 self.getDialectForKey(keyName,
false);
2536 py::object descriptor =
2540 .def(
"__getattr__", [=](
PyDialects &
self, std::string attrName) {
2541 MlirDialect dialect =
2542 self.getDialectForKey(attrName,
true);
2543 py::object descriptor =
2551 py::class_<PyDialect>(m,
"Dialect", py::module_local())
2552 .def(py::init<py::object>(), py::arg(
"descriptor"))
2553 .def_property_readonly(
2554 "descriptor", [](
PyDialect &
self) {
return self.getDescriptor(); })
2555 .def(
"__repr__", [](py::object
self) {
2556 auto clazz =
self.attr(
"__class__");
2557 return py::str(
"<Dialect ") +
2558 self.attr(
"descriptor").attr(
"namespace") + py::str(
" (class ") +
2559 clazz.attr(
"__module__") + py::str(
".") +
2560 clazz.attr(
"__name__") + py::str(
")>");
2566 py::class_<PyDialectRegistry>(m,
"DialectRegistry", py::module_local())
2568 &PyDialectRegistry::getCapsule)
2575 py::class_<PyLocation>(m,
"Location", py::module_local())
2578 .def(
"__enter__", &PyLocation::contextEnter)
2579 .def(
"__exit__", &PyLocation::contextExit)
2584 .def(
"__eq__", [](
PyLocation &
self, py::object other) {
return false; })
2585 .def_property_readonly_static(
2588 auto *loc = PyThreadContextEntry::getDefaultLocation();
2590 throw py::value_error(
"No current Location");
2593 "Gets the Location bound to the current thread or raises ValueError")
2600 py::arg(
"context") = py::none(),
2601 "Gets a Location representing an unknown location")
2604 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
2607 throw py::value_error(
"No caller frames provided");
2608 MlirLocation caller = frames.back().get();
2615 py::arg(
"callee"), py::arg(
"frames"), py::arg(
"context") = py::none(),
2619 [](std::string filename,
int line,
int col,
2626 py::arg(
"filename"), py::arg(
"line"), py::arg(
"col"),
2630 [](
const std::vector<PyLocation> &pyLocations,
2631 std::optional<PyAttribute> metadata,
2634 locations.reserve(pyLocations.size());
2635 for (
auto &pyLocation : pyLocations)
2636 locations.push_back(pyLocation.get());
2638 context->
get(), locations.size(), locations.data(),
2639 metadata ? metadata->get() : MlirAttribute{0});
2640 return PyLocation(context->getRef(), location);
2642 py::arg(
"locations"), py::arg(
"metadata") = py::none(),
2646 [](std::string name, std::optional<PyLocation> childLoc,
2652 childLoc ? childLoc->get()
2655 py::arg(
"name"), py::arg(
"childLoc") = py::none(),
2663 py::arg(
"attribute"), py::arg(
"context") = py::none(),
2664 "Gets a Location from a LocationAttr")
2665 .def_property_readonly(
2667 [](
PyLocation &
self) {
return self.getContext().getObject(); },
2668 "Context that owns the Location")
2669 .def_property_readonly(
2672 "Get the underlying LocationAttr")
2678 py::arg(
"message"),
"Emits an error at this location")
2683 return printAccum.
join();
2689 py::class_<PyModule>(m,
"Module", py::module_local())
2699 throw MLIRError(
"Unable to parse module assembly", errors.take());
2700 return PyModule::forModule(module).releaseObject();
2702 py::arg(
"asm"), py::arg(
"context") = py::none(),
2708 return PyModule::forModule(module).releaseObject();
2710 py::arg(
"loc") = py::none(),
"Creates an empty module")
2711 .def_property_readonly(
2713 [](
PyModule &
self) {
return self.getContext().getObject(); },
2714 "Context that created the Module")
2715 .def_property_readonly(
2718 return PyOperation::forOperation(
self.
getContext(),
2720 self.getRef().releaseObject())
2723 "Accesses the module as an operation")
2724 .def_property_readonly(
2729 self.getRef().releaseObject());
2733 "Return the block for this module")
2742 [](py::object
self) {
2744 return self.attr(
"operation").attr(
"__str__")();
2751 py::class_<PyOperationBase>(m,
"_OperationBase", py::module_local())
2754 return self.getOperation().getCapsule();
2766 .def_property_readonly(
"attributes",
2768 return PyOpAttributeMap(
2769 self.getOperation().getRef());
2771 .def_property_readonly(
2778 "Context that owns the Operation")
2779 .def_property_readonly(
"name",
2783 MlirOperation operation =
2784 concreteOperation.
get();
2789 .def_property_readonly(
"operands",
2791 return PyOpOperandList(
2792 self.getOperation().getRef());
2794 .def_property_readonly(
"regions",
2796 return PyRegionList(
2797 self.getOperation().getRef());
2799 .def_property_readonly(
2802 return PyOpResultList(
self.getOperation().getRef());
2804 "Returns the list of Operation results.")
2805 .def_property_readonly(
2808 auto &operation =
self.getOperation();
2810 if (numResults != 1) {
2812 throw py::value_error(
2813 (Twine(
"Cannot call .result on operation ") +
2814 StringRef(name.
data, name.
length) +
" which has " +
2816 " results (it is only valid for operations with a "
2820 return PyOpResult(operation.getRef(),
2823 "Shortcut to get an op result if it has only one (throws an error "
2825 .def_property_readonly(
2832 "Returns the source location the operation was defined or derived "
2834 .def_property_readonly(
"parent",
2837 self.getOperation().getParentOperation();
2839 return parent->getObject();
2845 return self.getAsm(
false,
2853 "Returns the assembly form of the operation.")
2856 py::arg(
"file") = py::none(), py::arg(
"binary") =
false,
2857 py::arg(
"large_elements_limit") = py::none(),
2858 py::arg(
"enable_debug_info") =
false,
2859 py::arg(
"pretty_debug_info") =
false,
2860 py::arg(
"print_generic_op_form") =
false,
2861 py::arg(
"use_local_scope") =
false,
2863 .def(
"write_bytecode", &PyOperationBase::writeBytecode, py::arg(
"file"),
2864 py::arg(
"desired_version") = py::none(),
2866 .def(
"get_asm", &PyOperationBase::getAsm,
2868 py::arg(
"binary") =
false,
2869 py::arg(
"large_elements_limit") = py::none(),
2870 py::arg(
"enable_debug_info") =
false,
2871 py::arg(
"pretty_debug_info") =
false,
2872 py::arg(
"print_generic_op_form") =
false,
2873 py::arg(
"use_local_scope") =
false,
2876 "Verify the operation. Raises MLIRError if verification fails, and "
2877 "returns true otherwise.")
2878 .def(
"move_after", &PyOperationBase::moveAfter, py::arg(
"other"),
2879 "Puts self immediately after the other operation in its parent "
2881 .def(
"move_before", &PyOperationBase::moveBefore, py::arg(
"other"),
2882 "Puts self immediately before the other operation in its parent "
2887 return self.getOperation().clone(ip);
2889 py::arg(
"ip") = py::none())
2891 "detach_from_parent",
2896 throw py::value_error(
"Detached operation has no parent.");
2901 "Detaches the operation from its parent block.")
2902 .def(
"erase", [](
PyOperationBase &
self) {
self.getOperation().erase(); });
2904 py::class_<PyOperation, PyOperationBase>(m,
"Operation", py::module_local())
2905 .def_static(
"create", &PyOperation::create, py::arg(
"name"),
2906 py::arg(
"results") = py::none(),
2907 py::arg(
"operands") = py::none(),
2908 py::arg(
"attributes") = py::none(),
2909 py::arg(
"successors") = py::none(), py::arg(
"regions") = 0,
2910 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
2914 [](
const std::string &sourceStr,
const std::string &sourceName,
2916 return PyOperation::parse(context->getRef(), sourceStr, sourceName)
2919 py::arg(
"source"), py::kw_only(), py::arg(
"source_name") =
"",
2920 py::arg(
"context") = py::none(),
2921 "Parses an operation. Supports both text assembly format and binary "
2924 &PyOperation::getCapsule)
2926 .def_property_readonly(
"operation", [](py::object
self) {
return self; })
2927 .def_property_readonly(
"opview", &PyOperation::createOpView);
2930 py::class_<PyOpView, PyOperationBase>(m,
"OpView", py::module_local())
2931 .def(py::init<py::object>(), py::arg(
"operation"))
2932 .def_property_readonly(
"operation", &PyOpView::getOperationObject)
2933 .def_property_readonly(
"opview", [](py::object
self) {
return self; })
2934 .def(
"__str__", [](
PyOpView &
self) {
2935 return py::str(
self.getOperationObject());
2937 opViewClass.attr(
"_ODS_REGIONS") = py::make_tuple(0,
true);
2938 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = py::none();
2939 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = py::none();
2941 &PyOpView::buildGeneric, py::arg(
"cls"), py::arg(
"results") = py::none(),
2942 py::arg(
"operands") = py::none(), py::arg(
"attributes") = py::none(),
2943 py::arg(
"successors") = py::none(), py::arg(
"regions") = py::none(),
2944 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
2945 "Builds a specific, generated OpView based on class level attributes.");
2947 [](
const py::object &cls,
const std::string &sourceStr,
2950 PyOperation::parse(context->getRef(), sourceStr, sourceName);
2957 std::string clsOpName =
2958 py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
2961 std::string_view parsedOpName(identifier.
data, identifier.
length);
2962 if (clsOpName != parsedOpName)
2963 throw MLIRError(Twine(
"Expected a '") + clsOpName +
"' op, got: '" +
2964 parsedOpName +
"'");
2965 return PyOpView::constructDerived(cls, *parsed.
get());
2967 py::arg(
"cls"), py::arg(
"source"), py::kw_only(),
2968 py::arg(
"source_name") =
"", py::arg(
"context") = py::none(),
2969 "Parses a specific, generated OpView based on class level attributes");
2974 py::class_<PyRegion>(m,
"Region", py::module_local())
2975 .def_property_readonly(
2978 return PyBlockList(
self.getParentOperation(),
self.
get());
2980 "Returns a forward-optimized sequence of blocks.")
2981 .def_property_readonly(
2984 return self.getParentOperation()->createOpView();
2986 "Returns the operation owning this region.")
2992 return PyBlockIterator(
self.getParentOperation(), firstBlock);
2994 "Iterates over blocks in the region.")
2997 return self.get().ptr == other.
get().ptr;
2999 .def(
"__eq__", [](
PyRegion &
self, py::object &other) {
return false; });
3004 py::class_<PyBlock>(m,
"Block", py::module_local())
3006 .def_property_readonly(
3009 return self.getParentOperation()->createOpView();
3011 "Returns the owning operation of this block.")
3012 .def_property_readonly(
3016 return PyRegion(
self.getParentOperation(), region);
3018 "Returns the owning region of this block.")
3019 .def_property_readonly(
3022 return PyBlockArgumentList(
self.getParentOperation(),
self.
get());
3024 "Returns a list of block arguments.")
3025 .def_property_readonly(
3028 return PyOperationList(
self.getParentOperation(),
self.
get());
3030 "Returns a forward-optimized sequence of operations.")
3033 [](
PyRegion &parent,
const py::list &pyArgTypes,
3034 const std::optional<py::sequence> &pyArgLocs) {
3036 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3040 py::arg(
"parent"), py::arg(
"arg_types") = py::list(),
3041 py::arg(
"arg_locs") = std::nullopt,
3042 "Creates and returns a new Block at the beginning of the given "
3043 "region (with given argument types and locations).")
3047 MlirBlock b =
self.get();
3052 "Append this block to a region, transferring ownership if necessary")
3055 [](
PyBlock &
self,
const py::args &pyArgTypes,
3056 const std::optional<py::sequence> &pyArgLocs) {
3058 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3061 return PyBlock(
self.getParentOperation(), block);
3063 py::arg(
"arg_locs") = std::nullopt,
3064 "Creates and returns a new Block before this block "
3065 "(with given argument types and locations).")
3068 [](
PyBlock &
self,
const py::args &pyArgTypes,
3069 const std::optional<py::sequence> &pyArgLocs) {
3071 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3074 return PyBlock(
self.getParentOperation(), block);
3076 py::arg(
"arg_locs") = std::nullopt,
3077 "Creates and returns a new Block after this block "
3078 "(with given argument types and locations).")
3083 MlirOperation firstOperation =
3085 return PyOperationIterator(
self.getParentOperation(),
3088 "Iterates over operations in the block.")
3091 return self.get().ptr == other.
get().ptr;
3093 .def(
"__eq__", [](
PyBlock &
self, py::object &other) {
return false; })
3105 return printAccum.
join();
3107 "Returns the assembly form of the block.")
3117 self.getParentOperation().getObject());
3119 py::arg(
"operation"),
3120 "Appends an operation to this block. If the operation is currently "
3121 "in another block, it will be moved.");
3127 py::class_<PyInsertionPoint>(m,
"InsertionPoint", py::module_local())
3128 .def(py::init<PyBlock &>(), py::arg(
"block"),
3129 "Inserts after the last operation but still inside the block.")
3130 .def(
"__enter__", &PyInsertionPoint::contextEnter)
3131 .def(
"__exit__", &PyInsertionPoint::contextExit)
3132 .def_property_readonly_static(
3135 auto *ip = PyThreadContextEntry::getDefaultInsertionPoint();
3137 throw py::value_error(
"No current InsertionPoint");
3140 "Gets the InsertionPoint bound to the current thread or raises "
3141 "ValueError if none has been set")
3142 .def(py::init<PyOperationBase &>(), py::arg(
"beforeOperation"),
3143 "Inserts before a referenced operation.")
3144 .def_static(
"at_block_begin", &PyInsertionPoint::atBlockBegin,
3145 py::arg(
"block"),
"Inserts at the beginning of the block.")
3146 .def_static(
"at_block_terminator", &PyInsertionPoint::atBlockTerminator,
3147 py::arg(
"block"),
"Inserts before the block terminator.")
3148 .def(
"insert", &PyInsertionPoint::insert, py::arg(
"operation"),
3149 "Inserts an operation.")
3150 .def_property_readonly(
3152 "Returns the block that this InsertionPoint points to.");
3157 py::class_<PyAttribute>(m,
"Attribute", py::module_local())
3160 .def(py::init<PyAttribute &>(), py::arg(
"cast_from_type"),
3161 "Casts the passed attribute to the generic Attribute")
3163 &PyAttribute::getCapsule)
3172 throw MLIRError(
"Unable to parse attribute", errors.take());
3175 py::arg(
"asm"), py::arg(
"context") = py::none(),
3176 "Parses an attribute from an assembly form. Raises an MLIRError on "
3178 .def_property_readonly(
3180 [](
PyAttribute &
self) {
return self.getContext().getObject(); },
3181 "Context that owns the Attribute")
3182 .def_property_readonly(
3189 py::keep_alive<0, 1>(),
"Binds a name to the attribute")
3192 .def(
"__eq__", [](
PyAttribute &
self, py::object &other) {
return false; })
3206 return printAccum.
join();
3208 "Returns the assembly form of the Attribute.")
3217 printAccum.
parts.append(
"Attribute(");
3220 printAccum.
parts.append(
")");
3221 return printAccum.
join();
3223 .def_property_readonly(
3228 "mlirTypeID was expected to be non-null.");
3234 "mlirTypeID was expected to be non-null.");
3235 std::optional<pybind11::function> typeCaster =
3239 return py::cast(
self);
3240 return typeCaster.value()(
self);
3246 py::class_<PyNamedAttribute>(m,
"NamedAttribute", py::module_local())
3250 printAccum.
parts.append(
"NamedAttribute(");
3251 printAccum.
parts.append(
3254 printAccum.
parts.append(
"=");
3258 printAccum.
parts.append(
")");
3259 return printAccum.
join();
3261 .def_property_readonly(
3267 "The name of the NamedAttribute binding")
3268 .def_property_readonly(
3271 py::keep_alive<0, 1>(),
3272 "The underlying generic attribute of the NamedAttribute binding");
3277 py::class_<PyType>(m,
"Type", py::module_local())
3280 .def(py::init<PyType &>(), py::arg(
"cast_from_type"),
3281 "Casts the passed type to the generic Type")
3291 throw MLIRError(
"Unable to parse type", errors.take());
3294 py::arg(
"asm"), py::arg(
"context") = py::none(),
3296 .def_property_readonly(
3297 "context", [](
PyType &
self) {
return self.getContext().getObject(); },
3298 "Context that owns the Type")
3299 .def(
"__eq__", [](
PyType &
self,
PyType &other) {
return self == other; })
3300 .def(
"__eq__", [](
PyType &
self, py::object &other) {
return false; })
3313 return printAccum.
join();
3315 "Returns the assembly form of the type.")
3323 printAccum.
parts.append(
"Type(");
3326 printAccum.
parts.append(
")");
3327 return printAccum.
join();
3333 "mlirTypeID was expected to be non-null.");
3334 std::optional<pybind11::function> typeCaster =
3338 return py::cast(
self);
3339 return typeCaster.value()(
self);
3341 .def_property_readonly(
"typeid", [](
PyType &
self) -> MlirTypeID {
3346 pybind11::repr(pybind11::cast(
self)).cast<std::string>();
3347 throw py::value_error(
3348 (origRepr + llvm::Twine(
" has no typeid.")).str());
3354 py::class_<PyTypeID>(m,
"TypeID", py::module_local())
3363 [](
PyTypeID &
self,
const py::object &other) {
return false; })
3367 .def(
"__hash__", [](
PyTypeID &
self) {
3374 py::class_<PyValue>(m,
"Value", py::module_local())
3375 .def(py::init<PyValue &>(), py::keep_alive<0, 1>(), py::arg(
"value"))
3378 .def_property_readonly(
3381 "Context in which the value lives.")
3385 .def_property_readonly(
3387 [](
PyValue &
self) -> py::object {
3388 MlirValue v =
self.get();
3393 "expected the owner of the value in Python to match that in "
3395 return self.getParentOperation().getObject();
3400 return py::cast(
PyBlock(
self.getParentOperation(), block));
3403 assert(
false &&
"Value must be a block argument or an op result");
3406 .def_property_readonly(
"uses",
3408 return PyOpOperandIterator(
3413 return self.get().ptr == other.
get().ptr;
3415 .def(
"__eq__", [](
PyValue &
self, py::object other) {
return false; })
3424 printAccum.
parts.append(
"Value(");
3427 printAccum.
parts.append(
")");
3428 return printAccum.
join();
3433 [](
PyValue &
self, std::optional<bool> useLocalScope,
3434 std::optional<std::reference_wrapper<PyAsmState>> state) {
3436 MlirOpPrintingFlags flags;
3437 MlirAsmState valueState;
3440 valueState = state.value().get().get();
3442 if (useLocalScope.has_value())
3443 throw py::value_error(
3444 "setting AsmState and local scope together not supported");
3447 if (useLocalScope.value_or(
false))
3458 return printAccum.
join();
3460 py::arg(
"use_local_scope") = std::nullopt,
3462 .def_property_readonly(
3471 "replace_all_uses_with",
3476 PyBlockArgument::bind(m);
3477 PyOpResult::bind(m);
3478 PyOpOperand::bind(m);
3480 py::class_<PyAsmState>(m,
"AsmState", py::module_local())
3481 .def(py::init<PyValue &, bool>(), py::arg(
"value"),
3482 py::arg(
"use_local_scope") =
false)
3483 .def(py::init<PyOperationBase &, bool>(), py::arg(
"op"),
3484 py::arg(
"use_local_scope") =
false);
3489 py::class_<PySymbolTable>(m,
"SymbolTable", py::module_local())
3490 .def(py::init<PyOperationBase &>())
3491 .def(
"__getitem__", &PySymbolTable::dunderGetItem)
3492 .def(
"insert", &PySymbolTable::insert, py::arg(
"operation"))
3493 .def(
"erase", &PySymbolTable::erase, py::arg(
"operation"))
3494 .def(
"__delitem__", &PySymbolTable::dunderDel)
3495 .def(
"__contains__",
3501 .def_static(
"set_symbol_name", &PySymbolTable::setSymbolName,
3502 py::arg(
"symbol"), py::arg(
"name"))
3503 .def_static(
"get_symbol_name", &PySymbolTable::getSymbolName,
3505 .def_static(
"get_visibility", &PySymbolTable::getVisibility,
3507 .def_static(
"set_visibility", &PySymbolTable::setVisibility,
3508 py::arg(
"symbol"), py::arg(
"visibility"))
3509 .def_static(
"replace_all_symbol_uses",
3510 &PySymbolTable::replaceAllSymbolUses, py::arg(
"old_symbol"),
3511 py::arg(
"new_symbol"), py::arg(
"from_op"))
3512 .def_static(
"walk_symbol_tables", &PySymbolTable::walkSymbolTables,
3513 py::arg(
"from_op"), py::arg(
"all_sym_uses_visible"),
3514 py::arg(
"callback"));
3517 PyBlockArgumentList::bind(m);
3518 PyBlockIterator::bind(m);
3519 PyBlockList::bind(m);
3520 PyOperationIterator::bind(m);
3521 PyOperationList::bind(m);
3522 PyOpAttributeMap::bind(m);
3523 PyOpOperandIterator::bind(m);
3524 PyOpOperandList::bind(m);
3525 PyOpResultList::bind(m);
3526 PyRegionIterator::bind(m);
3527 PyRegionList::bind(m);
3535 py::register_local_exception_translator([](std::exception_ptr p) {
3540 std::rethrow_exception(p);
3544 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 const char kValueReplaceAllUsesWithDocstring[]
static py::object createCustomDialectWrapper(const std::string &dialectNamespace, py::object dialectDescriptor)
static const char kContextGetNameLocationDocString[]
static const char kGetNameAsOperand[]
static MlirStringRef toMlirStringRef(const std::string &s)
static const char kModuleParseDocstring[]
static const char kOperationStrDunderDocstring[]
static const char kOperationPrintDocstring[]
static const char kContextGetFileLocationDocstring[]
static const char kDumpDocstring[]
static const char kAppendBlockDocstring[]
static const char kContextGetFusedLocationDocstring[]
static void maybeInsertOperation(PyOperationRef &op, const py::object &maybeIp)
static MlirBlock createBlock(const py::sequence &pyArgTypes, const std::optional< py::sequence > &pyArgLocs)
Create a block, using the current location context if no locations are specified.
static const char kOperationPrintBytecodeDocstring[]
static const char kOperationGetAsmDocstring[]
static void populateResultTypes(StringRef name, py::list resultTypeList, const py::object &resultSegmentSpecObj, std::vector< int32_t > &resultSegmentLengths, std::vector< PyType * > &resultTypes)
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 MLIRContext * getContext(OpFoldResult val)
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
#define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR
Attribute on MLIR Python objects that expose a function for downcasting the corresponding Python obje...
static PyObject * mlirPythonTypeIDToCapsule(MlirTypeID typeID)
Creates a capsule object encapsulating the raw C-API MlirTypeID.
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule.
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
static MlirTypeID mlirPythonCapsuleToTypeID(PyObject *capsule)
Extracts an MlirTypeID from a capsule as produced from mlirPythonTypeIDToCapsule.
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
#define MAKE_MLIR_PYTHON_QUALNAME(local)
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
static PyObject * mlirPythonBlockToCapsule(MlirBlock block)
Creates a capsule object encapsulating the raw C-API MlirBlock.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
static PyObject * mlirPythonContextToCapsule(MlirContext context)
Creates a capsule object encapsulating the raw C-API MlirContext.
static LogicalResult nextIndex(ArrayRef< int64_t > shape, MutableArrayRef< int64_t > index)
Walks over the indices of the elements of a tensor of a given shape by updating index in place to the...
static std::string diag(const llvm::Value &value)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
MLIRContext * getContext()
Return the context this operation is associated with.
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.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAttribute.
bool operator==(const PyAttribute &other) const
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)
static PyGlobals & get()
Most code should get the globals via this static accessor.
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 buildGeneric(const pybind11::object &cls, std::optional< 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)
static pybind11::object constructDerived(const pybind11::object &cls, const PyOperation &operation)
Construct an instance of a class deriving from OpView, bypassing its __init__ method.
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.
void writeBytecode(const pybind11::object &fileObject, std::optional< int64_t > bytecodeVersion)
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.
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.
MlirOperation get() const
void setAttached(const pybind11::object &parent=pybind11::object())
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, bool inferType)
Creates an operation. See corresponding python docstring.
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 ...
static void replaceAllSymbolUses(const std::string &oldSymbol, const std::string &newSymbol, PyOperationBase &from)
Replaces all symbol uses within an operation.
static void setVisibility(PyOperationBase &symbol, const std::string &visibility)
static void setSymbolName(PyOperationBase &symbol, const std::string &name)
MlirAttribute insert(PyOperationBase &symbol)
Inserts the given operation into the symbol table.
void erase(PyOperationBase &symbol)
Removes the given operation from the symbol table and erases it.
PySymbolTable(PyOperationBase &operation)
Constructs a symbol table for the given operation.
static MlirAttribute getSymbolName(PyOperationBase &symbol)
Gets and sets the name of a symbol op.
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 MlirAttribute getVisibility(PyOperationBase &symbol)
Gets and sets the visibility of a symbol op.
static void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible, pybind11::object callback)
Walks all symbol tables under and including 'from'.
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()
A TypeID provides an efficient and unique identifier for a specific C++ type.
bool operator==(const PyTypeID &other) const
static PyTypeID createFromCapsule(pybind11::object capsule)
Creates a PyTypeID from the MlirTypeID wrapped by a capsule.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirTypeID.
PyTypeID(MlirTypeID typeID)
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.
PyType(PyMlirContextRef contextRef, MlirType type)
bool operator==(const PyType &other) const
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.
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 void mlirValueReplaceAllUsesOfWith(MlirValue of, MlirValue with)
Replace all uses of 'of' value with the 'with' value, updating anything in the IR that uses 'of' to u...
MLIR_CAPI_EXPORTED void mlirValuePrintAsOperand(MlirValue value, MlirAsmState state, MlirStringCallback callback, void *userData)
Prints a value as an operand (i.e., the ValueID).
MLIR_CAPI_EXPORTED MlirLocation mlirLocationUnknownGet(MlirContext context)
Creates a location with unknown position owned by the given context.
MLIR_CAPI_EXPORTED void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, MlirAttribute attr)
Sets an attribute by name, replacing the existing if it exists or adding a new one otherwise.
MLIR_CAPI_EXPORTED MlirOperation mlirOpOperandGetOwner(MlirOpOperand opOperand)
Returns the owner operation of an op operand.
MLIR_CAPI_EXPORTED MlirDialect mlirAttributeGetDialect(MlirAttribute attribute)
Gets the dialect of the attribute.
MLIR_CAPI_EXPORTED void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, void *userData)
Prints an attribute by sending chunks of the string representation and forwarding userData tocallback...
MLIR_CAPI_EXPORTED MlirRegion mlirBlockGetParentRegion(MlirBlock block)
Returns the region that contains this block.
MLIR_CAPI_EXPORTED void mlirOperationMoveBefore(MlirOperation op, MlirOperation other)
Moves the given operation immediately before the other operation in its parent block.
static bool mlirValueIsNull(MlirValue value)
Returns whether the value is null.
MLIR_CAPI_EXPORTED void 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...
MLIR_CAPI_EXPORTED void mlirAsmStateDestroy(MlirAsmState state)
Destroys printing flags created with mlirAsmStateCreate.
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
MLIR_CAPI_EXPORTED MlirDialect mlirContextGetOrLoadDialect(MlirContext context, MlirStringRef name)
Gets the dialect instance owned by the given context using the dialect namespace to identify it,...
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsElideLargeElementsAttrs(MlirOpPrintingFlags flags, intptr_t largeElementLimit)
Enables the elision of large elements attributes by printing a lexically valid but otherwise meaningl...
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it after the (non-owned) reference block in the given r...
MLIR_CAPI_EXPORTED void mlirBlockArgumentSetType(MlirValue value, MlirType type)
Sets the type of the block argument to the given type.
MLIR_CAPI_EXPORTED MlirContext mlirOperationGetContext(MlirOperation op)
Gets the context this operation is associated with.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args, MlirLocation const *locs)
Creates a new empty block with the given argument types and transfers ownership to the caller.
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
MLIR_CAPI_EXPORTED void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation)
Takes an operation owned by the caller and appends it to the block.
MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos)
Returns pos-th argument of the block.
MLIR_CAPI_EXPORTED MlirOperation mlirSymbolTableLookup(MlirSymbolTable symbolTable, MlirStringRef name)
Looks up a symbol with the given name in the given symbol table and returns the operation that corres...
MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type)
Gets the context that a type was created with.
MLIR_CAPI_EXPORTED void mlirValueDump(MlirValue value)
Prints the value to the standard error stream.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateEmpty(MlirLocation location)
Creates a new, empty module and transfers ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirOpOperandIsNull(MlirOpOperand opOperand)
Returns whether the op operand is null.
MLIR_CAPI_EXPORTED MlirSymbolTable mlirSymbolTableCreate(MlirOperation operation)
Creates a symbol table for the given operation.
MLIR_CAPI_EXPORTED bool mlirLocationEqual(MlirLocation l1, MlirLocation l2)
Checks if two locations are equal.
MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetBlock(MlirOperation op)
Gets the block that owns this operation, returning null if the operation is not owned.
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
MLIR_CAPI_EXPORTED bool mlirOperationEqual(MlirOperation op, MlirOperation other)
Checks whether two operation handles point to the same operation.
MLIR_CAPI_EXPORTED 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 MlirTypeID mlirTypeGetTypeID(MlirType type)
Gets the type ID of the type.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetVisibilityAttributeName(void)
Returns the name of the attribute used to store symbol visibility.
static bool mlirDialectIsNull(MlirDialect dialect)
Checks if the dialect is null.
MLIR_CAPI_EXPORTED void mlirBytecodeWriterConfigDestroy(MlirBytecodeWriterConfig config)
Destroys printing flags created with mlirBytecodeWriterConfigCreate.
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos)
Returns pos-th operand of the operation.
MLIR_CAPI_EXPORTED void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, MlirNamedAttribute const *attributes)
MLIR_CAPI_EXPORTED MlirBlock mlirBlockGetNextInRegion(MlirBlock block)
Returns the block immediately following the given block in its parent region.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller)
Creates a call site location with a callee and a caller.
MLIR_CAPI_EXPORTED MlirOperation mlirOpResultGetOwner(MlirValue value)
Returns an operation that produced this value as its result.
MLIR_CAPI_EXPORTED bool mlirValueIsAOpResult(MlirValue value)
Returns 1 if the value is an operation result, 0 otherwise.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumOperands(MlirOperation op)
Returns the number of operands of the operation.
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
MLIR_CAPI_EXPORTED 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 MlirBytecodeWriterConfig mlirBytecodeWriterConfigCreate(void)
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED MlirContext mlirAttributeGetContext(MlirAttribute attribute)
Gets the context that an attribute was created with.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockArgumentGetOwner(MlirValue value)
Returns the block in which this value is defined as an argument.
static bool mlirRegionIsNull(MlirRegion region)
Checks whether a region is null.
MLIR_CAPI_EXPORTED void mlirOperationDestroy(MlirOperation op)
Takes an operation owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos)
Returns pos-th region attached to the operation.
MLIR_CAPI_EXPORTED MlirDialect mlirTypeGetDialect(MlirType type)
Gets the dialect a type belongs to.
MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
MLIR_CAPI_EXPORTED void mlirContextLoadAllAvailableDialects(MlirContext context)
Eagerly loads all available dialects registered with a context, making them available for use for IR ...
MLIR_CAPI_EXPORTED void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, MlirRegion const *regions)
MLIR_CAPI_EXPORTED void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, MlirBlock const *successors)
MLIR_CAPI_EXPORTED MlirBlock mlirModuleGetBody(MlirModule module)
Gets the body of the module, i.e. the only block it contains.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags)
Destroys printing flags created with mlirOpPrintingFlagsCreate.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGet(MlirContext context, MlirStringRef name, MlirLocation childLoc)
Creates a name location owned by the given context.
MLIR_CAPI_EXPORTED void mlirContextEnableMultithreading(MlirContext context, bool enable)
Set threading mode (must be set to false to mlir-print-ir-after-all).
MLIR_CAPI_EXPORTED void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, void *userData)
Prints a block by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirBytecodeWriterConfigDesiredEmitVersion(MlirBytecodeWriterConfig flags, int64_t version)
Sets the version to emit in the writer config.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetSymbolAttributeName(void)
Returns the name of the attribute used to store symbol names compatible with symbol tables.
MLIR_CAPI_EXPORTED MlirRegion mlirRegionCreate(void)
Creates a new empty region and transfers ownership to the caller.
MLIR_CAPI_EXPORTED void mlirBlockDetach(MlirBlock block)
Detach a block from the owning region and assume ownership.
MLIR_CAPI_EXPORTED void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, MlirType const *results)
Adds a list of components to the operation state.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, bool enable, bool prettyForm)
Enable or disable printing of debug information (based on enable).
MLIR_CAPI_EXPORTED MlirLocation mlirOperationGetLocation(MlirOperation op)
Gets the location of the operation.
MLIR_CAPI_EXPORTED MlirTypeID mlirAttributeGetTypeID(MlirAttribute attribute)
Gets the type id of the attribute.
MLIR_CAPI_EXPORTED void mlirOperationSetOperand(MlirOperation op, intptr_t pos, MlirValue newValue)
Sets the pos-th operand of the operation.
MLIR_CAPI_EXPORTED void mlirOperationDump(MlirOperation op)
Prints an operation to stderr.
MLIR_CAPI_EXPORTED intptr_t mlirOpResultGetResultNumber(MlirValue value)
Returns the position of the value in the list of results of the operation that produced it.
MLIR_CAPI_EXPORTED MlirOpPrintingFlags mlirOpPrintingFlagsCreate(void)
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED MlirContext mlirContextCreate(void)
Creates an MLIR context and transfers its ownership to the caller.
MLIR_CAPI_EXPORTED MlirAsmState mlirAsmStateCreateForValue(MlirValue value, MlirOpPrintingFlags flags)
Creates new AsmState from value.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreate(MlirOperationState *state)
Creates an operation and transfers ownership to the caller.
static bool mlirSymbolTableIsNull(MlirSymbolTable symbolTable)
Returns true if the symbol table is null.
MLIR_CAPI_EXPORTED bool mlirContextGetAllowUnregisteredDialects(MlirContext context)
Returns whether the context allows unregistered dialects.
MLIR_CAPI_EXPORTED void mlirOperationMoveAfter(MlirOperation op, MlirOperation other)
Moves the given operation immediately after the other operation in its parent block.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumAttributes(MlirOperation op)
Returns the number of attributes attached to the operation.
MLIR_CAPI_EXPORTED void mlirValuePrint(MlirValue value, MlirStringCallback callback, void *userData)
Prints a value by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirOperationWriteBytecodeWithConfig(MlirOperation op, MlirBytecodeWriterConfig config, MlirStringCallback callback, void *userData)
Same as mlirOperationWriteBytecode but with writer config and returns failure only if desired bytecod...
MLIR_CAPI_EXPORTED void mlirValueSetType(MlirValue value, MlirType type)
Set the type of the value.
MLIR_CAPI_EXPORTED MlirType mlirValueGetType(MlirValue value)
Returns the type of the value.
MLIR_CAPI_EXPORTED void mlirContextDestroy(MlirContext context)
Takes an MLIR context owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreateParse(MlirContext context, MlirStringRef sourceStr, MlirStringRef sourceName)
Parses an operation, giving ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2)
Checks if two attributes are equal.
static bool mlirOperationIsNull(MlirOperation op)
Checks whether the underlying operation is null.
MLIR_CAPI_EXPORTED MlirBlock mlirRegionGetFirstBlock(MlirRegion region)
Gets the first block in the region.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
static MlirLogicalResult mlirLogicalResultFailure(void)
Creates a logical result representing a failure.
MLIR_CAPI_EXPORTED size_t mlirTypeIDHashValue(MlirTypeID typeID)
Returns the hash value of the type id.
static MlirLogicalResult mlirLogicalResultSuccess(void)
Creates a logical result representing a success.
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
static bool mlirTypeIDIsNull(MlirTypeID typeID)
Checks whether a type id is null.
MLIR_CAPI_EXPORTED bool mlirTypeIDEqual(MlirTypeID typeID1, MlirTypeID typeID2)
Checks if two type ids are equal.
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
void populateIRCore(pybind11::module &m)
PyObjectRef< PyOperation > PyOperationRef
This header declares functions that assist transformations in the MemRef dialect.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
A logical result value, essentially a boolean with named states.
An auxiliary class for constructing operations.
A pointer to a sized fragment of a string, not necessarily null-terminated.
const char * data
Pointer to the first symbol.
size_t length
Length of the fragment.
static bool dunderContains(const std::string &attributeKind)
static void dundeSetItemNamed(const std::string &attributeKind, py::function func, bool replace)
static py::function dundeGetItemNamed(const std::string &attributeKind)
static void bind(py::module &m)
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)