Commit Graph

269 Commits

Author SHA1 Message Date
Kazu Hirata
7d9f9938ff [Transform] Avoid repeated hash lookups (NFC) (#111620) 2024-10-09 06:43:35 -07:00
Mehdi Amini
6c7a3f80e7 Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef (#110938)
This macros is always defined: either 0 or 1. The correct pattern is to
use #if.

Re-apply #110185 with more fixes for debug build with the ABI breaking
checks disabled.
2024-10-03 01:24:14 +02:00
Christopher Di Bella
45ad1ac4a3 Revert "Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if inst… (#110923)
…ead of #ifdef (#110883)"

This reverts commit 1905cdbf4e, which
causes lots of failures where LLVM doesn't have the right header guards.
The errors can be seen on
[BuildKite](https://buildkite.com/llvm-project/upstream-bazel/builds/112362#01924eae-231c-4d06-ba87-2c538cf40e04),
where the source uses `#ifndef NDEBUG`, but the content in question is
defined when `LLVM_ENABLE_ABI_BREAKING_CHECKS == 1`.

For example, `llvm/include/llvm/Support/GenericDomTreeConstruction.h`
has the following:

```cpp
// Helper struct used during edge insertions.
struct InsertionInfo {
  // ...
#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
  SmallVector<TreeNodePtr, 8> VisitedUnaffected;
#endif
};

// ...

InsertionInfo II;
// ...
#ifndef NDEBUG
            II.VisitedUnaffected.push_back(SuccTN);
#endif
```
2024-10-02 13:54:09 -07:00
Mehdi Amini
1905cdbf4e Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef (#110883)
This macros is always defined: either 0 or 1. The correct pattern is to
use #if.

Reapply https://github.com/llvm/llvm-project/pull/110185 with fixes.
2024-10-02 18:43:16 +02:00
Mehdi Amini
68ddd6c80e Revert "Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef" (#110310)
Reverts llvm/llvm-project#110185

There are inconsistencies in some of these macros, which unfortunately
isn't caught by a single upstream bot.
2024-09-27 20:34:14 +02:00
Mehdi Amini
5e98136679 Fix LLVM_ENABLE_ABI_BREAKING_CHECKS macro check: use #if instead of #ifdef (#110185)
This macros is always defined: either 0 or 1. The correct pattern is to
use #if.
2024-09-27 11:52:22 +02:00
Youngsuk Kim
123e8c735d [mlir] Don't call llvm::raw_string_ostream::flush() (NFC)
Don't call raw_string_ostream::flush(), which is essentially a no-op.
As specified in the docs, raw_string_ostream is always unbuffered.
( 65b13610a5 for further reference )
2024-09-22 15:37:34 -05:00
JOE1994
884221eddb [mlir] Tidy uses of llvm::raw_stream_ostream (NFC)
As specified in the docs,
1) raw_string_ostream is always unbuffered and
2) the underlying buffer may be used directly

( 65b13610a5 for further reference )

* Don't call raw_string_ostream::flush(), which is essentially a no-op.
* Avoid unneeded calls to raw_string_ostream::str(), to avoid excess indirection.
2024-09-16 23:23:25 -04:00
Jianjian Guan
e323b40bf1 [NFC][mlir] Simplify code (#108346) 2024-09-13 10:31:30 +08:00
Kazu Hirata
67e7f05aa0 [Dialect] Avoid repeated hash lookups (NFC) (#108319) 2024-09-12 00:52:17 -07:00
Amy Wang
6634d44e5e [MLIR][Transform] Allow stateInitializer and stateExporter for applyTransforms (#101186)
This is discussed in RFC:

https://discourse.llvm.org/t/rfc-making-the-constructor-of-the-transformstate-class-protected/80377
2024-09-09 10:57:13 -04:00
Nikhil Kalra
84cc1865ef [mlir] Support DialectRegistry extension comparison (#101119)
`PassManager::run` loads the dependent dialects for each pass into the
current context prior to invoking the individual passes. If the
dependent dialect is already loaded into the context, this should be a
no-op. However, if there are extensions registered in the
`DialectRegistry`, the dependent dialects are unconditionally registered
into the context.

This poses a problem for dynamic pass pipelines, however, because they
will likely be executing while the context is in an immutable state
(because of the parent pass pipeline being run).

To solve this, we'll update the extension registration API on
`DialectRegistry` to require a type ID for each extension that is
registered. Then, instead of unconditionally registered dialects into a
context if extensions are present, we'll check against the extension
type IDs already present in the context's internal `DialectRegistry`.
The context will only be marked as dirty if there are net-new extension
types present in the `DialectRegistry` populated by
`PassManager::getDependentDialects`.

Note: this PR removes the `addExtension` overload that utilizes
`std::function` as the parameter. This is because `std::function` is
copyable and potentially allocates memory for the contained function so
we can't use the function pointer as the unique type ID for the
extension.

Downstream changes required:
- Existing `DialectExtension` subclasses will need a type ID to be
registered for each subclass. More details on how to register a type ID
can be found here:
8b68e06731/mlir/include/mlir/Support/TypeID.h (L30)
- Existing uses of the `std::function` overload of `addExtension` will
need to be refactored into dedicated `DialectExtension` classes with
associated type IDs. The attached `std::function` can either be inlined
into or called directly from `DialectExtension::apply`.

---------

Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
2024-08-06 01:32:36 +02:00
Kazu Hirata
5262865aac [mlir] Construct SmallVector with ArrayRef (NFC) (#101896) 2024-08-04 11:43:05 -07:00
Guillermo Callaghan
d1ca1d017f [mlir] Makes zip_shortest an optional keyword in transform.foreach (#98492)
This PR addresses a [comment] made by @ftynse about the syntax for
`ForeachOp`. The syntax was modified by @muneebkhan85 in #82792, where
the attribute dictionary was moved to the middle.
This patch moves it back to its original place at the end. And
introduces an optional keyword for `zip_shortest`.

[comment]:
https://github.com/llvm/llvm-project/pull/82792#pullrequestreview-2132814144
2024-07-19 17:36:12 +02:00
Ramkumar Ramachandra
db791b278a mlir/LogicalResult: move into llvm (#97309)
This patch is part of a project to move the Presburger library into
LLVM.
2024-07-02 10:42:33 +01:00
Kazu Hirata
b7b337fb91 [mlir] Use llvm::unique (NFC) (#96415) 2024-06-24 11:54:02 -07:00
muneebkhan85
a9efcbf490 [MLIR] Add continuous tiling to transform dialect (#82792)
This patch enables continuous tiling of a target structured op using
diminishing tile sizes. In cases where the tensor dimensions are not
exactly divisible by the tile size, we are left with leftover tensor
chunks that are irregularly tiled. This approach enables tiling of the
leftover chunk with a smaller tile size and repeats this process
recursively using exponentially diminishing tile sizes. This eventually
generates a chain of loops that apply tiling using diminishing tile
sizes.

Adds `continuous_tile_sizes` op to the transform dialect. This op, when
given a tile size and a dimension, computes a series of diminishing tile
sizes that can be used to tile the target along the given dimension.
Additionally, this op also generates a series of chunk sizes that the
corresponding tile sizes should be applied to along the given dimension.

Adds `multiway` attribute to `transform.structured.split` that enables
multiway splitting of a single target op along the given dimension, as
specified in a list enumerating the chunk sizes.
2024-06-21 16:39:43 +02:00
donald chen
2c1ae801e1 [mlir][side effect] refactor(*): Include more precise side effects (#94213)
This patch adds more precise side effects to the current ops with memory
effects, allowing us to determine which OpOperand/OpResult/BlockArgument
the
operation reads or writes, rather than just recording the reading and
writing
of values. This allows for convenient use of precise side effects to
achieve
analysis and optimization.

Related discussions:
https://discourse.llvm.org/t/rfc-add-operandindex-to-sideeffect-instance/79243
2024-06-19 22:10:34 +08:00
Rolf Morel
d462bf6875 [mlir][Transform] Extend transform.foreach to take multiple arguments (#93705)
Changes transform.foreach's interface to take multiple arguments, e.g.
transform.foreach %ops1, %ops2, %params : ... { ^bb0(%op1, %op2,
%param): BODY } The semantics are that the payloads for these handles
get iterated over as if the payloads have been zipped-up together - BODY
gets executed once for each such tuple. The documentation explains that
this implementation requires that the payloads have the same length.

This change also enables the target argument(s) to be any op/value/param
handle.

The added test cases demonstrate some use cases for this change.
2024-06-14 17:02:47 +02:00
Daniel Kuts
4527adc500 Fix null pointer dereference in logging in mlir TransformOps (#92237)
A variable `typeConverterOp` may be nullptr after dynamic cast. There is
a security guard for this, but during logging error message the variable
getting dereferenced.
Found with static analysis.
2024-05-15 08:15:13 -07:00
srcarroll
2c1c67674c [mlir][transform] Consistent linalg transform op syntax for dynamic index lists (#90897)
This patch is a first pass at making consistent syntax across the
`LinalgTransformOp`s that use dynamic index lists for size parameters.
Previously, there were two different forms: inline types in the list, or
place them in the functional style tuple. This patch goes for the
latter.

In order to do this, the `printPackedOrDynamicIndexList`,
`printDynamicIndexList` and their `parse` counterparts were modified so
that the types can be optionally provided to the corresponding custom
directives.

All affected ops now use tablegen `assemblyFormat`, so custom
`parse`/`print` functions have been removed. There are a couple ops that
will likely add dynamic size support, and once that happens it should be
made sure that the assembly remains consistent with the changes in this
patch.

The affected ops are as follows: `pack`, `pack_greedily`,
`tile_using_forall`. The `tile_using_for` and `vectorize` ops already
used this syntax, but their custom assembly was removed.

---------

Co-authored-by: Oleksandr "Alex" Zinenko <ftynse@gmail.com>
2024-05-08 09:11:53 -05:00
Oleksandr "Alex" Zinenko
e4b04b391f [mlir] make transform.foreach_match forward arguments (#89920)
It may be useful to have access to additional handles or parameters when
performing matches and actions in `foreach_match`, for example, to
parameterize the matcher by rank or restrict it in a non-trivial way.
Enable `foreach_match` to forward additional handles from operands to
matcher symbols and from action symbols to results.
2024-05-03 10:15:44 +02:00
Oleksandr "Alex" Zinenko
105c992c83 [mlir] use irdl as matcher description in transform (#89779)
Introduce a new Transform dialect extension that uses IRDL op
definitions as matcher descriptors. IRDL allows one to essentially
define additional op constraits to be verified and, unlike PDL, does not
assume rewriting will happen. Leverage IRDL verification capability to
filter out ops that match an IRDL definition without actually
registering the corresponding operation with the system.
2024-05-02 15:03:30 +02:00
Oleksandr "Alex" Zinenko
a2e1f54bb7 [mlir] remove test-tranfsorm-dialect-interpreter (#89931)
This pass has been deprecated for more than two months, alternative is
available via `-transform-interpreter` and `-transform-preload-library`.


https://discourse.llvm.org/t/psa-deprecating-test-transform-dialect-interpreter/76904
2024-05-02 14:52:17 +02:00
Christian Sigg
a5757c5b65 Switch member calls to isa/dyn_cast/cast/... to free function calls. (#89356)
This change cleans up call sites. Next step is to mark the member
functions deprecated.

See https://mlir.llvm.org/deprecation and
https://discourse.llvm.org/t/preferred-casting-style-going-forward.
2024-04-19 15:58:27 +02:00
Oleksandr "Alex" Zinenko
37b26bf48b [mlir] transform.apply_patterns support more config options (#88484)
Greedy rewrite driver has options to control the number of rewrites
applies. Expose those via the corresponding transform op.
2024-04-17 14:24:51 +02:00
Jakub Kuderski
a8cfa7cbdf [mlir][TD] Allow op printing flags as transform.print attrs (#86846)
Introduce 3 new optional attributes to the `transform.print` ops:
* `assume_verified`
* `use_local_scope`
* `skip_regions`

The primary motivation is to allow printing on large inputs that
otherwise take forever to print and verify. For the full context, see
this IREE issue: https://github.com/openxla/iree/issues/16901.

Also add some tests and fix the op description.
2024-04-01 12:32:23 -04:00
Jakub Kuderski
971b852546 [mlir][NFC] Simplify type checks with isa predicates (#87183)
For more context on isa predicates, see:
https://github.com/llvm/llvm-project/pull/83753.
2024-04-01 11:40:09 -04:00
Oleksandr "Alex" Zinenko
0b790572b1 [mlir] propagate silenceable failures in transform.foreach_match (#86956)
The original implementation was eagerly reporting silenceable failures
from actions as definite failures. Since silenceable failures are
intended for cases when the IR has not been irreversibly modified, it's
okay to propagate them as silenceable failures of the parent op.

Fixes #86834.
2024-03-28 18:52:10 +01:00
Oleksandr "Alex" Zinenko
91856b34e3 [mlir] move MatchOpInterface under Transform/Interfaces (#86899)
This is similar to the TransformOpInterface move.
2024-03-28 14:00:22 +01:00
Oleksandr "Alex" Zinenko
fa1b807bef [mlir] fix crash in transform.print verification (#86679)
Transform op trait verification calls `getEffects`, and since trait
verification runs before op verification, this call cannot assume the op
to be valid. However, the operand getters now return a `TypedValue` that
unconditionally casts the value to the expected type, leading to an
assertion failure. Use the untyped mechanism instead.

Fixes #84701.
2024-03-27 02:58:06 +01:00
Oleksandr "Alex" Zinenko
5a9bdd85ee [mlir] split transform interfaces into a separate library (#85221)
Transform interfaces are implemented, direction or via extensions, in
libraries belonging to multiple other dialects. Those dialects don't
need to depend on the non-interface part of the transform dialect, which
includes the growing number of ops and transitive dependency footprint.

Split out the interfaces into a separate library. This in turn requires
flipping the dependency from the interface on the dialect that has crept
in because both co-existed in one library. The interface shouldn't
depend on the transform dialect either.

As a consequence of splitting, the capability of the interpreter to
automatically walk the payload IR to identify payload ops of a certain
kind based on the type used for the entry point symbol argument is
disabled. This is a good move by itself as it simplifies the interpreter
logic. This functionality can be trivially replaced by a
`transform.structured.match` operation.
2024-03-20 22:15:17 +01:00
Matthias Springer
102273a9b4 [mlir][Transform] Remove notifyOperationErased workaround (#84134)
D144193 (#66771) has been merged.
2024-03-15 10:29:36 +09:00
Matthias Springer
c1029b6a9b [mlir][Transform] apply_conversion_patterns: Update handles (#83950)
Until now, `transform.apply_conversion_patterns` consumed the target
handle and potentially invalidated handles. This commit adds tracking
functionality similar to `transform.apply_patterns`, such that handles
are no longer invalidated, but updated based on op replacements
performed by the dialect conversion.

This new functionality is hidden behind a `preserve_handles` attribute
for now.
2024-03-10 12:10:53 +09:00
Oleksandr "Alex" Zinenko
5468f88413 [mlir] update remaining transform tests to main pass (#81279)
Use the main transform interpreter pass instead of the test pass. The
only tests that are not updated are specific to the operation of the
test pass.
2024-02-28 11:06:53 +01:00
Matthias Springer
914e607487 [mlir][IR][NFC] Rename notify*Removed to notify*Erased (#82253)
Rename listener callback names:
* `notifyOperationRemoved` -> `notifyOperationErased`
* `notifyBlockRemoved` -> `notifyBlockErased`

The current callback names are misnomers. The callbacks are triggered
when an operation/block is erased, not when it is removed (unlinked).

E.g.:
```c++
/// Notify the listener that the specified operation is about to be erased.
/// At this point, the operation has zero uses.
///
/// Note: This notification is not triggered when unlinking an operation.
virtual void notifyOperationErased(Operation *op) {}
```

This change is in preparation of adding listener support to the dialect
conversion. The dialect conversion internally unlinks IR before erasing
it at a later point of time. There is an important difference between
"remove" and "erase". Lister callback names should be accurate to avoid
confusion.
2024-02-20 09:08:19 +01:00
Mehdi Amini
1ddc5413b1 Apply clang-tidy fixes for readability-simplify-boolean-expr in TransformOps.cpp (NFC) 2024-02-14 10:11:37 -08:00
Mehdi Amini
70ebc78efb Apply clang-tidy fixes for performance-unnecessary-value-param in TransformOps.cpp (NFC) 2024-02-13 20:56:05 -08:00
Mehdi Amini
153661db5c Apply clang-tidy fixes for llvm-qualified-auto in TransformOps.cpp (NFC) 2024-02-13 20:56:05 -08:00
Oleksandr "Alex" Zinenko
b33b91a217 [mlir] update transform dialect tutorials (#81199)
Use the "main" transform-interpreter pass instead of the test pass.
This, along with the previously introduced debug extension, now allow
tutorials to no longer depend on test passes and extensions.
2024-02-09 17:35:14 +01:00
Matthias Springer
9a028afdd6 [mlir][IR][NFC] Listener::notifyMatchFailure returns void (#80704)
There are two `notifyMatchFailure` methods: one in the rewriter and one
in the listener. The one in the rewriter notifies the listener and
returns "failure" for convenience. The one in the listener should not
return anything; it is just a notification. It can currently be abused
to return "success" from the rewriter function. That would be a
violation of the rewriter API rules.

Also make sure that the listener is always notified about match
failures, not just with `NDEBUG`. The current implementation is
consistent: one `notifyMatchFailure` overload notifies only in debug
mode and another one notifies all the time.
2024-02-07 09:00:32 +01:00
Quinn Dawkins
42b160356f [mlir][transform] Add an op for replacing values with function calls (#78398)
Adds `transform.func.cast_and_call` that takes a set of inputs and
outputs and replaces the uses of those outputs with a call to a function
at a specified insertion point.

The idea with this operation is to allow users to author independent IR
outside of a to-be-compiled module, and then match and replace a slice
of the program with a call to the external function.

Additionally adds a mechanism for populating a type converter with a set
of conversion materialization functions that allow insertion of
casts on the inputs/outputs to and from the types of the function
signature.
2024-01-19 13:21:52 -05:00
Quinn Dawkins
5caab8bbc0 [mlir][transform] Add transform.get_operand op (#78397)
Similar to `transform.get_result`, except it returns a handle to the
operand indicated by a positional specification, same as is defined for
the linalg match ops.

Additionally updates `get_result` to take the same positional specification.
This makes the use case of wanting to get all of the results of an
operation easier by no longer requiring the user to reconstruct the list
of results one-by-one.
2024-01-18 09:33:14 -05:00
Oleksandr "Alex" Zinenko
2798b72ae7 [mlir] introduce debug transform dialect extension (#77595)
Introduce a new extension for simple print-debugging of the transform
dialect scripts. The initial version of this extension consists of two
ops that are printing the payload objects associated with transform
dialect values. Similar ops were already available in the test extenion
and several downstream projects, and were extensively used for testing.
2024-01-12 13:24:02 +01:00
Oleksandr "Alex" Zinenko
633d9184f5 [mlir] introduce transform.collect_matching (#76724)
Introduce a new match combinator into the transform dialect. This
operation collects all operations that are yielded by a satisfactory
match into its results. This is a simpler version of `foreach_match`
that can be inserted directly into existing transform scripts.
2024-01-09 13:18:57 +01:00
Oleksandr "Alex" Zinenko
71c17424b5 [mlir][TD] update more tests to use the "main" interpreter pass (#76963)
Update several tests under mlir/test/Dialect/Transform to use the "main"
transform interpreter pass with named entry points rather than the test
interpreter pass.

This helped discover a logic error in the expensive checks mechanism
that was exiting too early.
2024-01-04 21:33:51 +01:00
Oleksandr "Alex" Zinenko
f90b609004 [mlir] introduce transform.num_associations (#76723)
Add a new transform operation that creates a new parameter containing the number of payload objects (operations, values or attributes) associated with the argument. This is useful in matching and for debugging purposes. This replaces three ad-hoc operations previously provided by the test extension.
2024-01-03 13:33:18 +01:00
Kunwar Grover
282d501476 [mlir][Transform] Fix crash with invalid ir for transform libraries (#75649)
This patch fixes a crash caused when the transform library interpreter
is given an IR that fails to parse.
2023-12-19 23:16:19 +05:30
Kazu Hirata
88d319a29f [mlir] Use StringRef::{starts,ends}_with (NFC)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-13 22:58:30 -08:00
Matthias Springer
e8ae0e72b7 [mlir][transform] TrackingListener: Improve dead handles detection (#74290)
The tracking listener should not report op replacement errors for
payload ops that are not mapped to any live handles. The handle liveless
analysis did not work properly with transform IR that has named
sequences.

A handle is live if it has a user after the transform op that is
currently being applied. With named sequences, we need to maintain a
stack of currently applied transform ops. That stack already exists
(`regionStack`), the only thing that's missing is the current transform
op for each stack frame.

This commit fixes #72931.
2023-12-06 16:32:22 +09:00