Age | Commit message (Collapse) | Author | Files | Lines |
|
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
|
|
`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())`.
|
|
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.
|
|
(#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`.
|
|
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.
|
|
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.
|
|
`getfieldop` (#145605)
Add support to the emitter for `ClassOp`, `FieldOp` and `GetFieldOp`.
These ops were introduced in #141158
|
|
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.
|
|
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.
|
|
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.
|
|
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;
}
```
|
|
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.
|
|
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.
|
|
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`.
|
|
Fixes https://github.com/llvm/llvm-project/issues/124086.
|
|
Now a `emitc.switch` with argument of `emitc.expression` wouldn't emit
its argument to cpp. This patch fix it.
|
|
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.
|
|
(#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`.
|
|
|
|
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>
|
|
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
|
|
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.
|
|
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>
|
|
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`.
|
|
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.
|
|
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>
|
|
`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.
|
|
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>
|
|
For pointer types the indices are restricted to one integer-like
operand.
For opaque types no further restrictions are made.
|
|
For more context on isa predicates, see:
https://github.com/llvm/llvm-project/pull/83753.
|
|
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.
|
|
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.
|
|
|
|
This adds an `emitc.conditional` operation for the ternary conditional
operator. Furthermore, this adds a converion from `arith.select` to the
new op.
|
|
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.
|
|
* Add a conversion from `arith.constant` to `emitc.constant`.
* Drop the translation for `arith.constant`s.
|
|
This adds operations for the unary minus and the unary plus operator.
|
|
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.
|
|
This adds operations for bitwise operators. Furthermore, an UnaryOp
class and a helper to print unary operations are introduced.
|
|
This adds operations for the logical operators AND, NOT and OR.
|
|
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.
|
|
|
|
This adds the `emitc.declare_func` operation that allows to emit the
declaration of an `emitc.func` at a specific location.
|
|
This adds a conversion from an externaly defined `func.func`, a
`func.func` without function body, to an `emitc.func` with an `extern`
specifier.
|
|
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.
|
|
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>
|
|
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.
|
|
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.
|
|
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.
|
|
- Do not emit variables-at-top for literals
- Do not emit an error for a missing name for literals used as call
operands.
|