-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
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
Changes from 1 commit
222c9f5
f878d78
e3f4f8b
fa005f3
83ccea7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1387,21 +1387,28 @@ nop_out(cfg_instr **instrs, int size) | |
} | ||
} | ||
|
||
/* Does not steal reference to "newconst" */ | ||
static bool | ||
/* Does not steal reference to "newconst". | ||
Return 1 if changed instruction to LOAD_SMALL_INT. | ||
Return 0 if could not change instruction to LOAD_SMALL_INT. | ||
Return -1 on error. | ||
*/ | ||
static int | ||
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); | ||
if (val == -1 && PyErr_Occurred()) { | ||
return -1; | ||
} | ||
if (!overflow && _PY_IS_SMALL_INT(val)) { | ||
assert(_Py_IsImmortal(newconst)); | ||
INSTR_SET_OP1(instr, LOAD_SMALL_INT, (int)val); | ||
return true; | ||
return 1; | ||
} | ||
} | ||
return false; | ||
return 0; | ||
} | ||
|
||
|
||
|
@@ -1410,9 +1417,9 @@ static int | |
instr_make_load_const(cfg_instr *instr, PyObject *newconst, | ||
PyObject *consts, PyObject *const_cache) | ||
{ | ||
if (maybe_instr_make_load_smallint(instr, newconst, consts, const_cache)) { | ||
assert(instr->i_opcode == LOAD_SMALL_INT); | ||
return SUCCESS; | ||
int res = maybe_instr_make_load_smallint(instr, newconst, consts, const_cache); | ||
if (res) { | ||
return res == -1 ? ERROR : SUCCESS; | ||
} | ||
int oparg = add_const(newconst, consts, const_cache); | ||
RETURN_IF_ERROR(oparg); | ||
|
@@ -2054,8 +2061,11 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject * | |
cfg_instr *inst = &bb->b_instr[i]; | ||
if (inst->i_opcode == LOAD_CONST) { | ||
PyObject *constant = get_const_value(inst->i_opcode, inst->i_oparg, consts); | ||
(void)maybe_instr_make_load_smallint(inst, constant, consts, const_cache); | ||
int res = maybe_instr_make_load_smallint(inst, constant, consts, const_cache); | ||
Py_DECREF(constant); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
if (res < 0) { | ||
return ERROR; | ||
} | ||
Comment on lines
+2070
to
+2072
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok. |
||
} | ||
bool is_copy_of_load_const = (opcode == LOAD_CONST && | ||
inst->i_opcode == COPY && | ||
|
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.
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
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.