Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions Python/flowgraph.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Member

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?

Copy link
Contributor Author

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:

else if (PyLong_CheckExact(obj)) {
int long_overflow;
value = PyLong_AsLongAndOverflow(obj, &long_overflow);
if (long_overflow)
goto overflow;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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;
}


Expand All @@ -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);
Expand Down Expand Up @@ -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);
Copy link
Contributor Author

@WolframAlph WolframAlph Feb 23, 2025

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.

if (res < 0) {
return ERROR;
}
Comment on lines +2070 to +2072
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RETURN_IF_ERROR(res);

Copy link
Contributor Author

@WolframAlph WolframAlph Mar 14, 2025

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.

Copy link
Member

Choose a reason for hiding this comment

The 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 &&
Expand Down
Loading