-
Notifications
You must be signed in to change notification settings - Fork 96
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
Conversation
Sorry for the delay here, taking a look next week! |
Rebased onto the latest |
There was a problem hiding this 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?
llvm::TypeSize | ||
MethodType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, | ||
mlir::DataLayoutEntryListRef params) const { | ||
// TODO: consider size differences under different ABIs |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
- 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) - On 32-bit platforms both of
fnptr_t
andptrdiff_t
becomeint32_t
and the member function pointer size changes as well. - 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 }
.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
5a70a59
to
09c3c4a
Compare
09c3c4a
to
36e644a
Compare
Rebased onto the latest |
There was a problem hiding this 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.
llvm::TypeSize | ||
MethodType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, | ||
mlir::DataLayoutEntryListRef params) const { | ||
// TODO: consider size differences under different ABIs |
There was a problem hiding this comment.
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?
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.
36e644a
to
e827663
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, LGTM
…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.
…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.
…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.
…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.
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 tonon-virtualmember 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.