100 Commits

Author SHA1 Message Date
Jacques Pienaar
4bf33958da
[mlir] Update builders to use new form. (#154132)
Mechanically applied using clang-tidy.
2025-08-18 15:19:34 +00:00
Andrey Timonin
dfa1335db1
[mlir][emitc] Add verification for the emitc.get_field op (#152577)
This MR adds a `verifier` for the `emitc.get_field` op. 
- The `verifier` checks that the `emitc.get_field` operation is nested
  inside an `emitc.class` op.
- Additionally, appropriate tests for erroneous cases were added for
  class-related operations in `invalid_ops.mlir`.
2025-08-15 18:32:12 +02:00
Andrey Timonin
3fbb553f7d
[mlir][emitc] Simplify emitc::isSupportedFloatType (NFC) (#152464) 2025-08-07 17:53:05 +02:00
Jaden Angella
149d4b5033
[mlir][EmitC]Allow Fields to have initial values (#151437)
This will ensure that:
- The `field` of a class can have an initial value
- The `field` op is emitted correctly
- The `getfield` op is emitted correctly
2025-08-01 11:20:13 -07:00
Jaden Angella
af1ca08ddb
[mlir][EmitC]Remove the Unused Option in the wrap-emitc-func-in-class Pass (#150577)
This patch removes the option `namedAttribute` which is not used in this
pass.
2025-07-25 09:30:55 -07:00
Longsheng Mou
f047b735e9
[mlir][NFC] Use getDefiningOp<OpTy>() instead of dyn_cast<OpTy>(getDefiningOp()) (#150428)
This PR uses `val.getDefiningOp<OpTy>()` to replace `dyn_cast<OpTy>(val.getDefiningOp())` , `dyn_cast_or_null<OpTy>(val.getDefiningOp())` and `dyn_cast_if_present<OpTy>(val.getDefiningOp())`.
2025-07-25 10:35:51 +08:00
Yanzuo Liu
9cd2413601
[MLIR][EmitC][NFC] Use llvm::function_ref<> instead of std::optional<llvm::function_ref<>> (#146478)
There is no need to distinguish between null `optional` and null
`function_ref` in this case.
2025-07-25 08:59:09 +08:00
Maksim Levental
dce6679cf5
[mlir][NFC] update mlir/Dialect create APIs (16/n) (#149922)
See https://github.com/llvm/llvm-project/pull/147168 for more info.
2025-07-21 19:57:30 -04:00
Kazu Hirata
cac806bcc5
[mlir] Remove unused includes (NFC) (#148535) 2025-07-13 13:13:01 -07:00
Kazu Hirata
70dce3d987
[mlir] Migrate away from std::nullopt (NFC) (#145842)
ArrayRef has a constructor that accepts std::nullopt.  This
constructor dates back to the days when we still had llvm::Optional.

Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.

This patch replaces {} with std::nullopt.
2025-06-26 08:41:02 -07:00
Jaden Angella
e615544e2b
[mlir][EmitC] Add pass to wrap a func in class (#141158)
Goal: Enable using C++ classes to AOT compile models for MLGO.

This commit introduces a transformation pass that converts standalone
`emitc.func` operations into `emitc.class `structures to support
class-based C++ code generation for MLGO.

Transformation details:
- Wrap `emitc.func @func_name` into `emitc.class @Myfunc_nameClass`
- Converts function arguments to class fields with preserved attributes
- Transforms function body into an `execute()` method with no arguments
- Replaces argument references with `get_field` operations

Before: emitc.func @Model(%arg0, %arg1, %arg2) with direct argument
access
After: emitc.class with fields and execute() method using get_field
operations

This enables generating C++ classes that can be instantiated and
executed as self-contained model objects for AOT compilation workflows.
2025-06-24 13:07:22 -07:00
Kirill Chibisov
74687180dd
[mlir][emitc] Make CExpression trait into interface (#142771)
By defining `CExpressionInterface`, we move the side effect detection
logic from `emitc.expression` into the individual operations
implementing the interface allowing operations to gradually tune the
side effect.

It also allows checking for side effects each operation individually.
2025-06-18 07:38:47 +02:00
Vlad Lazar
6cbb67f84c
[mlir][emitc] Fix the emitc::ExpressionOp (#143894)
Fix the lack of verification that the definingOp of the return value
belongs to emitc::ExpressionOp.
2025-06-16 23:51:49 +02:00
Kazu Hirata
15f7c6ed70
[mlir] Remove unused local variables (NFC) (#138481) 2025-05-05 10:08:00 -07:00
Simon Camphausen
0009a17834
[mlir][EmitC] Add pass that combines all available emitc conversions (#117549) 2025-05-01 07:24:01 -07:00
Kazu Hirata
28c0d9d37c
[mlir] Use llvm::append_range (NFC) (#136257)
This patch replaces:

  llvm::copy(Src, std::back_inserter(Dst));

with:

  llvm::append_range(Dst, Src);

for breavity.

One side benefit is that llvm::append_range eventually calls
llvm::SmallVector::reserve if Dst is of llvm::SmallVector.
2025-04-18 12:03:49 -07:00
lorenzo chelini
105c8c38dc
[MLIR][NFC] Retire let constructor for EmitC (#133732)
`let constructor` is legacy (do not use in tree!) since the tableGen
backend emits most of the glue logic to build a pass.
2025-04-01 18:22:40 +02:00
Andrey Timonin
1e1bf7971b
[mlir][emitc] Add an option to cast array type to ptr type (#126385) 2025-02-20 17:40:06 +01:00
Matthias Gehre
c4f8da94a1 [MLIR][emitc]: Remove unused functions (NFC) 2025-02-19 08:46:53 +01:00
Kazu Hirata
2c05d02683 [mlir] Fix warnings
This patch fixes:

  mlir/lib/Dialect/EmitC/IR/EmitC.cpp:994:20: error: unused function
  'parseVariadicTypeFmtArgs' [-Werror,-Wunused-function]

  mlir/lib/Dialect/EmitC/IR/EmitC.cpp:1010:13: error: unused function
  'printVariadicTypeFmtArgs' [-Werror,-Wunused-function]
2025-02-18 12:49:52 -08:00
Matthias Gehre
0049adfe12
[MLIR] emitc: Add fmtArgs to verbatim (#123294)
Allows to print code snippets that refer to arguments or local
variables. E.g. `emitc.verbatim "#pragma abc var={}" args %arg0 :
!emitc.ptr<i32>` is printed as `#pragma abc var=v1` when the translator
had decided to print `%arg0` as `v1`.

As a follow-up PR, we will use the same infra to extend opaque type,
which provides a way to generate template types depending on the
spelling of other types.
2025-02-18 21:37:37 +01:00
Matthias Gehre
4cc7d60fe3
[MLIR] emitc: Add emitc.file op (#123298)
A `emitc.file` represents a file that can be emitted
into a single C++ file.

This allows to manage multiple source files within the same MLIR module,
but emit them into separate files.

This feature is opt-in.
By default, `mlir-translate` emits all ops outside of `emitc.file`
and ignores all `emitc.file` ops and their bodies.

When specifying the `-file-id=id` flag,
`mlir-translate` emits all ops outside of `emitc.file` and
the ops within the `emitc.file` with matching `id`.

Example:

```mlir
emitc.file "main" {
  func @func_one() {
    return
  }
}
emitc.file "test" {
  func @func_two() {
   return
  }
}
```

`mlir-translate -file-id=main` will emit `func_one` and
`mlir-translate -file-id=test` will emit `func_two`.
2025-02-18 15:21:17 +01:00
jeanPerier
327d627066
[mlir] share argument attributes interface between calls and callables (#123176)
This patch shares core interface methods dealing with argument and
result attributes from CallableOpInterface with the CallOpInterface and
makes them mandatory to gives more consistent guarantees about concrete
operations using these interfaces.

This allows adding argument attributes on call like operations, which is
sometimes required to get proper ABI, like with  llvm.call (and llvm.invoke).


The patch adds optional `arg_attrs` and `res_attrs` attributes to operations using
these interfaces that did not have that already.
They can then re-use the common "rich function signature"
printing/parsing helpers if they want (for the LLVM dialect, this is
done in the next patch).

Part of RFC: https://discourse.llvm.org/t/mlir-rfc-adding-argument-and-result-attributes-to-llvm-call/84107
2025-02-03 11:27:14 +01:00
Matthias Gehre
0bd0765252
EmitC: Allow arrays of size zero (#123292)
This is allowed as a GCC extension, see
https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html.
2025-01-17 09:06:04 +01:00
Matthias Springer
3ace685105
[mlir][Transforms] Support 1:N mappings in ConversionValueMapping (#116524)
This commit updates the internal `ConversionValueMapping` data structure
in the dialect conversion driver to support 1:N replacements. This is
the last major commit for adding 1:N support to the dialect conversion
driver.

Since #116470, the infrastructure already supports 1:N replacements. But
the `ConversionValueMapping` still stored 1:1 value mappings. To that
end, the driver inserted temporary argument materializations (converting
N SSA values into 1 value). This is no longer the case. Argument
materializations are now entirely gone. (They will be deleted from the
type converter after some time, when we delete the old 1:N dialect
conversion driver.)

Note for LLVM integration: Replace all occurrences of
`addArgumentMaterialization` (except for 1:N dialect conversion passes)
with `addSourceMaterialization`.

---------

Co-authored-by: Markus Böck <markus.boeck02@gmail.com>
2025-01-03 16:11:56 +01:00
Jacques Pienaar
09dfc5713d
[mlir] Enable decoupling two kinds of greedy behavior. (#104649)
The greedy rewriter is used in many different flows and it has a lot of
convenience (work list management, debugging actions, tracing, etc). But
it combines two kinds of greedy behavior 1) how ops are matched, 2)
folding wherever it can.

These are independent forms of greedy and leads to inefficiency. E.g.,
cases where one need to create different phases in lowering and is
required to applying patterns in specific order split across different
passes. Using the driver one ends up needlessly retrying folding/having
multiple rounds of folding attempts, where one final run would have
sufficed.

Of course folks can locally avoid this behavior by just building their
own, but this is also a common requested feature that folks keep on
working around locally in suboptimal ways.

For downstream users, there should be no behavioral change. Updating
from the deprecated should just be a find and replace (e.g., `find ./
-type f -exec sed -i
's|applyPatternsAndFoldGreedily|applyPatternsGreedily|g' {} \;` variety)
as the API arguments hasn't changed between the two.
2024-12-20 08:15:48 -08:00
Matthias Springer
f18c3e4e73
[mlir][Transforms] Dialect Conversion: Simplify materialization fn result type (#113031)
This commit simplifies the result type of materialization functions.

Previously: `std::optional<Value>`
Now: `Value`

The previous implementation allowed 3 possible return values:
- Non-null value: The materialization function produced a valid
materialization.
- `std::nullopt`: The materialization function failed, but another
materialization can be attempted.
- `Value()`: The materialization failed and so should the dialect
conversion. (Previously: Dialect conversion can roll back.)

This commit removes the last variant. It is not particularly useful
because the dialect conversion will fail anyway if all other
materialization functions produced `std::nullopt`.

Furthermore, in contrast to type conversions, at least one
materialization callback is expected to succeed. In case of a failing
type conversion, the current dialect conversion can roll back and try a
different pattern. This also used to be the case for materializations,
but that functionality was removed with #107109: failed materializations
can no longer trigger a rollback. (They can just make the entire dialect
conversion fail without rollback.) With this in mind, it is even less
useful to have an additional error state for materialization functions.

This commit is in preparation of merging the 1:1 and 1:N type
converters. Target materializations will have to return multiple values
instead of a single one. With this commit, we can keep the API simple:
`SmallVector<Value>` instead of `std::optional<SmallVector<Value>>`.

Note for LLVM integration: All 1:1 materializations should return
`Value` instead of `std::optional<Value>`. Instead of `std::nullopt`
return `Value()`.
2024-10-23 07:29:17 -07:00
Jianjian Guan
d4f97da132
[mlir] Support emit fp16 and bf16 type to cpp (#105803) 2024-08-27 16:56:46 +08:00
Marius Brehler
5032fa89ad
[MLIR][EmitC] Allow ptrdiff_t as result in sub op (#104921)
This explicitly allows the `emitc.ptrdiff_t` type for the result of
substrating two pointers and changes the example accordingly.
2024-08-20 17:36:51 +02:00
Simon Camphausen
e47b507562
[mlir][EmitC] Model lvalues as a type in EmitC (#91475)
This adds an `emitc.lvalue` type which models assignable lvlaues in the
type system. Operations modifying memory are restricted to this type
accordingly.

See also the discussion on
[discourse](https://discourse.llvm.org/t/rfc-separate-variables-from-ssa-values-in-emitc/75224/9).
The most notable changes are as follows.

- `emitc.variable` and `emitc.global` ops are restricted to return
`emitc.array` or `emitc.lvalue` types
- Taking the address of a value is restricted to operands with lvalue
type
- Conversion from lvalues into SSA values is done with the new
`emitc.load` op
- The var operand of the `emitc.assign` op is restricted to lvalue type 
- The result of the `emitc.subscript` and `emitc.get_global` ops is a
lvalue type
- The operands and results of the `emitc.member` and
`emitc.member_of_ptr` ops are restricted to lvalue types

---------

Co-authored-by: Matthias Gehre <matthias.gehre@amd.com>
2024-08-20 11:52:16 +02:00
Andrey Timonin
97f0ab71c0
[mlir][emitc] Add 'emitc.switch' op to the dialect (#102331)
This PR is continuation of the [previous
one](https://github.com/llvm/llvm-project/pull/101478). As a result, the
`emitc::SwitchOp` op was developed inspired by `scf::IndexSwitchOp`.

Main points of PR:

- Added the `emitc::SwitchOp` op  to the EmitC dialect + CppEmitter
- Corresponding tests were added
- Conversion from the SCF dialect to the EmitC dialect for the op
2024-08-16 18:25:06 +02:00
Marius Brehler
a5cf99d02c
[mlir][EmitC] Add member access ops (#98460)
This adds an `emitc.member` and `emitc.member_of_ptr` operation for the
corresponding member access operators. Furthermore, `emitc.assign` is
adjusted to be used with the member access operators.
2024-07-13 14:43:07 +02:00
Simon Camphausen
d521324e9f
[mlir][EmitC] Unify handling of operations which are emitted in a deferred way (#97804)
Several operations from the EmitC dialect don't produce output directly
during emission, but rather when being used as an operand. These changes
unify the handling of such operations and fix a bug in the emission of
global ops.

Co-authored-by: Marius Brehler <marius.brehler@iml.fraunhofer.de>
2024-07-10 15:24:32 +02:00
Corentin Ferry
3cead572e9
[mlir][emitc] Add EmitC index types (#93155)
This commit adds `emitc.size_t`, `emitc.ssize_t` and `emitc.ptrdiff_t`
types to the EmitC dialect. These are used to map `index` types to C/C++
types with an explicit signedness, and are emitted in C/C++ as `size_t`,
`ssize_t` and `ptrdiff_t`.
2024-06-17 13:53:55 +02:00
Marius Brehler
8760d4ba4c [mlir][EmitC] Update comment (NFC) 2024-05-27 12:25:06 +00:00
Chris
09adb53118
[MLIR][EmitC] Fix bug in EmitC form-expressions pass (#91084)
An `emitc.expression` can only yield a single result, but some
operations which have the `CExpression` trait can have multiple results,
which can result in a crash when applying the `fold-expressions` pass.
This change adds a check for the single-result condition and a simple
test.
2024-05-06 06:12:39 -06:00
Matthias Gehre
654846560c
EmitC: Add emitc.global and emitc.get_global (#145) (#88701)
This adds
- `emitc.global` and `emitc.get_global` ops to model global variables
similar to how `memref.global` and `memref.get_global` work.
- translation of those ops to C++
- lowering of `memref.global` and `memref.get_global` into those ops

---------

Co-authored-by: Simon Camphausen <simon.camphausen@iml.fraunhofer.de>
2024-04-23 09:28:37 +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
Tina Jung
95ffa8a2ac
[mlir][emitc] Restrict types in EmitC (#88391)
Restrict the types which are valid for EmitC operations. Use what is
currently supported by the emitter as restriction. Define a utility
functions for valid types, such that they can be used to restrict the
operations in table gen as well as being available for reuse in dialect
conversions.
2024-04-19 10:52:31 +02:00
Simon Camphausen
1f268092c7
[mlir][EmitC] Add support for pointer and opaque types to subscript op (#86266)
For pointer types the indices are restricted to one integer-like
operand.
For opaque types no further restrictions are made.
2024-04-03 13:06:14 +02: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
Kirill Chibisov
5344a370fe
[mlir][emitc] Fix form-expressions inside expression (#86081)
Make form-expressions not create `emitc.expression`s for operations
inside the `emitc.expression`s, since they are invalid.
2024-03-21 14:35:00 +01:00
Tina Jung
647d75d3a8
[mlir][emitc] Restrict integer and float types (#85788)
Restrict which integers and floating-point types are valid in EmitC.
This should cover the types which are supported in C++ and is aligned
with what the emitter currently supports.

The checks are implemented as functions and not fully in tablegen to
allow them to be re-used by conversions to EmitC.
2024-03-20 16:00:05 +01:00
Matthias Gehre
01a31cee56
[MLIR] EmitC: Add subscript operator (#84783)
Introduces a SubscriptOp that allows to write IR like
```
func.func @load_store(%arg0: !emitc.array<4x8xf32>, %arg1: !emitc.array<3x5xf32>, %arg2: index, %arg3: index) {
  %0 = emitc.subscript %arg0[%arg2, %arg3] : <4x8xf32>, index, index
  %1 = emitc.subscript %arg1[%arg2, %arg3] : <3x5xf32>, index, index
  emitc.assign %0 : f32 to %1 : f32
  return
}
```
which gets translated into the C++ code
```
v1[v2][v3] = v0[v1][v2];
```

To make this happen, this
- adds the SubscriptOp
- allows the subscript op as rhs of emitc.assign
- updates the emitter to print SubscriptOps

The emitter prints emitc.subscript in a delayed fashing to allow it
being used as lvalue.
I.e. while processing
```
%0 = emitc.subscript %arg0[%arg2, %arg3] : <4x8xf32>, index, index
```
it will not emit any text, but record in the `valueMapper` that the name
for `%0` is `v0[v1][v2]`, see `CppEmitter::getSubscriptName`. Only when
that result is then used (here in `emitc.assign`), that name is inserted
into the text.
2024-03-15 11:08:34 +01:00
Matthias Gehre
818af71b72
[mlir][emitc] Add ArrayType (#83386)
This models a one or multi-dimensional C/C++ array.

The type implements the `ShapedTypeInterface` and prints similar to
memref/tensor:
```
  %arg0: !emitc.array<1xf32>,
  %arg1: !emitc.array<10x20x30xi32>,
  %arg2: !emitc.array<30x!emitc.ptr<i32>>,
  %arg3: !emitc.array<30x!emitc.opaque<"int">>
```

It can be translated to a C array type when used as function parameter
or as `emitc.variable` type.
2024-03-11 16:40:57 +01:00
Marius Brehler
7c63431cc2
[mlir][EmitC] Introduce a CExpression trait (#84177)
This adds a `CExpression` trait and replaces the `isCExpression()`
function.
2024-03-07 08:37:47 +01:00
Matthias Springer
91d5653e3a
[mlir] Use OpBuilder::createBlock in op builders and patterns (#82770)
When creating a new block in (conversion) rewrite patterns,
`OpBuilder::createBlock` must be used. Otherwise, no
`notifyBlockInserted` notification is sent to the listener.

Note: The dialect conversion relies on listener notifications to keep
track of IR modifications. Creating blocks without the builder API can
lead to memory leaks during rollback.
2024-02-24 09:10:07 +01:00
Marius Brehler
03881dc0a7
[mlir][emitc] Add a declare_func operation (#80297)
This adds the `emitc.declare_func` operation that allows to emit the
declaration of an `emitc.func` at a specific location.
2024-02-06 08:49:10 +01:00
Marius Brehler
9a87c5d440
[mlir][EmitC] Add support for external functions (#80547)
This adds a conversion from an externaly defined `func.func`, a
`func.func` without function body, to an `emitc.func` with an `extern`
specifier.
2024-02-05 16:58:10 +01:00
Marius Brehler
e7d40a87ff
[mlir][EmitC] Add func, call and return operations and conversions (#79612)
This adds a `func`, `call` and `return` operation to the EmitC dialect,
closely related to the corresponding operations of the Func dialect. In
contrast to the operations of the Func dialect, the EmitC operations do
not support multiple results. The `emitc.func` op features a
`specifiers` argument that for example allows, with corresponding
support in the emitter, to emit `inline static` functions.

Furthermore, this adds patterns and a pass to convert the Func dialect
to EmitC. A `func.func` op that is `private` is converted to
`emitc.func` with a `"static"` specifier.
2024-02-01 10:04:36 +01:00