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][CIRGen] Add CIRGen support for pointer-to-member-functions #722

Merged
merged 1 commit into from
Aug 20, 2024

Conversation

Lancern
Copy link
Member

@Lancern Lancern commented Jul 6, 2024

This PR adds the initial CIRGen support for pointer-to-member-functions. It contains the following new types, attributes, and operations:

  • !cir.method, which represents the pointer-to-member-function type.
  • #cir.method, which represents a literal pointer-to-member-function value that points to non-virtual member functions.
  • #cir.virtual_method, which represents a literal pointer-to-member-function value that points to virtual member functions.
  • cir.get_method_callee cir.get_method, which resolves a pointer-to-member-function to a function pointer as the callee.

See the new test at clang/test/CIR/CIRGen/pointer-to-member-func.cpp for how these new CIR stuff works to support pointer-to-member-functions.

@bcardosolopes
Copy link
Member

Sorry for the delay here, taking a look next week!

@Lancern
Copy link
Member Author

Lancern commented Jul 28, 2024

Rebased onto the latest main.

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 cool, a nice missing feature!

Some comments inline. Should I assume lowering prepare LLVM comes next?

clang/include/clang/CIR/Dialect/IR/CIROps.td Outdated Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRDialect.cpp Outdated Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRDialect.cpp Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRDialect.cpp Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
llvm::TypeSize
MethodType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
// TODO: consider size differences under different ABIs
Copy link
Member

Choose a reason for hiding this comment

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

We already have a better ABI infra, you should implement what's necessary here, at least for one target.

Copy link
Member Author

Choose a reason for hiding this comment

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

How should I query for ABI specific information in the data layout interface? Btw this problem also exists in ABI-related other types such as pointers and members.

Copy link
Member

Choose a reason for hiding this comment

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

I was thinking about forwarding the question to the actual behavior this corresponds in the lower level. For example: !cir.method<!cir.func<!void (!s32i)> in !ty_22Foo22>, is this ends up being a pair of integer? I see LLVM generates:

define dso_local { i64, i64 } @make_virtual()() {
  ret { i64, i64 } { i64 9, i64 0 }, !dbg !22
}

We could say that the getTypeSizeInBits here is the getTypeSizeInBits of a struct { i64, i64 };. Perhaps it's equivalent to the size of a pair of two pointer ABI size? Seems like we can compose an answer here. By the way, where does llvm::TypeSize::getFixed(128) comes from?

Copy link
Member Author

Choose a reason for hiding this comment

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

This could be more subtle. The Itanium ABI actually defines the layout of a member function pointer as something like struct { fnptr_t, ptrdiff_t } where fnptr_t is the type for normal function pointers. Thus on most 64-bit platforms a member function pointer will end up being a struct { int64_t, int64_t }, and its size is 128 bits, thus the default implementation llvm::TypeSize::getFixed(128).

Three points worth mentioning here:

  1. Nothing in the standard stops ptrdiff_t from having a different size or alignment requirement than a normal pointer. (but this is rare and I doubt if there are any implementations doing this)
  2. On 32-bit platforms both of fnptr_t and ptrdiff_t become int32_t and the member function pointer size changes as well.
  3. In MSVC ABI a member function pointer has the same layout as a single function pointer, which is totally different from Itanium ABI.

For now we're focusing on the Itanium ABI only, so maybe let's first tackle the second point. A better type size query implementation for the member function pointers would then be the size of a struct { pointer, pointer }.

Copy link
Member

Choose a reason for hiding this comment

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

For now we're focusing on the Itanium ABI only, so maybe let's first tackle the second point. A better type size query implementation for the member function pointers would then be the size of a struct { pointer, pointer }.

Sounds good to me, please change it to the size of a struct { pointer, pointer } and add a missing feature assert for MSVC ABI.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

@Lancern
Copy link
Member Author

Lancern commented Aug 11, 2024

Rebased onto the latest main.

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.

Sorry, I just realized I had pending commits that I didn't submit. Updated.

clang/lib/CIR/Dialect/IR/CIRDialect.cpp Show resolved Hide resolved
llvm::TypeSize
MethodType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
// TODO: consider size differences under different ABIs
Copy link
Member

Choose a reason for hiding this comment

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

I was thinking about forwarding the question to the actual behavior this corresponds in the lower level. For example: !cir.method<!cir.func<!void (!s32i)> in !ty_22Foo22>, is this ends up being a pair of integer? I see LLVM generates:

define dso_local { i64, i64 } @make_virtual()() {
  ret { i64, i64 } { i64 9, i64 0 }, !dbg !22
}

We could say that the getTypeSizeInBits here is the getTypeSizeInBits of a struct { i64, i64 };. Perhaps it's equivalent to the size of a pair of two pointer ABI size? Seems like we can compose an answer here. By the way, where does llvm::TypeSize::getFixed(128) comes from?

@bcardosolopes
Copy link
Member

Also one conflict

This patch adds the initial CIRGen support for pointer-to-member-functions. It
contains the following new types, attributes, and operations:

  - `!cir.method`, which represents the pointer-to-member-function type.
  - `#cir.method`, which represents a literal pointer-to-member-function value
    that points to member functions.
  - `cir.get_method`, which resolves a pointer-to-member-function to a function
    pointer as the callee.

See the new test at `clang/test/CIR/CIRGen/pointer-to-member-func.cpp` for how
these new CIR stuff works to support pointer-to-member-functions.
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, LGTM

@bcardosolopes bcardosolopes merged commit 1006c88 into llvm:main Aug 20, 2024
6 checks passed
@Lancern Lancern deleted the member-func-ptr branch August 21, 2024 06:39
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
…m#722)

This PR adds the initial CIRGen support for pointer-to-member-functions.
It contains the following new types, attributes, and operations:

  - `!cir.method`, which represents the pointer-to-member-function type.
- `#cir.method`, which represents a literal pointer-to-member-function
value that points to ~~non-virtual~~ member functions.
- ~~`#cir.virtual_method`, which represents a literal
pointer-to-member-function value that points to virtual member
functions.~~
- ~~`cir.get_method_callee`~~ `cir.get_method`, which resolves a
pointer-to-member-function to a function pointer as the callee.

See the new test at `clang/test/CIR/CIRGen/pointer-to-member-func.cpp`
for how these new CIR stuff works to support
pointer-to-member-functions.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…m#722)

This PR adds the initial CIRGen support for pointer-to-member-functions.
It contains the following new types, attributes, and operations:

  - `!cir.method`, which represents the pointer-to-member-function type.
- `#cir.method`, which represents a literal pointer-to-member-function
value that points to ~~non-virtual~~ member functions.
- ~~`#cir.virtual_method`, which represents a literal
pointer-to-member-function value that points to virtual member
functions.~~
- ~~`cir.get_method_callee`~~ `cir.get_method`, which resolves a
pointer-to-member-function to a function pointer as the callee.

See the new test at `clang/test/CIR/CIRGen/pointer-to-member-func.cpp`
for how these new CIR stuff works to support
pointer-to-member-functions.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…m#722)

This PR adds the initial CIRGen support for pointer-to-member-functions.
It contains the following new types, attributes, and operations:

  - `!cir.method`, which represents the pointer-to-member-function type.
- `#cir.method`, which represents a literal pointer-to-member-function
value that points to ~~non-virtual~~ member functions.
- ~~`#cir.virtual_method`, which represents a literal
pointer-to-member-function value that points to virtual member
functions.~~
- ~~`cir.get_method_callee`~~ `cir.get_method`, which resolves a
pointer-to-member-function to a function pointer as the callee.

See the new test at `clang/test/CIR/CIRGen/pointer-to-member-func.cpp`
for how these new CIR stuff works to support
pointer-to-member-functions.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
…m#722)

This PR adds the initial CIRGen support for pointer-to-member-functions.
It contains the following new types, attributes, and operations:

  - `!cir.method`, which represents the pointer-to-member-function type.
- `#cir.method`, which represents a literal pointer-to-member-function
value that points to ~~non-virtual~~ member functions.
- ~~`#cir.virtual_method`, which represents a literal
pointer-to-member-function value that points to virtual member
functions.~~
- ~~`cir.get_method_callee`~~ `cir.get_method`, which resolves a
pointer-to-member-function to a function pointer as the callee.

See the new test at `clang/test/CIR/CIRGen/pointer-to-member-func.cpp`
for how these new CIR stuff works to support
pointer-to-member-functions.
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