Description
Currently there are two parts that we repeat a ton in the types specializer:
- Constant evaluation.
- Setting the type/constant value.
Item 1. will be solved by python/cpython#132732
For item 2., I propose the following type annotations (again) to our current DSL, specific only to the optimizer DSL. This means no change to bytecodes.c
, only to optimizer_bytecodes.c
.
For example,
Current:
op(_GUARD_TOS_INT, (tos -- tos)) {
sym_set_type(tos, &PyLong_Type);
}
Improved
op(_GUARD_TOS_INT, (tos -- tos PyLong_Type)) {
}
The code generator generates sym_set_type/sym_new_type
automatically (depending on peek or not respectively).
Constant type values:
Current:
op(_GUARD_IS_TRUE_POP, (flag -- )) {
sym_set_const(flag, Py_False);
}
Improved:
op(_GUARD_IS_TRUE_POP, (flag const Py_False -- )) {
}
The code generator generates sym_set_const
automatically.
I chose name type
instead of name: type
as name: type
already represents casting in the exiting bytecodes DSL, and I want to avoid confusion. An alternative notation we can use is name :: type
or type name
.
This will save a huge amount of manual handwriting and also express our intentions more clearly in the DSL, rather than having to involve ourselves with the C internals of the types specializer. Errors/bugs may also become more obvious as it's part of the DSL rather than part of a gigantic C body.
We should keep the codegen simple. As others have pointed out the cases generator is getting quite complex. This means we still allow falling back to sym_set_*
for complex cases that the DSL cannot handle, such as conditionally setting the type. The main savings are for the bulk of operations that are simple and mostly menial to add type information. Check out this issue python/cpython#131798, where Brandt points out we have a ton of uops (over 100) left to add type information. I don't think it's ergonomic to handwrite all of this manually. It's almost repetitive even.