Repository navigation
Move const folding to the peephole optimizer #126835
Description
Activity
- addedtype-featureA feature request or enhancementA feature request or enhancementinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
on Nov 14, 2024 We had a discussion with @tomasr8 and decided that splitting this into parts would be good. Initially, I tried to do it in one PR, but realized that it would be impossible to review, as it would do a lot of unrelated things.
To begin, we decided to start by moving tuple folding from AST optimizer to CFG.
Problem: Currently compiler emits a warning if
is/is notoperators are used with constants1 (because it can evaluate them toTruewhich is an implementation detail of CPython, other implementations might evaluateconst is consttoFalse).
So, the compiler (especially the codegen part) assumes that tuples are already folded, and has (in AST terms)Constant_kind. This breaks when we fold tuples later and they have aTuple_kindat the codegen phase.Possible solution: Perform this in a CFG after folding. This will be slower (I have no information on how slower it will be, but I assume it will) than performing this in codegen phase.
Footnotes
Reacted by Tomas R., Mikhail Efimov and Michael KashirinIs there a plan what parts/in what order should be moved from ast optimizer to cfg? Does it make sense to create sub issues to make it more granular (instead of just PRs linked to this issue)? This issue
Remove the AST optimizerseems too general and broad IMO.- added a commit that references this issue
on Feb 1, 2025 I'm currently looking into moving unaryop/binop folding (though I'm at Fosdem atm so It might take a bit longer) Anything else is up for grabs I'd say, unless Kirill is working on something currently?
I am looking into binop folding as well (almost done). Do you want to pass it or should I take something else?
Problem with binop I discovered is that after moving it to cfg, we, for instance, run into problem with case matching which @Eclips4 mentioned in issue description. For example:
match x: case 0 + 0j: pass
raises
File "/Users/yyanchii/Desktop/cpython/internal/t.py", line 2 case 0 + 0j: ^^^^^^ SyntaxError: patterns may only match literals and attribute lookups
It is raised from:
Lines 6022 to 6025 in 89fe067
if (!MATCH_VALUE_EXPR(value)) { const char *e = "patterns may only match literals and attribute lookups"; return _PyCompile_Error(c, LOC(p), e); }
So at codegen stage, it already expects (in this case) binops to be folded. @tomasr8 did you run into this already? We would need to add more logic in here which doesn't look good to me. On the other hand, how would we move binop folding to CFG then?I think the current priority is to move unaryop folding from AST optimizer to codegen phase.
I'm looking into it.Then we should have to think about binaryop folding :)
Reacted by Tomas R.Placing this here, not to forget in future: #129568 (comment). Maybe in future we get rid of emitting
LOAD_SMALL_INTin codegen and let CFG do it insteadcc @iritkatriel
We need to decide on what to do with theoptimizeparameter ofast.parseand thePyCF_OPTIMIZED_ASTflag.
If we remove the AST optimizer, these two will become obsolete.
Should we deprecate them in 3.14 (after the AST optimizer is removed) and remove them in 3.19?@Eclips4 as I am reading https://docs.python.org/3/library/ast.html#ast.parse, it is not clear to me whetherfeature_versionalso works for constant folding case.But I guessBest-effortpart makes it clear that one cannot rely on the consistent output.130 remaining items
@Eclips4 does this change deserve having "What's New" entry? Seems like not very interesting to the end user. Or am I wrong?
I guess some users may have been relying on the behavior of the previous ast optimizer, but now it's gone.
There was no explanation of exactly whatast.parse(optimize=1)does, but even with that some users may still have used it.
So, I think we should at least "warn" them in "What's new".Reacted by Mikhail Efimov and Irit Katriel- added a commit that references this issue
on Mar 30, 2026
Feature or enhancement
Proposal:
For additional context see #126830 (comment).
Flow graph optimizer has more information and can do better job.
The problem is that we need to convert from
UNARY_OP(-, CONST(1))toCONST(-1), still before the code generation phase, because this leads to a few problems, one of which is shown below.cc @markshannon
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response
Linked PRs
optimize_if_const_subscrrefleaks #129634test_peepholer.py::TestTranforms#131826