89 Commits

Author SHA1 Message Date
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
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
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
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
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
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
Simon Camphausen
96c23ebd3b
[mlir][EmitC] Use declarative assembly format for opaque types and attributes (#76066)
The parser and printer of string attributes were changed to handle
escape sequences. Therefore, we no longer require a custom parser and
printer. Verification is moved from the parser to the verifier
accordingly.
2024-01-04 15:43:33 +01:00
Simon Camphausen
795c989c38
[mlir][EmitC] Disallow string attributes as initial values (#75310) 2024-01-02 16:53:36 +01:00
Gil Rapaport
d9803841f2
[mlir][emitc] Add op modelling C expressions (#71631)
Add an emitc.expression operation that models C expressions, and provide
transforms to form and fold expressions. The translator emits the body
of
emitc.expression ops as a single C expression.
This expression is emitted by default as the RHS of an EmitC SSA value,
but if
possible, expressions with a single use that is not another expression
are
instead inlined. Specific expression's inlining can be fine tuned by
lowering
passes and transforms.
2023-12-20 15:04:46 +02:00
Marius Brehler
c4fd1fd6d4
[mlir][emitc] Rename call op to call_opaque (#72494)
This renames the `emitc.call` op to `emitc.call_opaque` as the existing
call op does not refer to the callee by symbol. The rename allows to
introduce a new call op alongside with a future `emitc.func` op to model
and facilitate functions and function calls.
2023-11-17 10:22:15 +01:00
Gil Rapaport
2633d94f28
[mlir][emitc] Add a structured for operation (#68206)
Add an emitc.for op to the EmitC dialect as a lowering target for
scf.for, replacing its current direct translation to C; The translator
now handles emitc.for instead.
2023-10-26 16:40:18 +03:00
Gil Rapaport
a5b4ada6fe Recommit "Add a structured if operation (#67234)"
This patch recommits 126f0374cbc2110aa97e2141ac898014a8b9531a, reverted by
3ada774d0f65b44f21b360d222f446e533df1a34, along with the missing dependence.
2023-09-28 01:52:30 +03:00
Gil Rapaport
3ada774d0f Revert "Add a structured if operation (#67234)"
This reverts commit 126f0374cbc2110aa97e2141ac898014a8b9531a.

Reverting due to bot failures.
2023-09-28 00:22:42 +03:00
Gil Rapaport
126f0374cb
Add a structured if operation (#67234)
Add an emitc.if op to the EmitC dialect. A new convert-scf-to-emitc
pass replaces the existing direct translation of scf.if to C; The
translator now handles emitc.if instead.

The emitc.if op doesn't return any value and its then/else regions are
terminated with a new scf.yield op. Values returned by scf.if are
lowered using emitc.variable ops, assigned to in the then/else regions
using a new emitc.assign op.
2023-09-27 22:40:15 +03:00
Mogball
b3a5f5394f [mlir] Add empty to StringAttr
It was common to see `value.getValue().empty()` or `value.size()`
instead of the idiomatic `value.empty()`.

Depends on D159455

Differential Revision: https://reviews.llvm.org/D159456
2023-09-05 21:45:27 +00:00