summaryrefslogtreecommitdiff
path: root/mlir/lib/CAPI/IR/IR.cpp
AgeCommit message (Collapse)Author
2025-11-21[mlir][py][c] Enable setting block arg locations. (#169033)Jacques Pienaar
This enables changing the location of a block argument. Follows the approach for updating type of block arg.
2025-10-01[MLIR][Python] expose Operation::setLoc (#161594)Maksim Levental
2025-09-02[MLIR][Python] fix operation hashing (#156514)Maksim Levental
https://github.com/llvm/llvm-project/pull/155114 broke op hashing (because the python objects ceased to be reference equivalent). This PR fixes by binding `OperationEquivalence::computeHash`.
2025-09-01[MLIR][Python] remove `liveOperations` (#155114)Maksim Levental
Historical context: `PyMlirContext::liveOperations` was an optimization meant to cut down on the number of Python object allocations and (partially) a mechanism for updating validity of ops after transformation. E.g. during walking/transforming the AST. See original patch [here](https://reviews.llvm.org/D87958). Inspired by a [renewed](https://github.com/llvm/llvm-project/pull/139721#issuecomment-3217131918) interest in https://github.com/llvm/llvm-project/pull/139721 (which has become a little stale...) <p align="center"> <img width="504" height="375" alt="image" src="https://github.com/user-attachments/assets/0daad562-d3d1-4876-8d01-5dba382ab186" /> </p> In the previous go-around (https://github.com/llvm/llvm-project/pull/92631) there were two issues which have been resolved 1. ops that were "fetched" under a root op which has been transformed are no longer reported as invalid. We simply "[formally forbid](https://github.com/llvm/llvm-project/pull/92631#issuecomment-2119397018)" this; 2. `Module._CAPICreate(module_capsule)` must now be followed by a `module._clear_mlir_module()` to prevent double-freeing of the actual `ModuleOp` object (i.e. calling the dtor on the `OwningOpRef<ModuleOp>`): ```python module = ... module_dup = Module._CAPICreate(module._CAPIPtr) module._clear_mlir_module() ``` - **the alternative choice** here is to remove the `Module._CAPICreate` API altogether and replace it with something like `Module._move(module)` which will do both `Module._CAPICreate` and `module._clear_mlir_module`. Note, the other approach I explored last year was a [weakref system](https://github.com/llvm/llvm-project/pull/97340) for `mlir::Operation` which would effectively hoist this `liveOperations` thing into MLIR core. Possibly doable but I now believe it's a bad idea. The other potentially breaking change is `is`, which checks object equality rather than value equality, will now report `False` because we are always allocating `new` Python objects (ie that's the whole point of this change). Users wanting to check equality for `Operation` and `Module` should use `==`.
2025-07-23[mlir][python,CAPI] expose Op::isBeforeInBlock (#150271)Maksim Levental
2025-06-23[mlir][python] bind block predecessors and successors (#145116)Maksim Levental
bind `block.getSuccessor` and `block.getPredecessors`.
2025-03-10[MLIR][py] Add PyThreadPool as wrapper around MlirLlvmThreadPool in MLIR ↵vfdev
python bindings (#130109) In some projects like JAX ir.Context are used with disabled multi-threading to avoid caching multiple threading pools: https://github.com/jax-ml/jax/blob/623865fe9538100d877ba9d36f788d0f95a11ed2/jax/_src/interpreters/mlir.py#L606-L611 However, when context has enabled multithreading it also uses locks on the StorageUniquers and this can be helpful to avoid data races in the multi-threaded execution (for example with free-threaded cpython, https://github.com/jax-ml/jax/issues/26272). With this PR user can enable the multi-threading: 1) enables additional locking and 2) set a shared threading pool such that cached contexts can have one global pool.
2025-03-10[mlir][CAPI][python] bind CallSiteLoc, FileLineColRange, FusedLoc, NameLoc ↵Maksim Levental
(#129351) This PR extends the python bindings for CallSiteLoc, FileLineColRange, FusedLoc, NameLoc with field accessors. It also adds the missing `value.location` accessor. I also did some "spring cleaning" here (`cast` -> `dyn_cast`) after running into some of my own illegal casts.
2025-03-04[mlir][py] Plumb OpPrintingFlags::printNameLocAsPrefix() through the ↵Jacques Pienaar
C/Python APIs (#129607)
2025-02-12[mlir] Python: Parse ModuleOp from file path (#126572)Nikhil Kalra
For extremely large models, it may be inefficient to load the model into memory in Python prior to passing it to the MLIR C APIs for deserialization. This change adds an API to parse a ModuleOp directly from a file path. Re-lands [4e14b8a](https://github.com/llvm/llvm-project/commit/4e14b8afb44af58ab7073bb8c0b52875599b0ae1).
2025-02-10Revert "[mlir] Python: Parse ModuleOp from file path" (#126482)Mehdi Amini
Reverts llvm/llvm-project#125736 The gcc7 Bot is broken at the moment.
2025-02-05[mlir] Python: Parse ModuleOp from file path (#125736)Nikhil Kalra
For extremely large models, it may be inefficient to load the model into memory in Python prior to passing it to the MLIR C APIs for deserialization. This change adds an API to parse a ModuleOp directly from a file path.
2025-01-22[mlir] Add C and Python interface for file range (#123276)Jacques Pienaar
Plumbs through creating file ranges to C and Python.
2024-11-19[mlir,python] Expose replaceAllUsesExcept to Python bindings (#115850)Perry Gibson
Problem originally described in [the forums here](https://discourse.llvm.org/t/mlir-python-expose-replaceallusesexcept/83068/1). Using the MLIR Python bindings, the method [`replaceAllUsesWith`](https://mlir.llvm.org/doxygen/classmlir_1_1Value.html#ac56b0fdb6246bcf7fa1805ba0eb71aa2) for `Value` is exposed, e.g., ```python orig_value.replace_all_uses_with( new_value ) ``` However, in my use-case I am separating a block into multiple blocks, so thus want to exclude certain Operations from having their Values replaced (since I want them to diverge). Within Value, we have [`replaceAllUsesExcept`](https://mlir.llvm.org/doxygen/classmlir_1_1Value.html#a9ec8d5c61f8a6aada4062f609372cce4), where we can pass the Operations which should be skipped. This is not currently exposed in the Python bindings: this PR fixes this. Adds `replace_all_uses_except`, which works with individual Operations, and lists of Operations.
2024-10-18eliminating g++ warnings (#105520)Frank Schlimbach
Eliminating g++ warnings. Mostly declaring "[[maybe_unused]]", adding return statements where missing and fixing casts. @rengolin --------- Co-authored-by: Benjamin Maxwell <macdue@dueutil.tech> Co-authored-by: Renato Golin <rengolin@systemcall.eu>
2024-07-08[mlir][c-api] expose elideLargeResourceString (#98050)Brendan Hansknecht
Expose `elideLargeResourceString` to the c api. This was done in the same way as `elideLargeElementsAttrs` is exposed. The docs were grabbed from the `elideLargeResourceString` method and forwarded here.
2024-06-20[mlir] Expose skipRegions option for Op printing in the C and Python ↵Jonas Rickert
bindings (#96150) The MLIR C and Python Bindings expose various methods from `mlir::OpPrintingFlags` . This PR adds a binding for the `skipRegions` method, which allows to skip the printing of Regions when printing Ops. It also exposes this option as parameter in the python `get_asm` and `print` methods
2024-06-05[mlir][python]Python Bindings for select edit operations on Block arguments ↵Sandeep Dasgupta
(#94305) The PR implements MLIR Python Bindings for a few simple edit operations on Block arguments, namely, `add_argument`, `erase_argument`, and `erase_arguments`.
2024-04-17[mlir][python] Add `walk` method to PyOperationBase (#87962)Hideto Ueno
This commit adds `walk` method to PyOperationBase that uses a python object as a callback, e.g. `op.walk(callback)`. Currently callback must return a walk result explicitly. We(SiFive) have implemented walk method with python in our internal python tool for a while. However the overhead of python is expensive and it didn't scale well for large MLIR files. Just replacing walk with this version reduced the entire execution time of the tool by 30~40% and there are a few configs that the tool takes several hours to finish so this commit significantly improves tool performance.
2024-03-02Split the llvm::ThreadPool into an abstract base class and an implementation ↵Mehdi Amini
(#82094) This decouples the public API used to enqueue tasks and wait for completion from the actual implementation, and opens up the possibility for clients to set their own thread pool implementation for the pool. https://discourse.llvm.org/t/construct-threadpool-from-vector-of-existing-threads/76883
2024-01-03[mlir] fix Operation::getDiscardableAttrs in absence of properties (#76816)Oleksandr "Alex" Zinenko
When properties are not enabled in an operation, inherent attributes are stored in the common dictionary with discardable attributes. However, `getDiscardableAttrs` and `getDiscardableAttrDictionary` were returning the entire dictionary, making the caller mistakenly believe that all inherent attributes are discardable. Fix this by filtering out attributes whose names are registered with the operation, i.e., inherent attributes. This requires an API change so `getDiscardableAttrs` returns a filter range.
2023-12-11[mlir][CAPI] Add mlirOpOperandGetValue (#75032)Shenghang Tsai
2023-11-03[mlir][c] Add mlirOperationPrintWithStateJacques Pienaar
Enable passing in MlirAsmState optionally (allow for passing in null) to allow using the more efficient print calling API. The existing print behavior results in a new AsmState is implicitly created by walking the parent op and renumbering values. This makes the cost more explicit and avoidable (by reusing an AsmState).
2023-10-20[MLIR][python bindings] invalidate ops after PassManager run (#69746)Maksim Levental
Fixes https://github.com/llvm/llvm-project/issues/69730 (also see https://reviews.llvm.org/D155543). There are two things outstanding (why I didn't land before): 1. add some C API tests for `mlirOperationWalk`; 2. potentially refactor how the invalidation in `run` works; the first version of the code looked like this: ```cpp if (invalidateOps) { auto *context = op.getOperation().getContext().get(); MlirOperationWalkCallback invalidatingCallback = [](MlirOperation op, void *userData) { PyMlirContext *context = static_cast<PyMlirContext *>(userData); context->setOperationInvalid(op); }; auto numRegions = mlirOperationGetNumRegions(op.getOperation().get()); for (int i = 0; i < numRegions; ++i) { MlirRegion region = mlirOperationGetRegion(op.getOperation().get(), i); for (MlirBlock block = mlirRegionGetFirstBlock(region); !mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) for (MlirOperation childOp = mlirBlockGetFirstOperation(block); !mlirOperationIsNull(childOp); childOp = mlirOperationGetNextInBlock(childOp)) mlirOperationWalk(childOp, invalidatingCallback, context, MlirWalkPostOrder); } } ``` This is verbose and ugly but it has the important benefit of not executing `mlirOperationEqual(rootOp->get(), op)` for every op underneath the root op. Supposing there's no desire for the slightly more efficient but highly convoluted approach, I can land this "posthaste". But, since we have eyes on this now, any suggestions or approaches (or needs/concerns) are welcome.
2023-10-02[mlir][CAPI, python bindings] Expose `Operation::setSuccessor` (#67922)Maksim Levental
This is useful for emitting (using the python bindings) `cf.br` to blocks that are declared lexically post block creation.
2023-09-26Simplify diagnostic error management for MLIR properties API (NFC) (#67409)Mehdi Amini
This is a follow-up to 8c2bff1ab929 which lazy-initialized the diagnostic and removed the need to dynamically abandon() an InFlightDiagnostic. This further simplifies the code to not needed to return a reference to an InFlightDiagnostic and instead eagerly emit errors. Also use `emitError` as name instead of `getDiag` which seems more explicit and in-line with the common usage.
2023-09-26[MLIR] Introduce new C bindings to differentiate between discardable and ↵Mehdi Amini
inherent attributes (#66332) This is part of the transition toward properly splitting the two groups. This only introduces new C APIs, the Python bindings are unaffected. No API is removed.
2023-09-18[mlir][c] Expose AsmState. (#66693)Jacques Pienaar
Enable usage where capturing AsmState is good (e.g., avoiding creating AsmState over and over again when walking IR and printing). This also only changes one C API to verify plumbing. But using the AsmState makes the cost more explicit than the flags interface (which hides the traversals and construction here) and also enables a more efficient usage C side.
2023-09-11Lazy initialize diagnostic when handling MLIR properties (#65868)Mehdi Amini
Instead of eagerly creating a diagnostic that will be discarded in the normal case, switch to lazy initialization on error.
2023-07-26add set_type to ir.Valuemax
Differential Revision: https://reviews.llvm.org/D156289
2023-07-24Update ODS variadic segments "magic" attributes to use native PropertiesMehdi Amini
The operand_segment_sizes and result_segment_sizes Attributes are now inlined in the operation as native propertie. We continue to support building an Attribute on the fly for `getAttr("operand_segment_sizes")` and setting the property from an attribute with `setAttr("operand_segment_sizes", attr)`. A new bytecode version is introduced to support backward compatibility and backdeployments. Differential Revision: https://reviews.llvm.org/D155919
2023-07-23[mlir] Enable converting properties during C createJacques Pienaar
This enables querying properties passed as attributes during construction time. In particular needed for type inference where the Operation has not been created at this point. This allows Python construction of operations whose type inference depends on properties. Differential Revision: https://reviews.llvm.org/D156070
2023-07-12[MLIR] Add a number of methods to the C APIAdam Paszke
Those include: - mlirFuncSetArgAttr - mlirOperationSetOperands - mlirRegionTakeBody - mlirBlockInsertArgument Reviewed By: ftynse, jpienaar Differential Revision: https://reviews.llvm.org/D155091
2023-07-10[mlir][CAPI] Expose the rest of MLIRContext's constructorsKrzysztof Drewniak
It's recommended practice that people calling MLIR in a loop pre-create a LLVM ThreadPool and a dialect registry and then explicitly pass those into a MLIRContext for each compilation. However, the C API does not expose the functions needed to follow this recommendation from a project that isn't calling MLIR's C++ dilectly. Add the necessary APIs to mlir-c, including a wrapper around LLVM's ThreadPool struct (so as to avoid having to amend or re-export parts of the LLVM API). Reviewed By: makslevental Differential Revision: https://reviews.llvm.org/D153593
2023-06-07[MLIR][python bindings] TypeCasters for Attributesmax
Differential Revision: https://reviews.llvm.org/D151840
2023-05-26[MLIR][python bindings] Add TypeCaster for returning refined types from ↵max
python APIs depends on D150839 This diff uses `MlirTypeID` to register `TypeCaster`s (i.e., `[](PyType pyType) -> DerivedTy { return pyType; }`) for all concrete types (i.e., `PyConcrete<...>`) that are then queried for (by `MlirTypeID`) and called in `struct type_caster<MlirType>::cast`. The result is that anywhere an `MlirType mlirType` is returned from a python binding, that `mlirType` is automatically cast to the correct concrete type. For example: ``` c0 = arith.ConstantOp(f32, 0.0) # CHECK: F32Type(f32) print(repr(c0.result.type)) unranked_tensor_type = UnrankedTensorType.get(f32) unranked_tensor = tensor.FromElementsOp(unranked_tensor_type, [c0]).result # CHECK: UnrankedTensorType print(type(unranked_tensor.type).__name__) # CHECK: UnrankedTensorType(tensor<*xf32>) print(repr(unranked_tensor.type)) ``` This functionality immediately extends to typed attributes (i.e., `attr.type`). The diff also implements similar functionality for `mlir_type_subclass`es but in a slightly different way - for such types (which have no cpp corresponding `class` or `struct`) the user must provide a type caster in python (similar to how `AttrBuilder` works) or in cpp as a `py::cpp_function`. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D150927
2023-05-12[mlir] Update method cast calls to function callsTres Popp
The MLIR classes Type/Attribute/Operation/Op/Value support cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast functionality in addition to defining methods with the same name. This change begins the migration of uses of the method to the corresponding function call as has been decided as more consistent. Note that there still exist classes that only define methods directly, such as AffineExpr, and this does not include work currently to support a functional cast/isa call. Context: * https://mlir.llvm.org/deprecation/ at "Use the free function variants for dyn_cast/cast/isa/…" * Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443 Implementation: This follows a previous patch that updated calls `op.cast<T>()-> cast<T>(op)`. However some cases could not handle an unprefixed `cast` call due to occurrences of variables named cast, or occurring inside of class definitions which would resolve to the method. All C++ files that did not work automatically with `cast<T>()` are updated here to `llvm::cast` and similar with the intention that they can be easily updated after the methods are removed through a find-replace. See https://github.com/llvm/llvm-project/compare/main...tpopp:llvm-project:tidy-cast-check for the clang-tidy check that is used and then update printed occurrences of the function to include `llvm::` before. One can then run the following: ``` ninja -C $BUILD_DIR clang-tidy run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\ -export-fixes /tmp/cast/casts.yaml mlir/*\ -header-filter=mlir/ -fix rm -rf $BUILD_DIR/tools/mlir/**/*.inc ``` Differential Revision: https://reviews.llvm.org/D150348
2023-05-08[MLIR][python bindings] Add `PyValue.print_as_operand` (`Value::printAsOperand`)max
Useful for easier debugging (no need to regex out all of the stuff around the id). Differential Revision: https://reviews.llvm.org/D149902
2023-05-01Introduce MLIR Op PropertiesMehdi Amini
This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Recommit d572cd1b067f after fixing python bindings build. Differential Revision: https://reviews.llvm.org/D141742
2023-05-01Revert "Introduce MLIR Op Properties"Mehdi Amini
This reverts commit d572cd1b067f1177a981a4711bf2e501eaa8117b. Some bots are broken and investigation is needed before relanding.
2023-05-01Introduce MLIR Op PropertiesMehdi Amini
This new features enabled to dedicate custom storage inline within operations. This storage can be used as an alternative to attributes to store data that is specific to an operation. Attribute can also be stored inside the properties storage if desired, but any kind of data can be present as well. This offers a way to store and mutate data without uniquing in the Context like Attribute. See the OpPropertiesTest.cpp for an example where a struct with a std::vector<> is attached to an operation and mutated in-place: struct TestProperties { int a = -1; float b = -1.; std::vector<int64_t> array = {-33}; }; More complex scheme (including reference-counting) are also possible. The only constraint to enable storing a C++ object as "properties" on an operation is to implement three functions: - convert from the candidate object to an Attribute - convert from the Attribute to the candidate object - hash the object Optional the parsing and printing can also be customized with 2 extra functions. A new options is introduced to ODS to allow dialects to specify: let usePropertiesForAttributes = 1; When set to true, the inherent attributes for all the ops in this dialect will be using properties instead of being stored alongside discardable attributes. The TestDialect showcases this feature. Another change is that we introduce new APIs on the Operation class to access separately the inherent attributes from the discardable ones. We envision deprecating and removing the `getAttr()`, `getAttrsDictionary()`, and other similar method which don't make the distinction explicit, leading to an entirely separate namespace for discardable attributes. Differential Revision: https://reviews.llvm.org/D141742
2023-04-30[mlir][bytecode] Return error instead of min versionJacques Pienaar
Can't return a well-formed IR output while enabling version to be bumped up during emission. Previously it would return min version but potentially invalid IR which was confusing, instead make it return error and abort immediately instead. Differential Revision: https://reviews.llvm.org/D149569
2023-04-29[mlir][bytecode] Allow client to specify a desired version.Jacques Pienaar
Add method to set a desired bytecode file format to generate. Change write method to be able to return status including the minimum bytecode version needed by reader. This enables generating an older version of the bytecode (not dialect ops, attributes or types). But this does not guarantee that an older version can always be generated, e.g., if a dialect uses a new encoding only available at later bytecode version. This clamps setting to at most current version. Differential Revision: https://reviews.llvm.org/D146555
2023-04-26[MLIR][python bindings] Reimplement `replace_all_uses_with` on `PyValue`max
Differential Revision: https://reviews.llvm.org/D149261
2023-04-25Revert "[MLIR][python bindings] implement `replace_all_uses_with` on `PyValue`"max
This reverts commit 3bab7cb089d92cc7025ebc57ef3a74d3ce94ecd8 because it breaks sanitizers. Differential Revision: https://reviews.llvm.org/D149188
2023-04-24[MLIR][python bindings] implement `replace_all_uses_with` on `PyValue`max
Differential Revision: https://reviews.llvm.org/D148816
2023-03-01[mlir][python] Add generic operation parse APIsrkayaith
Currently the bindings only allow for parsing IR with a top-level `builtin.module` op, since the parse APIs insert an implicit module op. This change adds `Operation.parse`, which returns whatever top-level op is actually in the source. To simplify parsing of specific operations, `OpView.parse` is also added, which handles the error checking for `OpView` subclasses. Reviewed By: ftynse, stellaraccident Differential Revision: https://reviews.llvm.org/D143352
2023-02-26[mlir][python] Don't emit diagnostics when printing invalid opsRahul Kayaith
The asm printer grew the ability to automatically fall back to the generic format for invalid ops, so this logic doesn't need to be in the bindings anymore. The printer already handles supressing diagnostics that get emitted while checking if the op is valid. Reviewed By: mehdi_amini, stellaraccident Differential Revision: https://reviews.llvm.org/D144805
2023-01-24[MLIR] Expose LocationAttrs in the C APIAndrew Young
This patch adds three functions to the C API: - mlirAttributeIsALocation: returns true if the attribute is a LocationAttr, false otherwise. - mlirLocationGetAttribute: returns the underlying LocationAttr of a Location. - mlirLocationFromAttribute: gets a Location from a LocationAttr. Reviewed By: mikeurbach, Mogball Differential Revision: https://reviews.llvm.org/D142182
2023-01-14[mlir] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to remove #include "llvm/ADT/Optional.h". This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716