Add two unit tests having a `struct` -> `array` -> `struct` access,
where the offset is computed through a `shl` operation, applied to a
dynamic index obtained through the argument.
Add a unit test having a `struct` -> `array` -> `struct` access, where
the offset is computed through a `mul` operation, applied to a dynamic
index obtained through an argument.
Add a `EmitFieldAccess` unit test where we perform am `array` access,
using a dynamic index contained in another field of the `struct`
containing the `array` itself.
Additional test in to struct-ptradd-access.mlir that exercises the case
where the base pointer information comes from the offset operand (RHS)
of ptr_add rather than the pointer operand (LHS).
This tests the relaxed assumptions introduced in the previous commit
where `composePtrAdd` no longer requires the `PointerOperand` to be an
`Address` `PA`.
The `EmitFieldAccesses` pass transforms `clift` by taking pointer-typed
expressions computed via integerr arithmetic with type-safe field
accesses and array accesses.
The transformation is split in three main phases:
1) `PointerArithmetic` computation.
2) `BestTraversal` computation.
3) `FieldAccess` `clift` rewrite.
The high level driver is implemented in the `EmitFieldAccesses` header
and cpp, while the nested 3 phases are implemented respectively in
`PointerArithmetic`, `BestTraversal` and `FieldAccessReplacement`.
The `computerPointerArithmetic` phase is concerned with taking a
pointer-typed `ExpressionOp`, called `PointerToReplace`, and expressing
it in a `BasePointer+Offset` form.
The `computeBestTraversal` phase is concerned with computing the best
traversal of the type pointed to by `BasePointer`, that can be used to
rewrite the pointer arithmetic in `clift` with just field accesses and
array subscripts.
The `replaceFieldAccess` phase takes the `Traversal` computed at the
previous step, and actually rewrites in `clift` the `PointerToReplace`
in terms of field accesses and array accesses w.r.t. the `BasePointer`.
Change the `get_model` and `set_model` interface of `StorageProvider` so
that it is responsibility of the `StorageProvider` to
serialize/deserialize the model before returning to the caller.
This is in preparation to the model migration being implemented, since
it's now a responsibility of the storage provider to deserialize it it
can trivially re-save it to disk if it is migrated.
Instead of executing `chdir` when using the `-C` option, which is
fragile when other paths are involved, store the option in the click
context and propagate it to the required code paths that require knowing
what the base directory is.
Handles were previously assigned in the model name import pipe, but as
they are not expected to change often, they can be improted in the
Clifter. Additionally, in some cases it may be desirable to emit C
using generated names instead of those imported from the model, in which
case no handles would be available.
A hexadecimal escape sequences consume an unlimited number of
hexadecimal digits, causing invalid code emission in the case that the
sequence is followed by an unrelated hexadecimal digit.
In the new pipeline the root module is split off in its individual
isolated modules at the end of `isolate`. Before splitting, there are a
lot of global variables in the root module and only a small part is
going to be needed after splitting for each module. To avoid excessive
memory usage employ `ConservativeModuleCloner` in `Isolate` so that
only the needed global variables are actually cloned when splitting off.
Add the functionality the the pipeline infrastructure and CLI to run
individual pipe and analyses as subcommands instead of in-process. This
allow better debuggability of individual pipes.
Improve the handling of signals by leveraging the `Py_AtExit`
functionality to trigger cleanup when the interpreter exits.
When receiving SIGINT handle it specially because exceptions in python
are only thrown when the interpreter is running and not when C code is.
Add infrastructure to pypeline that allows containers to be notified
when they are being used last, this allows two things:
* `Pipe`s eagerly clearing those containers once they are done reading
their contents
* `ScheduledTask`s clearing those out at the end of their execution in
case the pipe did not do it
This overall should improve memory usage as container no longer take up
memory if they are no longer used as part of a `Schedule`.
Inline the body of `PipelineNode.run` into `ScheduledTask.run`, making
`PipelineNode` a pure data structure. This also allows eliding all the
arguments since all of them as properties of `ScheduledTask`.