Description
Please don't work on this. I'm planning on sprinting on this with new contributors at an event this weekend.
Currently, the JIT optimizer uses the _COMPARE_OP
family, _CONTAINS_OP
, _IS_OP
, and the _TO_BOOL
family to narrow the types of the input values and the type of the output value.
However, by "peeking ahead" and seeing how a value will be used, we can narrow these types to constants as well. As a simple example, consider _TO_BOOL_INT + _GUARD_IS_FALSE_CHECK
on an unknown value. After the _TO_BOOL_INT
, it can be narrowed to a known class, int
(we do this today). However, after the _GUARD_IS_FALSE_CHECK
, we can actually narrow it to a constant value, 0
.
An example implementation of this idea for _TO_BOOL_BOOL
is here: main...brandtbucher:cpython:hack-night-to-bool-bool
I've divided this work into 3 "waves" of increasing complexity. Tasks in bold are probably a bit harder, tasks in italics are probably a bit easier.
Narrow types to constants in branches involving truthiness:
-
_TO_BOOL + _GUARD_IS_*_POP
-
_TO_BOOL_BOOL + _GUARD_IS_*_POP
-
_TO_BOOL_INT + _GUARD_IS_*_POP
-
_TO_BOOL_LIST + _GUARD_IS_*_POP
-
_TO_BOOL_STR + _GUARD_IS_*_POP
Narrow types to constants in branches involving comparisons with a constant:
-
_COMPARE_OP + _GUARD_IS_*_POP
(==
,!=
) -
_COMPARE_OP_FLOAT + _GUARD_IS_*_POP
(==
,!=
) -
_COMPARE_OP_INT + _GUARD_IS_*_POP
(==
,!=
) -
_COMPARE_OP_STR + _GUARD_IS_*_POP
(==
,!=
) -
_CONTAINS_OP + _GUARD_IS_*_POP
(in
,not in
) -
_IS_OP + _GUARD_IS_*_POP
(is
,is not
)
Evaluate comparisons involving two constants:
This is related, but a bit more involved, since we need a way to pop two values from the stack and push a constant (_POP_TWO_LOAD_CONST_INLINE_BORROW
). We should also teach remove_unneeded_uops
about this new instruction.
-
_COMPARE_OP
(==
,!=
,<
,>
,<=
,>=
) -
_COMPARE_OP_FLOAT
(==
,!=
,<
,>
,<=
,>=
) -
_COMPARE_OP_INT
(==
,!=
,<
,>
,<=
,>=
) -
_COMPARE_OP_STR
(==
,!=
,<
,>
,<=
,>=
) -
_CONTAINS_OP
(in
,not in
) -
_IS_OP
(is
,is not
)