Merging LOAD_METHOD and LOAD_ATTR for better specialization · faster-cpython/ideas · Discussion #400 (original) (raw)

I'm suggesting using the specializer instead of the compiler. Using your example again,

LOAD_FAST                0 (x)
LOAD_METHOD              0 (m)    # Pushes NULL, type(x).m
CALL

If m is an instance attribute the specializer does this:

LOAD_FAST                0 (x)
LOAD_ATTR                01 (m)    # Pushes NULL, m
CALL

Eventually, the specializer just specializes that as a typical LOAD_ATTR. And we get all the benefits of that.

This transformation isn't one way, if the LOAD_ATTR_ADAPTIVE index<<1 | 1 instruction at specialization time notices that it's commonly dealing with unbound methods, then it can specialize to LOAD_METHOD. Note that LOAD_ATTR index<<1 | 1 only exists as a specialized form of LOAD_METHOD. It cannot appear via other means.

This makes LOAD_METHOD and LOAD_ATTR index<<1 | 1 interchangeable by the specializer. So the state diagram is something like this:

image

If we don't want it to be two way, inline_cache_entries(LOAD_METHOD) >= inline_cache_entries(LOAD_ATTR). But if we want them to be interchangeable, their inline cache entry counts must be identical.