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.
111 skip_regions: Whether to skip printing regions. Defaults to False.
115 R
"(Prints the assembly form of the operation to a file like object.
118 file: The file like object to write to. Defaults to sys.stdout.
119 binary: Whether to write bytes (True) or str (False). Defaults to False.
120 state: AsmState capturing the operation numbering and flags.
124 R
"(Gets the assembly form of the operation with all options available.
127 binary: Whether to return a bytes (True) or str (False) object. Defaults to
129 ... others ...: See the print() method for common keyword arguments for
130 configuring the printout.
132 Either a bytes or str object, depending on the setting of the 'binary'
137 R
"(Write the bytecode form of the operation to a file like object.
140 file: The file like object to write to.
141 desired_version: The version of bytecode to emit.
143 The bytecode writer status.
147 R
"(Gets the assembly form of the operation with default options.
149 If more advanced control over the assembly formatting or I/O options is needed,
150 use the dedicated print or get_asm method, which supports keyword arguments to
155 R
"(Dumps a debug representation of the object to stderr.)";
158 R
"(Appends a new block, with argument types as positional args.
165 R
"(Returns the string form of the value.
167 If the value is a block argument, this is the assembly form of its type and the
168 position in the argument list. If the value is an operation result, this is
169 equivalent to printing the operation that produced it.
173 R
"(Returns the string form of value as an operand (i.e., the ValueID).
177 R
"(Replace all uses of value with the new value, updating anything in
178 the IR that uses 'self' to use the other value instead.
182 R
"("Replace all uses of this value with the 'with' value, except for those
183 in 'exceptions'. 'exceptions' can be either a single operation or a list of
192 template <
class Func,
typename... Args>
194 py::object cf = py::cpp_function(f, args...);
195 return py::reinterpret_borrow<py::object>((PyClassMethod_New(cf.ptr())));
200 py::object dialectDescriptor) {
201 auto dialectClass =
PyGlobals::get().lookupDialectClass(dialectNamespace);
204 return py::cast(
PyDialect(std::move(dialectDescriptor)));
208 return (*dialectClass)(std::move(dialectDescriptor));
218 const std::optional<py::sequence> &pyArgLocs) {
220 argTypes.reserve(pyArgTypes.size());
221 for (
const auto &pyType : pyArgTypes)
222 argTypes.push_back(pyType.cast<
PyType &>());
226 argLocs.reserve(pyArgLocs->size());
227 for (
const auto &pyLoc : *pyArgLocs)
228 argLocs.push_back(pyLoc.cast<
PyLocation &>());
229 }
else if (!argTypes.empty()) {
230 argLocs.assign(argTypes.size(), DefaultingPyLocation::resolve());
233 if (argTypes.size() != argLocs.size())
234 throw py::value_error((
"Expected " + Twine(argTypes.size()) +
235 " locations, got: " + Twine(argLocs.size()))
237 return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
246 static void bind(py::module &m) {
248 py::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug", py::module_local())
253 [](
const std::string &type) {
256 "types"_a,
"Sets specific debug types to be produced by LLVM")
257 .def_static(
"set_types", [](
const std::vector<std::string> &types) {
258 std::vector<const char *> pointers;
259 pointers.reserve(types.size());
260 for (
const std::string &str : types)
261 pointers.push_back(str.c_str());
269 return PyGlobals::get().lookupAttributeBuilder(attributeKind).has_value();
272 auto builder =
PyGlobals::get().lookupAttributeBuilder(attributeKind);
274 throw py::key_error(attributeKind);
278 py::function func,
bool replace) {
279 PyGlobals::get().registerAttributeBuilder(attributeKind, std::move(func),
283 static void bind(py::module &m) {
284 py::class_<PyAttrBuilderMap>(m,
"AttrBuilder", py::module_local())
288 "attribute_kind"_a,
"attr_builder"_a,
"replace"_a =
false,
289 "Register an attribute builder for building MLIR "
290 "attributes from python values.");
298 py::object PyBlock::getCapsule() {
308 class PyRegionIterator {
311 : operation(std::move(operation)) {}
313 PyRegionIterator &dunderIter() {
return *
this; }
318 throw py::stop_iteration();
324 static void bind(py::module &m) {
325 py::class_<PyRegionIterator>(m,
"RegionIterator", py::module_local())
326 .def(
"__iter__", &PyRegionIterator::dunderIter)
327 .def(
"__next__", &PyRegionIterator::dunderNext);
339 PyRegionList(
PyOperationRef operation) : operation(std::move(operation)) {}
341 PyRegionIterator dunderIter() {
343 return PyRegionIterator(operation);
346 intptr_t dunderLen() {
347 operation->checkValid();
351 PyRegion dunderGetItem(intptr_t index) {
353 if (index < 0 || index >= dunderLen()) {
354 throw py::index_error(
"attempt to access out of bounds region");
360 static void bind(py::module &m) {
361 py::class_<PyRegionList>(m,
"RegionSequence", py::module_local())
362 .def(
"__len__", &PyRegionList::dunderLen)
363 .def(
"__iter__", &PyRegionList::dunderIter)
364 .def(
"__getitem__", &PyRegionList::dunderGetItem);
371 class PyBlockIterator {
374 : operation(std::move(operation)), next(next) {}
376 PyBlockIterator &dunderIter() {
return *
this; }
381 throw py::stop_iteration();
384 PyBlock returnBlock(operation, next);
389 static void bind(py::module &m) {
390 py::class_<PyBlockIterator>(m,
"BlockIterator", py::module_local())
391 .def(
"__iter__", &PyBlockIterator::dunderIter)
392 .def(
"__next__", &PyBlockIterator::dunderNext);
406 : operation(std::move(operation)), region(region) {}
408 PyBlockIterator dunderIter() {
413 intptr_t dunderLen() {
414 operation->checkValid();
424 PyBlock dunderGetItem(intptr_t index) {
427 throw py::index_error(
"attempt to access out of bounds block");
432 return PyBlock(operation, block);
437 throw py::index_error(
"attempt to access out of bounds block");
440 PyBlock appendBlock(
const py::args &pyArgTypes,
441 const std::optional<py::sequence> &pyArgLocs) {
443 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
445 return PyBlock(operation, block);
448 static void bind(py::module &m) {
449 py::class_<PyBlockList>(m,
"BlockList", py::module_local())
450 .def(
"__getitem__", &PyBlockList::dunderGetItem)
451 .def(
"__iter__", &PyBlockList::dunderIter)
452 .def(
"__len__", &PyBlockList::dunderLen)
454 py::arg(
"arg_locs") = std::nullopt);
462 class PyOperationIterator {
464 PyOperationIterator(
PyOperationRef parentOperation, MlirOperation next)
465 : parentOperation(std::move(parentOperation)), next(next) {}
467 PyOperationIterator &dunderIter() {
return *
this; }
469 py::object dunderNext() {
472 throw py::stop_iteration();
476 PyOperation::forOperation(parentOperation->getContext(), next);
481 static void bind(py::module &m) {
482 py::class_<PyOperationIterator>(m,
"OperationIterator", py::module_local())
483 .def(
"__iter__", &PyOperationIterator::dunderIter)
484 .def(
"__next__", &PyOperationIterator::dunderNext);
496 class PyOperationList {
499 : parentOperation(std::move(parentOperation)), block(block) {}
501 PyOperationIterator dunderIter() {
503 return PyOperationIterator(parentOperation,
507 intptr_t dunderLen() {
508 parentOperation->checkValid();
518 py::object dunderGetItem(intptr_t index) {
519 parentOperation->checkValid();
521 throw py::index_error(
"attempt to access out of bounds operation");
526 return PyOperation::forOperation(parentOperation->getContext(), childOp)
532 throw py::index_error(
"attempt to access out of bounds operation");
535 static void bind(py::module &m) {
536 py::class_<PyOperationList>(m,
"OperationList", py::module_local())
537 .def(
"__getitem__", &PyOperationList::dunderGetItem)
538 .def(
"__iter__", &PyOperationList::dunderIter)
539 .def(
"__len__", &PyOperationList::dunderLen);
549 PyOpOperand(MlirOpOperand opOperand) : opOperand(opOperand) {}
551 py::object getOwner() {
555 return PyOperation::forOperation(context, owner)->createOpView();
560 static void bind(py::module &m) {
561 py::class_<PyOpOperand>(m,
"OpOperand", py::module_local())
562 .def_property_readonly(
"owner", &PyOpOperand::getOwner)
563 .def_property_readonly(
"operand_number",
564 &PyOpOperand::getOperandNumber);
568 MlirOpOperand opOperand;
571 class PyOpOperandIterator {
573 PyOpOperandIterator(MlirOpOperand opOperand) : opOperand(opOperand) {}
575 PyOpOperandIterator &dunderIter() {
return *
this; }
577 PyOpOperand dunderNext() {
579 throw py::stop_iteration();
581 PyOpOperand returnOpOperand(opOperand);
583 return returnOpOperand;
586 static void bind(py::module &m) {
587 py::class_<PyOpOperandIterator>(m,
"OpOperandIterator", py::module_local())
588 .def(
"__iter__", &PyOpOperandIterator::dunderIter)
589 .def(
"__next__", &PyOpOperandIterator::dunderNext);
593 MlirOpOperand opOperand;
602 PyMlirContext::PyMlirContext(MlirContext context) : context(context) {
603 py::gil_scoped_acquire acquire;
604 auto &liveContexts = getLiveContexts();
605 liveContexts[context.ptr] =
this;
612 py::gil_scoped_acquire acquire;
613 getLiveContexts().erase(context.ptr);
624 throw py::error_already_set();
634 py::gil_scoped_acquire acquire;
635 auto &liveContexts = getLiveContexts();
636 auto it = liveContexts.find(context.ptr);
637 if (it == liveContexts.end()) {
640 py::object pyRef = py::cast(unownedContextWrapper);
641 assert(pyRef &&
"cast to py::object failed");
642 liveContexts[context.ptr] = unownedContextWrapper;
646 py::object pyRef = py::cast(it->second);
651 static LiveContextMap liveContexts;
660 std::vector<PyOperation *> liveObjects;
661 for (
auto &entry : liveOperations)
662 liveObjects.push_back(entry.second.second);
667 for (
auto &op : liveOperations)
668 op.second.second->setInvalid();
669 size_t numInvalidated = liveOperations.size();
670 liveOperations.clear();
671 return numInvalidated;
675 auto it = liveOperations.find(op.ptr);
676 if (it != liveOperations.end()) {
677 it->second.second->setInvalid();
678 liveOperations.erase(it);
692 callBackData *data =
static_cast<callBackData *
>(userData);
693 if (LLVM_LIKELY(data->rootSeen))
694 data->rootOp.getOperation().getContext()->clearOperation(op);
696 data->rootSeen =
true;
725 const pybind11::object &excVal,
726 const pybind11::object &excTb) {
735 py::object pyHandlerObject =
736 py::cast(pyHandler, py::return_value_policy::take_ownership);
737 pyHandlerObject.inc_ref();
741 auto handlerCallback =
744 py::object pyDiagnosticObject =
745 py::cast(pyDiagnostic, py::return_value_policy::take_ownership);
752 py::gil_scoped_acquire gil;
754 result = py::cast<bool>(pyHandler->callback(pyDiagnostic));
755 }
catch (std::exception &e) {
756 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
758 pyHandler->hadError =
true;
765 auto deleteCallback = +[](
void *userData) {
767 assert(pyHandler->registeredID &&
"handler is not registered");
768 pyHandler->registeredID.reset();
771 py::object pyHandlerObject =
772 py::cast(pyHandler, py::return_value_policy::reference);
773 pyHandlerObject.dec_ref();
777 get(), handlerCallback,
static_cast<void *
>(pyHandler), deleteCallback);
778 return pyHandlerObject;
785 if (self->ctx->emitErrorDiagnostics)
798 throw std::runtime_error(
799 "An MLIR function requires a Context but none was provided in the call "
800 "or from the surrounding environment. Either pass to the function with "
801 "a 'context=' argument or establish a default using 'with Context():'");
811 static thread_local std::vector<PyThreadContextEntry> stack;
816 auto &stack = getStack();
819 return &stack.back();
822 void PyThreadContextEntry::push(FrameKind frameKind, py::object context,
823 py::object insertionPoint,
824 py::object location) {
825 auto &stack = getStack();
826 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
827 std::move(location));
831 if (stack.size() > 1) {
832 auto &prev = *(stack.rbegin() + 1);
833 auto ¤t = stack.back();
834 if (current.context.is(prev.context)) {
836 if (!current.insertionPoint)
837 current.insertionPoint = prev.insertionPoint;
838 if (!current.location)
839 current.location = prev.location;
847 return py::cast<PyMlirContext *>(context);
853 return py::cast<PyInsertionPoint *>(insertionPoint);
859 return py::cast<PyLocation *>(location);
863 auto *tos = getTopOfStack();
864 return tos ? tos->getContext() :
nullptr;
868 auto *tos = getTopOfStack();
869 return tos ? tos->getInsertionPoint() :
nullptr;
873 auto *tos = getTopOfStack();
874 return tos ? tos->getLocation() :
nullptr;
878 py::object contextObj = py::cast(context);
879 push(FrameKind::Context, contextObj,
886 auto &stack = getStack();
888 throw std::runtime_error(
"Unbalanced Context enter/exit");
889 auto &tos = stack.back();
890 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
891 throw std::runtime_error(
"Unbalanced Context enter/exit");
897 py::object contextObj =
899 py::object insertionPointObj = py::cast(insertionPoint);
900 push(FrameKind::InsertionPoint,
904 return insertionPointObj;
908 auto &stack = getStack();
910 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
911 auto &tos = stack.back();
912 if (tos.frameKind != FrameKind::InsertionPoint &&
913 tos.getInsertionPoint() != &insertionPoint)
914 throw std::runtime_error(
"Unbalanced InsertionPoint enter/exit");
920 py::object locationObj = py::cast(location);
921 push(FrameKind::Location, contextObj,
928 auto &stack = getStack();
930 throw std::runtime_error(
"Unbalanced Location enter/exit");
931 auto &tos = stack.back();
932 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
933 throw std::runtime_error(
"Unbalanced Location enter/exit");
943 if (materializedNotes) {
944 for (
auto ¬eObject : *materializedNotes) {
945 PyDiagnostic *note = py::cast<PyDiagnostic *>(noteObject);
953 : context(context), callback(std::move(callback)) {}
962 assert(!registeredID &&
"should have unregistered");
968 void PyDiagnostic::checkValid() {
970 throw std::invalid_argument(
971 "Diagnostic is invalid (used outside of callback)");
989 py::object fileObject = py::module::import(
"io").attr(
"StringIO")();
992 return fileObject.attr(
"getvalue")();
997 if (materializedNotes)
998 return *materializedNotes;
1000 materializedNotes = py::tuple(numNotes);
1001 for (intptr_t i = 0; i < numNotes; ++i) {
1005 return *materializedNotes;
1009 std::vector<DiagnosticInfo> notes;
1022 {key.data(), key.size()});
1024 std::string msg = (Twine(
"Dialect '") + key +
"' not found").str();
1026 throw py::attribute_error(msg);
1027 throw py::index_error(msg);
1033 return py::reinterpret_steal<py::object>(
1038 MlirDialectRegistry rawRegistry =
1041 throw py::error_already_set();
1056 throw py::error_already_set();
1066 const pybind11::object &excVal,
1067 const pybind11::object &excTb) {
1074 throw std::runtime_error(
1075 "An MLIR function requires a Location but none was provided in the "
1076 "call or from the surrounding environment. Either pass to the function "
1077 "with a 'loc=' argument or establish a default using 'with loc:'");
1090 py::gil_scoped_acquire acquire;
1091 auto &liveModules =
getContext()->liveModules;
1092 assert(liveModules.count(module.ptr) == 1 &&
1093 "destroying module not in live map");
1094 liveModules.erase(module.ptr);
1102 py::gil_scoped_acquire acquire;
1103 auto &liveModules = contextRef->liveModules;
1104 auto it = liveModules.find(module.ptr);
1105 if (it == liveModules.end()) {
1112 py::cast(unownedModule, py::return_value_policy::take_ownership);
1113 unownedModule->handle = pyRef;
1114 liveModules[module.ptr] =
1115 std::make_pair(unownedModule->handle, unownedModule);
1116 return PyModuleRef(unownedModule, std::move(pyRef));
1119 PyModule *existing = it->second.second;
1120 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
1127 throw py::error_already_set();
1139 PyOperation::PyOperation(
PyMlirContextRef contextRef, MlirOperation operation)
1160 MlirOperation operation,
1161 py::object parentKeepAlive) {
1162 auto &liveOperations = contextRef->liveOperations;
1165 new PyOperation(std::move(contextRef), operation);
1170 py::cast(unownedOperation, py::return_value_policy::take_ownership);
1171 unownedOperation->handle = pyRef;
1172 if (parentKeepAlive) {
1173 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
1175 liveOperations[operation.ptr] = std::make_pair(pyRef, unownedOperation);
1180 MlirOperation operation,
1181 py::object parentKeepAlive) {
1182 auto &liveOperations = contextRef->liveOperations;
1183 auto it = liveOperations.find(operation.ptr);
1184 if (it == liveOperations.end()) {
1186 return createInstance(std::move(contextRef), operation,
1187 std::move(parentKeepAlive));
1191 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
1196 MlirOperation operation,
1197 py::object parentKeepAlive) {
1198 auto &liveOperations = contextRef->liveOperations;
1199 assert(liveOperations.count(operation.ptr) == 0 &&
1200 "cannot create detached operation that already exists");
1201 (void)liveOperations;
1203 PyOperationRef created = createInstance(std::move(contextRef), operation,
1204 std::move(parentKeepAlive));
1205 created->attached =
false;
1210 const std::string &sourceStr,
1211 const std::string &sourceName) {
1217 throw MLIRError(
"Unable to parse operation assembly", errors.
take());
1223 throw std::runtime_error(
"the operation has been invalidated");
1228 bool enableDebugInfo,
bool prettyDebugInfo,
1229 bool printGenericOpForm,
bool useLocalScope,
1230 bool assumeVerified, py::object fileObject,
1231 bool binary,
bool skipRegions) {
1234 if (fileObject.is_none())
1235 fileObject = py::module::import(
"sys").attr(
"stdout");
1238 if (largeElementsLimit)
1240 if (enableDebugInfo)
1243 if (printGenericOpForm)
1262 if (fileObject.is_none())
1263 fileObject = py::module::import(
"sys").attr(
"stdout");
1270 std::optional<int64_t> bytecodeVersion) {
1275 if (!bytecodeVersion.has_value())
1285 throw py::value_error((Twine(
"Unable to honor desired bytecode version ") +
1286 Twine(*bytecodeVersion))
1298 std::string exceptionWhat;
1299 py::object exceptionType;
1301 UserData userData{callback,
false, {}, {}};
1304 UserData *calleeUserData =
static_cast<UserData *
>(userData);
1306 return (calleeUserData->callback)(op);
1307 }
catch (py::error_already_set &e) {
1308 calleeUserData->gotException =
true;
1309 calleeUserData->exceptionWhat = e.what();
1310 calleeUserData->exceptionType = e.type();
1315 if (userData.gotException) {
1316 std::string message(
"Exception raised in callback: ");
1317 message.append(userData.exceptionWhat);
1318 throw std::runtime_error(message);
1323 std::optional<int64_t> largeElementsLimit,
1324 bool enableDebugInfo,
bool prettyDebugInfo,
1325 bool printGenericOpForm,
bool useLocalScope,
1326 bool assumeVerified,
bool skipRegions) {
1327 py::object fileObject;
1329 fileObject = py::module::import(
"io").attr(
"BytesIO")();
1331 fileObject = py::module::import(
"io").attr(
"StringIO")();
1333 print(largeElementsLimit,
1343 return fileObject.attr(
"getvalue")();
1352 operation.parentKeepAlive = otherOp.parentKeepAlive;
1361 operation.parentKeepAlive = otherOp.parentKeepAlive;
1375 throw py::value_error(
"Detached operations have no parent");
1386 assert(!
mlirBlockIsNull(block) &&
"Attached operation has null parent");
1387 assert(parentOperation &&
"Operation has no parent");
1388 return PyBlock{std::move(*parentOperation), block};
1399 throw py::error_already_set();
1406 const py::object &maybeIp) {
1408 if (!maybeIp.is(py::cast(
false))) {
1410 if (maybeIp.is_none()) {
1413 ip = py::cast<PyInsertionPoint *>(maybeIp);
1421 std::optional<std::vector<PyType *>> results,
1422 std::optional<std::vector<PyValue *>> operands,
1423 std::optional<py::dict> attributes,
1424 std::optional<std::vector<PyBlock *>> successors,
1426 const py::object &maybeIp,
bool inferType) {
1434 throw py::value_error(
"number of regions must be >= 0");
1438 mlirOperands.reserve(operands->size());
1439 for (
PyValue *operand : *operands) {
1441 throw py::value_error(
"operand value cannot be None");
1442 mlirOperands.push_back(operand->get());
1448 mlirResults.reserve(results->size());
1449 for (
PyType *result : *results) {
1452 throw py::value_error(
"result type cannot be None");
1453 mlirResults.push_back(*result);
1458 mlirAttributes.reserve(attributes->size());
1459 for (
auto &it : *attributes) {
1462 key = it.first.cast<std::string>();
1463 }
catch (py::cast_error &err) {
1464 std::string msg =
"Invalid attribute key (not a string) when "
1465 "attempting to create the operation \"" +
1466 name +
"\" (" + err.what() +
")";
1467 throw py::cast_error(msg);
1470 auto &attribute = it.second.cast<
PyAttribute &>();
1472 mlirAttributes.emplace_back(std::move(key), attribute);
1473 }
catch (py::reference_cast_error &) {
1476 "Found an invalid (`None`?) attribute value for the key \"" + key +
1477 "\" when attempting to create the operation \"" + name +
"\"";
1478 throw py::cast_error(msg);
1479 }
catch (py::cast_error &err) {
1480 std::string msg =
"Invalid attribute value for the key \"" + key +
1481 "\" when attempting to create the operation \"" +
1482 name +
"\" (" + err.what() +
")";
1483 throw py::cast_error(msg);
1489 mlirSuccessors.reserve(successors->size());
1490 for (
auto *successor : *successors) {
1493 throw py::value_error(
"successor block cannot be None");
1494 mlirSuccessors.push_back(successor->get());
1502 if (!mlirOperands.empty())
1504 mlirOperands.data());
1505 state.enableResultTypeInference = inferType;
1506 if (!mlirResults.empty())
1508 mlirResults.data());
1509 if (!mlirAttributes.empty()) {
1514 mlirNamedAttributes.reserve(mlirAttributes.size());
1515 for (
auto &it : mlirAttributes)
1521 mlirNamedAttributes.data());
1523 if (!mlirSuccessors.empty())
1525 mlirSuccessors.data());
1528 mlirRegions.resize(regions);
1529 for (
int i = 0; i < regions; ++i)
1532 mlirRegions.data());
1538 throw py::value_error(
"Operation creation failed");
1577 const py::object &resultSegmentSpecObj,
1578 std::vector<int32_t> &resultSegmentLengths,
1579 std::vector<PyType *> &resultTypes) {
1580 resultTypes.reserve(resultTypeList.size());
1581 if (resultSegmentSpecObj.is_none()) {
1585 resultTypes.push_back(py::cast<PyType *>(it.value()));
1586 if (!resultTypes.back())
1587 throw py::cast_error();
1588 }
catch (py::cast_error &err) {
1589 throw py::value_error((llvm::Twine(
"Result ") +
1590 llvm::Twine(it.index()) +
" of operation \"" +
1591 name +
"\" must be a Type (" + err.what() +
")")
1597 auto resultSegmentSpec = py::cast<std::vector<int>>(resultSegmentSpecObj);
1598 if (resultSegmentSpec.size() != resultTypeList.size()) {
1599 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1601 llvm::Twine(resultSegmentSpec.size()) +
1602 " result segments but was provided " +
1603 llvm::Twine(resultTypeList.size()))
1606 resultSegmentLengths.reserve(resultTypeList.size());
1607 for (
const auto &it :
1609 int segmentSpec = std::get<1>(it.value());
1610 if (segmentSpec == 1 || segmentSpec == 0) {
1613 auto *resultType = py::cast<PyType *>(std::get<0>(it.value()));
1615 resultTypes.push_back(resultType);
1616 resultSegmentLengths.push_back(1);
1617 }
else if (segmentSpec == 0) {
1619 resultSegmentLengths.push_back(0);
1621 throw py::cast_error(
"was None and result is not optional");
1623 }
catch (py::cast_error &err) {
1624 throw py::value_error((llvm::Twine(
"Result ") +
1625 llvm::Twine(it.index()) +
" of operation \"" +
1626 name +
"\" must be a Type (" + err.what() +
1630 }
else if (segmentSpec == -1) {
1633 if (std::get<0>(it.value()).is_none()) {
1635 resultSegmentLengths.push_back(0);
1638 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1639 for (py::object segmentItem : segment) {
1640 resultTypes.push_back(py::cast<PyType *>(segmentItem));
1641 if (!resultTypes.back()) {
1642 throw py::cast_error(
"contained a None item");
1645 resultSegmentLengths.push_back(segment.size());
1647 }
catch (std::exception &err) {
1651 throw py::value_error((llvm::Twine(
"Result ") +
1652 llvm::Twine(it.index()) +
" of operation \"" +
1653 name +
"\" must be a Sequence of Types (" +
1658 throw py::value_error(
"Unexpected segment spec");
1665 const py::object &cls, std::optional<py::list> resultTypeList,
1666 py::list operandList, std::optional<py::dict> attributes,
1667 std::optional<std::vector<PyBlock *>> successors,
1669 const py::object &maybeIp) {
1672 std::string name = py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
1678 py::object operandSegmentSpecObj = cls.attr(
"_ODS_OPERAND_SEGMENTS");
1679 py::object resultSegmentSpecObj = cls.attr(
"_ODS_RESULT_SEGMENTS");
1681 std::vector<int32_t> operandSegmentLengths;
1682 std::vector<int32_t> resultSegmentLengths;
1685 auto opRegionSpec = py::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
1686 int opMinRegionCount = std::get<0>(opRegionSpec);
1687 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1689 regions = opMinRegionCount;
1691 if (*regions < opMinRegionCount) {
1692 throw py::value_error(
1693 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1694 llvm::Twine(opMinRegionCount) +
1695 " regions but was built with regions=" + llvm::Twine(*regions))
1698 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1699 throw py::value_error(
1700 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1701 llvm::Twine(opMinRegionCount) +
1702 " regions but was built with regions=" + llvm::Twine(*regions))
1707 std::vector<PyType *> resultTypes;
1708 if (resultTypeList.has_value()) {
1710 resultSegmentLengths, resultTypes);
1714 std::vector<PyValue *> operands;
1715 operands.reserve(operands.size());
1716 if (operandSegmentSpecObj.is_none()) {
1720 operands.push_back(py::cast<PyValue *>(it.value()));
1721 if (!operands.back())
1722 throw py::cast_error();
1723 }
catch (py::cast_error &err) {
1724 throw py::value_error((llvm::Twine(
"Operand ") +
1725 llvm::Twine(it.index()) +
" of operation \"" +
1726 name +
"\" must be a Value (" + err.what() +
")")
1732 auto operandSegmentSpec = py::cast<std::vector<int>>(operandSegmentSpecObj);
1733 if (operandSegmentSpec.size() != operandList.size()) {
1734 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1736 llvm::Twine(operandSegmentSpec.size()) +
1737 "operand segments but was provided " +
1738 llvm::Twine(operandList.size()))
1741 operandSegmentLengths.reserve(operandList.size());
1742 for (
const auto &it :
1744 int segmentSpec = std::get<1>(it.value());
1745 if (segmentSpec == 1 || segmentSpec == 0) {
1748 auto *operandValue = py::cast<PyValue *>(std::get<0>(it.value()));
1750 operands.push_back(operandValue);
1751 operandSegmentLengths.push_back(1);
1752 }
else if (segmentSpec == 0) {
1754 operandSegmentLengths.push_back(0);
1756 throw py::cast_error(
"was None and operand is not optional");
1758 }
catch (py::cast_error &err) {
1759 throw py::value_error((llvm::Twine(
"Operand ") +
1760 llvm::Twine(it.index()) +
" of operation \"" +
1761 name +
"\" must be a Value (" + err.what() +
1765 }
else if (segmentSpec == -1) {
1768 if (std::get<0>(it.value()).is_none()) {
1770 operandSegmentLengths.push_back(0);
1773 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1774 for (py::object segmentItem : segment) {
1775 operands.push_back(py::cast<PyValue *>(segmentItem));
1776 if (!operands.back()) {
1777 throw py::cast_error(
"contained a None item");
1780 operandSegmentLengths.push_back(segment.size());
1782 }
catch (std::exception &err) {
1786 throw py::value_error((llvm::Twine(
"Operand ") +
1787 llvm::Twine(it.index()) +
" of operation \"" +
1788 name +
"\" must be a Sequence of Values (" +
1793 throw py::value_error(
"Unexpected segment spec");
1799 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1802 attributes = py::dict(*attributes);
1804 attributes = py::dict();
1806 if (attributes->contains(
"resultSegmentSizes") ||
1807 attributes->contains(
"operandSegmentSizes")) {
1808 throw py::value_error(
"Manually setting a 'resultSegmentSizes' or "
1809 "'operandSegmentSizes' attribute is unsupported. "
1810 "Use Operation.create for such low-level access.");
1814 if (!resultSegmentLengths.empty()) {
1815 MlirAttribute segmentLengthAttr =
1817 resultSegmentLengths.data());
1818 (*attributes)[
"resultSegmentSizes"] =
1823 if (!operandSegmentLengths.empty()) {
1824 MlirAttribute segmentLengthAttr =
1826 operandSegmentLengths.data());
1827 (*attributes)[
"operandSegmentSizes"] =
1834 std::move(resultTypes),
1835 std::move(operands),
1836 std::move(attributes),
1837 std::move(successors),
1838 *regions, location, maybeIp,
1847 py::handle opViewType = py::detail::get_type_handle(
typeid(
PyOpView),
true);
1848 py::object instance = cls.attr(
"__new__")(cls);
1849 opViewType.attr(
"__init__")(instance, operation);
1857 operationObject(operation.getRef().getObject()) {}
1866 : refOperation(beforeOperationBase.getOperation().getRef()),
1867 block((*refOperation)->getBlock()) {}
1872 throw py::value_error(
1873 "Attempt to insert operation that is already attached");
1874 block.getParentOperation()->checkValid();
1875 MlirOperation beforeOp = {
nullptr};
1878 (*refOperation)->checkValid();
1879 beforeOp = (*refOperation)->get();
1885 throw py::index_error(
"Cannot insert operation at the end of a block "
1886 "that already has a terminator. Did you mean to "
1887 "use 'InsertionPoint.at_block_terminator(block)' "
1888 "versus 'InsertionPoint(block)'?");
1911 throw py::value_error(
"Block has no terminator");
1922 const pybind11::object &excVal,
1923 const pybind11::object &excTb) {
1942 throw py::error_already_set();
1952 : ownedName(new std::string(std::move(ownedName))) {
1974 throw py::error_already_set();
1990 throw py::error_already_set();
2009 "mlirTypeID was expected to be non-null.");
2010 std::optional<pybind11::function> valueCaster =
2014 py::object thisObj = py::cast(
this, py::return_value_policy::move);
2017 return valueCaster.value()(thisObj);
2023 throw py::error_already_set();
2024 MlirOperation owner;
2030 throw py::error_already_set();
2034 return PyValue(ownerRef, value);
2042 : operation(operation.getOperation().getRef()) {
2045 throw py::cast_error(
"Operation is not a Symbol Table.");
2050 operation->checkValid();
2054 throw py::key_error(
"Symbol '" + name +
"' not in the symbol table.");
2057 operation.getObject())
2062 operation->checkValid();
2073 erase(py::cast<PyOperationBase &>(operation));
2077 operation->checkValid();
2082 throw py::value_error(
"Expected operation to have a symbol name.");
2091 MlirAttribute existingNameAttr =
2094 throw py::value_error(
"Expected operation to have a symbol name.");
2095 return existingNameAttr;
2099 const std::string &name) {
2104 MlirAttribute existingNameAttr =
2107 throw py::value_error(
"Expected operation to have a symbol name.");
2108 MlirAttribute newNameAttr =
2117 MlirAttribute existingVisAttr =
2120 throw py::value_error(
"Expected operation to have a symbol visibility.");
2121 return existingVisAttr;
2125 const std::string &visibility) {
2126 if (visibility !=
"public" && visibility !=
"private" &&
2127 visibility !=
"nested")
2128 throw py::value_error(
2129 "Expected visibility to be 'public', 'private' or 'nested'");
2133 MlirAttribute existingVisAttr =
2136 throw py::value_error(
"Expected operation to have a symbol visibility.");
2143 const std::string &newSymbol,
2151 throw py::value_error(
"Symbol rename failed");
2155 bool allSymUsesVisible,
2156 py::object callback) {
2161 py::object callback;
2163 std::string exceptionWhat;
2164 py::object exceptionType;
2167 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
2169 fromOperation.
get(), allSymUsesVisible,
2170 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
2171 UserData *calleeUserData = static_cast<UserData *>(calleeUserDataVoid);
2173 PyOperation::forOperation(calleeUserData->context, foundOp);
2174 if (calleeUserData->gotException)
2177 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
2178 } catch (py::error_already_set &e) {
2179 calleeUserData->gotException =
true;
2180 calleeUserData->exceptionWhat = e.what();
2181 calleeUserData->exceptionType = e.type();
2184 static_cast<void *
>(&userData));
2185 if (userData.gotException) {
2186 std::string message(
"Exception raised in callback: ");
2187 message.append(userData.exceptionWhat);
2188 throw std::runtime_error(message);
2196 template <
typename DerivedTy>
2197 class PyConcreteValue :
public PyValue {
2203 using ClassTy = py::class_<DerivedTy, PyValue>;
2204 using IsAFunctionTy = bool (*)(MlirValue);
2206 PyConcreteValue() =
default;
2208 :
PyValue(operationRef, value) {}
2209 PyConcreteValue(
PyValue &orig)
2210 : PyConcreteValue(orig.getParentOperation(), castFrom(orig)) {}
2214 static MlirValue castFrom(
PyValue &orig) {
2215 if (!DerivedTy::isaFunction(orig.
get())) {
2216 auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
2217 throw py::value_error((Twine(
"Cannot cast value to ") +
2218 DerivedTy::pyClassName +
" (from " + origRepr +
2226 static void bind(py::module &m) {
2227 auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
2228 cls.def(py::init<PyValue &>(), py::keep_alive<0, 1>(), py::arg(
"value"));
2231 [](
PyValue &otherValue) ->
bool {
2232 return DerivedTy::isaFunction(otherValue);
2234 py::arg(
"other_value"));
2236 [](
DerivedTy &
self) {
return self.maybeDownCast(); });
2237 DerivedTy::bindDerived(cls);
2241 static void bindDerived(ClassTy &m) {}
2245 class PyBlockArgument :
public PyConcreteValue<PyBlockArgument> {
2248 static constexpr
const char *pyClassName =
"BlockArgument";
2249 using PyConcreteValue::PyConcreteValue;
2251 static void bindDerived(ClassTy &c) {
2252 c.def_property_readonly(
"owner", [](PyBlockArgument &
self) {
2253 return PyBlock(
self.getParentOperation(),
2256 c.def_property_readonly(
"arg_number", [](PyBlockArgument &
self) {
2261 [](PyBlockArgument &
self,
PyType type) {
2269 class PyOpResult :
public PyConcreteValue<PyOpResult> {
2272 static constexpr
const char *pyClassName =
"OpResult";
2273 using PyConcreteValue::PyConcreteValue;
2275 static void bindDerived(ClassTy &c) {
2276 c.def_property_readonly(
"owner", [](PyOpResult &
self) {
2280 "expected the owner of the value in Python to match that in the IR");
2281 return self.getParentOperation().getObject();
2283 c.def_property_readonly(
"result_number", [](PyOpResult &
self) {
2290 template <
typename Container>
2291 static std::vector<MlirType> getValueTypes(Container &container,
2293 std::vector<MlirType> result;
2294 result.reserve(container.size());
2295 for (
int i = 0, e = container.size(); i < e; ++i) {
2305 class PyBlockArgumentList
2306 :
public Sliceable<PyBlockArgumentList, PyBlockArgument> {
2308 static constexpr
const char *pyClassName =
"BlockArgumentList";
2312 intptr_t startIndex = 0, intptr_t length = -1,
2317 operation(std::move(operation)), block(block) {}
2319 static void bindDerived(ClassTy &c) {
2320 c.def_property_readonly(
"types", [](PyBlockArgumentList &
self) {
2321 return getValueTypes(
self,
self.operation->getContext());
2327 friend class Sliceable<PyBlockArgumentList, PyBlockArgument>;
2330 intptr_t getRawNumElements() {
2331 operation->checkValid();
2336 PyBlockArgument getRawElement(intptr_t pos) {
2338 return PyBlockArgument(operation, argument);
2342 PyBlockArgumentList slice(intptr_t startIndex, intptr_t length,
2344 return PyBlockArgumentList(operation, block, startIndex, length, step);
2355 class PyOpOperandList :
public Sliceable<PyOpOperandList, PyValue> {
2357 static constexpr
const char *pyClassName =
"OpOperandList";
2360 PyOpOperandList(
PyOperationRef operation, intptr_t startIndex = 0,
2361 intptr_t length = -1, intptr_t step = 1)
2366 operation(operation) {}
2368 void dunderSetItem(intptr_t index,
PyValue value) {
2369 index = wrapIndex(index);
2373 static void bindDerived(ClassTy &c) {
2374 c.def(
"__setitem__", &PyOpOperandList::dunderSetItem);
2381 intptr_t getRawNumElements() {
2386 PyValue getRawElement(intptr_t pos) {
2388 MlirOperation owner;
2394 assert(
false &&
"Value must be an block arg or op result.");
2396 PyOperation::forOperation(operation->getContext(), owner);
2397 return PyValue(pyOwner, operand);
2400 PyOpOperandList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2401 return PyOpOperandList(operation, startIndex, length, step);
2411 class PyOpResultList :
public Sliceable<PyOpResultList, PyOpResult> {
2413 static constexpr
const char *pyClassName =
"OpResultList";
2416 PyOpResultList(
PyOperationRef operation, intptr_t startIndex = 0,
2417 intptr_t length = -1, intptr_t step = 1)
2422 operation(std::move(operation)) {}
2424 static void bindDerived(ClassTy &c) {
2425 c.def_property_readonly(
"types", [](PyOpResultList &
self) {
2426 return getValueTypes(
self,
self.operation->getContext());
2428 c.def_property_readonly(
"owner", [](PyOpResultList &
self) {
2429 return self.operation->createOpView();
2435 friend class Sliceable<PyOpResultList, PyOpResult>;
2437 intptr_t getRawNumElements() {
2438 operation->checkValid();
2442 PyOpResult getRawElement(intptr_t index) {
2444 return PyOpResult(value);
2447 PyOpResultList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2448 return PyOpResultList(operation, startIndex, length, step);
2458 class PyOpSuccessors :
public Sliceable<PyOpSuccessors, PyBlock> {
2460 static constexpr
const char *pyClassName =
"OpSuccessors";
2462 PyOpSuccessors(
PyOperationRef operation, intptr_t startIndex = 0,
2463 intptr_t length = -1, intptr_t step = 1)
2468 operation(operation) {}
2470 void dunderSetItem(intptr_t index,
PyBlock block) {
2471 index = wrapIndex(index);
2475 static void bindDerived(ClassTy &c) {
2476 c.def(
"__setitem__", &PyOpSuccessors::dunderSetItem);
2483 intptr_t getRawNumElements() {
2488 PyBlock getRawElement(intptr_t pos) {
2490 return PyBlock(operation, block);
2493 PyOpSuccessors slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2494 return PyOpSuccessors(operation, startIndex, length, step);
2502 class PyOpAttributeMap {
2505 : operation(std::move(operation)) {}
2507 MlirAttribute dunderGetItemNamed(
const std::string &name) {
2511 throw py::key_error(
"attempt to access a non-existent attribute");
2517 if (index < 0 || index >= dunderLen()) {
2518 throw py::index_error(
"attempt to access out of bounds attribute");
2528 void dunderSetItem(
const std::string &name,
const PyAttribute &attr) {
2533 void dunderDelItem(
const std::string &name) {
2537 throw py::key_error(
"attempt to delete a non-existent attribute");
2540 intptr_t dunderLen() {
2544 bool dunderContains(
const std::string &name) {
2549 static void bind(py::module &m) {
2550 py::class_<PyOpAttributeMap>(m,
"OpAttributeMap", py::module_local())
2551 .def(
"__contains__", &PyOpAttributeMap::dunderContains)
2552 .def(
"__len__", &PyOpAttributeMap::dunderLen)
2553 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
2554 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
2555 .def(
"__setitem__", &PyOpAttributeMap::dunderSetItem)
2556 .def(
"__delitem__", &PyOpAttributeMap::dunderDelItem);
2573 py::enum_<MlirDiagnosticSeverity>(m,
"DiagnosticSeverity", py::module_local())
2579 py::enum_<MlirWalkOrder>(m,
"WalkOrder", py::module_local())
2583 py::enum_<MlirWalkResult>(m,
"WalkResult", py::module_local())
2591 py::class_<PyDiagnostic>(m,
"Diagnostic", py::module_local())
2592 .def_property_readonly(
"severity", &PyDiagnostic::getSeverity)
2593 .def_property_readonly(
"location", &PyDiagnostic::getLocation)
2594 .def_property_readonly(
"message", &PyDiagnostic::getMessage)
2595 .def_property_readonly(
"notes", &PyDiagnostic::getNotes)
2597 if (!
self.isValid())
2598 return "<Invalid Diagnostic>";
2599 return self.getMessage();
2602 py::class_<PyDiagnostic::DiagnosticInfo>(m,
"DiagnosticInfo",
2605 .def_readonly(
"severity", &PyDiagnostic::DiagnosticInfo::severity)
2606 .def_readonly(
"location", &PyDiagnostic::DiagnosticInfo::location)
2607 .def_readonly(
"message", &PyDiagnostic::DiagnosticInfo::message)
2608 .def_readonly(
"notes", &PyDiagnostic::DiagnosticInfo::notes)
2612 py::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler", py::module_local())
2613 .def(
"detach", &PyDiagnosticHandler::detach)
2614 .def_property_readonly(
"attached", &PyDiagnosticHandler::isAttached)
2615 .def_property_readonly(
"had_error", &PyDiagnosticHandler::getHadError)
2616 .def(
"__enter__", &PyDiagnosticHandler::contextEnter)
2617 .def(
"__exit__", &PyDiagnosticHandler::contextExit);
2625 py::class_<PyMlirContext>(m,
"_BaseContext", py::module_local())
2626 .def(py::init<>(&PyMlirContext::createNewContextForInit))
2627 .def_static(
"_get_live_count", &PyMlirContext::getLiveCount)
2628 .def(
"_get_context_again",
2633 .def(
"_get_live_operation_count", &PyMlirContext::getLiveOperationCount)
2634 .def(
"_get_live_operation_objects",
2635 &PyMlirContext::getLiveOperationObjects)
2636 .def(
"_clear_live_operations", &PyMlirContext::clearLiveOperations)
2637 .def(
"_clear_live_operations_inside",
2638 py::overload_cast<MlirOperation>(
2639 &PyMlirContext::clearOperationsInside))
2640 .def(
"_get_live_module_count", &PyMlirContext::getLiveModuleCount)
2642 &PyMlirContext::getCapsule)
2644 .def(
"__enter__", &PyMlirContext::contextEnter)
2645 .def(
"__exit__", &PyMlirContext::contextExit)
2646 .def_property_readonly_static(
2651 return py::none().cast<py::object>();
2652 return py::cast(context);
2654 "Gets the Context bound to the current thread or raises ValueError")
2655 .def_property_readonly(
2658 "Gets a container for accessing dialects by name")
2659 .def_property_readonly(
2661 "Alias for 'dialect'")
2663 "get_dialect_descriptor",
2666 self.
get(), {name.data(), name.size()});
2668 throw py::value_error(
2669 (Twine(
"Dialect '") + name +
"' not found").str());
2673 py::arg(
"dialect_name"),
2674 "Gets or loads a dialect by name, returning its descriptor object")
2676 "allow_unregistered_dialects",
2683 .def(
"attach_diagnostic_handler", &PyMlirContext::attachDiagnosticHandler,
2684 py::arg(
"callback"),
2685 "Attaches a diagnostic handler that will receive callbacks")
2687 "enable_multithreading",
2693 "is_registered_operation",
2698 py::arg(
"operation_name"))
2700 "append_dialect_registry",
2704 py::arg(
"registry"))
2705 .def_property(
"emit_error_diagnostics",
nullptr,
2706 &PyMlirContext::setEmitErrorDiagnostics,
2707 "Emit error diagnostics to diagnostic handlers. By default "
2708 "error diagnostics are captured and reported through "
2709 "MLIRError exceptions.")
2710 .def(
"load_all_available_dialects", [](
PyMlirContext &
self) {
2717 py::class_<PyDialectDescriptor>(m,
"DialectDescriptor", py::module_local())
2718 .def_property_readonly(
"namespace",
2726 std::string repr(
"<DialectDescriptor ");
2735 py::class_<PyDialects>(m,
"Dialects", py::module_local())
2738 MlirDialect dialect =
2739 self.getDialectForKey(keyName,
false);
2740 py::object descriptor =
2744 .def(
"__getattr__", [=](
PyDialects &
self, std::string attrName) {
2745 MlirDialect dialect =
2746 self.getDialectForKey(attrName,
true);
2747 py::object descriptor =
2755 py::class_<PyDialect>(m,
"Dialect", py::module_local())
2756 .def(py::init<py::object>(), py::arg(
"descriptor"))
2757 .def_property_readonly(
2758 "descriptor", [](
PyDialect &
self) {
return self.getDescriptor(); })
2759 .def(
"__repr__", [](py::object
self) {
2760 auto clazz =
self.attr(
"__class__");
2761 return py::str(
"<Dialect ") +
2762 self.attr(
"descriptor").attr(
"namespace") + py::str(
" (class ") +
2763 clazz.attr(
"__module__") + py::str(
".") +
2764 clazz.attr(
"__name__") + py::str(
")>");
2770 py::class_<PyDialectRegistry>(m,
"DialectRegistry", py::module_local())
2772 &PyDialectRegistry::getCapsule)
2779 py::class_<PyLocation>(m,
"Location", py::module_local())
2782 .def(
"__enter__", &PyLocation::contextEnter)
2783 .def(
"__exit__", &PyLocation::contextExit)
2788 .def(
"__eq__", [](
PyLocation &
self, py::object other) {
return false; })
2789 .def_property_readonly_static(
2792 auto *loc = PyThreadContextEntry::getDefaultLocation();
2794 throw py::value_error(
"No current Location");
2797 "Gets the Location bound to the current thread or raises ValueError")
2804 py::arg(
"context") = py::none(),
2805 "Gets a Location representing an unknown location")
2808 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
2811 throw py::value_error(
"No caller frames provided");
2812 MlirLocation caller = frames.back().get();
2819 py::arg(
"callee"), py::arg(
"frames"), py::arg(
"context") = py::none(),
2823 [](std::string filename,
int line,
int col,
2830 py::arg(
"filename"), py::arg(
"line"), py::arg(
"col"),
2834 [](
const std::vector<PyLocation> &pyLocations,
2835 std::optional<PyAttribute> metadata,
2838 locations.reserve(pyLocations.size());
2839 for (
auto &pyLocation : pyLocations)
2840 locations.push_back(pyLocation.get());
2842 context->
get(), locations.size(), locations.data(),
2843 metadata ? metadata->get() : MlirAttribute{0});
2844 return PyLocation(context->getRef(), location);
2846 py::arg(
"locations"), py::arg(
"metadata") = py::none(),
2850 [](std::string name, std::optional<PyLocation> childLoc,
2856 childLoc ? childLoc->get()
2859 py::arg(
"name"), py::arg(
"childLoc") = py::none(),
2867 py::arg(
"attribute"), py::arg(
"context") = py::none(),
2868 "Gets a Location from a LocationAttr")
2869 .def_property_readonly(
2871 [](
PyLocation &
self) {
return self.getContext().getObject(); },
2872 "Context that owns the Location")
2873 .def_property_readonly(
2876 "Get the underlying LocationAttr")
2882 py::arg(
"message"),
"Emits an error at this location")
2887 return printAccum.
join();
2893 py::class_<PyModule>(m,
"Module", py::module_local())
2903 throw MLIRError(
"Unable to parse module assembly", errors.take());
2904 return PyModule::forModule(module).releaseObject();
2906 py::arg(
"asm"), py::arg(
"context") = py::none(),
2912 return PyModule::forModule(module).releaseObject();
2914 py::arg(
"loc") = py::none(),
"Creates an empty module")
2915 .def_property_readonly(
2917 [](
PyModule &
self) {
return self.getContext().getObject(); },
2918 "Context that created the Module")
2919 .def_property_readonly(
2922 return PyOperation::forOperation(
self.
getContext(),
2924 self.getRef().releaseObject())
2927 "Accesses the module as an operation")
2928 .def_property_readonly(
2933 self.getRef().releaseObject());
2937 "Return the block for this module")
2946 [](py::object
self) {
2948 return self.attr(
"operation").attr(
"__str__")();
2955 py::class_<PyOperationBase>(m,
"_OperationBase", py::module_local())
2958 return self.getOperation().getCapsule();
2970 .def_property_readonly(
"attributes",
2972 return PyOpAttributeMap(
2973 self.getOperation().getRef());
2975 .def_property_readonly(
2982 "Context that owns the Operation")
2983 .def_property_readonly(
"name",
2987 MlirOperation operation =
2988 concreteOperation.
get();
2993 .def_property_readonly(
"operands",
2995 return PyOpOperandList(
2996 self.getOperation().getRef());
2998 .def_property_readonly(
"regions",
3000 return PyRegionList(
3001 self.getOperation().getRef());
3003 .def_property_readonly(
3006 return PyOpResultList(
self.getOperation().getRef());
3008 "Returns the list of Operation results.")
3009 .def_property_readonly(
3012 auto &operation =
self.getOperation();
3014 if (numResults != 1) {
3016 throw py::value_error(
3017 (Twine(
"Cannot call .result on operation ") +
3018 StringRef(name.
data, name.
length) +
" which has " +
3020 " results (it is only valid for operations with a "
3024 return PyOpResult(operation.getRef(),
3028 "Shortcut to get an op result if it has only one (throws an error "
3030 .def_property_readonly(
3037 "Returns the source location the operation was defined or derived "
3039 .def_property_readonly(
"parent",
3042 self.getOperation().getParentOperation();
3044 return parent->getObject();
3050 return self.getAsm(
false,
3059 "Returns the assembly form of the operation.")
3061 py::overload_cast<PyAsmState &, pybind11::object, bool>(
3063 py::arg(
"state"), py::arg(
"file") = py::none(),
3066 py::overload_cast<std::optional<int64_t>,
bool,
bool,
bool,
bool,
3067 bool, py::object,
bool,
bool>(
3070 py::arg(
"large_elements_limit") = py::none(),
3071 py::arg(
"enable_debug_info") =
false,
3072 py::arg(
"pretty_debug_info") =
false,
3073 py::arg(
"print_generic_op_form") =
false,
3074 py::arg(
"use_local_scope") =
false,
3075 py::arg(
"assume_verified") =
false, py::arg(
"file") = py::none(),
3076 py::arg(
"binary") =
false, py::arg(
"skip_regions") =
false,
3078 .def(
"write_bytecode", &PyOperationBase::writeBytecode, py::arg(
"file"),
3079 py::arg(
"desired_version") = py::none(),
3081 .def(
"get_asm", &PyOperationBase::getAsm,
3083 py::arg(
"binary") =
false,
3084 py::arg(
"large_elements_limit") = py::none(),
3085 py::arg(
"enable_debug_info") =
false,
3086 py::arg(
"pretty_debug_info") =
false,
3087 py::arg(
"print_generic_op_form") =
false,
3088 py::arg(
"use_local_scope") =
false,
3089 py::arg(
"assume_verified") =
false, py::arg(
"skip_regions") =
false,
3092 "Verify the operation. Raises MLIRError if verification fails, and "
3093 "returns true otherwise.")
3094 .def(
"move_after", &PyOperationBase::moveAfter, py::arg(
"other"),
3095 "Puts self immediately after the other operation in its parent "
3097 .def(
"move_before", &PyOperationBase::moveBefore, py::arg(
"other"),
3098 "Puts self immediately before the other operation in its parent "
3103 return self.getOperation().clone(ip);
3105 py::arg(
"ip") = py::none())
3107 "detach_from_parent",
3112 throw py::value_error(
"Detached operation has no parent.");
3117 "Detaches the operation from its parent block.")
3118 .def(
"erase", [](
PyOperationBase &
self) {
self.getOperation().erase(); })
3122 py::class_<PyOperation, PyOperationBase>(m,
"Operation", py::module_local())
3123 .def_static(
"create", &PyOperation::create, py::arg(
"name"),
3124 py::arg(
"results") = py::none(),
3125 py::arg(
"operands") = py::none(),
3126 py::arg(
"attributes") = py::none(),
3127 py::arg(
"successors") = py::none(), py::arg(
"regions") = 0,
3128 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
3132 [](
const std::string &sourceStr,
const std::string &sourceName,
3137 py::arg(
"source"), py::kw_only(), py::arg(
"source_name") =
"",
3138 py::arg(
"context") = py::none(),
3139 "Parses an operation. Supports both text assembly format and binary "
3142 &PyOperation::getCapsule)
3144 .def_property_readonly(
"operation", [](py::object
self) {
return self; })
3145 .def_property_readonly(
"opview", &PyOperation::createOpView)
3146 .def_property_readonly(
3149 return PyOpSuccessors(
self.getOperation().getRef());
3151 "Returns the list of Operation successors.");
3154 py::class_<PyOpView, PyOperationBase>(m,
"OpView", py::module_local())
3155 .def(py::init<py::object>(), py::arg(
"operation"))
3156 .def_property_readonly(
"operation", &PyOpView::getOperationObject)
3157 .def_property_readonly(
"opview", [](py::object
self) {
return self; })
3160 [](
PyOpView &
self) {
return py::str(
self.getOperationObject()); })
3161 .def_property_readonly(
3164 return PyOpSuccessors(
self.getOperation().getRef());
3166 "Returns the list of Operation successors.");
3167 opViewClass.attr(
"_ODS_REGIONS") = py::make_tuple(0,
true);
3168 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = py::none();
3169 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = py::none();
3171 &PyOpView::buildGeneric, py::arg(
"cls"), py::arg(
"results") = py::none(),
3172 py::arg(
"operands") = py::none(), py::arg(
"attributes") = py::none(),
3173 py::arg(
"successors") = py::none(), py::arg(
"regions") = py::none(),
3174 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
3175 "Builds a specific, generated OpView based on class level attributes.");
3177 [](
const py::object &cls,
const std::string &sourceStr,
3187 std::string clsOpName =
3188 py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
3191 std::string_view parsedOpName(identifier.
data, identifier.
length);
3192 if (clsOpName != parsedOpName)
3193 throw MLIRError(Twine(
"Expected a '") + clsOpName +
"' op, got: '" +
3194 parsedOpName +
"'");
3195 return PyOpView::constructDerived(cls, *parsed.
get());
3197 py::arg(
"cls"), py::arg(
"source"), py::kw_only(),
3198 py::arg(
"source_name") =
"", py::arg(
"context") = py::none(),
3199 "Parses a specific, generated OpView based on class level attributes");
3204 py::class_<PyRegion>(m,
"Region", py::module_local())
3205 .def_property_readonly(
3208 return PyBlockList(
self.getParentOperation(),
self.
get());
3210 "Returns a forward-optimized sequence of blocks.")
3211 .def_property_readonly(
3214 return self.getParentOperation()->createOpView();
3216 "Returns the operation owning this region.")
3222 return PyBlockIterator(
self.getParentOperation(), firstBlock);
3224 "Iterates over blocks in the region.")
3227 return self.get().ptr == other.
get().ptr;
3229 .def(
"__eq__", [](
PyRegion &
self, py::object &other) {
return false; });
3234 py::class_<PyBlock>(m,
"Block", py::module_local())
3236 .def_property_readonly(
3239 return self.getParentOperation()->createOpView();
3241 "Returns the owning operation of this block.")
3242 .def_property_readonly(
3246 return PyRegion(
self.getParentOperation(), region);
3248 "Returns the owning region of this block.")
3249 .def_property_readonly(
3252 return PyBlockArgumentList(
self.getParentOperation(),
self.
get());
3254 "Returns a list of block arguments.")
3260 "Append an argument of the specified type to the block and returns "
3261 "the newly added argument.")
3264 [](
PyBlock &
self,
unsigned index) {
3267 "Erase the argument at 'index' and remove it from the argument list.")
3268 .def_property_readonly(
3271 return PyOperationList(
self.getParentOperation(),
self.
get());
3273 "Returns a forward-optimized sequence of operations.")
3276 [](
PyRegion &parent,
const py::list &pyArgTypes,
3277 const std::optional<py::sequence> &pyArgLocs) {
3279 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3283 py::arg(
"parent"), py::arg(
"arg_types") = py::list(),
3284 py::arg(
"arg_locs") = std::nullopt,
3285 "Creates and returns a new Block at the beginning of the given "
3286 "region (with given argument types and locations).")
3290 MlirBlock b =
self.get();
3295 "Append this block to a region, transferring ownership if necessary")
3298 [](
PyBlock &
self,
const py::args &pyArgTypes,
3299 const std::optional<py::sequence> &pyArgLocs) {
3301 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3304 return PyBlock(
self.getParentOperation(), block);
3306 py::arg(
"arg_locs") = std::nullopt,
3307 "Creates and returns a new Block before this block "
3308 "(with given argument types and locations).")
3311 [](
PyBlock &
self,
const py::args &pyArgTypes,
3312 const std::optional<py::sequence> &pyArgLocs) {
3314 MlirBlock block =
createBlock(pyArgTypes, pyArgLocs);
3317 return PyBlock(
self.getParentOperation(), block);
3319 py::arg(
"arg_locs") = std::nullopt,
3320 "Creates and returns a new Block after this block "
3321 "(with given argument types and locations).")
3326 MlirOperation firstOperation =
3328 return PyOperationIterator(
self.getParentOperation(),
3331 "Iterates over operations in the block.")
3334 return self.get().ptr == other.
get().ptr;
3336 .def(
"__eq__", [](
PyBlock &
self, py::object &other) {
return false; })
3348 return printAccum.
join();
3350 "Returns the assembly form of the block.")
3360 self.getParentOperation().getObject());
3362 py::arg(
"operation"),
3363 "Appends an operation to this block. If the operation is currently "
3364 "in another block, it will be moved.");
3370 py::class_<PyInsertionPoint>(m,
"InsertionPoint", py::module_local())
3371 .def(py::init<PyBlock &>(), py::arg(
"block"),
3372 "Inserts after the last operation but still inside the block.")
3373 .def(
"__enter__", &PyInsertionPoint::contextEnter)
3374 .def(
"__exit__", &PyInsertionPoint::contextExit)
3375 .def_property_readonly_static(
3378 auto *ip = PyThreadContextEntry::getDefaultInsertionPoint();
3380 throw py::value_error(
"No current InsertionPoint");
3383 "Gets the InsertionPoint bound to the current thread or raises "
3384 "ValueError if none has been set")
3385 .def(py::init<PyOperationBase &>(), py::arg(
"beforeOperation"),
3386 "Inserts before a referenced operation.")
3387 .def_static(
"at_block_begin", &PyInsertionPoint::atBlockBegin,
3388 py::arg(
"block"),
"Inserts at the beginning of the block.")
3389 .def_static(
"at_block_terminator", &PyInsertionPoint::atBlockTerminator,
3390 py::arg(
"block"),
"Inserts before the block terminator.")
3391 .def(
"insert", &PyInsertionPoint::insert, py::arg(
"operation"),
3392 "Inserts an operation.")
3393 .def_property_readonly(
3395 "Returns the block that this InsertionPoint points to.")
3396 .def_property_readonly(
3399 auto refOperation =
self.getRefOperation();
3401 return refOperation->getObject();
3404 "The reference operation before which new operations are "
3405 "inserted, or None if the insertion point is at the end of "
3411 py::class_<PyAttribute>(m,
"Attribute", py::module_local())
3414 .def(py::init<PyAttribute &>(), py::arg(
"cast_from_type"),
3415 "Casts the passed attribute to the generic Attribute")
3417 &PyAttribute::getCapsule)
3426 throw MLIRError(
"Unable to parse attribute", errors.take());
3429 py::arg(
"asm"), py::arg(
"context") = py::none(),
3430 "Parses an attribute from an assembly form. Raises an MLIRError on "
3432 .def_property_readonly(
3434 [](
PyAttribute &
self) {
return self.getContext().getObject(); },
3435 "Context that owns the Attribute")
3436 .def_property_readonly(
3443 py::keep_alive<0, 1>(),
"Binds a name to the attribute")
3446 .def(
"__eq__", [](
PyAttribute &
self, py::object &other) {
return false; })
3460 return printAccum.
join();
3462 "Returns the assembly form of the Attribute.")
3471 printAccum.
parts.append(
"Attribute(");
3474 printAccum.
parts.append(
")");
3475 return printAccum.
join();
3477 .def_property_readonly(
3482 "mlirTypeID was expected to be non-null.");
3488 "mlirTypeID was expected to be non-null.");
3489 std::optional<pybind11::function> typeCaster =
3493 return py::cast(
self);
3494 return typeCaster.value()(
self);
3500 py::class_<PyNamedAttribute>(m,
"NamedAttribute", py::module_local())
3504 printAccum.
parts.append(
"NamedAttribute(");
3505 printAccum.
parts.append(
3508 printAccum.
parts.append(
"=");
3512 printAccum.
parts.append(
")");
3513 return printAccum.
join();
3515 .def_property_readonly(
3521 "The name of the NamedAttribute binding")
3522 .def_property_readonly(
3525 py::keep_alive<0, 1>(),
3526 "The underlying generic attribute of the NamedAttribute binding");
3531 py::class_<PyType>(m,
"Type", py::module_local())
3534 .def(py::init<PyType &>(), py::arg(
"cast_from_type"),
3535 "Casts the passed type to the generic Type")
3545 throw MLIRError(
"Unable to parse type", errors.take());
3548 py::arg(
"asm"), py::arg(
"context") = py::none(),
3550 .def_property_readonly(
3551 "context", [](
PyType &
self) {
return self.getContext().getObject(); },
3552 "Context that owns the Type")
3553 .def(
"__eq__", [](
PyType &
self,
PyType &other) {
return self == other; })
3554 .def(
"__eq__", [](
PyType &
self, py::object &other) {
return false; })
3567 return printAccum.
join();
3569 "Returns the assembly form of the type.")
3577 printAccum.
parts.append(
"Type(");
3580 printAccum.
parts.append(
")");
3581 return printAccum.
join();
3587 "mlirTypeID was expected to be non-null.");
3588 std::optional<pybind11::function> typeCaster =
3592 return py::cast(
self);
3593 return typeCaster.value()(
self);
3595 .def_property_readonly(
"typeid", [](
PyType &
self) -> MlirTypeID {
3600 pybind11::repr(pybind11::cast(
self)).cast<std::string>();
3601 throw py::value_error(
3602 (origRepr + llvm::Twine(
" has no typeid.")).str());
3608 py::class_<PyTypeID>(m,
"TypeID", py::module_local())
3617 [](
PyTypeID &
self,
const py::object &other) {
return false; })
3621 .def(
"__hash__", [](
PyTypeID &
self) {
3628 py::class_<PyValue>(m,
"Value", py::module_local())
3629 .def(py::init<PyValue &>(), py::keep_alive<0, 1>(), py::arg(
"value"))
3632 .def_property_readonly(
3635 "Context in which the value lives.")
3639 .def_property_readonly(
3641 [](
PyValue &
self) -> py::object {
3642 MlirValue v =
self.get();
3647 "expected the owner of the value in Python to match that in "
3649 return self.getParentOperation().getObject();
3654 return py::cast(
PyBlock(
self.getParentOperation(), block));
3657 assert(
false &&
"Value must be a block argument or an op result");
3660 .def_property_readonly(
"uses",
3662 return PyOpOperandIterator(
3667 return self.get().ptr == other.
get().ptr;
3669 .def(
"__eq__", [](
PyValue &
self, py::object other) {
return false; })
3678 printAccum.
parts.append(
"Value(");
3681 printAccum.
parts.append(
")");
3682 return printAccum.
join();
3687 [](
PyValue &
self,
bool useLocalScope) {
3692 MlirAsmState valueState =
3699 return printAccum.
join();
3701 py::arg(
"use_local_scope") =
false)
3704 [](
PyValue &
self, std::reference_wrapper<PyAsmState> state) {
3706 MlirAsmState valueState = state.get().get();
3710 return printAccum.
join();
3713 .def_property_readonly(
3722 "replace_all_uses_with",
3728 "replace_all_uses_except",
3729 [](MlirValue
self, MlirValue with,
PyOperation &exception) {
3730 MlirOperation exceptedUser = exception.
get();
3733 py::arg(
"with"), py::arg(
"exceptions"),
3736 "replace_all_uses_except",
3737 [](MlirValue
self, MlirValue with, py::list exceptions) {
3740 for (py::handle exception : exceptions) {
3745 self, with,
static_cast<intptr_t
>(exceptionOps.size()),
3746 exceptionOps.data());
3748 py::arg(
"with"), py::arg(
"exceptions"),
3751 [](
PyValue &
self) {
return self.maybeDownCast(); });
3752 PyBlockArgument::bind(m);
3753 PyOpResult::bind(m);
3754 PyOpOperand::bind(m);
3756 py::class_<PyAsmState>(m,
"AsmState", py::module_local())
3757 .def(py::init<PyValue &, bool>(), py::arg(
"value"),
3758 py::arg(
"use_local_scope") =
false)
3759 .def(py::init<PyOperationBase &, bool>(), py::arg(
"op"),
3760 py::arg(
"use_local_scope") =
false);
3765 py::class_<PySymbolTable>(m,
"SymbolTable", py::module_local())
3766 .def(py::init<PyOperationBase &>())
3767 .def(
"__getitem__", &PySymbolTable::dunderGetItem)
3768 .def(
"insert", &PySymbolTable::insert, py::arg(
"operation"))
3769 .def(
"erase", &PySymbolTable::erase, py::arg(
"operation"))
3770 .def(
"__delitem__", &PySymbolTable::dunderDel)
3771 .def(
"__contains__",
3777 .def_static(
"set_symbol_name", &PySymbolTable::setSymbolName,
3778 py::arg(
"symbol"), py::arg(
"name"))
3779 .def_static(
"get_symbol_name", &PySymbolTable::getSymbolName,
3781 .def_static(
"get_visibility", &PySymbolTable::getVisibility,
3783 .def_static(
"set_visibility", &PySymbolTable::setVisibility,
3784 py::arg(
"symbol"), py::arg(
"visibility"))
3785 .def_static(
"replace_all_symbol_uses",
3786 &PySymbolTable::replaceAllSymbolUses, py::arg(
"old_symbol"),
3787 py::arg(
"new_symbol"), py::arg(
"from_op"))
3788 .def_static(
"walk_symbol_tables", &PySymbolTable::walkSymbolTables,
3789 py::arg(
"from_op"), py::arg(
"all_sym_uses_visible"),
3790 py::arg(
"callback"));
3793 PyBlockArgumentList::bind(m);
3794 PyBlockIterator::bind(m);
3795 PyBlockList::bind(m);
3796 PyOperationIterator::bind(m);
3797 PyOperationList::bind(m);
3798 PyOpAttributeMap::bind(m);
3799 PyOpOperandIterator::bind(m);
3800 PyOpOperandList::bind(m);
3801 PyOpResultList::bind(m);
3802 PyOpSuccessors::bind(m);
3803 PyRegionIterator::bind(m);
3804 PyRegionList::bind(m);
3812 py::register_local_exception_translator([](std::exception_ptr p) {
3817 std::rethrow_exception(p);
3821 PyErr_SetObject(PyExc_Exception, obj.ptr());
MLIR_CAPI_EXPORTED void mlirSetGlobalDebugType(const char *type)
Sets the current debug type, similarly to -debug-only=type in the command-line tools.
MLIR_CAPI_EXPORTED void mlirSetGlobalDebugTypes(const char **types, intptr_t n)
Sets multiple current debug types, similarly to `-debug-only=type1,type2" in the command-line tools.
MLIR_CAPI_EXPORTED bool mlirIsGlobalDebugEnabled()
Retuns true if the global debugging flag is set, false otherwise.
MLIR_CAPI_EXPORTED void mlirEnableGlobalDebug(bool enable)
Sets the global debugging flag.
static const char kOperationPrintStateDocstring[]
static const char kValueReplaceAllUsesWithDocstring[]
static 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 const char kValueReplaceAllUsesExceptDocstring[]
static MLIRContext * getContext(OpFoldResult val)
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
#define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR
Attribute on MLIR Python objects that expose a function for downcasting the corresponding Python obje...
static PyObject * mlirPythonTypeIDToCapsule(MlirTypeID typeID)
Creates a capsule object encapsulating the raw C-API MlirTypeID.
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule.
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
static MlirTypeID mlirPythonCapsuleToTypeID(PyObject *capsule)
Extracts an MlirTypeID from a capsule as produced from mlirPythonTypeIDToCapsule.
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
#define MAKE_MLIR_PYTHON_QUALNAME(local)
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
static PyObject * mlirPythonBlockToCapsule(MlirBlock block)
Creates a capsule object encapsulating the raw C-API MlirBlock.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
static PyObject * mlirPythonContextToCapsule(MlirContext context)
Creates a capsule object encapsulating the raw C-API MlirContext.
static LogicalResult nextIndex(ArrayRef< int64_t > shape, MutableArrayRef< int64_t > index)
Walks over the indices of the elements of a tensor of a given shape by updating index in place to the...
static std::string diag(const llvm::Value &value)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
static sycl::context getDefaultContext()
Accumulates int a python file-like object, either writing text (default) or binary.
MlirStringCallback getCallback()
A CRTP base class for pseudo-containers willing to support Python-type slicing access on top of index...
Base class for all objects that directly or indirectly depend on an MlirContext.
PyMlirContextRef & getContext()
Accesses the context reference.
Used in function arguments when None should resolve to the current context manager set instance.
static PyLocation & resolve()
Used in function arguments when None should resolve to the current context manager set instance.
static PyMlirContext & resolve()
ReferrentTy * get() const
Wrapper around an MlirAsmState.
Wrapper around the generic MlirAttribute.
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
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.
std::optional< pybind11::function > lookupValueCaster(MlirTypeID mlirTypeID, MlirDialect dialect)
Returns the custom value caster for MlirTypeID mlirTypeID.
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.
PyMlirContextRef getRef()
Gets a strong reference to this context, which will ensure it is kept alive for the life of the refer...
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyMlirContext from the MlirContext wrapped by a capsule.
void clearOperationsInside(PyOperationBase &op)
Clears all operations nested inside the given op using clearOperation(MlirOperation).
static size_t getLiveCount()
Gets the count of live context objects. Used for testing.
void clearOperationAndInside(PyOperationBase &op)
Clears the operaiton and all operations inside using clearOperation(MlirOperation).
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.
std::vector< PyOperation * > getLiveOperationObjects()
Get a list of Python objects which are still in the live context map.
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
void clearOperation(MlirOperation op)
Removes an operation from the live operations map and sets it invalid.
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
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...
void print(std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified, py::object fileObject, bool binary, bool skipRegions)
Implements the bound 'print' method and helps with others.
void walk(std::function< MlirWalkResult(MlirOperation)> callback, MlirWalkOrder walkOrder)
virtual PyOperation & getOperation()=0
Each must provide access to the raw Operation.
void writeBytecode(const pybind11::object &fileObject, std::optional< int64_t > bytecodeVersion)
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
void moveBefore(PyOperationBase &other)
bool verify()
Verify the operation.
pybind11::object getAsm(bool binary, std::optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified, bool skipRegions)
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.
pybind11::object maybeDownCast()
MLIR_CAPI_EXPORTED intptr_t mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic)
Returns the number of notes attached to the diagnostic.
MLIR_CAPI_EXPORTED MlirDiagnosticSeverity mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic)
Returns the severity of the diagnostic.
MLIR_CAPI_EXPORTED void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback, void *userData)
Prints a diagnostic using the provided callback.
MlirDiagnosticSeverity
Severity of a diagnostic.
MLIR_CAPI_EXPORTED MlirDiagnostic mlirDiagnosticGetNote(MlirDiagnostic diagnostic, intptr_t pos)
Returns pos-th note attached to the diagnostic.
MLIR_CAPI_EXPORTED void mlirEmitError(MlirLocation location, const char *message)
Emits an error at the given location through the diagnostics engine.
MLIR_CAPI_EXPORTED MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(MlirContext context, MlirDiagnosticHandler handler, void *userData, void(*deleteUserData)(void *))
Attaches the diagnostic handler to the context.
MLIR_CAPI_EXPORTED void mlirContextDetachDiagnosticHandler(MlirContext context, MlirDiagnosticHandlerID id)
Detaches an attached diagnostic handler from the context given its identifier.
uint64_t MlirDiagnosticHandlerID
Opaque identifier of a diagnostic handler, useful to detach a handler.
MLIR_CAPI_EXPORTED MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic)
Returns the location at which the diagnostic is reported.
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI32ArrayGet(MlirContext ctx, intptr_t size, int32_t const *values)
MLIR_CAPI_EXPORTED MlirAttribute mlirStringAttrGet(MlirContext ctx, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
MLIR_CAPI_EXPORTED MlirAttribute mlirLocationGetAttribute(MlirLocation location)
Returns the underlying location attribute of this location.
MLIR_CAPI_EXPORTED intptr_t mlirBlockArgumentGetArgNumber(MlirValue value)
Returns the position of the value in the argument list of its block.
static bool mlirAttributeIsNull(MlirAttribute attr)
Checks whether an attribute is null.
MlirWalkResult(* MlirOperationWalkCallback)(MlirOperation, void *userData)
Operation walker type.
MLIR_CAPI_EXPORTED void mlirOperationWriteBytecode(MlirOperation op, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but writing the bytecode format.
MLIR_CAPI_EXPORTED MlirIdentifier mlirOperationGetName(MlirOperation op)
Gets the name of the operation as an identifier.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFileLineColGet(MlirContext context, MlirStringRef filename, unsigned line, unsigned col)
Creates an File/Line/Column location owned by the given context.
MLIR_CAPI_EXPORTED void mlirSymbolTableWalkSymbolTables(MlirOperation from, bool allSymUsesVisible, void(*callback)(MlirOperation, bool, void *userData), void *userData)
Walks all symbol table operations nested within, and including, op.
MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect)
Returns the namespace of the given dialect.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumResults(MlirOperation op)
Returns the number of results of the operation.
MLIR_CAPI_EXPORTED MlirAttribute mlirSymbolTableInsert(MlirSymbolTable symbolTable, MlirOperation operation)
Inserts the given operation into the given symbol table.
MlirWalkOrder
Traversal order for operation walk.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos)
Return pos-th attribute of the operation.
MLIR_CAPI_EXPORTED void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n, MlirValue const *operands)
MLIR_CAPI_EXPORTED void mlirModuleDestroy(MlirModule module)
Takes a module owned by the caller and deletes it.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, MlirAttribute attr)
Associates an attribute with the name. Takes ownership of neither.
MLIR_CAPI_EXPORTED void mlirSymbolTableErase(MlirSymbolTable symbolTable, MlirOperation operation)
Removes the given operation from the symbol table and erases it.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags)
Use local scope when printing the operation.
MLIR_CAPI_EXPORTED bool mlirValueIsABlockArgument(MlirValue value)
Returns 1 if the value is a block argument, 0 otherwise.
MLIR_CAPI_EXPORTED void mlirContextAppendDialectRegistry(MlirContext ctx, MlirDialectRegistry registry)
Append the contents of the given dialect registry to the registry associated with the context.
MLIR_CAPI_EXPORTED MlirStringRef mlirIdentifierStr(MlirIdentifier ident)
Gets the string value of the identifier.
static bool mlirModuleIsNull(MlirModule module)
Checks whether a module is null.
MLIR_CAPI_EXPORTED MlirType mlirTypeParseGet(MlirContext context, MlirStringRef type)
Parses a type. The type is owned by the context.
MLIR_CAPI_EXPORTED MlirOpOperand mlirOpOperandGetNextUse(MlirOpOperand opOperand)
Returns an op operand representing the next use of the value, or a null op operand if there is no nex...
MLIR_CAPI_EXPORTED MlirType mlirAttributeGetType(MlirAttribute attribute)
Gets the type of this attribute.
MLIR_CAPI_EXPORTED void mlirContextSetAllowUnregisteredDialects(MlirContext context, bool allow)
Sets whether unregistered dialects are allowed in this context.
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockBefore(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it before the (non-owned) reference block in the given ...
MLIR_CAPI_EXPORTED void mlirValueReplaceAllUsesOfWith(MlirValue of, MlirValue with)
Replace all uses of 'of' value with the 'with' value, updating anything in the IR that uses 'of' to u...
MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetSuccessor(MlirOperation op, intptr_t pos)
Returns pos-th successor of the operation.
MLIR_CAPI_EXPORTED void mlirValuePrintAsOperand(MlirValue value, MlirAsmState state, MlirStringCallback callback, void *userData)
Prints a value as an operand (i.e., the ValueID).
MLIR_CAPI_EXPORTED MlirLocation mlirLocationUnknownGet(MlirContext context)
Creates a location with unknown position owned by the given context.
MLIR_CAPI_EXPORTED void mlirTypePrint(MlirType type, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirOperationSetAttributeByName(MlirOperation op, MlirStringRef name, MlirAttribute attr)
Sets an attribute by name, replacing the existing if it exists or adding a new one otherwise.
MLIR_CAPI_EXPORTED MlirOperation mlirOpOperandGetOwner(MlirOpOperand opOperand)
Returns the owner operation of an op operand.
MLIR_CAPI_EXPORTED MlirDialect mlirAttributeGetDialect(MlirAttribute attribute)
Gets the dialect of the attribute.
MLIR_CAPI_EXPORTED void mlirAttributePrint(MlirAttribute attr, MlirStringCallback callback, void *userData)
Prints an attribute by sending chunks of the string representation and forwarding userData tocallback...
MLIR_CAPI_EXPORTED MlirRegion mlirBlockGetParentRegion(MlirBlock block)
Returns the region that contains this block.
MLIR_CAPI_EXPORTED void mlirOperationMoveBefore(MlirOperation op, MlirOperation other)
Moves the given operation immediately before the other operation in its parent block.
static bool mlirValueIsNull(MlirValue value)
Returns whether the value is null.
MLIR_CAPI_EXPORTED void mlirValueReplaceAllUsesExcept(MlirValue of, MlirValue with, intptr_t numExceptions, MlirOperation *exceptions)
Replace all uses of 'of' value with 'with' value, updating anything in the IR that uses 'of' to use '...
MLIR_CAPI_EXPORTED void mlirOperationPrintWithState(MlirOperation op, MlirAsmState state, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but accepts AsmState controlling the printing behavior as well as caching ...
MlirWalkResult
Operation walk result.
@ MlirWalkResultInterrupt
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlock(MlirRegion region, intptr_t pos, MlirBlock block)
Takes a block owned by the caller and inserts it at pos to the given region.
MLIR_CAPI_EXPORTED MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, MlirStringRef name)
Returns an attribute attached to the operation given its name.
static bool mlirTypeIsNull(MlirType type)
Checks whether a type is null.
MLIR_CAPI_EXPORTED bool mlirContextIsRegisteredOperation(MlirContext context, MlirStringRef name)
Returns whether the given fully-qualified operation (i.e.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumSuccessors(MlirOperation op)
Returns the number of successor blocks of the operation.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationClone(MlirOperation op)
Creates a deep copy of an operation.
MLIR_CAPI_EXPORTED intptr_t mlirBlockGetNumArguments(MlirBlock block)
Returns the number of arguments of the block.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsPrintGenericOpForm(MlirOpPrintingFlags flags)
Always print operations in the generic form.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFusedGet(MlirContext ctx, intptr_t nLocations, MlirLocation const *locations, MlirAttribute metadata)
Creates a fused location with an array of locations and metadata.
MLIR_CAPI_EXPORTED void mlirBlockInsertOwnedOperationBefore(MlirBlock block, MlirOperation reference, MlirOperation operation)
Takes an operation owned by the caller and inserts it before the (non-owned) reference operation in t...
MLIR_CAPI_EXPORTED void mlirAsmStateDestroy(MlirAsmState state)
Destroys printing flags created with mlirAsmStateCreate.
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
MLIR_CAPI_EXPORTED MlirDialect mlirContextGetOrLoadDialect(MlirContext context, MlirStringRef name)
Gets the dialect instance owned by the given context using the dialect namespace to identify it,...
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsElideLargeElementsAttrs(MlirOpPrintingFlags flags, intptr_t largeElementLimit)
Enables the elision of large elements attributes by printing a lexically valid but otherwise meaningl...
MLIR_CAPI_EXPORTED void mlirRegionInsertOwnedBlockAfter(MlirRegion region, MlirBlock reference, MlirBlock block)
Takes a block owned by the caller and inserts it after the (non-owned) reference block in the given r...
MLIR_CAPI_EXPORTED void mlirBlockArgumentSetType(MlirValue value, MlirType type)
Sets the type of the block argument to the given type.
MLIR_CAPI_EXPORTED MlirContext mlirOperationGetContext(MlirOperation op)
Gets the context this operation is associated with.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockCreate(intptr_t nArgs, MlirType const *args, MlirLocation const *locs)
Creates a new empty block with the given argument types and transfers ownership to the caller.
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
MLIR_CAPI_EXPORTED void mlirBlockAppendOwnedOperation(MlirBlock block, MlirOperation operation)
Takes an operation owned by the caller and appends it to the block.
MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos)
Returns pos-th argument of the block.
MLIR_CAPI_EXPORTED MlirOperation mlirSymbolTableLookup(MlirSymbolTable symbolTable, MlirStringRef name)
Looks up a symbol with the given name in the given symbol table and returns the operation that corres...
MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type)
Gets the context that a type was created with.
MLIR_CAPI_EXPORTED void mlirValueDump(MlirValue value)
Prints the value to the standard error stream.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateEmpty(MlirLocation location)
Creates a new, empty module and transfers ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirOpOperandIsNull(MlirOpOperand opOperand)
Returns whether the op operand is null.
MLIR_CAPI_EXPORTED MlirSymbolTable mlirSymbolTableCreate(MlirOperation operation)
Creates a symbol table for the given operation.
MLIR_CAPI_EXPORTED bool mlirLocationEqual(MlirLocation l1, MlirLocation l2)
Checks if two locations are equal.
MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetBlock(MlirOperation op)
Gets the block that owns this operation, returning null if the operation is not owned.
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
MLIR_CAPI_EXPORTED bool mlirOperationEqual(MlirOperation op, MlirOperation other)
Checks whether two operation handles point to the same operation.
MLIR_CAPI_EXPORTED MlirValue mlirBlockAddArgument(MlirBlock block, MlirType type, MlirLocation loc)
Appends an argument of the specified type to the block.
MLIR_CAPI_EXPORTED void mlirOperationPrintWithFlags(MlirOperation op, MlirOpPrintingFlags flags, MlirStringCallback callback, void *userData)
Same as mlirOperationPrint but accepts flags controlling the printing behavior.
MLIR_CAPI_EXPORTED MlirOpOperand mlirValueGetFirstUse(MlirValue value)
Returns an op operand representing the first use of the value, or a null op operand if there are no u...
MLIR_CAPI_EXPORTED void mlirLocationPrint(MlirLocation location, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED bool mlirOperationVerify(MlirOperation op)
Verify the operation and return true if it passes, false if it fails.
MLIR_CAPI_EXPORTED MlirOperation mlirModuleGetOperation(MlirModule module)
Views the module as a generic operation.
MLIR_CAPI_EXPORTED bool mlirTypeEqual(MlirType t1, MlirType t2)
Checks if two types are equal.
MLIR_CAPI_EXPORTED MlirOperationState mlirOperationStateGet(MlirStringRef name, MlirLocation loc)
Constructs an operation state from a name and a location.
MLIR_CAPI_EXPORTED unsigned mlirOpOperandGetOperandNumber(MlirOpOperand opOperand)
Returns the operand number of an op operand.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetTerminator(MlirBlock block)
Returns the terminator operation in the block or null if no terminator.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsSkipRegions(MlirOpPrintingFlags flags)
Skip printing regions.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationGetNextInBlock(MlirOperation op)
Returns an operation immediately following the given operation it its enclosing block.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationGetParentOperation(MlirOperation op)
Gets the operation that owns this operation, returning null if the operation is not owned.
MLIR_CAPI_EXPORTED MlirContext mlirModuleGetContext(MlirModule module)
Gets the context that a module was created with.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationFromAttribute(MlirAttribute attribute)
Creates a location from a location attribute.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsAssumeVerified(MlirOpPrintingFlags flags)
Do not verify the operation when using custom operation printers.
MLIR_CAPI_EXPORTED MlirTypeID mlirTypeGetTypeID(MlirType type)
Gets the type ID of the type.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetVisibilityAttributeName(void)
Returns the name of the attribute used to store symbol visibility.
static bool mlirDialectIsNull(MlirDialect dialect)
Checks if the dialect is null.
MLIR_CAPI_EXPORTED void mlirBytecodeWriterConfigDestroy(MlirBytecodeWriterConfig config)
Destroys printing flags created with mlirBytecodeWriterConfigCreate.
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos)
Returns pos-th operand of the operation.
MLIR_CAPI_EXPORTED void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, MlirNamedAttribute const *attributes)
MLIR_CAPI_EXPORTED MlirBlock mlirBlockGetNextInRegion(MlirBlock block)
Returns the block immediately following the given block in its parent region.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller)
Creates a call site location with a callee and a caller.
MLIR_CAPI_EXPORTED MlirOperation mlirOpResultGetOwner(MlirValue value)
Returns an operation that produced this value as its result.
MLIR_CAPI_EXPORTED bool mlirValueIsAOpResult(MlirValue value)
Returns 1 if the value is an operation result, 0 otherwise.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumOperands(MlirOperation op)
Returns the number of operands of the operation.
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
MLIR_CAPI_EXPORTED void mlirOperationWalk(MlirOperation op, MlirOperationWalkCallback callback, void *userData, MlirWalkOrder walkOrder)
Walks operation op in walkOrder and calls callback on that operation.
MLIR_CAPI_EXPORTED MlirContext mlirContextCreateWithThreading(bool threadingEnabled)
Creates an MLIR context with an explicit setting of the multithreading setting and transfers its owne...
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetParentOperation(MlirBlock)
Returns the closest surrounding operation that contains this block.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumRegions(MlirOperation op)
Returns the number of regions attached to the given operation.
MLIR_CAPI_EXPORTED MlirContext mlirLocationGetContext(MlirLocation location)
Gets the context that a location was created with.
MLIR_CAPI_EXPORTED void mlirBlockEraseArgument(MlirBlock block, unsigned index)
Erase the argument at 'index' and remove it from the argument list.
MLIR_CAPI_EXPORTED bool mlirOperationRemoveAttributeByName(MlirOperation op, MlirStringRef name)
Removes an attribute by name.
MLIR_CAPI_EXPORTED void mlirAttributeDump(MlirAttribute attr)
Prints the attribute to the standard error stream.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirSymbolTableReplaceAllSymbolUses(MlirStringRef oldSymbol, MlirStringRef newSymbol, MlirOperation from)
Attempt to replace all uses that are nested within the given operation of the given symbol 'oldSymbol...
MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeParseGet(MlirContext context, MlirStringRef attr)
Parses an attribute. The attribute is owned by the context.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateParse(MlirContext context, MlirStringRef module)
Parses a module from the string and transfers ownership to the caller.
MLIR_CAPI_EXPORTED void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block)
Takes a block owned by the caller and appends it to the given region.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetFirstOperation(MlirBlock block)
Returns the first operation in the block.
MLIR_CAPI_EXPORTED void mlirTypeDump(MlirType type)
Prints the type to the standard error stream.
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos)
Returns pos-th result of the operation.
MLIR_CAPI_EXPORTED MlirBytecodeWriterConfig mlirBytecodeWriterConfigCreate(void)
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED MlirContext mlirAttributeGetContext(MlirAttribute attribute)
Gets the context that an attribute was created with.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockArgumentGetOwner(MlirValue value)
Returns the block in which this value is defined as an argument.
static bool mlirRegionIsNull(MlirRegion region)
Checks whether a region is null.
MLIR_CAPI_EXPORTED void mlirOperationDestroy(MlirOperation op)
Takes an operation owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos)
Returns pos-th region attached to the operation.
MLIR_CAPI_EXPORTED MlirDialect mlirTypeGetDialect(MlirType type)
Gets the dialect a type belongs to.
MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
MLIR_CAPI_EXPORTED void mlirOperationSetSuccessor(MlirOperation op, intptr_t pos, MlirBlock block)
Set pos-th successor of the operation.
MLIR_CAPI_EXPORTED void mlirContextLoadAllAvailableDialects(MlirContext context)
Eagerly loads all available dialects registered with a context, making them available for use for IR ...
MLIR_CAPI_EXPORTED void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, MlirRegion const *regions)
MLIR_CAPI_EXPORTED void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, MlirBlock const *successors)
MLIR_CAPI_EXPORTED MlirBlock mlirModuleGetBody(MlirModule module)
Gets the body of the module, i.e. the only block it contains.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags)
Destroys printing flags created with mlirOpPrintingFlagsCreate.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGet(MlirContext context, MlirStringRef name, MlirLocation childLoc)
Creates a name location owned by the given context.
MLIR_CAPI_EXPORTED void mlirContextEnableMultithreading(MlirContext context, bool enable)
Set threading mode (must be set to false to mlir-print-ir-after-all).
MLIR_CAPI_EXPORTED void mlirBlockPrint(MlirBlock block, MlirStringCallback callback, void *userData)
Prints a block by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED void mlirBytecodeWriterConfigDesiredEmitVersion(MlirBytecodeWriterConfig flags, int64_t version)
Sets the version to emit in the writer config.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetSymbolAttributeName(void)
Returns the name of the attribute used to store symbol names compatible with symbol tables.
MLIR_CAPI_EXPORTED MlirRegion mlirRegionCreate(void)
Creates a new empty region and transfers ownership to the caller.
MLIR_CAPI_EXPORTED void mlirBlockDetach(MlirBlock block)
Detach a block from the owning region and assume ownership.
MLIR_CAPI_EXPORTED void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, MlirType const *results)
Adds a list of components to the operation state.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, bool enable, bool prettyForm)
Enable or disable printing of debug information (based on enable).
MLIR_CAPI_EXPORTED MlirLocation mlirOperationGetLocation(MlirOperation op)
Gets the location of the operation.
MLIR_CAPI_EXPORTED MlirTypeID mlirAttributeGetTypeID(MlirAttribute attribute)
Gets the type id of the attribute.
MLIR_CAPI_EXPORTED void mlirOperationSetOperand(MlirOperation op, intptr_t pos, MlirValue newValue)
Sets the pos-th operand of the operation.
MLIR_CAPI_EXPORTED void mlirOperationDump(MlirOperation op)
Prints an operation to stderr.
MLIR_CAPI_EXPORTED intptr_t mlirOpResultGetResultNumber(MlirValue value)
Returns the position of the value in the list of results of the operation that produced it.
MLIR_CAPI_EXPORTED MlirOpPrintingFlags mlirOpPrintingFlagsCreate(void)
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED MlirAsmState mlirAsmStateCreateForValue(MlirValue value, MlirOpPrintingFlags flags)
Creates new AsmState from value.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreate(MlirOperationState *state)
Creates an operation and transfers ownership to the caller.
static bool mlirSymbolTableIsNull(MlirSymbolTable symbolTable)
Returns true if the symbol table is null.
MLIR_CAPI_EXPORTED bool mlirContextGetAllowUnregisteredDialects(MlirContext context)
Returns whether the context allows unregistered dialects.
MLIR_CAPI_EXPORTED void mlirOperationMoveAfter(MlirOperation op, MlirOperation other)
Moves the given operation immediately after the other operation in its parent block.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumAttributes(MlirOperation op)
Returns the number of attributes attached to the operation.
MLIR_CAPI_EXPORTED void mlirValuePrint(MlirValue value, MlirStringCallback callback, void *userData)
Prints a value by sending chunks of the string representation and forwarding userData tocallback`.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirOperationWriteBytecodeWithConfig(MlirOperation op, MlirBytecodeWriterConfig config, MlirStringCallback callback, void *userData)
Same as mlirOperationWriteBytecode but with writer config and returns failure only if desired bytecod...
MLIR_CAPI_EXPORTED void mlirValueSetType(MlirValue value, MlirType type)
Set the type of the value.
MLIR_CAPI_EXPORTED MlirType mlirValueGetType(MlirValue value)
Returns the type of the value.
MLIR_CAPI_EXPORTED void mlirContextDestroy(MlirContext context)
Takes an MLIR context owned by the caller and destroys it.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreateParse(MlirContext context, MlirStringRef sourceStr, MlirStringRef sourceName)
Parses an operation, giving ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2)
Checks if two attributes are equal.
static bool mlirOperationIsNull(MlirOperation op)
Checks whether the underlying operation is null.
MLIR_CAPI_EXPORTED MlirBlock mlirRegionGetFirstBlock(MlirRegion region)
Gets the first block in the region.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
static MlirLogicalResult mlirLogicalResultFailure(void)
Creates a logical result representing a failure.
MLIR_CAPI_EXPORTED size_t mlirTypeIDHashValue(MlirTypeID typeID)
Returns the hash value of the type id.
static MlirLogicalResult mlirLogicalResultSuccess(void)
Creates a logical result representing a success.
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
static bool mlirTypeIDIsNull(MlirTypeID typeID)
Checks whether a type id is null.
MLIR_CAPI_EXPORTED bool mlirTypeIDEqual(MlirTypeID typeID1, MlirTypeID typeID2)
Checks if two type ids are equal.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
inline ::llvm::hash_code hash_value(const PolynomialBase< D, T > &arg)
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
PyObjectRef< PyModule > PyModuleRef
void populateIRCore(pybind11::module &m)
PyObjectRef< PyOperation > PyOperationRef
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
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)