-
-
Notifications
You must be signed in to change notification settings - Fork 2.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
[mypyc] Constant fold int operations and str concat #11194
Conversation
Replace things like '5 + 8' with '13' at IR level. Arithmetic operations that produce int results and bitwise operations are supported. Comparisons are not supported. This is made a little tricky through error cases, such as division by zero. The approach here is to avoid constant folding error cases. We still won't produce compile-time errors for them.
For example, this (silly) microbenchmark now goes about 2.9x faster that before when compiled, since we won't need to perform the multiplication on every loop iteration: def bench() -> None:
i = 0
while i < 1000 * 1000 * 500:
i += 1 This is also basically a prerequisite for fixed-width integers (mypyc/mypyc#837). |
Is this ready for review now? I can take a look |
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.
The implementation looks good to me, only one minor code structure point.
@@ -0,0 +1,99 @@ | |||
"""Constant folding of IR values. |
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.
Should this file be in the transform
folder?
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.
I put the file here since transform
contains IR-to-IR tranforms, and this is basically an AST analysis pass, which seems closer to what is happening in irbuild
overall.
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.
sounds good, then I don't have anything else blocking this from merging.
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 great!
def constant_fold_binary_str_op(op: str, left: str, right: str) -> Optional[str]: | ||
if op == '+': | ||
return left + right | ||
return None |
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.
A random thought: add support for "A" * 20
?
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.
Yeah, that's a good idea. We already have an item about this (and a few other things) in the issue mypyc/mypyc#772. My intention is to add support for this and a few more cases in follow-up PRs (e.g. float arithmetic).
Work on mypyc/mypyc#772.
Replace things like '5 + 8' with '13' during IR building. Also adds
support for negative int literals, such as -5 (the negation gets
constant folded).
Arithmetic and bitwise operations that produce int results
are supported, plus string concatenation. Comparisons and float
operations are not supported yet, among other things.
This is a little tricky because of error cases, such as division by
zero. The approach here is to avoid constant folding error cases. We
still won't produce compile-time errors for them.
We do potentially lots of extra work by repeatedly trying to constant
fold expressions, but it didn't seem to slow down self-compilation
measurably, so the effect seems minor at most. Some caching could
help this if it becomes a problem.