Skip to content

Eliminate redundant refcounting in the JIT #134584

Open
@Fidget-Spinner

Description

@Fidget-Spinner

Feature or enhancement

Proposal:

Thanks to Matt's work on borrowed LOAD_FAST, we can now eliminate reference counting trivially in the JIT.

Ideally, we should use the cases generator to automatically do this. However, as a simple proof of concept, I will start with manually doing it for floats, as those are special cased and need to be manually written anyways.

I will then build on this by automatically doing it in the cases generator by analyzing the bytecodes for the vast majority of the operations.

This will finally allow proper register allocation in the JIT, as we won't have to spill everywhere there's a PyStackRef_CLOSE or something.

How to contribute.

Now that reference tracking in the JIT optimizer is in place, the first thing we need to do is to convert ops to make the decref an explicit uop. Mark is working on a demo for ints, floats, strs. After he opens that PR, we can parallelize the work.

For escaping decref ops (ie, ops that decref could run the GC), we would need to refactor them so their decrefs are eliminated via specialization of pops. For example: the following op (which is not an escaping op, but just purely for demonstration!):

macro(BINARY_OP_ADD_INT) =
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_ADD_INT;

becomes

macro(BINARY_OP_ADD_INT) =
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_ADD_INT + _POP_TWO_SPECIALIZED_INT;

Previously _BINARY_OP_ADD_INT's stack effect looked like this: (left, right -- res). The new version should look like (left, right -- res, left, right).
So for all the decref specializations, we would just need a _POP_X of their variants! This means no explosion of uop and their decref variants. We just specialize _POP_X to _POP_X_NO_DECREF in the JIT. Keeping things clean

Please hold off for now:

  • Rewrite BINARY_OP_X_FLOAT
  • BINARY_OP_X_INT
  • BINARY_OP_X_STR
  • COMPARE_OP_X
    For the above, Mark is working on something.

For anything that is escaping (anything that operates on non-int/str/float), these are open for contributors to take!

Once that's done, we can think about further ops.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetopic-JITtype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions