20 #include "llvm/ADT/ArrayRef.h" 21 #include "llvm/ADT/SmallVector.h" 30 using llvm::StringRef;
38 R
"(Parses the assembly form of a type. 40 Returns a Type object or raises a ValueError if the type cannot be parsed. 42 See also: https://mlir.llvm.org/docs/LangRef/#type-system 46 R
"(Gets a Location representing a caller and callsite)"; 49 R
"(Gets a Location representing a file, line and column)"; 52 R
"(Gets a Location representing a fused location with optional metadata)"; 55 R
"(Gets a Location representing a named location with optional child location)"; 58 R
"(Parses a module's assembly format from a string. 60 Returns a new MlirModule or raises a ValueError if the parsing fails. 62 See also: https://mlir.llvm.org/docs/LangRef/ 66 R
"(Creates a new operation. 69 name: Operation name (e.g. "dialect.operation"). 70 results: Sequence of Type representing op result types. 71 attributes: Dict of str:Attribute. 72 successors: List of Block for the operation's successors. 73 regions: Number of regions to create. 74 location: A Location object (defaults to resolve from context manager). 75 ip: An InsertionPoint (defaults to resolve from context manager or set to 76 False to disable insertion, even with an insertion point set in the 79 A new "detached" Operation object. Detached operations can be added 80 to blocks, which causes them to become "attached." 84 R
"(Prints the assembly form of the operation to a file like object. 87 file: The file like object to write to. Defaults to sys.stdout. 88 binary: Whether to write bytes (True) or str (False). Defaults to False. 89 large_elements_limit: Whether to elide elements attributes above this 90 number of elements. Defaults to None (no limit). 91 enable_debug_info: Whether to print debug/location information. Defaults 93 pretty_debug_info: Whether to format debug information for easier reading 94 by a human (warning: the result is unparseable). 95 print_generic_op_form: Whether to print the generic assembly forms of all 96 ops. Defaults to False. 97 use_local_Scope: Whether to print in a way that is more optimized for 98 multi-threaded access but may not be consistent with how the overall 100 assume_verified: By default, if not printing generic form, the verifier 101 will be run and if it fails, generic form will be printed with a comment 102 about failed verification. While a reasonable default for interactive use, 103 for systematic use, it is often better for the caller to verify explicitly 104 and report failures in a more robust fashion. Set this to True if doing this 105 in order to avoid running a redundant verification. If the IR is actually 106 invalid, behavior is undefined. 110 R
"(Gets the assembly form of the operation with all options available. 113 binary: Whether to return a bytes (True) or str (False) object. Defaults to 115 ... others ...: See the print() method for common keyword arguments for 116 configuring the printout. 118 Either a bytes or str object, depending on the setting of the 'binary' 123 R
"(Gets the assembly form of the operation with default options. 125 If more advanced control over the assembly formatting or I/O options is needed, 126 use the dedicated print or get_asm method, which supports keyword arguments to 131 R
"(Dumps a debug representation of the object to stderr.)"; 134 R
"(Appends a new block, with argument types as positional args. 141 R
"(Returns the string form of the value. 143 If the value is a block argument, this is the assembly form of its type and the 144 position in the argument list. If the value is an operation result, this is 145 equivalent to printing the operation that produced it. 153 template <
class Func,
typename... Args>
155 py::object cf = py::cpp_function(f, args...);
156 return py::reinterpret_borrow<py::object>((PyClassMethod_New(cf.ptr())));
161 py::object dialectDescriptor) {
165 return py::cast(
PyDialect(std::move(dialectDescriptor)));
169 return (*dialectClass)(std::move(dialectDescriptor));
182 static void bind(py::module &m) {
184 py::class_<PyGlobalDebugFlag>(m,
"_GlobalDebug", py::module_local())
196 class PyRegionIterator {
199 : operation(std::move(operation)) {}
201 PyRegionIterator &dunderIter() {
return *
this; }
206 throw py::stop_iteration();
212 static void bind(py::module &m) {
213 py::class_<PyRegionIterator>(m,
"RegionIterator", py::module_local())
214 .def(
"__iter__", &PyRegionIterator::dunderIter)
215 .def(
"__next__", &PyRegionIterator::dunderNext);
227 PyRegionList(
PyOperationRef operation) : operation(std::move(operation)) {}
229 intptr_t dunderLen() {
234 PyRegion dunderGetItem(intptr_t index) {
236 if (index < 0 || index >= dunderLen()) {
238 "attempt to access out of bounds region");
244 static void bind(py::module &m) {
245 py::class_<PyRegionList>(m,
"RegionSequence", py::module_local())
246 .def(
"__len__", &PyRegionList::dunderLen)
247 .def(
"__getitem__", &PyRegionList::dunderGetItem);
254 class PyBlockIterator {
257 : operation(std::move(operation)), next(next) {}
259 PyBlockIterator &dunderIter() {
return *
this; }
264 throw py::stop_iteration();
267 PyBlock returnBlock(operation, next);
272 static void bind(py::module &m) {
273 py::class_<PyBlockIterator>(m,
"BlockIterator", py::module_local())
274 .def(
"__iter__", &PyBlockIterator::dunderIter)
275 .def(
"__next__", &PyBlockIterator::dunderNext);
289 : operation(std::move(operation)), region(region) {}
291 PyBlockIterator dunderIter() {
296 intptr_t dunderLen() {
307 PyBlock dunderGetItem(intptr_t index) {
311 "attempt to access out of bounds block");
316 return PyBlock(operation, block);
321 throw SetPyError(PyExc_IndexError,
"attempt to access out of bounds block");
324 PyBlock appendBlock(
const py::args &pyArgTypes) {
328 argTypes.reserve(pyArgTypes.size());
329 argLocs.reserve(pyArgTypes.size());
330 for (
auto &pyArg : pyArgTypes) {
331 argTypes.push_back(pyArg.cast<
PyType &>());
340 return PyBlock(operation, block);
343 static void bind(py::module &m) {
344 py::class_<PyBlockList>(m,
"BlockList", py::module_local())
345 .def(
"__getitem__", &PyBlockList::dunderGetItem)
346 .def(
"__iter__", &PyBlockList::dunderIter)
347 .def(
"__len__", &PyBlockList::dunderLen)
356 class PyOperationIterator {
358 PyOperationIterator(
PyOperationRef parentOperation, MlirOperation next)
359 : parentOperation(std::move(parentOperation)), next(next) {}
361 PyOperationIterator &dunderIter() {
return *
this; }
363 py::object dunderNext() {
366 throw py::stop_iteration();
375 static void bind(py::module &m) {
376 py::class_<PyOperationIterator>(m,
"OperationIterator", py::module_local())
377 .def(
"__iter__", &PyOperationIterator::dunderIter)
378 .def(
"__next__", &PyOperationIterator::dunderNext);
390 class PyOperationList {
393 : parentOperation(std::move(parentOperation)), block(block) {}
395 PyOperationIterator dunderIter() {
397 return PyOperationIterator(parentOperation,
401 intptr_t dunderLen() {
412 py::object dunderGetItem(intptr_t index) {
416 "attempt to access out of bounds operation");
428 "attempt to access out of bounds operation");
431 static void bind(py::module &m) {
432 py::class_<PyOperationList>(m,
"OperationList", py::module_local())
433 .def(
"__getitem__", &PyOperationList::dunderGetItem)
434 .def(
"__iter__", &PyOperationList::dunderIter)
435 .def(
"__len__", &PyOperationList::dunderLen);
450 py::gil_scoped_acquire acquire;
451 auto &liveContexts = getLiveContexts();
452 liveContexts[context.ptr] =
this;
459 py::gil_scoped_acquire acquire;
460 getLiveContexts().erase(context.ptr);
471 throw py::error_already_set();
472 return forContext(rawContext).releaseObject();
481 py::gil_scoped_acquire acquire;
482 auto &liveContexts = getLiveContexts();
483 auto it = liveContexts.find(context.ptr);
484 if (it == liveContexts.end()) {
487 py::object pyRef = py::cast(unownedContextWrapper);
488 assert(pyRef &&
"cast to py::object failed");
489 liveContexts[context.ptr] = unownedContextWrapper;
493 py::object pyRef = py::cast(it->second);
507 for (
auto &op : liveOperations)
508 op.second.second->setInvalid();
509 size_t numInvalidated = liveOperations.size();
510 liveOperations.clear();
511 return numInvalidated;
521 const pybind11::object &excVal,
522 const pybind11::object &excTb) {
531 py::object pyHandlerObject =
532 py::cast(pyHandler, py::return_value_policy::take_ownership);
533 pyHandlerObject.inc_ref();
537 auto handlerCallback =
540 py::object pyDiagnosticObject =
541 py::cast(pyDiagnostic, py::return_value_policy::take_ownership);
548 py::gil_scoped_acquire gil;
550 result = py::cast<bool>(pyHandler->callback(pyDiagnostic));
551 }
catch (std::exception &e) {
552 fprintf(stderr,
"MLIR Python Diagnostic handler raised exception: %s\n",
554 pyHandler->hadError =
true;
561 auto deleteCallback = +[](
void *userData) {
563 assert(pyHandler->registeredID &&
"handler is not registered");
564 pyHandler->registeredID.reset();
567 py::object pyHandlerObject =
568 py::cast(pyHandler, py::return_value_policy::reference);
569 pyHandlerObject.dec_ref();
573 get(), handlerCallback, static_cast<void *>(pyHandler), deleteCallback);
574 return pyHandlerObject;
582 "An MLIR function requires a Context but none was provided in the call " 583 "or from the surrounding environment. Either pass to the function with " 584 "a 'context=' argument or establish a default using 'with Context():'");
594 static thread_local std::vector<PyThreadContextEntry> stack;
599 auto &stack = getStack();
602 return &stack.back();
605 void PyThreadContextEntry::push(
FrameKind frameKind, py::object context,
606 py::object insertionPoint,
607 py::object location) {
608 auto &stack = getStack();
609 stack.emplace_back(frameKind, std::move(context), std::move(insertionPoint),
610 std::move(location));
614 if (stack.size() > 1) {
615 auto &prev = *(stack.rbegin() + 1);
616 auto ¤t = stack.back();
617 if (current.context.is(prev.context)) {
619 if (!current.insertionPoint)
620 current.insertionPoint = prev.insertionPoint;
621 if (!current.location)
622 current.location = prev.location;
630 return py::cast<PyMlirContext *>(context);
636 return py::cast<PyInsertionPoint *>(insertionPoint);
642 return py::cast<PyLocation *>(location);
646 auto *tos = getTopOfStack();
647 return tos ? tos->getContext() :
nullptr;
651 auto *tos = getTopOfStack();
652 return tos ? tos->getInsertionPoint() :
nullptr;
656 auto *tos = getTopOfStack();
657 return tos ? tos->getLocation() :
nullptr;
661 py::object contextObj = py::cast(context);
662 push(FrameKind::Context, contextObj,
669 auto &stack = getStack();
671 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Context enter/exit");
672 auto &tos = stack.back();
673 if (tos.frameKind != FrameKind::Context && tos.getContext() != &context)
674 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Context enter/exit");
680 py::object contextObj =
682 py::object insertionPointObj = py::cast(insertionPoint);
683 push(FrameKind::InsertionPoint,
687 return insertionPointObj;
691 auto &stack = getStack();
694 "Unbalanced InsertionPoint enter/exit");
695 auto &tos = stack.back();
696 if (tos.frameKind != FrameKind::InsertionPoint &&
697 tos.getInsertionPoint() != &insertionPoint)
699 "Unbalanced InsertionPoint enter/exit");
705 py::object locationObj = py::cast(location);
706 push(FrameKind::Location, contextObj,
713 auto &stack = getStack();
715 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Location enter/exit");
716 auto &tos = stack.back();
717 if (tos.frameKind != FrameKind::Location && tos.getLocation() != &location)
718 throw SetPyError(PyExc_RuntimeError,
"Unbalanced Location enter/exit");
728 if (materializedNotes) {
729 for (
auto ¬eObject : *materializedNotes) {
730 PyDiagnostic *note = py::cast<PyDiagnostic *>(noteObject);
738 : context(context), callback(std::move(callback)) {}
747 assert(!registeredID &&
"should have unregistered");
753 void PyDiagnostic::checkValid() {
755 throw std::invalid_argument(
756 "Diagnostic is invalid (used outside of callback)");
774 py::object fileObject = py::module::import(
"io").attr(
"StringIO")();
777 return fileObject.attr(
"getvalue")();
782 if (materializedNotes)
783 return *materializedNotes;
785 materializedNotes = py::tuple(numNotes);
786 for (intptr_t i = 0; i < numNotes; ++i) {
790 return *materializedNotes;
800 {key.data(), key.size()});
802 throw SetPyError(attrError ? PyExc_AttributeError : PyExc_IndexError,
803 Twine(
"Dialect '") + key +
"' not found");
809 return py::reinterpret_steal<py::object>(
814 MlirDialectRegistry rawRegistry =
817 throw py::error_already_set();
832 throw py::error_already_set();
842 const pybind11::object &excVal,
843 const pybind11::object &excTb) {
852 "An MLIR function requires a Location but none was provided in the " 853 "call or from the surrounding environment. Either pass to the function " 854 "with a 'loc=' argument or establish a default using 'with loc:'");
867 py::gil_scoped_acquire acquire;
868 auto &liveModules = getContext()->liveModules;
869 assert(liveModules.count(module.ptr) == 1 &&
870 "destroying module not in live map");
871 liveModules.erase(module.ptr);
879 py::gil_scoped_acquire acquire;
880 auto &liveModules = contextRef->liveModules;
881 auto it = liveModules.find(module.ptr);
882 if (it == liveModules.end()) {
889 py::cast(unownedModule, py::return_value_policy::take_ownership);
890 unownedModule->handle = pyRef;
891 liveModules[module.ptr] =
892 std::make_pair(unownedModule->handle, unownedModule);
893 return PyModuleRef(unownedModule, std::move(pyRef));
896 PyModule *existing = it->second.second;
897 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
904 throw py::error_already_set();
905 return forModule(rawModule).releaseObject();
916 PyOperation::PyOperation(
PyMlirContextRef contextRef, MlirOperation operation)
923 auto &liveOperations = getContext()->liveOperations;
924 assert(liveOperations.count(operation.ptr) == 1 &&
925 "destroying operation not in live map");
926 liveOperations.erase(operation.ptr);
933 MlirOperation operation,
934 py::object parentKeepAlive) {
935 auto &liveOperations = contextRef->liveOperations;
943 py::cast(unownedOperation, py::return_value_policy::take_ownership);
944 unownedOperation->handle = pyRef;
945 if (parentKeepAlive) {
946 unownedOperation->parentKeepAlive = std::move(parentKeepAlive);
948 liveOperations[operation.ptr] = std::make_pair(pyRef, unownedOperation);
953 MlirOperation operation,
954 py::object parentKeepAlive) {
955 auto &liveOperations = contextRef->liveOperations;
956 auto it = liveOperations.find(operation.ptr);
957 if (it == liveOperations.end()) {
959 return createInstance(std::move(contextRef), operation,
960 std::move(parentKeepAlive));
964 py::object pyRef = py::reinterpret_borrow<py::object>(it->second.first);
969 MlirOperation operation,
970 py::object parentKeepAlive) {
971 auto &liveOperations = contextRef->liveOperations;
972 assert(liveOperations.count(operation.ptr) == 0 &&
973 "cannot create detached operation that already exists");
974 (
void)liveOperations;
976 PyOperationRef created = createInstance(std::move(contextRef), operation,
977 std::move(parentKeepAlive));
978 created->attached =
false;
984 throw SetPyError(PyExc_RuntimeError,
"the operation has been invalidated");
990 bool enableDebugInfo,
bool prettyDebugInfo,
991 bool printGenericOpForm,
bool useLocalScope,
992 bool assumeVerified) {
995 if (fileObject.is_none())
996 fileObject = py::module::import(
"sys").attr(
"stdout");
998 if (!assumeVerified && !printGenericOpForm &&
1000 std::string message(
"// Verification failed, printing generic form\n");
1002 fileObject.attr(
"write")(py::bytes(message));
1004 fileObject.attr(
"write")(py::str(message));
1006 printGenericOpForm =
true;
1010 if (largeElementsLimit)
1012 if (enableDebugInfo)
1014 if (printGenericOpForm)
1027 bool enableDebugInfo,
bool prettyDebugInfo,
1028 bool printGenericOpForm,
bool useLocalScope,
1029 bool assumeVerified) {
1030 py::object fileObject;
1032 fileObject = py::module::import(
"io").attr(
"BytesIO")();
1034 fileObject = py::module::import(
"io").attr(
"StringIO")();
1036 print(fileObject, binary,
1044 return fileObject.attr(
"getvalue")();
1053 operation.parentKeepAlive = otherOp.parentKeepAlive;
1062 operation.parentKeepAlive = otherOp.parentKeepAlive;
1068 throw SetPyError(PyExc_ValueError,
"Detached operations have no parent");
1079 assert(!
mlirBlockIsNull(block) &&
"Attached operation has null parent");
1080 assert(parentOperation &&
"Operation has no parent");
1081 return PyBlock{std::move(*parentOperation), block};
1092 throw py::error_already_set();
1099 const py::object &maybeIp) {
1101 if (!maybeIp.is(py::cast(
false))) {
1103 if (maybeIp.is_none()) {
1106 ip = py::cast<PyInsertionPoint *>(maybeIp);
1114 const std::string &name,
llvm::Optional<std::vector<PyType *>> results,
1126 throw SetPyError(PyExc_ValueError,
"number of regions must be >= 0");
1130 mlirOperands.reserve(operands->size());
1131 for (
PyValue *operand : *operands) {
1133 throw SetPyError(PyExc_ValueError,
"operand value cannot be None");
1134 mlirOperands.push_back(operand->get());
1140 mlirResults.reserve(results->size());
1141 for (
PyType *result : *results) {
1144 throw SetPyError(PyExc_ValueError,
"result type cannot be None");
1145 mlirResults.push_back(*result);
1150 mlirAttributes.reserve(attributes->size());
1151 for (
auto &it : *attributes) {
1154 key = it.first.cast<std::string>();
1155 }
catch (py::cast_error &err) {
1156 std::string msg =
"Invalid attribute key (not a string) when " 1157 "attempting to create the operation \"" +
1158 name +
"\" (" + err.what() +
")";
1159 throw py::cast_error(msg);
1162 auto &attribute = it.second.cast<
PyAttribute &>();
1164 mlirAttributes.emplace_back(std::move(key), attribute);
1165 }
catch (py::reference_cast_error &) {
1168 "Found an invalid (`None`?) attribute value for the key \"" + key +
1169 "\" when attempting to create the operation \"" + name +
"\"";
1170 throw py::cast_error(msg);
1171 }
catch (py::cast_error &err) {
1172 std::string msg =
"Invalid attribute value for the key \"" + key +
1173 "\" when attempting to create the operation \"" +
1174 name +
"\" (" + err.what() +
")";
1175 throw py::cast_error(msg);
1181 mlirSuccessors.reserve(successors->size());
1182 for (
auto *successor : *successors) {
1185 throw SetPyError(PyExc_ValueError,
"successor block cannot be None");
1186 mlirSuccessors.push_back(successor->get());
1194 if (!mlirOperands.empty())
1196 mlirOperands.data());
1197 if (!mlirResults.empty())
1199 mlirResults.data());
1200 if (!mlirAttributes.empty()) {
1205 mlirNamedAttributes.reserve(mlirAttributes.size());
1206 for (
auto &it : mlirAttributes)
1212 mlirNamedAttributes.data());
1214 if (!mlirSuccessors.empty())
1216 mlirSuccessors.data());
1219 mlirRegions.resize(regions);
1220 for (
int i = 0; i < regions; ++i)
1223 mlirRegions.data());
1251 return (*opViewClass)(getRef().getObject());
1252 return py::cast(
PyOpView(getRef().getObject()));
1260 auto &liveOperations = getContext()->liveOperations;
1261 if (liveOperations.count(operation.ptr))
1262 liveOperations.erase(operation.ptr);
1272 const py::object &cls, py::list resultTypeList, py::list operandList,
1276 const py::object &maybeIp) {
1279 std::string name = py::cast<std::string>(cls.attr(
"OPERATION_NAME"));
1285 py::object operandSegmentSpecObj = cls.attr(
"_ODS_OPERAND_SEGMENTS");
1286 py::object resultSegmentSpecObj = cls.attr(
"_ODS_RESULT_SEGMENTS");
1288 std::vector<int32_t> operandSegmentLengths;
1289 std::vector<int32_t> resultSegmentLengths;
1292 auto opRegionSpec = py::cast<std::tuple<int, bool>>(cls.attr(
"_ODS_REGIONS"));
1293 int opMinRegionCount = std::get<0>(opRegionSpec);
1294 bool opHasNoVariadicRegions = std::get<1>(opRegionSpec);
1296 regions = opMinRegionCount;
1298 if (*regions < opMinRegionCount) {
1299 throw py::value_error(
1300 (llvm::Twine(
"Operation \"") + name +
"\" requires a minimum of " +
1301 llvm::Twine(opMinRegionCount) +
1302 " regions but was built with regions=" + llvm::Twine(*regions))
1305 if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
1306 throw py::value_error(
1307 (llvm::Twine(
"Operation \"") + name +
"\" requires a maximum of " +
1308 llvm::Twine(opMinRegionCount) +
1309 " regions but was built with regions=" + llvm::Twine(*regions))
1314 std::vector<PyType *> resultTypes;
1315 resultTypes.reserve(resultTypeList.size());
1316 if (resultSegmentSpecObj.is_none()) {
1320 resultTypes.push_back(py::cast<PyType *>(it.value()));
1321 if (!resultTypes.back())
1322 throw py::cast_error();
1323 }
catch (py::cast_error &err) {
1324 throw py::value_error((llvm::Twine(
"Result ") +
1325 llvm::Twine(it.index()) +
" of operation \"" +
1326 name +
"\" must be a Type (" + err.what() +
")")
1332 auto resultSegmentSpec = py::cast<std::vector<int>>(resultSegmentSpecObj);
1333 if (resultSegmentSpec.size() != resultTypeList.size()) {
1334 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1336 llvm::Twine(resultSegmentSpec.size()) +
1337 " result segments but was provided " +
1338 llvm::Twine(resultTypeList.size()))
1341 resultSegmentLengths.reserve(resultTypeList.size());
1342 for (
const auto &it :
1344 int segmentSpec = std::get<1>(it.value());
1345 if (segmentSpec == 1 || segmentSpec == 0) {
1348 auto *resultType = py::cast<PyType *>(std::get<0>(it.value()));
1350 resultTypes.push_back(resultType);
1351 resultSegmentLengths.push_back(1);
1352 }
else if (segmentSpec == 0) {
1354 resultSegmentLengths.push_back(0);
1356 throw py::cast_error(
"was None and result is not optional");
1358 }
catch (py::cast_error &err) {
1359 throw py::value_error((llvm::Twine(
"Result ") +
1360 llvm::Twine(it.index()) +
" of operation \"" +
1361 name +
"\" must be a Type (" + err.what() +
1365 }
else if (segmentSpec == -1) {
1368 if (std::get<0>(it.value()).is_none()) {
1370 resultSegmentLengths.push_back(0);
1373 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1374 for (py::object segmentItem : segment) {
1375 resultTypes.push_back(py::cast<PyType *>(segmentItem));
1376 if (!resultTypes.back()) {
1377 throw py::cast_error(
"contained a None item");
1380 resultSegmentLengths.push_back(segment.size());
1382 }
catch (std::exception &err) {
1386 throw py::value_error((llvm::Twine(
"Result ") +
1387 llvm::Twine(it.index()) +
" of operation \"" +
1388 name +
"\" must be a Sequence of Types (" +
1393 throw py::value_error(
"Unexpected segment spec");
1399 std::vector<PyValue *> operands;
1400 operands.reserve(operands.size());
1401 if (operandSegmentSpecObj.is_none()) {
1405 operands.push_back(py::cast<PyValue *>(it.value()));
1406 if (!operands.back())
1407 throw py::cast_error();
1408 }
catch (py::cast_error &err) {
1409 throw py::value_error((llvm::Twine(
"Operand ") +
1410 llvm::Twine(it.index()) +
" of operation \"" +
1411 name +
"\" must be a Value (" + err.what() +
")")
1417 auto operandSegmentSpec = py::cast<std::vector<int>>(operandSegmentSpecObj);
1418 if (operandSegmentSpec.size() != operandList.size()) {
1419 throw py::value_error((llvm::Twine(
"Operation \"") + name +
1421 llvm::Twine(operandSegmentSpec.size()) +
1422 "operand segments but was provided " +
1423 llvm::Twine(operandList.size()))
1426 operandSegmentLengths.reserve(operandList.size());
1427 for (
const auto &it :
1429 int segmentSpec = std::get<1>(it.value());
1430 if (segmentSpec == 1 || segmentSpec == 0) {
1433 auto *operandValue = py::cast<PyValue *>(std::get<0>(it.value()));
1435 operands.push_back(operandValue);
1436 operandSegmentLengths.push_back(1);
1437 }
else if (segmentSpec == 0) {
1439 operandSegmentLengths.push_back(0);
1441 throw py::cast_error(
"was None and operand is not optional");
1443 }
catch (py::cast_error &err) {
1444 throw py::value_error((llvm::Twine(
"Operand ") +
1445 llvm::Twine(it.index()) +
" of operation \"" +
1446 name +
"\" must be a Value (" + err.what() +
1450 }
else if (segmentSpec == -1) {
1453 if (std::get<0>(it.value()).is_none()) {
1455 operandSegmentLengths.push_back(0);
1458 auto segment = py::cast<py::sequence>(std::get<0>(it.value()));
1459 for (py::object segmentItem : segment) {
1460 operands.push_back(py::cast<PyValue *>(segmentItem));
1461 if (!operands.back()) {
1462 throw py::cast_error(
"contained a None item");
1465 operandSegmentLengths.push_back(segment.size());
1467 }
catch (std::exception &err) {
1471 throw py::value_error((llvm::Twine(
"Operand ") +
1472 llvm::Twine(it.index()) +
" of operation \"" +
1473 name +
"\" must be a Sequence of Values (" +
1478 throw py::value_error(
"Unexpected segment spec");
1484 if (!operandSegmentLengths.empty() || !resultSegmentLengths.empty()) {
1487 attributes = py::dict(*attributes);
1489 attributes = py::dict();
1491 if (attributes->contains(
"result_segment_sizes") ||
1492 attributes->contains(
"operand_segment_sizes")) {
1493 throw py::value_error(
"Manually setting a 'result_segment_sizes' or " 1494 "'operand_segment_sizes' attribute is unsupported. " 1495 "Use Operation.create for such low-level access.");
1499 if (!resultSegmentLengths.empty()) {
1500 MlirAttribute segmentLengthAttr =
1502 resultSegmentLengths.data());
1503 (*attributes)[
"result_segment_sizes"] =
1508 if (!operandSegmentLengths.empty()) {
1509 MlirAttribute segmentLengthAttr =
1511 operandSegmentLengths.data());
1512 (*attributes)[
"operand_segment_sizes"] =
1519 std::move(resultTypes),
1520 std::move(operands),
1521 std::move(attributes),
1522 std::move(successors),
1523 *regions, location, maybeIp);
1530 operationObject(operation.getRef().getObject()) {}
1554 py::object parentMetaclass =
1555 py::reinterpret_borrow<py::object>((PyObject *)&PyType_Type);
1556 py::dict attributes;
1560 auto opViewType = py::detail::get_type_handle(
typeid(
PyOpView),
true);
1561 attributes[
"__init__"] = opViewType.attr(
"__init__");
1562 py::str origName = userClass.attr(
"__name__");
1563 py::str newName = py::str(
"_") + origName;
1564 return parentMetaclass(newName, py::make_tuple(userClass), attributes);
1574 : refOperation(beforeOperationBase.getOperation().getRef()),
1575 block((*refOperation)->
getBlock()) {}
1581 "Attempt to insert operation that is already attached");
1583 MlirOperation beforeOp = {
nullptr};
1586 (*refOperation)->checkValid();
1587 beforeOp = (*refOperation)->get();
1593 throw py::index_error(
"Cannot insert operation at the end of a block " 1594 "that already has a terminator. Did you mean to " 1595 "use 'InsertionPoint.at_block_terminator(block)' " 1596 "versus 'InsertionPoint(block)'?");
1619 throw SetPyError(PyExc_ValueError,
"Block has no terminator");
1630 const pybind11::object &excVal,
1631 const pybind11::object &excTb) {
1650 throw py::error_already_set();
1660 : ownedName(new std::string(std::move(ownedName))) {
1682 throw py::error_already_set();
1698 throw py::error_already_set();
1699 MlirOperation owner;
1705 throw py::error_already_set();
1709 return PyValue(ownerRef, value);
1717 : operation(operation.getOperation().getRef()) {
1720 throw py::cast_error(
"Operation is not a Symbol Table.");
1729 throw py::key_error(
"Symbol '" + name +
"' not in the symbol table.");
1748 erase(py::cast<PyOperationBase &>(operation));
1757 throw py::value_error(
"Expected operation to have a symbol name.");
1768 MlirAttribute existingNameAttr =
1771 throw py::value_error(
"Expected operation to have a symbol name.");
1776 const std::string &name) {
1781 MlirAttribute existingNameAttr =
1784 throw py::value_error(
"Expected operation to have a symbol name.");
1785 MlirAttribute newNameAttr =
1794 MlirAttribute existingVisAttr =
1797 throw py::value_error(
"Expected operation to have a symbol visibility.");
1802 const std::string &visibility) {
1803 if (visibility !=
"public" && visibility !=
"private" &&
1804 visibility !=
"nested")
1805 throw py::value_error(
1806 "Expected visibility to be 'public', 'private' or 'nested'");
1810 MlirAttribute existingVisAttr =
1813 throw py::value_error(
"Expected operation to have a symbol visibility.");
1820 const std::string &newSymbol,
1828 throw py::value_error(
"Symbol rename failed");
1832 bool allSymUsesVisible,
1833 py::object callback) {
1838 py::object callback;
1840 std::string exceptionWhat;
1841 py::object exceptionType;
1844 fromOperation.
getContext(), std::move(callback),
false, {}, {}};
1846 fromOperation.
get(), allSymUsesVisible,
1847 [](MlirOperation foundOp,
bool isVisible,
void *calleeUserDataVoid) {
1848 UserData *calleeUserData =
static_cast<UserData *
>(calleeUserDataVoid);
1851 if (calleeUserData->gotException)
1854 calleeUserData->callback(pyFoundOp.getObject(), isVisible);
1855 }
catch (py::error_already_set &e) {
1856 calleeUserData->gotException =
true;
1857 calleeUserData->exceptionWhat = e.what();
1858 calleeUserData->exceptionType = e.type();
1861 static_cast<void *
>(&userData));
1862 if (userData.gotException) {
1863 std::string message(
"Exception raised in callback: ");
1864 message.append(userData.exceptionWhat);
1865 throw std::runtime_error(message);
1873 template <
typename DerivedTy>
1874 class PyConcreteValue :
public PyValue {
1880 using ClassTy = py::class_<DerivedTy, PyValue>;
1881 using IsAFunctionTy = bool (*)(MlirValue);
1883 PyConcreteValue() =
default;
1885 :
PyValue(operationRef, value) {}
1886 PyConcreteValue(
PyValue &orig)
1891 static MlirValue castFrom(
PyValue &orig) {
1892 if (!DerivedTy::isaFunction(orig.
get())) {
1893 auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
1894 throw SetPyError(PyExc_ValueError, Twine(
"Cannot cast value to ") +
1895 DerivedTy::pyClassName +
1896 " (from " + origRepr +
")");
1902 static void bind(py::module &m) {
1903 auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
1904 cls.def(py::init<PyValue &>(), py::keep_alive<0, 1>(), py::arg(
"value"));
1907 [](
PyValue &otherValue) ->
bool {
1908 return DerivedTy::isaFunction(otherValue);
1910 py::arg(
"other_value"));
1911 DerivedTy::bindDerived(cls);
1915 static void bindDerived(ClassTy &m) {}
1919 class PyBlockArgument :
public PyConcreteValue<PyBlockArgument> {
1922 static constexpr
const char *pyClassName =
"BlockArgument";
1923 using PyConcreteValue::PyConcreteValue;
1925 static void bindDerived(ClassTy &c) {
1926 c.def_property_readonly(
"owner", [](PyBlockArgument &
self) {
1927 return PyBlock(
self.getParentOperation(),
1930 c.def_property_readonly(
"arg_number", [](PyBlockArgument &
self) {
1935 [](PyBlockArgument &
self,
PyType type) {
1943 class PyOpResult :
public PyConcreteValue<PyOpResult> {
1946 static constexpr
const char *pyClassName =
"OpResult";
1947 using PyConcreteValue::PyConcreteValue;
1949 static void bindDerived(ClassTy &c) {
1950 c.def_property_readonly(
"owner", [](PyOpResult &
self) {
1954 "expected the owner of the value in Python to match that in the IR");
1955 return self.getParentOperation().getObject();
1957 c.def_property_readonly(
"result_number", [](PyOpResult &
self) {
1964 template <
typename Container>
1965 static std::vector<PyType> getValueTypes(Container &container,
1967 std::vector<PyType> result;
1968 result.reserve(container.size());
1969 for (
int i = 0, e = container.size(); i < e; ++i) {
1980 class PyBlockArgumentList
1981 :
public Sliceable<PyBlockArgumentList, PyBlockArgument> {
1983 static constexpr
const char *pyClassName =
"BlockArgumentList";
1986 intptr_t startIndex = 0, intptr_t length = -1,
1991 operation(std::move(operation)), block(block) {}
1993 static void bindDerived(ClassTy &c) {
1994 c.def_property_readonly(
"types", [](PyBlockArgumentList &
self) {
1995 return getValueTypes(
self,
self.operation->
getContext());
2001 friend class Sliceable<PyBlockArgumentList, PyBlockArgument>;
2004 intptr_t getRawNumElements() {
2010 PyBlockArgument getRawElement(intptr_t pos) {
2012 return PyBlockArgument(operation, argument);
2016 PyBlockArgumentList slice(intptr_t startIndex, intptr_t length,
2018 return PyBlockArgumentList(operation, block, startIndex, length, step);
2029 class PyOpOperandList :
public Sliceable<PyOpOperandList, PyValue> {
2031 static constexpr
const char *pyClassName =
"OpOperandList";
2033 PyOpOperandList(
PyOperationRef operation, intptr_t startIndex = 0,
2034 intptr_t length = -1, intptr_t step = 1)
2039 operation(operation) {}
2042 index = wrapIndex(index);
2046 static void bindDerived(ClassTy &c) {
2047 c.def(
"__setitem__", &PyOpOperandList::dunderSetItem);
2052 friend class Sliceable<PyOpOperandList, PyValue>;
2054 intptr_t getRawNumElements() {
2059 PyValue getRawElement(intptr_t pos) {
2061 MlirOperation owner;
2067 assert(
false &&
"Value must be an block arg or op result.");
2070 return PyValue(pyOwner, operand);
2073 PyOpOperandList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2074 return PyOpOperandList(operation, startIndex, length, step);
2084 class PyOpResultList :
public Sliceable<PyOpResultList, PyOpResult> {
2086 static constexpr
const char *pyClassName =
"OpResultList";
2088 PyOpResultList(
PyOperationRef operation, intptr_t startIndex = 0,
2089 intptr_t length = -1, intptr_t step = 1)
2094 operation(operation) {}
2096 static void bindDerived(ClassTy &c) {
2097 c.def_property_readonly(
"types", [](PyOpResultList &
self) {
2098 return getValueTypes(
self,
self.operation->
getContext());
2104 friend class Sliceable<PyOpResultList, PyOpResult>;
2106 intptr_t getRawNumElements() {
2111 PyOpResult getRawElement(intptr_t index) {
2113 return PyOpResult(value);
2116 PyOpResultList slice(intptr_t startIndex, intptr_t length, intptr_t step) {
2117 return PyOpResultList(operation, startIndex, length, step);
2125 class PyOpAttributeMap {
2128 : operation(std::move(operation)) {}
2130 PyAttribute dunderGetItemNamed(
const std::string &name) {
2135 "attempt to access a non-existent attribute");
2141 if (index < 0 || index >= dunderLen()) {
2143 "attempt to access out of bounds attribute");
2153 void dunderSetItem(
const std::string &name,
const PyAttribute &attr) {
2158 void dunderDelItem(
const std::string &name) {
2163 "attempt to delete a non-existent attribute");
2166 intptr_t dunderLen() {
2170 bool dunderContains(
const std::string &name) {
2175 static void bind(py::module &m) {
2176 py::class_<PyOpAttributeMap>(m,
"OpAttributeMap", py::module_local())
2177 .def(
"__contains__", &PyOpAttributeMap::dunderContains)
2178 .def(
"__len__", &PyOpAttributeMap::dunderLen)
2179 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemNamed)
2180 .def(
"__getitem__", &PyOpAttributeMap::dunderGetItemIndexed)
2181 .def(
"__setitem__", &PyOpAttributeMap::dunderSetItem)
2182 .def(
"__delitem__", &PyOpAttributeMap::dunderDelItem);
2199 py::enum_<MlirDiagnosticSeverity>(m,
"DiagnosticSeverity", py::module_local())
2208 py::class_<PyDiagnostic>(m,
"Diagnostic", py::module_local())
2214 if (!
self.isValid())
2215 return "<Invalid Diagnostic>";
2216 return self.getMessage();
2219 py::class_<PyDiagnosticHandler>(m,
"DiagnosticHandler", py::module_local())
2232 py::class_<PyMlirContext>(m,
"_BaseContext", py::module_local())
2235 .def(
"_get_context_again",
2248 .def_property_readonly_static(
2253 throw SetPyError(PyExc_ValueError,
"No current Context");
2256 "Gets the Context bound to the current thread or raises ValueError")
2257 .def_property_readonly(
2260 "Gets a container for accessing dialects by name")
2261 .def_property_readonly(
2263 "Alias for 'dialect'")
2265 "get_dialect_descriptor",
2268 self.
get(), {name.data(), name.size()});
2271 Twine(
"Dialect '") + name +
"' not found");
2275 py::arg(
"dialect_name"),
2276 "Gets or loads a dialect by name, returning its descriptor object")
2278 "allow_unregistered_dialects",
2286 py::arg(
"callback"),
2287 "Attaches a diagnostic handler that will receive callbacks")
2289 "enable_multithreading",
2295 "is_registered_operation",
2300 py::arg(
"operation_name"))
2302 "append_dialect_registry",
2306 py::arg(
"registry"))
2307 .def(
"load_all_available_dialects", [](
PyMlirContext &
self) {
2314 py::class_<PyDialectDescriptor>(m,
"DialectDescriptor", py::module_local())
2315 .def_property_readonly(
"namespace",
2323 std::string repr(
"<DialectDescriptor ");
2332 py::class_<PyDialects>(m,
"Dialects", py::module_local())
2335 MlirDialect dialect =
2336 self.getDialectForKey(keyName,
false);
2337 py::object descriptor =
2341 .def(
"__getattr__", [=](
PyDialects &
self, std::string attrName) {
2342 MlirDialect dialect =
2343 self.getDialectForKey(attrName,
true);
2344 py::object descriptor =
2352 py::class_<PyDialect>(m,
"Dialect", py::module_local())
2353 .def(py::init<py::object>(), py::arg(
"descriptor"))
2354 .def_property_readonly(
2355 "descriptor", [](
PyDialect &
self) {
return self.getDescriptor(); })
2356 .def(
"__repr__", [](py::object
self) {
2357 auto clazz =
self.attr(
"__class__");
2358 return py::str(
"<Dialect ") +
2359 self.attr(
"descriptor").attr(
"namespace") + py::str(
" (class ") +
2360 clazz.attr(
"__module__") + py::str(
".") +
2361 clazz.attr(
"__name__") + py::str(
")>");
2367 py::class_<PyDialectRegistry>(m,
"DialectRegistry", py::module_local())
2376 py::class_<PyLocation>(m,
"Location", py::module_local())
2385 .def(
"__eq__", [](
PyLocation &
self, py::object other) {
return false; })
2386 .def_property_readonly_static(
2391 throw SetPyError(PyExc_ValueError,
"No current Location");
2394 "Gets the Location bound to the current thread or raises ValueError")
2401 py::arg(
"context") = py::none(),
2402 "Gets a Location representing an unknown location")
2405 [](
PyLocation callee,
const std::vector<PyLocation> &frames,
2408 throw py::value_error(
"No caller frames provided");
2409 MlirLocation caller = frames.back().get();
2411 llvm::reverse(llvm::makeArrayRef(frames).drop_back()))
2416 py::arg(
"callee"), py::arg(
"frames"), py::arg(
"context") = py::none(),
2420 [](std::string filename,
int line,
int col,
2427 py::arg(
"filename"), py::arg(
"line"), py::arg(
"col"),
2431 [](
const std::vector<PyLocation> &pyLocations,
2435 locations.reserve(pyLocations.size());
2436 for (
auto &pyLocation : pyLocations)
2437 locations.push_back(pyLocation.get());
2439 context->
get(), locations.size(), locations.data(),
2440 metadata ? metadata->get() : MlirAttribute{0});
2441 return PyLocation(context->getRef(), location);
2443 py::arg(
"locations"), py::arg(
"metadata") = py::none(),
2453 childLoc ? childLoc->get()
2456 py::arg(
"name"), py::arg(
"childLoc") = py::none(),
2458 .def_property_readonly(
2460 [](PyLocation &
self) {
return self.getContext().getObject(); },
2461 "Context that owns the Location")
2464 [](PyLocation &
self, std::string message) {
2467 py::arg(
"message"),
"Emits an error at this location")
2468 .def(
"__repr__", [](PyLocation &
self) {
2472 return printAccum.
join();
2478 py::class_<PyModule>(m,
"Module", py::module_local())
2491 "Unable to parse module assembly (see diagnostics)");
2495 py::arg(
"asm"), py::arg(
"context") = py::none(),
2503 py::arg(
"loc") = py::none(),
"Creates an empty module")
2504 .def_property_readonly(
2506 [](
PyModule &
self) {
return self.getContext().getObject(); },
2507 "Context that created the Module")
2508 .def_property_readonly(
2513 self.getRef().releaseObject())
2516 "Accesses the module as an operation")
2517 .def_property_readonly(
2522 self.getRef().releaseObject());
2526 "Return the block for this module")
2535 [](py::object
self) {
2537 return self.attr(
"operation").attr(
"__str__")();
2544 py::class_<PyOperationBase>(m,
"_OperationBase", py::module_local())
2547 return self.getOperation().getCapsule();
2559 .def_property_readonly(
"attributes",
2561 return PyOpAttributeMap(
2562 self.getOperation().getRef());
2564 .def_property_readonly(
"operands",
2566 return PyOpOperandList(
2567 self.getOperation().getRef());
2569 .def_property_readonly(
"regions",
2571 return PyRegionList(
2572 self.getOperation().getRef());
2574 .def_property_readonly(
2577 return PyOpResultList(
self.getOperation().getRef());
2579 "Returns the list of Operation results.")
2580 .def_property_readonly(
2583 auto &operation =
self.getOperation();
2585 if (numResults != 1) {
2589 Twine(
"Cannot call .result on operation ") +
2590 StringRef(name.data, name.length) +
" which has " +
2592 " results (it is only valid for operations with a " 2595 return PyOpResult(operation.getRef(),
2598 "Shortcut to get an op result if it has only one (throws an error " 2600 .def_property_readonly(
2607 "Returns the source location the operation was defined or derived " 2612 return self.getAsm(
false,
2620 "Returns the assembly form of the operation.")
2623 py::arg(
"file") = py::none(), py::arg(
"binary") =
false,
2624 py::arg(
"large_elements_limit") = py::none(),
2625 py::arg(
"enable_debug_info") =
false,
2626 py::arg(
"pretty_debug_info") =
false,
2627 py::arg(
"print_generic_op_form") =
false,
2628 py::arg(
"use_local_scope") =
false,
2632 py::arg(
"binary") =
false,
2633 py::arg(
"large_elements_limit") = py::none(),
2634 py::arg(
"enable_debug_info") =
false,
2635 py::arg(
"pretty_debug_info") =
false,
2636 py::arg(
"print_generic_op_form") =
false,
2637 py::arg(
"use_local_scope") =
false,
2644 "Verify the operation and return true if it passes, false if it " 2647 "Puts self immediately after the other operation in its parent " 2650 "Puts self immediately before the other operation in its parent " 2653 "detach_from_parent",
2658 throw py::value_error(
"Detached operation has no parent.");
2663 "Detaches the operation from its parent block.");
2665 py::class_<PyOperation, PyOperationBase>(m,
"Operation", py::module_local())
2667 py::arg(
"results") = py::none(),
2668 py::arg(
"operands") = py::none(),
2669 py::arg(
"attributes") = py::none(),
2670 py::arg(
"successors") = py::none(), py::arg(
"regions") = 0,
2671 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
2673 .def_property_readonly(
"parent",
2675 auto parent =
self.getParentOperation();
2677 return parent->getObject();
2685 .def_property_readonly(
"name",
2688 MlirOperation operation =
self.get();
2693 .def_property_readonly(
2697 return self.getContext().getObject();
2699 "Context that owns the Operation")
2703 py::class_<PyOpView, PyOperationBase>(m,
"OpView", py::module_local())
2704 .def(py::init<py::object>(), py::arg(
"operation"))
2706 .def_property_readonly(
2709 return self.getOperation().getContext().getObject();
2711 "Context that owns the Operation")
2712 .def(
"__str__", [](
PyOpView &
self) {
2713 return py::str(
self.getOperationObject());
2715 opViewClass.attr(
"_ODS_REGIONS") = py::make_tuple(0,
true);
2716 opViewClass.attr(
"_ODS_OPERAND_SEGMENTS") = py::none();
2717 opViewClass.attr(
"_ODS_RESULT_SEGMENTS") = py::none();
2720 py::arg(
"operands") = py::none(), py::arg(
"attributes") = py::none(),
2721 py::arg(
"successors") = py::none(), py::arg(
"regions") = py::none(),
2722 py::arg(
"loc") = py::none(), py::arg(
"ip") = py::none(),
2723 "Builds a specific, generated OpView based on class level attributes.");
2728 py::class_<PyRegion>(m,
"Region", py::module_local())
2729 .def_property_readonly(
2732 return PyBlockList(
self.getParentOperation(),
self.
get());
2734 "Returns a forward-optimized sequence of blocks.")
2735 .def_property_readonly(
2738 return self.getParentOperation()->createOpView();
2740 "Returns the operation owning this region.")
2746 return PyBlockIterator(
self.getParentOperation(), firstBlock);
2748 "Iterates over blocks in the region.")
2751 return self.get().ptr == other.
get().ptr;
2753 .def(
"__eq__", [](
PyRegion &
self, py::object &other) {
return false; });
2758 py::class_<PyBlock>(m,
"Block", py::module_local())
2759 .def_property_readonly(
2762 return self.getParentOperation()->createOpView();
2764 "Returns the owning operation of this block.")
2765 .def_property_readonly(
2769 return PyRegion(
self.getParentOperation(), region);
2771 "Returns the owning region of this block.")
2772 .def_property_readonly(
2775 return PyBlockArgumentList(
self.getParentOperation(),
self.
get());
2777 "Returns a list of block arguments.")
2778 .def_property_readonly(
2781 return PyOperationList(
self.getParentOperation(),
self.
get());
2783 "Returns a forward-optimized sequence of operations.")
2786 [](
PyRegion &parent, py::list pyArgTypes) {
2790 argTypes.reserve(pyArgTypes.size());
2791 argLocs.reserve(pyArgTypes.size());
2792 for (
auto &pyArg : pyArgTypes) {
2793 argTypes.push_back(pyArg.cast<
PyType &>());
2804 py::arg(
"parent"), py::arg(
"arg_types") = py::list(),
2805 "Creates and returns a new Block at the beginning of the given " 2806 "region (with given argument types).")
2810 MlirBlock b =
self.get();
2815 "Append this block to a region, transferring ownership if necessary")
2818 [](
PyBlock &
self, py::args pyArgTypes) {
2822 argTypes.reserve(pyArgTypes.size());
2823 argLocs.reserve(pyArgTypes.size());
2824 for (
auto &pyArg : pyArgTypes) {
2825 argTypes.push_back(pyArg.cast<
PyType &>());
2835 return PyBlock(
self.getParentOperation(), block);
2837 "Creates and returns a new Block before this block " 2838 "(with given argument types).")
2841 [](
PyBlock &
self, py::args pyArgTypes) {
2845 argTypes.reserve(pyArgTypes.size());
2846 argLocs.reserve(pyArgTypes.size());
2847 for (
auto &pyArg : pyArgTypes) {
2848 argTypes.push_back(pyArg.cast<
PyType &>());
2858 return PyBlock(
self.getParentOperation(), block);
2860 "Creates and returns a new Block after this block " 2861 "(with given argument types).")
2866 MlirOperation firstOperation =
2868 return PyOperationIterator(
self.getParentOperation(),
2871 "Iterates over operations in the block.")
2874 return self.get().ptr == other.
get().ptr;
2876 .def(
"__eq__", [](
PyBlock &
self, py::object &other) {
return false; })
2884 return printAccum.
join();
2886 "Returns the assembly form of the block.")
2896 self.getParentOperation().getObject());
2898 py::arg(
"operation"),
2899 "Appends an operation to this block. If the operation is currently " 2900 "in another block, it will be moved.");
2906 py::class_<PyInsertionPoint>(m,
"InsertionPoint", py::module_local())
2907 .def(py::init<PyBlock &>(), py::arg(
"block"),
2908 "Inserts after the last operation but still inside the block.")
2911 .def_property_readonly_static(
2916 throw SetPyError(PyExc_ValueError,
"No current InsertionPoint");
2919 "Gets the InsertionPoint bound to the current thread or raises " 2920 "ValueError if none has been set")
2921 .def(py::init<PyOperationBase &>(), py::arg(
"beforeOperation"),
2922 "Inserts before a referenced operation.")
2924 py::arg(
"block"),
"Inserts at the beginning of the block.")
2926 py::arg(
"block"),
"Inserts before the block terminator.")
2928 "Inserts an operation.")
2929 .def_property_readonly(
2931 "Returns the block that this InsertionPoint points to.");
2936 py::class_<PyAttribute>(m,
"Attribute", py::module_local())
2939 .def(py::init<PyAttribute &>(), py::arg(
"cast_from_type"),
2940 "Casts the passed attribute to the generic Attribute")
2953 Twine(
"Unable to parse attribute: '") +
2958 py::arg(
"asm"), py::arg(
"context") = py::none(),
2959 "Parses an attribute from an assembly form")
2960 .def_property_readonly(
2962 [](
PyAttribute &
self) {
return self.getContext().getObject(); },
2963 "Context that owns the Attribute")
2964 .def_property_readonly(
"type",
2966 return PyType(
self.getContext()->getRef(),
2974 py::keep_alive<0, 1>(),
"Binds a name to the attribute")
2977 .def(
"__eq__", [](
PyAttribute &
self, py::object &other) {
return false; })
2991 return printAccum.
join();
2993 "Returns the assembly form of the Attribute.")
3001 printAccum.
parts.append(
"Attribute(");
3004 printAccum.
parts.append(
")");
3005 return printAccum.
join();
3011 py::class_<PyNamedAttribute>(m,
"NamedAttribute", py::module_local())
3015 printAccum.
parts.append(
"NamedAttribute(");
3016 printAccum.
parts.append(
3019 printAccum.
parts.append(
"=");
3023 printAccum.
parts.append(
")");
3024 return printAccum.
join();
3026 .def_property_readonly(
3032 "The name of the NamedAttribute binding")
3033 .def_property_readonly(
3040 return PyAttribute(std::move(contextRef),
self.namedAttr.attribute);
3042 py::keep_alive<0, 1>(),
3043 "The underlying generic attribute of the NamedAttribute binding");
3048 py::class_<PyType>(m,
"Type", py::module_local())
3051 .def(py::init<PyType &>(), py::arg(
"cast_from_type"),
3052 "Casts the passed type to the generic Type")
3064 Twine(
"Unable to parse type: '") + typeSpec +
3067 return PyType(context->getRef(), type);
3069 py::arg(
"asm"), py::arg(
"context") = py::none(),
3071 .def_property_readonly(
3072 "context", [](
PyType &
self) {
return self.getContext().getObject(); },
3073 "Context that owns the Type")
3074 .def(
"__eq__", [](
PyType &
self,
PyType &other) {
return self == other; })
3075 .def(
"__eq__", [](
PyType &
self, py::object &other) {
return false; })
3088 return printAccum.
join();
3090 "Returns the assembly form of the type.")
3091 .def(
"__repr__", [](
PyType &
self) {
3097 printAccum.
parts.append(
"Type(");
3099 printAccum.
parts.append(
")");
3100 return printAccum.
join();
3106 py::class_<PyValue>(m,
"Value", py::module_local())
3109 .def_property_readonly(
3111 [](
PyValue &
self) {
return self.getParentOperation()->getContext(); },
3112 "Context in which the value lives.")
3116 .def_property_readonly(
3118 [](
PyValue &
self) -> py::object {
3119 MlirValue v =
self.get();
3124 "expected the owner of the value in Python to match that in " 3126 return self.getParentOperation().getObject();
3131 return py::cast(
PyBlock(
self.getParentOperation(), block));
3134 assert(
false &&
"Value must be a block argument or an op result");
3139 return self.get().ptr == other.
get().ptr;
3141 .def(
"__eq__", [](
PyValue &
self, py::object other) {
return false; })
3150 printAccum.
parts.append(
"Value(");
3153 printAccum.
parts.append(
")");
3154 return printAccum.
join();
3157 .def_property_readonly(
"type", [](
PyValue &
self) {
3158 return PyType(
self.getParentOperation()->getContext(),
3161 PyBlockArgument::bind(m);
3162 PyOpResult::bind(m);
3167 py::class_<PySymbolTable>(m,
"SymbolTable", py::module_local())
3168 .def(py::init<PyOperationBase &>())
3173 .def(
"__contains__",
3180 py::arg(
"symbol"), py::arg(
"name"))
3186 py::arg(
"symbol"), py::arg(
"visibility"))
3187 .def_static(
"replace_all_symbol_uses",
3189 py::arg(
"new_symbol"), py::arg(
"from_op"))
3191 py::arg(
"from_op"), py::arg(
"all_sym_uses_visible"),
3192 py::arg(
"callback"));
3195 PyBlockArgumentList::bind(m);
3196 PyBlockIterator::bind(m);
3197 PyBlockList::bind(m);
3198 PyOperationIterator::bind(m);
3199 PyOperationList::bind(m);
3200 PyOpAttributeMap::bind(m);
3201 PyOpOperandList::bind(m);
3202 PyOpResultList::bind(m);
3203 PyRegionIterator::bind(m);
3204 PyRegionList::bind(m);
PySymbolTable(PyOperationBase &operation)
Constructs a symbol table for the given operation.
static MlirStringRef toMlirStringRef(const std::string &s)
MLIR_CAPI_EXPORTED intptr_t mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic)
Returns the number of notes attached to the diagnostic.
Include the generated interface declarations.
static const char kOperationGetAsmDocstring[]
MLIR_CAPI_EXPORTED void mlirContextDetachDiagnosticHandler(MlirContext context, MlirDiagnosticHandlerID id)
Detaches an attached diagnostic handler from the context given its identifier.
PyAttribute insert(PyOperationBase &symbol)
Inserts the given operation into the symbol table.
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 MlirRegion mlirBlockGetParentRegion(MlirBlock block)
Returns the region that contains this block.
virtual PyOperation & getOperation()=0
Each must provide access to the raw Operation.
MLIR_CAPI_EXPORTED bool mlirOperationRemoveAttributeByName(MlirOperation op, MlirStringRef name)
Removes an attribute by name.
void setAttached(const pybind11::object &parent=pybind11::object())
MLIR_CAPI_EXPORTED MlirType mlirAttributeGetType(MlirAttribute attribute)
Gets the type of this attribute.
PyMlirContext * getContext()
MLIR_CAPI_EXPORTED void mlirOperationStateAddAttributes(MlirOperationState *state, intptr_t n, MlirNamedAttribute const *attributes)
static pybind11::object pushInsertionPoint(PyInsertionPoint &insertionPoint)
const char * data
Pointer to the first symbol.
void erase()
Erases the underlying MlirOperation, removes its pointer from the parent context's live operations ma...
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
static bool get(const py::object &)
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule. ...
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyMlirContext from the MlirContext wrapped by a capsule.
static const char kContextGetFusedLocationDocstring[]
static std::vector< PyThreadContextEntry > & getStack()
Gets the thread local stack.
static PyMlirContext * createNewContextForInit()
For the case of a python init (py::init) method, pybind11 is quite strict about needing to return a p...
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
pybind11::object attachDiagnosticHandler(pybind11::object callback)
Attaches a Python callback as a diagnostic handler, returning a registration object (internally a PyD...
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumResults(MlirOperation op)
Returns the number of results of the operation.
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
static MlirLogicalResult mlirLogicalResultSuccess()
Creates a logical result representing a success.
static void setVisibility(PyOperationBase &symbol, const std::string &visibility)
MLIR_CAPI_EXPORTED MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(MlirContext context, MlirDiagnosticHandler handler, void *userData, void(*deleteUserData)(void *))
Attaches the diagnostic handler to the context.
static const char kAppendBlockDocstring[]
MLIR_CAPI_EXPORTED MlirValue mlirBlockGetArgument(MlirBlock block, intptr_t pos)
Returns pos-th argument of the block.
pybind11::object getObject()
static PyAttribute createFromCapsule(pybind11::object capsule)
Creates a PyAttribute from the MlirAttribute wrapped by a capsule.
MLIR_CAPI_EXPORTED void mlirModuleDestroy(MlirModule module)
Takes a module owned by the caller and deletes it.
static pybind11::object createRawSubclass(const pybind11::object &userClass)
static bool mlirAttributeIsNull(MlirAttribute attr)
Checks whether an attribute is null.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetSymbolAttributeName()
Returns the name of the attribute used to store symbol names compatible with symbol tables...
MLIR_CAPI_EXPORTED MlirAttribute mlirDenseI32ArrayGet(MlirContext ctx, intptr_t size, int32_t const *values)
static PyDialectRegistry createFromCapsule(pybind11::object capsule)
MLIR_CAPI_EXPORTED MlirType mlirTypeParseGet(MlirContext context, MlirStringRef type)
Parses a type. The type is owned by the context.
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 ...
MLIR_CAPI_EXPORTED void mlirContextEnableMultithreading(MlirContext context, bool enable)
Set threading mode (must be set to false to mlir-print-ir-after-all).
Used in function arguments when None should resolve to the current context manager set instance...
static bool mlirRegionIsNull(MlirRegion region)
Checks whether a region is null.
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 void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback, void *userData)
Prints a diagnostic using the provided callback.
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
static PyLocation & resolve()
MLIR_CAPI_EXPORTED bool mlirIsGlobalDebugEnabled()
Retuns true if the global debugging flag is set, false otherwise.
ReferrentTy * get() const
static PyInsertionPoint atBlockTerminator(PyBlock &block)
Shortcut to create an insertion point before the block terminator.
MLIR_CAPI_EXPORTED MlirLocation mlirOperationGetLocation(MlirOperation op)
Gets the location of the operation.
PyOperation & getOperation() override
Each must provide access to the raw Operation.
static PyAttribute getSymbolName(PyOperationBase &symbol)
Gets and sets the name of a symbol op.
MLIR_CAPI_EXPORTED MlirOperation mlirModuleGetOperation(MlirModule module)
Views the module as a generic operation.
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
size_t clearLiveOperations()
Clears the live operations map, returning the number of entries which were invalidated.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirType.
static size_t getLiveCount()
Gets the count of live context objects. Used for testing.
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...
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
MLIR_CAPI_EXPORTED void mlirContextSetAllowUnregisteredDialects(MlirContext context, bool allow)
Sets whether unregistered dialects are allowed in this context.
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...
static pybind11::object pushLocation(PyLocation &location)
static const char kContextGetFileLocationDocstring[]
PyOpView(const pybind11::object &operationObject)
llvm::hash_code hash_value(const MPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAttribute.
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context...
MLIR_CAPI_EXPORTED MlirOperation mlirOpResultGetOwner(MlirValue value)
Returns an operation that produced this value as its result.
static void popLocation(PyLocation &location)
PyObjectRef< PyOperation > PyOperationRef
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
MLIR_CAPI_EXPORTED void mlirEnableGlobalDebug(bool enable)
Sets the global debugging flag.
Wrapper around an MlirBlock.
MLIR_CAPI_EXPORTED MlirAttribute mlirOperationGetAttributeByName(MlirOperation op, MlirStringRef name)
Returns an attribute attached to the operation given its name.
Wrapper around an MlirRegion.
Used in function arguments when None should resolve to the current context manager set instance...
MLIR_CAPI_EXPORTED MlirContext mlirAttributeGetContext(MlirAttribute attribute)
Gets the context that an attribute was created with.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetTerminator(MlirBlock block)
Returns the terminator operation in the block or null if no terminator.
Wrapper around an MlirDialect.
MlirDiagnosticSeverity
Severity of a diagnostic.
MLIR_CAPI_EXPORTED void mlirOperationMoveBefore(MlirOperation op, MlirOperation other)
Moves the given operation immediately before the other operation in its parent block.
MLIR_CAPI_EXPORTED MlirBlock mlirBlockArgumentGetOwner(MlirValue value)
Returns the block in which this value is defined as an argument.
static constexpr const bool value
MLIR_CAPI_EXPORTED MlirAttribute mlirSymbolTableInsert(MlirSymbolTable symbolTable, MlirOperation operation)
Inserts the given operation into the given symbol table.
MLIR_CAPI_EXPORTED MlirSymbolTable mlirSymbolTableCreate(MlirOperation operation)
Creates a symbol table for the given operation.
MlirDialect getDialectForKey(const std::string &key, bool attrError)
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 ...
py::object classmethod(Func f, Args... args)
Helper for creating an .
MLIR_CAPI_EXPORTED MlirType mlirValueGetType(MlirValue value)
Returns the type of the value.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationUnknownGet(MlirContext context)
Creates a location with unknown position owned by the given context.
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`...
static PyModuleRef forModule(MlirModule module)
Returns a PyModule reference for the given MlirModule.
PyOperationRef & getParentOperation()
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 MlirContext mlirModuleGetContext(MlirModule module)
Gets the context that a module was created with.
MLIR_CAPI_EXPORTED MlirBlock mlirRegionGetFirstBlock(MlirRegion region)
Gets the first block in the region.
static const char kContextGetCallSiteLocationDocstring[]
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsEnableDebugInfo(MlirOpPrintingFlags flags, bool prettyForm)
Enable printing of debug information.
PyOperationRef & getParentOperation()
PyInsertionPoint(PyBlock &block)
Creates an insertion point positioned after the last operation in the block, but still inside the blo...
PyBlock getBlock()
Gets the owning block or raises an exception if the operation has no owning block.
bool operator==(const PyAttribute &other)
pybind11::object releaseObject()
Releases the object held by this instance, returning it.
MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeParseGet(MlirContext context, MlirStringRef attr)
Parses an attribute. The attribute is owned by the context.
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...
Wrapper around the generic MlirType.
MLIR_CAPI_EXPORTED bool mlirContextGetAllowUnregisteredDialects(MlirContext context)
Returns whether the context allows unregistered dialects.
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
MLIR_CAPI_EXPORTED void mlirContextDestroy(MlirContext context)
Takes an MLIR context owned by the caller and destroys it.
static const char kOperationCreateDocstring[]
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsUseLocalScope(MlirOpPrintingFlags flags)
Use local scope when printing the operation.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
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...
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirLocation.
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirContext.
static PyThreadContextEntry * getTopOfStack()
Stack management.
static PyLocation * getDefaultLocation()
Gets the top of stack location and returns nullptr if not defined.
User-level dialect object.
pybind11::str getMessage()
Represents a diagnostic handler attached to the context.
MLIR_CAPI_EXPORTED MlirBlock mlirModuleGetBody(MlirModule module)
Gets the body of the module, i.e. the only block it contains.
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyOperation from the MlirOperation wrapped by a capsule.
static MlirLogicalResult mlirLogicalResultFailure()
Creates a logical result representing a failure.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetParentOperation(MlirBlock)
Returns the closest surrounding operation that contains this block.
MlirStringCallback getCallback()
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
uint64_t MlirDiagnosticHandlerID
Opaque identifier of a diagnostic handler, useful to detach a handler.
PyLocation * getLocation()
static void walkSymbolTables(PyOperationBase &from, bool allSymUsesVisible, pybind11::object callback)
Walks all symbol tables under and including 'from'.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsDestroy(MlirOpPrintingFlags flags)
Destroys printing flags created with mlirOpPrintingFlagsCreate.
static pybind11::object buildGeneric(const pybind11::object &cls, pybind11::list resultTypeList, pybind11::list operandList, llvm::Optional< pybind11::dict > attributes, llvm::Optional< std::vector< PyBlock *>> successors, llvm::Optional< int > regions, DefaultingPyLocation location, const pybind11::object &maybeIp)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
pybind11::object contextEnter()
Enter and exit the context manager.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
void erase(PyOperationBase &symbol)
Removes the given operation from the symbol table and erases it.
MLIR_CAPI_EXPORTED MlirBlock mlirOperationGetBlock(MlirOperation op)
Gets the block that owns this operation, returning null if the operation is not owned.
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.
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
pybind11::error_already_set SetPyError(PyObject *excClass, const llvm::Twine &message)
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...
static pybind11::object createFromCapsule(pybind11::object capsule)
Creates a PyModule from the MlirModule wrapped by a capsule.
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 void mlirOperationStateAddOperands(MlirOperationState *state, intptr_t n, MlirValue const *operands)
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetResult(MlirOperation op, intptr_t pos)
Returns pos-th result of the operation.
An insertion point maintains a pointer to a Block and a reference operation.
MlirOperation get() const
MLIR_CAPI_EXPORTED MlirValue mlirOperationGetOperand(MlirOperation op, intptr_t pos)
Returns pos-th operand of the operation.
static PyAttribute getVisibility(PyOperationBase &symbol)
Gets and sets the visibility of a symbol op.
MLIR_CAPI_EXPORTED MlirContext mlirLocationGetContext(MlirLocation location)
Gets the context that a location was created with.
User-level object for accessing dialects with dotted syntax such as: ctx.dialect.std.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirNamedAttributeGet(MlirIdentifier name, MlirAttribute attr)
Associates an attribute with the name. Takes ownership of neither.
A logical result value, essentially a boolean with named states.
static PyInsertionPoint atBlockBegin(PyBlock &block)
Shortcut to create an insertion point at the beginning of the block.
Wrapper around the generic MlirAttribute.
void moveBefore(PyOperationBase &other)
static PyMlirContext * getDefaultContext()
Gets the top of stack context and return nullptr if not defined.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateParse(MlirContext context, MlirStringRef module)
Parses a module from the string and transfers ownership to the caller.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationCallSiteGet(MlirLocation callee, MlirLocation caller)
Creates a call site location with a callee and a caller.
Wrapper around an MlirDialectRegistry.
MLIR_CAPI_EXPORTED bool mlirTypeEqual(MlirType t1, MlirType t2)
Checks if two types are equal.
PyDiagnosticHandler(MlirContext context, pybind11::object callback)
static void setSymbolName(PyOperationBase &symbol, const std::string &name)
MLIR_CAPI_EXPORTED MlirIdentifier mlirOperationGetName(MlirOperation op)
Gets the name of the operation as an identifier.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationCreate(MlirOperationState *state)
Creates an operation and transfers ownership to the caller.
MLIR_CAPI_EXPORTED MlirContext mlirOperationGetContext(MlirOperation op)
Gets the context this operation is associated with.
Wrapper for the global LLVM debugging flag.
void populateIRCore(pybind11::module &m)
static bool mlirSymbolTableIsNull(MlirSymbolTable symbolTable)
Returns true if the symbol table is null.
MLIR_CAPI_EXPORTED intptr_t mlirBlockGetNumArguments(MlirBlock block)
Returns the number of arguments of the block.
static const char kContextParseTypeDocstring[]
void detachFromParent()
Detaches the operation from its parent block and updates its state accordingly.
bool operator==(const PyType &other)
size_t length
Length of the fragment.
MLIR_CAPI_EXPORTED MlirModule mlirModuleCreateEmpty(MlirLocation location)
Creates a new, empty module and transfers ownership to the caller.
static PyGlobals & get()
Most code should get the globals via this static accessor.
MLIR_CAPI_EXPORTED bool mlirLocationEqual(MlirLocation l1, MlirLocation l2)
Checks if two locations are equal.
Wrapper around an MlirLocation.
MlirContext get()
Accesses the underlying MlirContext.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
static bool mlirValueIsNull(MlirValue value)
Returns whether the value is null.
MLIR_CAPI_EXPORTED void mlirOpPrintingFlagsPrintGenericOpForm(MlirOpPrintingFlags flags)
Always print operations in the generic form.
MlirStringCallback getCallback()
Accumulates into a python string from a method that accepts an MlirStringCallback.
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 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...
Base class for all objects that directly or indirectly depend on an MlirContext.
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...
MLIR_CAPI_EXPORTED bool mlirContextIsRegisteredOperation(MlirContext context, MlirStringRef name)
Returns whether the given fully-qualified operation (i.e.
pybind11::object getAsm(bool binary, llvm::Optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified)
static py::object createCustomDialectWrapper(const std::string &dialectNamespace, py::object dialectDescriptor)
MLIR_CAPI_EXPORTED MlirContext mlirTypeGetContext(MlirType type)
Gets the context that a type was created with.
static PyValue createFromCapsule(pybind11::object capsule)
Creates a PyValue from the MlirValue wrapped by a capsule.
A pointer to a sized fragment of a string, not necessarily null-terminated.
static const char kDumpDocstring[]
static void popInsertionPoint(PyInsertionPoint &insertionPoint)
A CRTP base class for pseudo-containers willing to support Python-type slicing access on top of index...
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirOperation.
MLIR_CAPI_EXPORTED bool mlirOperationEqual(MlirOperation op, MlirOperation other)
Checks whether two operation handles point to the same operation.
PyMlirContextRef & getContext()
Accesses the context reference.
MLIR_CAPI_EXPORTED MlirStringRef mlirDialectGetNamespace(MlirDialect dialect)
Returns the namespace of the given dialect.
static void replaceAllSymbolUses(const std::string &oldSymbol, const std::string &newSymbol, PyOperationBase &from)
Replaces all symbol uses within an operation.
MLIR_CAPI_EXPORTED void mlirAttributeDump(MlirAttribute attr)
Prints the attribute to the standard error stream.
MLIR_CAPI_EXPORTED bool mlirValueIsAOpResult(MlirValue value)
Returns 1 if the value is an operation result, 0 otherwise.
static const char kContextGetNameLocationDocString[]
An auxiliary class for constructing operations.
MLIR_CAPI_EXPORTED void mlirContextLoadAllAvailableDialects(MlirContext context)
Eagerly loads all available dialects registered with a context, making them available for use for IR ...
Represents a Python MlirNamedAttr, carrying an optional owned name.
static void maybeInsertOperation(PyOperationRef &op, const py::object &maybeIp)
static void set(py::object &o, bool enable)
static PyObject * mlirPythonContextToCapsule(MlirContext context)
Creates a capsule object encapsulating the raw C-API MlirContext.
static void bind(py::module &m)
MLIR_CAPI_EXPORTED MlirRegion mlirOperationGetRegion(MlirOperation op, intptr_t pos)
Returns pos-th region attached to the operation.
MLIR_CAPI_EXPORTED void mlirOperationStateAddOwnedRegions(MlirOperationState *state, intptr_t n, MlirRegion const *regions)
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
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 MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic)
Returns the location at which the diagnostic is reported.
pybind11::tuple getNotes()
static const char kOperationPrintDocstring[]
MLIR_CAPI_EXPORTED MlirBlock mlirBlockGetNextInRegion(MlirBlock block)
Returns the block immediately following the given block in its parent region.
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...
static PyLocation createFromCapsule(pybind11::object capsule)
Creates a PyLocation from the MlirLocation wrapped by a capsule.
static PyOperationRef createDetached(PyMlirContextRef contextRef, MlirOperation operation, pybind11::object parentKeepAlive=pybind11::object())
Creates a detached operation.
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 MlirOperation mlirOperationGetParentOperation(MlirOperation op)
Gets the operation that owns this operation, returning null if the operation is not owned...
MLIR_CAPI_EXPORTED MlirDiagnosticSeverity mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic)
Returns the severity of the diagnostic.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetFirstOperation(MlirBlock block)
Returns the first operation in the block.
Bindings for MLIR symbol tables.
MLIR_CAPI_EXPORTED void mlirTypeDump(MlirType type)
Prints the type to the standard error stream.
MLIR_CAPI_EXPORTED void mlirBlockDetach(MlirBlock block)
Detach a block from the owning region and assume ownership.
MLIR_CAPI_EXPORTED bool mlirAttributeEqual(MlirAttribute a1, MlirAttribute a2)
Checks if two attributes are equal.
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`...
llvm::Optional< pybind11::object > lookupDialectClass(const std::string &dialectNamespace)
Looks up a registered dialect class by namespace.
MLIR_CAPI_EXPORTED MlirStringRef mlirSymbolTableGetVisibilityAttributeName()
Returns the name of the attribute used to store symbol visibility.
void insert(PyOperationBase &operationBase)
Inserts an operation.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
static pybind11::object pushContext(PyMlirContext &context)
MLIR_CAPI_EXPORTED void mlirValueDump(MlirValue value)
Prints the value to the standard error stream.
MlirDiagnosticSeverity getSeverity()
MLIR_CAPI_EXPORTED void mlirOperationStateAddSuccessors(MlirOperationState *state, intptr_t n, MlirBlock const *successors)
MLIR_CAPI_EXPORTED MlirAttribute mlirStringAttrGet(MlirContext ctx, MlirStringRef str)
Creates a string attribute in the given context containing the given string.
static PyType createFromCapsule(pybind11::object capsule)
Creates a PyType from the MlirType wrapped by a capsule.
pybind11::object clone(const pybind11::object &ip)
Clones this operation.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirValue.
static void popContext(PyMlirContext &context)
MLIR_CAPI_EXPORTED intptr_t mlirBlockArgumentGetArgNumber(MlirValue value)
Returns the position of the value in the argument list of its block.
PyNamedAttribute(MlirAttribute attr, std::string ownedName)
Constructs a PyNamedAttr that retains an owned name.
MLIR_CAPI_EXPORTED void mlirOperationSetOperand(MlirOperation op, intptr_t pos, MlirValue newValue)
Sets the pos-th operand of the operation.
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 mlirSymbolTableErase(MlirSymbolTable symbolTable, MlirOperation operation)
Removes the given operation from the symbol table and erases it.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumRegions(MlirOperation op)
Returns the number of regions attached to the given operation.
MLIR_CAPI_EXPORTED MlirIdentifier mlirIdentifierGet(MlirContext context, MlirStringRef str)
Gets an identifier with the given string value.
MLIR_CAPI_EXPORTED bool mlirValueIsABlockArgument(MlirValue value)
Returns 1 if the value is a block argument, 0 otherwise.
A PyOpView is equivalent to the C++ "Op" wrappers: these are the basis for providing more instance-sp...
llvm::Optional< pybind11::object > lookupRawOpViewClass(llvm::StringRef operationName)
Looks up a registered raw OpView class by operation name.
MlirNamedAttribute namedAttr
static const char kOperationStrDunderDocstring[]
size_t getLiveOperationCount()
Gets the count of live operations associated with this context.
MLIR_CAPI_EXPORTED MlirDiagnostic mlirDiagnosticGetNote(MlirDiagnostic diagnostic, intptr_t pos)
Returns pos-th note attached to the diagnostic.
MLIR_CAPI_EXPORTED MlirStringRef mlirIdentifierStr(MlirIdentifier ident)
Gets the string value of the identifier.
Wrapper around the generic MlirValue.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumOperands(MlirOperation op)
Returns the number of operands of the operation.
void moveAfter(PyOperationBase &other)
Moves the operation before or after the other operation.
PyObjectRef< PyModule > PyModuleRef
static PyMlirContext & resolve()
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 MlirOperation mlirOperationGetNextInBlock(MlirOperation op)
Returns an operation immediately following the given operation it its enclosing block.
PyInsertionPoint * getInsertionPoint()
llvm::Optional< PyOperationRef > getParentOperation()
Gets the parent operation or raises an exception if the operation has no parent.
void detach()
Detaches the handler. Does nothing if not attached.
PyOperationRef & getParentOperation()
MLIR_CAPI_EXPORTED MlirRegion mlirRegionCreate()
Creates a new empty region and transfers ownership to the caller.
MLIR_CAPI_EXPORTED bool mlirOperationVerify(MlirOperation op)
Verify the operation and return true if it passes, false if it fails.
MLIR_CAPI_EXPORTED void mlirOperationDump(MlirOperation op)
Prints an operation to stderr.
static const char kValueDunderStrDocstring[]
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
MLIR_CAPI_EXPORTED intptr_t mlirOperationGetNumAttributes(MlirOperation op)
Returns the number of attributes attached to the operation.
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
size_t getLiveModuleCount()
Gets the count of live modules associated with this context.
Accumulates int a python file-like object, either writing text (default) or binary.
pybind11::object getOperationObject()
MLIR_CAPI_EXPORTED void mlirOperationStateAddResults(MlirOperationState *state, intptr_t n, MlirType const *results)
Adds a list of components to the operation state.
pybind11::object contextEnter()
MLIR_CAPI_EXPORTED MlirOpPrintingFlags mlirOpPrintingFlagsCreate()
Creates new printing flags with defaults, intended for customization.
MLIR_CAPI_EXPORTED void mlirRegionAppendOwnedBlock(MlirRegion region, MlirBlock block)
Takes a block owned by the caller and appends it to the given region.
pybind11::object contextEnter()
Enter and exit the context manager.
MLIR_CAPI_EXPORTED MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos)
Return pos-th attribute of the operation.
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 MlirContext mlirContextCreate()
Creates an MLIR context and transfers its ownership to the caller.
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
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 void mlirEmitError(MlirLocation location, const char *message)
Emits an error at the given location through the diagnostics engine.
static bool mlirDialectIsNull(MlirDialect dialect)
Checks if the dialect is null.
MLIR_CAPI_EXPORTED MlirOperation mlirOperationClone(MlirOperation op)
Creates a deep copy of an operation.
pybind11::object contextEnter()
Enter and exit the context manager.
MLIR_CAPI_EXPORTED void mlirBlockArgumentSetType(MlirValue value, MlirType type)
Sets the type of the block argument to the given type.
Tracks an entry in the thread context stack.
MLIR_CAPI_EXPORTED void mlirOperationDestroy(MlirOperation op)
Takes an operation owned by the caller and destroys it.
Base class for PyOperation and PyOpView which exposes the primary, user visible methods for manipulat...
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
MLIR_CAPI_EXPORTED MlirOperationState mlirOperationStateGet(MlirStringRef name, MlirLocation loc)
Constructs an operation state from a name and a location.
static PyInsertionPoint * getDefaultInsertionPoint()
Gets the top of stack insertion point and return nullptr if not defined.
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
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...
pybind11::object getCapsule()
static pybind11::object create(const std::string &name, llvm::Optional< std::vector< PyType *>> results, llvm::Optional< std::vector< PyValue *>> operands, llvm::Optional< pybind11::dict > attributes, llvm::Optional< std::vector< PyBlock *>> successors, int regions, DefaultingPyLocation location, const pybind11::object &ip)
Creates an operation. See corresponding python docstring.
static const char kModuleParseDocstring[]
PyModule(PyModule &)=delete
void contextExit(const pybind11::object &excType, const pybind11::object &excVal, const pybind11::object &excTb)
Python class mirroring the C MlirDiagnostic struct.
MLIR_CAPI_EXPORTED MlirLocation mlirLocationNameGet(MlirContext context, MlirStringRef name, MlirLocation childLoc)
Creates a name location owned by the given context.
static bool mlirOperationIsNull(MlirOperation op)
Checks whether the underlying operation is null.
static bool mlirTypeIsNull(MlirType type)
Checks whether a type is null.
void print(pybind11::object fileObject, bool binary, llvm::Optional< int64_t > largeElementsLimit, bool enableDebugInfo, bool prettyDebugInfo, bool printGenericOpForm, bool useLocalScope, bool assumeVerified)
Implements the bound 'print' method and helps with others.
static bool mlirModuleIsNull(MlirModule module)
Checks whether a module is null.
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirModule.
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
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...