89 Commits

Author SHA1 Message Date
Jianjian Guan
1eb5b18a04
[mlir][emitc] Support dense as init value for ShapedType (#144826) 2025-08-19 09:41:15 +08: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
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
Kazu Hirata
1a0f482de8
[mlir] Remove unused includes (NFC) (#150476)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-07-24 11:23:53 -07:00
Niklas Degener
5954e9c1a5
[MLIR][Target/Cpp] Fix variable naming conflict for function declarations (#147927)
This is a fix for https://github.com/llvm/llvm-project/pull/136102. It
missed scoping for `DeclareFuncOps`.
In scenarios with multiple function declarations, the `valueMapper`
wasn't updated and later uses of values in other functions still used
the assigned names in prior functions.

This is visible in the reproducer here
https://github.com/iree-org/iree/issues/21303: Although the counter for
variable enumeration was reset, as it is visible for the local vars, the
function arguments were mapped to old names. Due to this mapping, the
counter was never increased, and the local variables conflicted with the
arguments.

This fix adds proper scoping for declarations and a test-case to cover
the scenario with multiple `DeclareFuncOps`.
2025-07-10 16:09:49 +02:00
Niklas Degener
dcc692a42f
[MLIR][Target/Cpp] Natural induction variable naming. (#136102)
Changed naming of loop induction variables to follow natural naming (i,
j, k, ...). This helps readability and locating positions referred to.
Created new scopes to represent different behavior at function and loop
level, to still enable re-using value names between different functions
(as before). Removed unused scoping at other levels.
2025-07-08 09:18:00 +02:00
Jaden Angella
d4b5905a25
Addfinal specifier to the classop (#145977)
In some use cases of the `ClassOp`, eg MLGO, we would like to be able to declare the class as final. This specifier allows for that.
2025-06-29 19:00:59 -07:00
Jaden Angella
1dfdd1e6de
[mlir][emitC] Add support to emitter for classop, fieldop and getfieldop (#145605)
Add support to the emitter for `ClassOp`, `FieldOp` and `GetFieldOp`.
These ops were introduced in #141158
2025-06-26 13:54:05 -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
Vimal
b9d7ef7d5a
Fix handling of integer template argument in emitc.call_opaque (#141451)
Integer attributes supplied to `emitc.call_opaque` as arguments were
treated as index into the operands list. This should be the case only
for the normal arguments but not for the template arguments which can't
refer to SSA values. This commit updates the handling of template
arguments in mlir-to-cpp by removing special handling of integer
attributes.
2025-05-27 11:47:29 +08:00
Kirill Chibisov
0ca2d4d104
[mlir][emitc] mark emitc.load with CExpression (#130802)
Follow the `call` and `call_opaque` operations, as well as `apply`,
which already are marked as `CExpression` even though they have side
effects.

Even though `emitc.load` can be included inside the `emitc.expression`,
the inlining and `--form-expression` pass won't actually inline them
inside other expression due to it having a side effect, thus unless the
user manually writes the `emitc.load` inside the `emitc.expression` it
won't appear there.

--

It was brought
https://github.com/llvm/llvm-project/pull/91475#issuecomment-2302529428
and while there was some opposition due to `load` having a side effect,
`emitc` already allows all the rest operations that have it, so for
consistency reasons, enabling it doesn't really hurt from my point of
view. Especially given that `--form-expression` doesn't allow
it to really inline inside other expressions, which makes sense, since
if the users want such behavior, they should explicitly opt-in.
2025-04-22 09:03:42 +02:00
Andrey Timonin
75ab43b70e
[mlir][emitc][NFC] Eliminate the extra newline printout during emitc.switch emission (#129257)
Before the output was:
```c++
void emitc_switch_ptrdiff_t() {
  ptrdiff_t v1 = 1;

  switch (v1) {
  ...
  }
  return;
}
```
After:
```c++
void emitc_switch_ptrdiff_t() {
  ptrdiff_t v1 = 1;
  switch (v1) {
  ...
  }
  return;
}
```
2025-03-19 11:02:54 +01:00
gdehame
e481943f5f
[MLIR][EmitC][cf] Bugfix: correctly inline emitc.expression op in the emitted if condition of a cf.cond_br (#128958)
emitc.expression ops are expected to be inlined in the if condition in
the lowering of cf.cond_br if this is their only use but they weren't
inlined.
Instead, a use of the variable corresponding to the expression result
was generated but with no declaration/definition.
2025-02-28 15:00:16 +01: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
Jianjian Guan
375df714db
[emitc] Fix precedence when emit emit.expression (#124087)
Fixes https://github.com/llvm/llvm-project/issues/124086.
2025-02-05 10:04:40 +08:00
Jianjian Guan
3ef90f843f
[emitc] Fix the translation switchop with argument of expressionop (#123701)
Now a `emitc.switch` with argument of `emitc.expression` wouldn't emit
its argument to cpp. This patch fix it.
2025-01-23 10:30:30 +08:00
Kirill Chibisov
be96bd74f8
[mlir][emitc] Don't emit extra semicolon after bracket (#122464)
Extra semicolons were emitted for operations that should never have
them, since not every place was checking whether semicolon would be
actually needed.

Thus change the emitOperation to ignore trailingSemicolon field for such
operations.
2025-01-14 13:51:41 +01:00
Andrey Timonin
a1c9dd7c80
[mlir][emitc] Fix the error with closing bracket in CppEmitter in switchOp (#110269)
While working with `emitc::SwitchOp`, it was identified that
`mlir-translate` emits **invalid C code** for switch.
This commit fixes the issue with the closing bracket in `CppEmitter`
within `printOperation` for `emitc::SwitchOp`.
2024-10-10 13:31:18 +02:00
Jianjian Guan
d4f97da132
[mlir] Support emit fp16 and bf16 type to cpp (#105803) 2024-08-27 16:56:46 +08: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
Simon Camphausen
a934ddcf7e
[mlir][EmitC] Do not inline expressions used by ops with the CExpression trait (#93691)
Currently an expression is inlined without emitting enclosing
parentheses regardless of the context of the user. This could led to
wrong evaluation order depending on the precedence of both expressions.
If the inlining is intended, the user operation should be merged into
the expression op.

Fixes #93470.
2024-06-04 13:14:08 +02:00
Simon Camphausen
1594cebedd
[mlir][EmitC] Fix evaluation order of expressions (#93549)
Expressions with the same precedence were not parenthesized and
therefore were possibly evaluated in the wrong order depending on the
shape of the expression tree.

---------

Co-authored-by: Matthias Gehre <matthias.gehre@amd.com>
Co-authored-by: Corentin Ferry <corentin.ferry@amd.com>
2024-05-29 11:42:06 +02:00
Chris
657eda3672
[MLIR][EmitC] Don't translate expressions inline if user is emitc.subscript (#91087)
This change updates the logic that determines whether an `emitc.expression`
result is translated into a dedicated variable assignment. Due to how
the translation of `emitc.subscript` currently works, a previously
inline-able `emitc.expression` would produce incorrect C++ if its single user 
was a `emitc.subscript` operation.
2024-05-06 11:53:08 -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
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
Matthias Gehre
5cc228148e
TranslateToCpp: Emit floating point literals with suffix (#85392)
Emits `2.0e+00f` instead of `(float)2.0e+00`.

This helps consumers of the emitted code, especially when there are
large numbers of floating point literals, to have a simple AST.
2024-03-18 09:58:57 +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
Marius Brehler
2cf2ca3702
[mlir][Target][Cpp] Cleanup includes (#85105) 2024-03-14 10:39:16 +01:00
Marius Brehler
19266ca389
[mlir][EmitC] Add an emitc.conditional operator (#84883)
This adds an `emitc.conditional` operation for the ternary conditional
operator. Furthermore, this adds a converion from `arith.select` to the
new op.
2024-03-12 11:27:26 +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
Tina Jung
0ddb122147
[mlir][emitc] Arith to EmitC conversion: constants (#83798)
* Add a conversion from `arith.constant` to `emitc.constant`.
* Drop the translation for `arith.constant`s.
2024-03-08 09:16:10 +01:00
Marius Brehler
df9be017b7
[mlir][EmitC] Add unary_{minus,plus} operators (#84329)
This adds operations for the unary minus and the unary plus operator.
2024-03-08 08:34:56 +01:00
Marius Brehler
f355cd6f6c
[mlir][EmitC] Allow further ops within expressions (#84284)
This adds the `CExpression` trait to additional ops to allow to use
these ops within the expression operation. Furthermore, the operator
precedence is defined for those ops.
2024-03-07 15:48:11 +01:00
Marius Brehler
7ac03e8a36
[mlir][EmitC] Add bitwise operators (#83387)
This adds operations for bitwise operators. Furthermore, an UnaryOp
class and a helper to print unary operations are introduced.
2024-03-01 13:21:11 +01:00
Marius Brehler
b81bb0e1d0
[mlir][EmitC] Add logical operators (#83123)
This adds operations for the logical operators AND, NOT and OR.
2024-02-28 20:41:05 +01:00
Marius Brehler
dfb70c3a7c
[mlir][EmitC] Remove func.constant from emitter (#82342)
As part of the renaming the Standard dialect to Func dialect, *support*
for the `func.constant` operation was added to the emitter. However, the
emitter cannot emit function types. Hence the emission for a snippet
like

```
%0 = func.constant @myfn : (f32) -> f32

func.func private @myfn(%arg0: f32) -> f32 {
  return %arg0 : f32
}
```

failes with `func.mlir:1:6: error: cannot emit type '(f32) -> f32'`.
This removes `func.constant` from the emitter.
2024-02-20 14:16:34 +01:00
Simon Camphausen
8924a9ffcb
[mlir][EmitC] Remove unreachable code and fix Windows build warning (#80677) 2024-02-06 12:04:13 +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
e624648bd9
[mlir][EmitC] Add verbatim op (#79584)
The `verbatim` operation produces no results and the value is emitted as
is followed by a line break ('\n' character) during translation.

Note: Use with caution. This operation can have arbitrary effects on the
semantics of the emitted code. Use semantically more meaningful
operations whenever possible. Additionally this op is *NOT* intended to
be used to inject large snippets of code.

This operation can be used in situations where a more suitable operation
is not yet implemented in the dialect or where preprocessor directives
interfere with the structure of the code.

Co-authored-by: Marius Brehler <marius.brehler@iml.fraunhofer.de>
2024-01-31 11:56:16 +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
Simon Camphausen
68b071d9a2
[mlir][emitc] Fix corner case in translation of literal ops (#71375)
Fix a corner case missed in #71296 when operands generated by literals
are mixed with the args attribute of a call op.

Additionally remove a range check that is already handled by the CallOp
verifier.
2023-11-06 16:17:20 +01:00