-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
gh-130480: Move duplicate LOAD_SMALL_INT
optimization from codegen to CFG
#130481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
if (maybe_instr_make_load_smallint(inst, constant, consts, const_cache)) { | ||
assert(inst->i_opcode == LOAD_SMALL_INT); | ||
} | ||
Py_DECREF(constant); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For small ints this is effectively no-op as they are immortal, but it helps readability because get_const_value
returns new reference.
Overall, I think this change isn't worthwhile. It doesn't seem to simplify the code at all, but it will slow down the compiler by introducing extra values into the constant array, which then need removing again. |
@markshannon are we ok with having this logic in 2 places then? Also what is your take on #130016? |
What logic in two places? |
@markshannon this: Lines 1414 to 1422 in 8058390
&& Lines 284 to 291 in 8058390
|
3ecb918
to
f878d78
Compare
LOAD_SMALL_INT
optimization from codegen to CFGLOAD_SMALL_INT
optimization from codegen to CFG
@iritkatriel can I ask you to review? |
@@ -1584,7 +1587,8 @@ async def async_def(): | |||
Stack size: \\d+ | |||
Flags: OPTIMIZED, NEWLOCALS, COROUTINE | |||
Constants: | |||
0: None | |||
0: 1 | |||
1: None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are the constants [1, None]? I thought we always have None
in index 0 when there is no docstring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOAD_CONST 0 (1)
is added as the first constant, LOAD_CONST 1 (None)
is added as the second constant by _PyCodegen_AddReturnAtEnd
. Currently there is 1 slot that is always preserved for constant (in case it is docstring) at index 0. 1
is used constant, so it makes to the final co_consts
list, and we have 2 elements in it. Since 1
came first (therefore has lower index), it is first in the final co_consts
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is #130016 that addresses unused docstring slot which causes confusion.
/* Does not steal reference to "newconst" */ | ||
static bool | ||
maybe_instr_make_load_smallint(cfg_instr *instr, PyObject *newconst, | ||
PyObject *consts, PyObject *const_cache) | ||
{ | ||
if (PyLong_CheckExact(newconst)) { | ||
int overflow; | ||
long val = PyLong_AsLongAndOverflow(newconst, &overflow); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value of PyLong_AsLongAndOverflow
needs to be checked for error. Does this mean that maybe_instr_make_load_smallint should also return int, with -1 for error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value of PyLong_AsLongAndOverflow needs to be checked for error
I think it was not checked before due to PyLong_CheckExact
guard, but I agree we should check it anyway. This is by the way not the only place where this pattern occurs, for example:
cpython/Modules/_cursesmodule.c
Lines 378 to 383 in 10cbd1f
else if (PyLong_CheckExact(obj)) { | |
int long_overflow; | |
value = PyLong_AsLongAndOverflow(obj, &long_overflow); | |
if (long_overflow) | |
goto overflow; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
if (res < 0) { | ||
return ERROR; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RETURN_IF_ERROR(res);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe_instr_make_load_smallint
does not return SUCCESS
nor ERROR
explicitly, so I am not sure we should do it like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
LOAD_SMALL_INT
optimization from codegen to CFG #130480cc @Eclips4 @tomasr8