-
Notifications
You must be signed in to change notification settings - Fork 349
Add support for opaque pointers #1064
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
Conversation
This also adds an option to fallback to typed pointers. In particular, if LLVMLITE_DISABLE_OPAQUE_POINTERS=1, typed pointers are used. In any other case, opaque pointers are used.
This lets us handle each type independently and supports a phased roll out of typed pointers. This patch also improves how certain instructions handle their types to reduce how much we rely in typed pointers.
|
I note that this works with LLVM 15 but not 14. Given the imminent move to LLVM 15, I think it's not worth fixing for 14. |
|
Hi @gmarkall thanks, sounds good! I'll push a fix for the flake8 tests failing soon as well. |
|
Note from triage discussion - for function types, round tripping the type of arguments should still be able to work (correct me if this is wrong, @sklam) |
Looks good. The usecase is solely for getting function type back into a I happen to notice that on LLVM14 parse_assembly do not like the opaque pointer despite it is enabled. Is that a LLVM bug? % python -m unittest llvmlite.tests.test_binding.TestTypeRef.test_typeref_as_ir_for_wrappers_of_cpp_vector_struct
<string>:5:55: warning: ptr type is only supported in -opaque-pointers mode
declare void @"_Z3foo8Vector2DPS_"(<2 x float> %".1", ptr %".2")
^
E
======================================================================
ERROR: test_typeref_as_ir_for_wrappers_of_cpp_vector_struct (llvmlite.tests.test_binding.TestTypeRef)
Exercise extracting C++ struct types that are passed as vectors.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/to/llvmlite/tests/test_binding.py", line 2091, in test_typeref_as_ir_for_wrappers_of_cpp_vector_struct
self._check_typeref_as_ir_for_wrappers(
File "/path/to/llvmlite/tests/test_binding.py", line 2062, in _check_typeref_as_ir_for_wrappers
new_mod = llvm.parse_assembly(str(wrapper_mod))
File "/path/to/llvmlite/binding/module.py", line 25, in parse_assembly
raise RuntimeError("LLVM IR parsing error\n{0}".format(errmsg))
RuntimeError: LLVM IR parsing error
<string>:5:55: error: expected type
declare void @"_Z3foo8Vector2DPS_"(<2 x float> %".1", ptr %".2") |
Perfect, thanks for having a look!
I'm not sure, most of CI seems to be failing for the same reason though. When I spoke with @gmarkall we concluded it was probably not worth fixing given llvmlite will be moving to LLVM 15 soon. I can look into it though if you think that'd be useful. |
|
Let's wait for LLVM15 becoming default |
|
That sounds great, do you have an estimate of when that will be? |
gmarkall
left a comment
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've had a look over this and experimented locally with it (not encountering any issues so far in doing that). I've left a couple of comments on the diff, and will have another pass following discussing them.
|
Hi @gmarkall, thanks for having had a look! I'll work on the proposed changes and update the review soon. In the meantime, I've also left a few comments in reply to yours. If you can, please let me know what you think and I'll include any further changes in the next update. |
* Change logic `_disable_opaque_pointers` → `opaque_pointers_enabled` * Make leading underscore from `opaque_pointers_enabled` * Move `LLVMPY_GlobalGetValueType` back to `value.cpp` * Reinstate `LLVMPY_ABISizeOfElementType` and `LLVMPY_ABIAlignmentOfElementType` with error if used in opaque pointer mode
|
Hi @gmarkall, I believe I've addressed most of your comments in the last commit, in particular:
Please let me know if you have any other comments! |
gmarkall
left a comment
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.
Thanks for the updates! I think this is getting there, but I have left a few comments on the diff.
To summarise a few points from our discussions relevant to the continuation of this PR:
- I will push changes to update the CI setup to test with opaque pointers enabled and disabled.
- I will push changes to add some documentation (this won't need to be a long section, I think)
- This PR enables a transitional state where we're supporting a lot of the typed pointer APIs even if we're using opaque pointers in the underlying LLVM binding. This means we can enable opaque pointer usage in Numba without making a large set of changes to it. Once we have confidence in the use of opaque pointers, we can then modify all its API usage to only use the opaque pointer variant of the APIs, allowing the eventual removal of the typed mode in llvmlite. This gives us a simple, gradual, and safe transition path for Numba.
Many thanks for your efforts so far!
| Create from a llvmlite.binding.TypeRef | ||
| """ | ||
| if not opaque_pointers_enabled: | ||
| return _TypedPointerType.from_llvm(typeref, ir_ctx) |
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 results in the _TypedPointerType.__init__() method getting called twice, because:
If new() is invoked during object construction and it returns an instance of cls, then the new instance’s init() method will be invoked like init(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to the object constructor.
(from https://docs.python.org/3/reference/datamodel.html#object.__new__) - it is called once because the _TypedPointerType() form of the call on this line results in a call to __new__() and __init__(), then after the return of this __new__(), the __init__() method is called again.
I think it needs to be:
| return _TypedPointerType.from_llvm(typeref, ir_ctx) | |
| return return super().__new__(_TypedPointerType) |
instead.
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 suggestion was a mistake - see https://github.com/numba/llvmlite/pull/1064/files#r1699988799
* Default to opaque pointers disabled * Move a few imports to the top level * Refactor `if` logic in a few constructors * Fix double-init issue
|
Hi @gmarkall, thanks very much for your comments, I believe I've addressed them in the latest revision, in particular:
Please let me know if you have any other comments. |
|
@rj-jesus Thanks for this, I think it looks good - I'll update the CI configuration and docs. |
|
@gmarkall Thank you very much for the feedback! Please let me know if you need help with anything. |
This patch adds a couple of examples on how to use the new opaque pointer builder interfaces. The examples are based on the already existing examples with the same name.
gmarkall
left a comment
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 think the code changes here are good. I've marked as "waiting on second reviewer" because I've added:
- CI setup that runs with opaque pointers enabled
- Documentation
that could do with a check from someone else.
rj-jesus
left a comment
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.
Hi @gmarkall, Thanks for these commits, I've had a look at the documentation and everything checks out, I've just left a minor comment. Please let me know if you need anything else.
| IR layer | ||
| ~~~~~~~~ | ||
|
|
||
| Modify uses of ``.type.pointee`` of instructions to use ``.allocated_type`` |
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.
Maybe it's worth noting this is only valid for alloca instructions since they have a clear "allocated type" (https://llvm.org/docs/doxygen/Instructions_8h_source.html#l00115).
sklam
left a comment
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.
Docs and CI looks good
|
thanks for the patch |
This patch supports the transition of llvmlite from typed to opaque pointers, making the latter the default.
It also includes the following significant changes:
_TypedPointerType; objects of this class are created automatically fromPointerType's when pointee types are known in a way that's transparent to users.