Skip to content

gh-130480: Move duplicate LOAD_SMALL_INT optimization from codegen to CFG - #130481

Merged
iritkatriel merged 5 commits into
python:mainfrom
WolframAlph:move-smallint
Mar 14, 2025
Merged

gh-130480: Move duplicate LOAD_SMALL_INT optimization from codegen to CFG#130481
iritkatriel merged 5 commits into
python:mainfrom
WolframAlph:move-smallint

Conversation

@WolframAlph

@WolframAlphWolframAlph commented Feb 23, 2025

Copy link
Copy Markdown
Contributor

Comment threadPython/flowgraph.c
if (maybe_instr_make_load_smallint(inst, constant, consts, const_cache)) {
assert(inst->i_opcode == LOAD_SMALL_INT);
}
Py_DECREF(constant);

@WolframAlphWolframAlphFeb 23, 2025

Copy link
Copy Markdown
ContributorAuthor

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.

Comment threadPython/flowgraph.c Outdated
Comment threadPython/flowgraph.c Outdated
@markshannon

Copy link
Copy Markdown
Member

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.

@WolframAlph

Copy link
Copy Markdown
ContributorAuthor

@markshannon are we ok with having this logic in 2 places then? Also what is your take on #130016?

@markshannon

Copy link
Copy Markdown
Member

What logic in two places?
Codegen emits unoptimized instructions, the cfg optimize optimizes them. I don't see any change to that in this PR.

@WolframAlph

Copy link
Copy Markdown
ContributorAuthor

@markshannon this:

cpython/Python/flowgraph.c

Lines 1414 to 1422 in 8058390

if (PyLong_CheckExact(newconst)) {
intoverflow;
longval=PyLong_AsLongAndOverflow(newconst, &overflow);
if (!overflow&&_PY_IS_SMALL_INT(val)) {
assert(_Py_IsImmortal(newconst));
INSTR_SET_OP1(instr, LOAD_SMALL_INT, (int)val);
returnSUCCESS;
}
}

&&

cpython/Python/codegen.c

Lines 284 to 291 in 8058390

if (PyLong_CheckExact(o)) {
intoverflow;
longval=PyLong_AsLongAndOverflow(o, &overflow);
if (!overflow&&_PY_IS_SMALL_INT(val)) {
ADDOP_I(c, loc, LOAD_SMALL_INT, val);
returnSUCCESS;
}
}

@WolframAlphWolframAlph changed the title gh-130480: Move LOAD_SMALL_INT optimization from codegen to CFGgh-130480: Move duplicate LOAD_SMALL_INT optimization from codegen to CFGMar 13, 2025
@WolframAlph

Copy link
Copy Markdown
ContributorAuthor

@iritkatriel can I ask you to review?

Comment threadPython/flowgraph.c Outdated
Comment threadLib/test/test_dis.py
Constants:
0: None
0: 1
1: None

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
ContributorAuthor

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.

Copy link
Copy Markdown
ContributorAuthor

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.

@iritkatrieliritkatriel added skip news interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Mar 14, 2025
Comment threadPython/flowgraph.c
{
if (PyLong_CheckExact(newconst)) {
int overflow;
long val = PyLong_AsLongAndOverflow(newconst, &overflow);

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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:

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

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done.

Comment threadPython/flowgraph.c
Comment on lines +2066 to +2068
if (res < 0) {
return ERROR;
}

Copy link
Copy Markdown
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);

@WolframAlphWolframAlphMar 14, 2025

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
Member

Choose a reason for hiding this comment

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

ok.

@iritkatriel
iritkatriel merged commit 55815a6 into python:mainMar 14, 2025
plashchynski pushed a commit to plashchynski/cpython that referenced this pull request Mar 17, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)skip news

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@WolframAlph@markshannon@iritkatriel@sobolevn@tomasr8