Skip to content

[mypyc] Borrow references during chained attribute access #12805

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

Merged
merged 4 commits into from
May 18, 2022

Conversation

JukkaL
Copy link
Collaborator

@JukkaL JukkaL commented May 17, 2022

If we have multiple native attribute access operations in succession, we
can borrow the temporaries. This avoids an incref and decref. For
example, when evaluating x.y.z, we don't need to incref the result
of x.y.

We need to make sure that the objects from which we borrow
values are not freed too early by adding keep_alive ops.

This is part of a wider reference counting optimization workstream.
All the improvements together produced around 5% performance
improvement in the richards benchmark.

In carefully constructed microbenchmarks 50+% improvements are
possible.

@@ -105,6 +105,9 @@ def __init__(
self.blocks: List[BasicBlock] = []
# Stack of except handler entry blocks
self.error_handlers: List[Optional[BasicBlock]] = [None]
# Values that we need to keet alive as long as we have borrowed
Copy link
Member

Choose a reason for hiding this comment

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

Typo keet -> keep

@JukkaL JukkaL merged commit 74cfa3d into master May 18, 2022
@JukkaL JukkaL deleted the mypyc-refcount-getattr branch May 18, 2022 09:52
JukkaL added a commit that referenced this pull request May 19, 2022
Borrow an operand such as `x.y` (attribute of a native class) in various contexts 
when it's safe to do so. This reduces the number of incref/decref operations we 
need to perform. This continues work started in #12805.

These cases now support borrowing (for some subexpressions, in some contexts):
* `x.y is None`
* Cast source value
* `len(x.y)` (if the operand is a list)
* `isinstance(x.y, C)`
* `x.y[a.b]`
* `x.y.z = 1`
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