Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 33.9k
GH-98831: Simple input-output stack effects#99120
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
gvanrossum commented Nov 5, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
No arrays; no conditionals; no types; no cache effects.
Python/bytecodes.c Outdated
| // stack effect: (__0 -- ) | ||
| inst(BINARY_OP_MULTIPLY_INT){ | ||
| instr(BINARY_OP_MULTIPLY_INT, (left, right--prod)){ | ||
| // TODO: Don't pop from the stack before DEOPF_IF() calls. |
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.
Could you generate peeks at the beginning of the instruction and pops at the end just before the pushes?
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 why this is still a draft PR. :-)
gvanrossum commented Nov 5, 2022
@brandtbucher@markshannon: In bytecodes.c I now get red wiggles on every use of a variable defined through a stack effect (since the |
gvanrossum commented Nov 5, 2022
@markshannon I have some questions about how This expands to the following: Shall we make this part of the spec for |
brandtbucher commented Nov 5, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Perhaps we could make On my phone now, but something like: typedefPyObject*_dummy_stack_item; #defineinst_begin(NAME, ...) \ case (NAME):{\ _dummy_stack_item __VA_ARGS__; #defineinst_end } inst_begin(BINARY_OP, lhs, rhs, _, res) // Implementation goes here...inst_end |
Python/bytecodes.c Outdated
| if (TOP() ==NULL){ | ||
| goto error; | ||
| } | ||
| ERROR_IF(TOP() ==NULL, error); |
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.
TOP() —> res
Also detect whether names that occur in both inputs and outputs are at the same position.
gvanrossum commented Nov 7, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Some notes after converting a few basic instructions (and failing to convert a few outliers).
At this point I think the way forward is to merge this and then iterate, leaving the hardest cases for last. |
markshannon left a comment
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.
No need to justify not adding more features; smaller PRs are better. There is no need to convert all the instructions at once.
Let's add features to the code generator as we actually need them.
Have you benchmarked this?
Some of the instructions, particularly the BINARY_OP ones have been quite sensitive to minor code re-orderings.
Wiggly lines can be fixed by adding dummy static definitions to the top of bytecodes.c
Python/bytecodes.c Outdated
| // stack effect: (__0 -- ) | ||
| inst(BINARY_OP_INPLACE_ADD_UNICODE){ | ||
| // This is a weird one. It's a super-instruction for |
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.
Maybe drop the "This is a weird one."
It is unusual, but its there for a good reason, which is to maintain the historical behavior that s += ... in a loop is not quadratic.
| predictions=set() | ||
| forinstininstrs: | ||
| fortargetinre.findall(r"(?:PREDICT|GO_TO_INSTRUCTION)\((\w+)\)", inst.block.text): | ||
| defwrite_instr(instr: InstDef, predictions: set[str], indent: str, f: TextIO, dedent: int=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.
Note for future PRs.
We need to factor out the three parts:
- analysis
- translation
- output
| # Write the body | ||
| ninputs=len(instr.inputsor ()) | ||
| forlineinblocklines: | ||
| ifm:=re.match(r"(\s*)ERROR_IF\(([^,]+), (\w+)\);\s*$", line): |
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.
See comment in generated_cases.c.h about introducing code into the if (cond) goto... code.
Python/generated_cases.c.h Outdated
| } | ||
| SET_TOP(res); | ||
| Py_DECREF(container); | ||
| if (res==NULL){STACK_SHRINK(3); goto error} |
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.
Anything more than if (cond) goto ... introduces extra jumps around the conditional block and may slow things down.
E.g.
if (res==NULL){STACK_SHRINK(3); goto error}will be lowered to something like:
if (res!=NULL) goto next; STACK_SHRINK(3); goto error; next:The C compiler might move the STACK_SHRINK(3); goto error; out of line, but I think it better to do this in the code generator. Something like:
if (res==NULL) goto pop3_error; ... pop3_error: STACK_SHRINK(1); pop2_error: STACK_SHRINK(1); pop_error: STACK_SHRINK(1); error: ...gvanrossum commented Nov 8, 2022
I have benchmark results (thanks @brandtbucher!). Bottom line, it's a wash. We compared three commits:
The second and third both are 1% faster than the baseline. This suggests that there is no measurable effect from just this PR, or from the creation of super-instructions (which was merged into this commit from main, but not included in Mark's PEP 479 changes). I am going ahead with merging this. |
No arrays; no conditionals; no types; no cache effects.