-
-
Notifications
You must be signed in to change notification settings - Fork 30.8k
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
bpo-29469: Move constant folding at AST level #2858
Conversation
I'll check all comments in https://bugs.python.org/review/29469/ |
93677ba
to
86c73de
Compare
Overall, this looks great. The code is remarkably clean. |
a776555
to
b0b9db9
Compare
b0b9db9
to
a603d5b
Compare
|
See my comment on the tracker: https://bugs.python.org/issue29469#msg297596 |
Could you please remove |
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.
It may be worth to document this change in What's New. Even without additional optimizations it can optimize more than the peephole optimizer.
Python/ast_opt.c
Outdated
case NameConstant_kind: | ||
return e->v.NameConstant.value; | ||
default: | ||
assert(!is_const(e)); |
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.
Py_UNREACHABLE()
is now used in compile.c
.
Python/ast_opt.c
Outdated
} | ||
} | ||
|
||
static int make_const(expr_ty node, PyObject *val, PyArena *arena) |
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.
Move static int
to a separate line. And similarly in other functions below.
Python/ast_opt.c
Outdated
|
||
typedef PyObject *(*unary_op)(PyObject*); | ||
static const unary_op ops[] = { | ||
0, |
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.
AFAIK in C99 you can write
[Invert] = PyNumber_Invert,
[Not] = unary_not,
...
Python/ast_opt.c
Outdated
Py_ssize_t size = PyObject_Size(newval); | ||
if (size == -1) { | ||
if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) | ||
return 1; |
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.
newval
leaked.
} | ||
|
||
/* Avoid creating large constants. */ | ||
Py_ssize_t size = PyObject_Size(newval); |
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.
newval
can be NULL.
Python/ast_opt.c
Outdated
static int make_const(expr_ty node, PyObject *val, PyArena *arena) | ||
{ | ||
if (val == NULL) { | ||
if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) |
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.
Missed space after if
. Missed braces.
Python/ast_opt.c
Outdated
!is_const(arg) || | ||
/* TODO: handle other types of slices */ | ||
slice->kind != Index_kind || | ||
!is_const(slice->v.Index.value)) { |
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.
Move {
to a new line.
Python/ast_opt.c
Outdated
|
||
#undef CALL | ||
#undef CALL_OPT | ||
#undef CALL_SEQ |
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.
#undef CALL_INT_SEQ
Python/ast_opt.c
Outdated
#include "Python-ast.h" | ||
|
||
|
||
/* TODO: is_const and get_const_value is copied from Python/compile.c. |
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.
s/is/are/ ?
Lib/test/test_plistlib.py
Outdated
@@ -320,7 +320,6 @@ def test_tuple_members(self): | |||
'second': [1, 2], | |||
'third': [3, 4], | |||
}) | |||
self.assertIsNot(pl2['first'], pl2['second']) |
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.
Good catch! This test can fail in other implementations. It should be fixed in 3.6 too. Opened #4813 for this.
Python/ast_opt.c
Outdated
/* Avoid creating large constants. */ | ||
Py_ssize_t size = PyObject_Size(newval); | ||
if (size == -1) { | ||
if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) | ||
return 1; | ||
Py_DECREF(newval); |
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.
Only before return.
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.
LGTM if fix a one simple error.
Generated files not up to date. |
Great! Many thanks @methane for your work! Now I'll try to implement additional optimizations. |
expr_ty arg = node->v.UnaryOp.operand; | ||
|
||
if (!is_const(arg)) { | ||
/* Fold not into comparison */ |
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.
Looks like this makes this peephole pass unnecessary too?
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.
Ah, you're right.
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.
Created #4863. Thanks.
https://bugs.python.org/issue29469