-
Notifications
You must be signed in to change notification settings - Fork 52
Description
Taking the example superblock (removing the SAVE_IP for clarity, they are removed properly by a later pass)
CHECK_GLOBALS_DICT_KEY_VERSION
LOAD_GLOBAL_MODULE_UNCHECKED (typing)
CHECK_MODULE_DICT_VERSION
LOAD_ATTR_MODULE_UNCHECKED 3 (NULL|self + cast)
CHECK_BUILTINS_DICT_KEY_VERSION
LOAD_GLOBAL_BUILTINS_UNCHECKED (int)
LOAD_FAST 0 (x)
CHECK_FUNCTION_VERSION
PUSH_FRAME
CHECK_EVAL_BREAKER
LOAD_FAST 1 (val)
RETURN_VALUE
STORE_FAST 0 (x)
CHECK_GLOBALS_DICT_KEY_VERSION
LOAD_GLOBAL_MODULE_UNCHECKED (unpredicable)
EXIT # Can't predict where we are going
Specialization is mostly performed when generating the superblock, but there will still be redundancy.
E.g. in the example above, the final CHECK_GLOBALS_DICT_KEY_VERSION
can be removed the global's dict key has already been checked.
We can also remove some checks by moving from inline checks to global checks.
E.g. we can remove the CHECK_BUILTINS_DICT_KEY_VERSION
and deoptimization (discard) the superblock should the builtins dict ever change. We can also remove the function version check and replace the CHECK_MODULE_DICT_VERSION; LOAD_ATTR_MODULE_UNCHECKED
with LOAD_CONST
by adding a global check on the module's dictionary.
Applying these optimizations we get something like:
LOAD_CONST (typing)
POP_TOP
LOAD_CONST (typing.cast)
LOAD_CONST (int)
LOAD_FAST 0 (x)
PUSH_FRAME 2
CHECK_EVAL_BREAKER
LOAD_FAST 1 (val)
RETURN_VALUE
STORE_FAST 0 (x)
LOAD_GLOBAL_MODULE_UNCHECKED (unpredicable)
EXIT # Can't predict where we are going
The resulting superblock is invalidated if any of the following occur:
- The
typing
module's__dict__
is modified. - The function
typing.cast
changes - The builtins dict changes