Skip to content

Conversation

@rj-jesus
Copy link
Contributor

This patch supports the transition of llvmlite from typed to opaque pointers, making the latter the default.

It also includes the following significant changes:

  • Adds the option to fallback to typed pointers; in particular, if LLVMLITE_DISABLE_OPAQUE_POINTERS=1, typed pointers are used.
  • Decouples pointee data from llvmlite pointers, moving it to a new class _TypedPointerType; objects of this class are created automatically from PointerType's when pointee types are known in a way that's transparent to users.
  • Adds explicit types to certain instructions (e.g., loads, gep, etc.) to enable phasing out pointee types on a case-by-case basis.

rj-jesus added 2 commits June 17, 2024 14:05
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.
@gmarkall gmarkall self-requested a review June 25, 2024 15:43
@gmarkall
Copy link
Member

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.

@rj-jesus
Copy link
Contributor Author

Hi @gmarkall thanks, sounds good! I'll push a fix for the flake8 tests failing soon as well.

@rj-jesus
Copy link
Contributor Author

@sklam I believe this affects #1051. Do you have any thoughts on the changes in llvmlite/ir/types.py to PointerType to accommodatefrom_llvm on opaque pointers?

@gmarkall
Copy link
Member

gmarkall commented Jul 2, 2024

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)

@gmarkall gmarkall requested a review from sklam July 2, 2024 14:25
@gmarkall gmarkall added this to the v0.44.0 milestone Jul 2, 2024
@sklam
Copy link
Member

sklam commented Jul 2, 2024

@sklam I believe this affects #1051. Do you have any thoughts on the changes in llvmlite/ir/types.py to PointerType to accommodatefrom_llvm on opaque pointers?

Looks good. The usecase is solely for getting function type back into a ir.Type and all of that is still working as expected.

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")

@rj-jesus
Copy link
Contributor Author

rj-jesus commented Jul 3, 2024

Looks good. The usecase is solely for getting function type back into a ir.Type and all of that is still working as expected.

Perfect, thanks for having a look!

I happen to notice that on LLVM14 parse_assembly do not like the opaque pointer despite it is enabled. Is that a LLVM bug?

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.

@sklam
Copy link
Member

sklam commented Jul 8, 2024

Let's wait for LLVM15 becoming default

@rj-jesus
Copy link
Contributor Author

rj-jesus commented Jul 9, 2024

That sounds great, do you have an estimate of when that will be?

Copy link
Member

@gmarkall gmarkall left a 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.

@rj-jesus
Copy link
Contributor Author

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
@rj-jesus
Copy link
Contributor Author

Hi @gmarkall, I believe I've addressed most of your comments in the last commit, in particular:

  • Change logic _disable_opaque_pointersopaque_pointers_enabled
  • Remove 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

Please let me know if you have any other comments!

Copy link
Member

@gmarkall gmarkall 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 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:

  1. I will push changes to update the CI setup to test with opaque pointers enabled and disabled.
  2. I will push changes to add some documentation (this won't need to be a long section, I think)
  3. 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)
Copy link
Member

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:

Suggested change
return _TypedPointerType.from_llvm(typeref, ir_ctx)
return return super().__new__(_TypedPointerType)

instead.

Copy link
Member

Choose a reason for hiding this comment

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

* Default to opaque pointers disabled
* Move a few imports to the top level
* Refactor `if` logic in a few constructors
* Fix double-init issue
@rj-jesus
Copy link
Contributor Author

rj-jesus commented Aug 1, 2024

Hi @gmarkall, thanks very much for your comments, I believe I've addressed them in the latest revision, in particular:

  • We now default to opaque pointers disabled
  • Moved a few imports to the top-level
  • Refactored if logic in a few constructors
  • Fixed double-init issue you pointed out

Please let me know if you have any other comments.

@gmarkall
Copy link
Member

gmarkall commented Aug 6, 2024

@rj-jesus Thanks for this, I think it looks good - I'll update the CI configuration and docs.

@rj-jesus
Copy link
Contributor Author

rj-jesus commented Aug 6, 2024

@gmarkall Thank you very much for the feedback! Please let me know if you need help with anything.

gmarkall and others added 4 commits August 7, 2024 11:44
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.
Copy link
Member

@gmarkall gmarkall left a 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.

Copy link
Contributor Author

@rj-jesus rj-jesus left a 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``
Copy link
Contributor Author

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).

Copy link
Member

@sklam sklam left a 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

@esc
Copy link
Member

esc commented Sep 18, 2024

thanks for the patch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants