Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR][Codegen][Lowering] Introduce new bitfield layout #487

Merged
merged 33 commits into from
Mar 12, 2024

Conversation

gitoleg
Copy link
Collaborator

@gitoleg gitoleg commented Feb 29, 2024

This PR intends to fix some problems with packed structures support, so the #473 will work.

Problems

Basically, the main problem for the packed structures support is an absence of arbitrary sized integers in CIR. Well, one workaround is to use mlir::IntegerType for that, but it's kind of wrong way (please correct me if I'm wrong). Another way is to introduce this type in CIR. So far I suggest this way: instead of arbitrary sized integers we will create an array of bytes for bitfield storages whenever they doesn't fit into the CIR IntType.

Why

Well, the original codegen creates storages with alignment 8 - so it can be i24 storage type for instance. Previously, we just created storages that could be represented as CIR IntType: 8, 16, 32, 64. And it was working before I came up with a necessity to support packed structures. At first glance it's not a problem - just add determinePacked method from the original codegen and that's it. But it turned out that this method infers the fact if a structure is packed or not. It doesn't use the AST attribute for that as one could think - it works with offsets and alignments of fields. Thus, we either need to invent our own way to determine packed structures (which is error prone and maybe not doable at all) or try to use the existing one. Also, we go closer to the original lllvm's data layout in this case.

Implementation details

  1. I had to move the lowering details from the LoweringPrepare to the LowerToLLVM, because it's not possible to do a load from the array of bytes to the integer type - and it's ok in llvm dialect. Thus, all the math operations can be expressed without any problems. Basically the most of the diff you see is because of the changes in the lowering. The remaining part is more or less easy to read.
  2. There are minor changes in CIRRecordLayoutBuilder - as described above, we use may generate an array of bytes as a storage.
  3. Some cosmetic changes in CIRGenExpr - since we don't want to infer the storage type again and just use the one stored in the CIRGenBitFieldInfo.
  4. Helpers are introduced in the lowering - but nothing hard - just shifts and logical ops.
  5. I removed bitfield-ops test - because now the test cases covered there are all in bitfields.c and bitfields.cpp .

So ... This is still a suggestion, though I believe it's a good one. So you are welcome to discuss, suggest another ways to solve the problem and etc.

@gitoleg gitoleg changed the title New bitfield layout [CIR][Codegen][Lowering] Introduce new bitfield layout Feb 29, 2024
Copy link

github-actions bot commented Feb 29, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Oleg, thanks for improving the situation here and thanks for the detailed explanation on why this is necessary - very insightful. LGTM with some minor nitpicks:

  • Can you add some comments to the CIRGen parts where we now do differently from traditional CodeGen? Doesn't need to be a lot of content, but more something like // This is different from LLVM traditional codegen because CIRGen uses arrays of bytes instead of arbitrary-sized integers.
  • I also noticed both get_bitfield and set_bitfield are missing the MemRead and MemWrite markers, can you add that in a follow up PR?
  • Fix the remaining merge conflict

clang/lib/CIR/CodeGen/CIRGenBuilder.h Outdated Show resolved Hide resolved
@bcardosolopes bcardosolopes merged commit 278c391 into llvm:main Mar 12, 2024
6 checks passed
bcardosolopes added a commit that referenced this pull request Mar 15, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in #487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
lanza pushed a commit that referenced this pull request Mar 23, 2024
This PR intends to fix some problems with packed structures support, so
the #473 will work.

### Problems
Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

### Why
Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

### Implementation details
1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
lanza pushed a commit that referenced this pull request Mar 23, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in #487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
This PR intends to fix some problems with packed structures support, so
the llvm#473 will work.

### Problems
Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

### Why
Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

### Implementation details
1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in llvm#487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
lanza pushed a commit that referenced this pull request Apr 29, 2024
This PR intends to fix some problems with packed structures support, so
the #473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
lanza pushed a commit that referenced this pull request Apr 29, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in #487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
lanza pushed a commit that referenced this pull request Apr 29, 2024
This PR intends to fix some problems with packed structures support, so
the #473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
lanza pushed a commit that referenced this pull request Apr 29, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in #487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Apr 29, 2024
This PR intends to fix some problems with packed structures support, so
the llvm#473 will work.

### Problems
Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

### Why
Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

### Implementation details
1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Apr 29, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in llvm#487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
lanza pushed a commit that referenced this pull request Apr 29, 2024
This PR intends to fix some problems with packed structures support, so
the #473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
lanza pushed a commit that referenced this pull request Apr 29, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in #487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
bruteforceboy pushed a commit to bruteforceboy/clangir that referenced this pull request Oct 2, 2024
This PR intends to fix some problems with packed structures support, so
the llvm#473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
bruteforceboy pushed a commit to bruteforceboy/clangir that referenced this pull request Oct 2, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in llvm#487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
This PR intends to fix some problems with packed structures support, so
the llvm#473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in llvm#487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
This PR intends to fix some problems with packed structures support, so
the llvm#473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in llvm#487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
lanza pushed a commit that referenced this pull request Nov 5, 2024
This PR intends to fix some problems with packed structures support, so
the #473 will work.

Basically, the main problem for the packed structures support is an
absence of arbitrary sized integers in CIR. Well, one workaround is to
use `mlir::IntegerType` for that, but it's kind of wrong way (please
correct me if I'm wrong). Another way is to introduce this type in CIR.
So far I suggest this way: instead of arbitrary sized integers we will
create an array of bytes for bitfield storages whenever they doesn't fit
into the CIR `IntType`.

Well, the original codegen creates storages with alignment 8 - so it can
be `i24` storage type for instance. Previously, we just created storages
that could be represented as CIR `IntType`: 8, 16, 32, 64. And it was
working before I came up with a necessity to support packed structures.
At first glance it's not a problem - just add `determinePacked` method
from the original codegen and that's it. But it turned out that this
method _infers_ the fact if a structure is packed or not. It doesn't use
the AST attribute for that as one could think - it works with offsets
and alignments of fields. Thus, we either need to invent our own way to
determine packed structures (which is error prone and maybe not doable
at all) or try to use the existing one. Also, we go closer to the
original lllvm's data layout in this case.

1) I had to move the lowering details from the `LoweringPrepare` to the
`LowerToLLVM`, because it's not possible to do a `load` from the array
of bytes to the integer type - and it's ok in llvm dialect. Thus, all
the math operations can be expressed without any problems. Basically the
most of the diff you see is because of the changes in the lowering. The
remaining part is more or less easy to read.
2) There are minor changes in `CIRRecordLayoutBuilder` - as described
above, we use may generate an array of bytes as a storage.
3) Some cosmetic changes in `CIRGenExpr` - since we don't want to infer
the storage type again and just use the one stored in the
`CIRGenBitFieldInfo`.
4) Helpers are introduced in the lowering - but nothing hard - just
shifts and logical ops.
5) I removed `bitfield-ops` test - because now the test cases covered
there are all in `bitfields.c` and `bitfields.cpp` .

So ... This is still a suggestion, though I believe it's a good one. So
you are welcome to discuss, suggest another ways to solve the problem
and etc.
lanza pushed a commit that referenced this pull request Nov 5, 2024
This PR adds MemRead/MemWrite markers to the `GetBitfieldOp` and
`SetBitfieldOp` (as discussed in #487)
Also, minor renaming in the `SetBitfieldOp`

---------

Co-authored-by: Bruno Cardoso Lopes <bcardosolopes@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants