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 |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
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.
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.
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.
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; |
| } | ||
|
|
||
| /* Avoid creating large constants. */ | ||
| Py_ssize_t size = PyObject_Size(newval); |
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.
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)) { |
|
|
||
| #undef CALL | ||
| #undef CALL_OPT | ||
| #undef CALL_SEQ |
Python/ast_opt.c
Outdated
| #include "Python-ast.h" | ||
|
|
||
|
|
||
| /* TODO: is_const and get_const_value is copied from Python/compile.c. |
Lib/test/test_plistlib.py
Outdated
| 'second': [1, 2], | ||
| 'third': [3, 4], | ||
| }) | ||
| self.assertIsNot(pl2['first'], pl2['second']) |
There was a problem hiding this comment.
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
| if (size == -1) { | ||
| if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) | ||
| return 1; | ||
| Py_DECREF(newval); |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
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.
Looks like this makes this peephole pass unnecessary too?
https://bugs.python.org/issue29469