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] Bitfield operations #279

Merged
merged 20 commits into from
Nov 30, 2023
Merged

Conversation

gitoleg
Copy link
Collaborator

@gitoleg gitoleg commented Oct 11, 2023

As we discussed in #233, there is a desire to have CIR operations for bit fields set/get access and do all the stuff in the LoweringPrepare.

There is one thing I want to discuss, that's why the PR is marked as a draft now.
Looks like I have to introduce some redundant helpers for all these or and shift operations: while we were in the CodeGen area, we used CIRGenBuilder and we could easily extend it. I bet we don't want to depend from CodeGen in the LoweringPrepare. Once it's true. what is a good place for all this common things? As an idea, we could introduce one more layer for builder, with no state involved - just helpers and nothing else. But again, what is a good place for it from your point of view?

@bcardosolopes
Copy link
Member

There is one thing I want to discuss, that's why the PR is marked as a draft now.
Looks like I have to introduce some redundant helpers for all these or and shift operations: while we were in the CodeGen area, we used CIRGenBuilder and we could easily extend it. I bet we don't want to depend from CodeGen in the LoweringPrepare. Once it's true. what is a good place for all this common things? As an idea, we could introduce one more layer for builder, with no state involved - just helpers and nothing else. But again, what is a good place for it from your point of view?

This is a good idea, maybe something like Dialect/Builder? Any suggestion? Another possible solution is to put these things in clang/include/clang/CIR/Dialect/IR/CIRDialect.h for now and if it keeps growing you could move to another directory. Maybe Dialect/Builder would be best? Ideally if the codegen builder can end up reusing the same component that is also great.

@gitoleg
Copy link
Collaborator Author

gitoleg commented Oct 20, 2023

@bcardosolopes Summary, what's done

  1. most of the helpers from the CIRGenBuilder moved to the CIRBaseBuilder, the latter is a parent of the former now. The CIRBaseBuilder has no state, hence the helpers there.
  2. added expamples to the description of the operations. Don't know if it's really necessary, since the bitfield operations are erased on the LoweringPrepare stage

@gitoleg gitoleg marked this pull request as ready for review October 20, 2023 08:49
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.

Thanks for putting more effort on this.

  • Can you move the changes for CIRGenBuilder.h and helpers that aren't related with the added instructions to another pre-requisite PR? Should be an easy merge.
  • Can you add start adding testcases? Hard to look into PRs without testcases to play with.

Cheers!

clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
@bcardosolopes
Copy link
Member

2. added expamples to the description of the operations. Don't know if it's really necessary, since the bitfield operations are erased on the LoweringPrepare stage

Definitely useful for analysis paths before lowering prepare though!

@gitoleg
Copy link
Collaborator Author

gitoleg commented Oct 23, 2023

Can you add start adding testcases? Hard to look into PRs without testcases to play with.

well ... Is it possible to write tests that will work with cir before LoweringPrepare pass?
Otherwise, once the current bitfield tests work - we may think it's enough

@bcardosolopes
Copy link
Member

well ... Is it possible to write tests that will work with cir before LoweringPrepare pass?

Yes, plain -emit-cir will give you that. LoweringPrepare only really runs before -emit-llvm.

@bcardosolopes
Copy link
Member

Can you please rebase? @lanza applied one rebase against upstream round, and github is now confused!

@gitoleg
Copy link
Collaborator Author

gitoleg commented Oct 31, 2023

@bcardosolopes

Yes, plain -emit-cir will give you that. LoweringPrepare only really runs before -emit-llvm.

well, it could be a chance that something is wrong on my side, but I don't see any of these operations with -emit-cir. More than, old bitfields tests work with no changes from my side, i.e. with expectation of all these shifts, or-s and etc. Looks like loweringPrepare works in any case.

Speaking about custom asm - I can suggest to use just s-exp, as they are good for this amount of information I have to dump. Otherwise, I can fix it, and use any other separator on your taste.

So far I will prepare a separate PR for the builder.

bcardosolopes pushed a commit that referenced this pull request Nov 1, 2023
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
@bcardosolopes
Copy link
Member

well, it could be a chance that something is wrong on my side, but I don't see any of these operations with -emit-cir. More than, old bitfields tests work with no changes from my side, i.e. with expectation of all these shifts, or-s and etc. Looks like loweringPrepare works in any case.

We need tests that exercise what gets created by createSetBitfield and others. There's an example in clang/test/CIR/CodeGen/static.cpp.

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.

Thanks for the fixes, one more round of reviews!

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
@gitoleg
Copy link
Collaborator Author

gitoleg commented Nov 2, 2023

@bcardosolopes
ready!

Also, please add an alias for it in AliasResult getAlias(Attribute attr, raw_ostream &os) in CIRDialect.cpp so that operations can refer to an easy #bitfield_fileXYZ

Well, I'm not sure I did it right, I just dump the name as an alias for the whole bitfield info

Also, the next thought came to my mind: there is kind of redundancy or even something that is not really clean or clear. Look, we first emit get_member in order to have an access to a storage where a bitfield resides, and then call get_bitfield or set_bitfield:

%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!ty_22S22> -> !cir.ptr<!u32i>
%4 = cir.get_bitfield %3(#d) : !cir.ptr<!u32i> -> !s32i

Note, that in the get_member call we see the name of the bitfield, though it's not true - we just want to access a storage by index 1.
I would try to emit get_member in the LoweringPrepare as well, i.e. leave only get/set bitfield in the code before this pass. What do you think? if it's ok - I will prepare a separate PR once this one will be merged.

@bcardosolopes
Copy link
Member

bcardosolopes commented Nov 3, 2023

Note, that in the get_member call we see the name of the bitfield, though it's not true - we just want to access a storage by index 1.

The name is not really necessary, but we like to keep it around for making CIR a bit easier to read. Might be worth removing in the future, but should be good for now.

I would try to emit get_member in the LoweringPrepare as well, i.e. leave only get/set bitfield in the code before this pass. What do you think? if it's ok - I will prepare a separate PR once this one will be merged.

I can see where you come from, but turns out it's important that the get_member is explicit because we can always track the uses of structs by looking at those ops. If we instead embed it in {get,set}bitfield we now have to track one more operation for detecting member access in every analysis we could write.

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.

This is awesome, almost there. Thanks for adding the testcases and improving docs.

clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
@gitoleg
Copy link
Collaborator Author

gitoleg commented Nov 7, 2023

@bcardosolopes
one more round of changes is ready)

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.

Awesome, one last bit and this is ready to land.

clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
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.

One more comment on printing and needs rebasing!

clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
@gitoleg
Copy link
Collaborator Author

gitoleg commented Nov 30, 2023

@bcardosolopes don't forget about this one)

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.

Thanks for your patience, good to go!

@bcardosolopes bcardosolopes merged commit 4d5687a into llvm:main Nov 30, 2023
1 check passed
lanza pushed a commit that referenced this pull request Dec 20, 2023
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
lanza pushed a commit that referenced this pull request Dec 20, 2023
As we discussed in #233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
lanza pushed a commit that referenced this pull request Jan 29, 2024
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
lanza pushed a commit that referenced this pull request Jan 29, 2024
As we discussed in #233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
lanza pushed a commit that referenced this pull request Mar 23, 2024
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
lanza pushed a commit that referenced this pull request Mar 23, 2024
As we discussed in #233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
As discussed in llvm#279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
As we discussed in llvm#233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
As discussed in llvm#279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Mar 24, 2024
As we discussed in llvm#233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
lanza pushed a commit that referenced this pull request Apr 29, 2024
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
lanza pushed a commit that referenced this pull request Apr 29, 2024
As we discussed in #233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
lanza pushed a commit that referenced this pull request Apr 29, 2024
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
lanza pushed a commit that referenced this pull request Apr 29, 2024
As we discussed in #233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Apr 29, 2024
As discussed in llvm#279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
eZWALT pushed a commit to eZWALT/clangir that referenced this pull request Apr 29, 2024
As we discussed in llvm#233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
lanza pushed a commit that referenced this pull request Apr 29, 2024
As discussed in #279, we split `CIRGenBuilder` in two parts, which make
some of the helpers usable outside of the `CodeGen` part.
Basically, I placed casts and binary operations into a separate class,
`CIRBaseBuilder`. Later, it can be extended with another helpers. But
right now an idea to have a state less builder as a base one.
lanza pushed a commit that referenced this pull request Apr 29, 2024
As we discussed in #233, there is a desire to have CIR operations for
bit fields set/get access and do all the stuff in the `LoweringPrepare`.

There is one thing I want to discuss, that's why the PR is marked as a
draft now.
Looks like I have to introduce some redundant helpers for all these `or`
and `shift` operations: while we were in the `CodeGen` area, we used
`CIRGenBuilder` and we could easily extend it. I bet we don't want to
depend from `CodeGen` in the `LoweringPrepare`. Once it's true. what is
a good place for all this common things? As an idea, we could introduce
one more layer for builder, with no state involved - just helpers and
nothing else. But again, what is a good place for it from your point of
view?
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.

None yet

2 participants