Skip to content

gh-123080: Additional ast optimizations #123081

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

Closed
wants to merge 8 commits into from

Conversation

wrongnull
Copy link
Contributor

@wrongnull wrongnull commented Aug 16, 2024

This allows some expression templates to produce less bytecode and perform more folding operations in the fold_compare function.
For instance

>>> from dis import dis
>>> dis("1 in [1, 2, 3, 4]")
  0           RESUME                   0

  1           RETURN_CONST             0 (True)
>>> dis("1 == 1")
  0           RESUME                   0

  1           RETURN_CONST             0 (True)
>>> 

@wrongnull
Copy link
Contributor Author

I guess there is no need to update news for this

@terryjreedy
Copy link
Member

I believe that changing bytecode requires News and What's New items.

@terryjreedy terryjreedy requested a review from pablogsal August 16, 2024 20:38
@Eclips4 Eclips4 self-assigned this Aug 17, 2024
@wrongnull
Copy link
Contributor Author

I'll convert it to draft so far because of tests segfaults. Also I'll wait until #122667 will be merged

@wrongnull wrongnull marked this pull request as draft August 17, 2024 08:51
@wrongnull wrongnull marked this pull request as ready for review August 18, 2024 15:14
@wrongnull
Copy link
Contributor Author

wrongnull commented Aug 18, 2024

For now, everything works fine and all the previous optimizations are preserved. I'll wait for tests of ast optimizations to be merged and then I'll add test coverage for it.

Python/ast_opt.c Outdated

PyObject *newval = PyTuple_New(elts_len);
if (newval == NULL) {
if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
Copy link
Member

Choose a reason for hiding this comment

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

There is no need to match against PyExc_KeyboardInterrupt here. Just treat this like a regular error and bubble up

Python/ast_opt.c Outdated
for (Py_ssize_t j = 0; j < elts_len; j++) {
expr_ty e = (expr_ty)asdl_seq_GET(elts, j);
if (e->kind != Constant_kind) {
PyObject_GC_UnTrack(newval);
Copy link
Member

Choose a reason for hiding this comment

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

Why are you calling directly these GC functions? Just call a normal Py_DECREF when you are done with it

Python/ast_opt.c Outdated
if (is_lhs_constant &&
(v == (node->v.Compare.left->v.Constant.value)))
{
PyObject_GC_UnTrack(newval);
Copy link
Member

Choose a reason for hiding this comment

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

Python/ast_opt.c Outdated
}

if (arg->kind == Set_kind)
Copy link
Member

Choose a reason for hiding this comment

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

PEP 7: Add braces

Python/ast_opt.c Outdated
}

if (arg->kind == Set_kind)
Py_SETREF(newval, PyFrozenSet_New(newval));
Copy link
Member

Choose a reason for hiding this comment

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

PyFrozenSet_New can fail, you need to check for errors and handle the failure

Copy link
Member

Choose a reason for hiding this comment

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

This line was copied from fold_iter. So, fold_iter has the same issue (no error handling for NULL values on calls to PyFrozenSet_New). Do you think it's OK to address this issue in this PR?

return 0;
if (arg->kind == List_kind) {
asdl_expr_seq *list_elts = arg->v.List.elts;
if (has_starred(list_elts))
Copy link
Member

Choose a reason for hiding this comment

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

PEP 7: add braces

Python/ast_opt.c Outdated
(arg->kind == Constant_kind) &&
is_lhs_constant)
{
if ((node->v.Compare.left->v.Constant.value) == (arg->v.Constant.value))
Copy link
Member

Choose a reason for hiding this comment

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

PEP 7: Add braces

Python/ast_opt.c Outdated

ops = node->v.Compare.ops;
args = node->v.Compare.comparators;
/* Change literal list or set in 'in' or 'not in' into
tuple or frozenset respectively. */
i = asdl_seq_LEN(ops) - 1;
int op = asdl_seq_GET(ops, i);
arg = asdl_seq_GET(args, i);
_Bool is_lhs_constant = (node->v.Compare.left->kind) == Constant_kind;
//lhs_const = node->v.Compare.left->v.Constant.value;
Copy link
Member

Choose a reason for hiding this comment

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

Why is this commented out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I leave it by accident

Copy link
Member

@pablogsal pablogsal left a comment

Choose a reason for hiding this comment

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

Left some comments

@bedevere-app
Copy link

bedevere-app bot commented Aug 19, 2024

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Python/ast_opt.c Outdated
Comment on lines 681 to 682
PyObject_GC_UnTrack(newval);
PyObject_GC_Del(newval);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
PyObject_GC_UnTrack(newval);
PyObject_GC_Del(newval);
Py_DECREF(newval);

Python/ast_opt.c Outdated
}

if (arg->kind == Set_kind)
Py_SETREF(newval, PyFrozenSet_New(newval));
Copy link
Member

Choose a reason for hiding this comment

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

This line was copied from fold_iter. So, fold_iter has the same issue (no error handling for NULL values on calls to PyFrozenSet_New). Do you think it's OK to address this issue in this PR?

@wrongnull wrongnull requested review from pablogsal and Eclips4 August 20, 2024 06:20
@pablogsal
Copy link
Member

Do you think it's OK to address this issue in this PR?

I prefer to do that separately because we want to back port it. I will take care of that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants