You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[CIR][CIRGen] Support mutable and recursive named records
This allows a named StructType to be mutated after it has been created,
if it is identified and incomplete.
The motivation for this is to improve the codegen of CIR in certain
scenarios where an incomplete type is used and later completed. These
usually leave the IR in an inconsistent state, where there are two
records types with the same identifier but different definitions (one
complete the other incomplete).
For example:
```c++
struct Node {
Node *next;
};
void test(struct Node n) {}
```
Generates:
```mlir
!temp_struct = !cir.struct<struct "Node" incomplete>
!full_struct = !cir.struct<struct "Node" {!cir.ptr<!temp_struct>}>
```
To generate the `Node` struct type, its members must be created first.
However, the `next` member is a recursive reference, so it can only be
completed after its parent. This generates a temporary incomplete
definition of the `Node` type that remains in the code even after the
type to which it refers is completed. As a consequence, accessing the
`next` member of a `Node` value fetches the old incomplete version of
the type which affects CIR's type-checking capabilities.
This patch ensures that, once the parent is fully visited, the `next`
member can be completed in place, automatically updating any references
to it at a low cost. To represent recursive types, the StructType now
is equipped with self-references. These are represented by a
`cir.struct` type with just the name of the parent struct that it
refers to. The same snippet of code will not generate the following
CIR IR:
```mlir
!full_struct = !cir.struct<struct "Node" {!cir.ptr<!cir.struct<struct "Node">>}>
```
Summary of the changes made:
- Named records are now uniquely identified by their name. An attempt
to create a new record with the same will fail.
- Anonymous records are uniquely identified by members and other
relevant attributes.
- StructType has a new `mutate` method that allows it to be mutated
after it has been created. Each type can only be mutated if it is
identified and incomplete, rendering further changes impossible.
- When building a new name StructType, the builder will try to first
create, then complete the type, ensuring that:
- Inexistent types are created
- Existing incomplete types are completed
- Existing complete types with matching attributes are reused
- Existing complete types with different attributes raise errors
- StructType now uses the CyclicParser/Printer guard to avoid infinite
recursion and identify when it should print/parse a self-reference.
ghstack-source-id: a6d4f65
Pull Request resolved: #303
0 commit comments