faster-cpython / ideas

1.67k stars 49 forks source link

Superblock optimization: Specialization #560

Open markshannon opened 1 year ago

markshannon commented 1 year ago

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:

Fidget-Spinner commented 6 months ago

Just checking -- the global checks you are referring to are what _CHECK_VALIDITY are for right?