GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GH-98831: Remove super-instruction definitions, use macro instructions instead by gvanrossum · Pull Request #100124 · python/cpython

Conversation

@gvanrossum

@gvanrossum gvanrossum commented Dec 8, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Replace all super-instructions with macros, using a special JOIN op to extract the next oparg. JOIN has a cache effect of one word that is equivalent to bumping next_instr.

Rip out all code for parsing and generating super-instructions.

  • Issue: Generate the interpreter #98831

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-bot bedevere-bot mentioned this pull request Dec 8, 2022
Generate the interpreter #98831
Closed
@bedevere-bot bedevere-bot added the awaiting core review label Dec 8, 2022
@gvanrossum
gvanrossum requested a review from brandtbucher December 8, 2022 23:44
@gvanrossum gvanrossum mentioned this pull request Dec 8, 2022
GH-98831: Get rid of super(), just use macro() #100095
Closed
@brandtbucher

brandtbucher commented Dec 8, 2022

Copy link
Copy Markdown
Member

Not gonna lie, the PR title scared me.

AlexWaygood and gvanrossum reacted with laugh emoji
All reactions
  • 😄 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum gvanrossum mentioned this pull request Dec 8, 2022
Remove special syntax for super(X) = A + B in favor of macro(X) = A + JOIN + B faster-cpython/ideas#508
Closed
gvanrossum added 2 commits December 8, 2022 16:00
@gvanrossum
Change all super() to macro() using op(JOIN)
d2573b6
@gvanrossum
Rip out parser and generator support for super()
eadca51
@gvanrossum
gvanrossum force-pushed the remove-supers branch from 6706827 to eadca51 Compare December 9, 2022 00:01
@gvanrossum gvanrossum added the skip news label Dec 9, 2022
@gvanrossum gvanrossum changed the title GH-98831: Remove super() GH-98831: Remove super-instruction definitions, use macro instructions instead Dec 9, 2022
@gvanrossum

gvanrossum commented Dec 9, 2022

Copy link
Copy Markdown
Member Author

Clearly I should use more provocative PR titles more often. :-)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

brandtbucher
brandtbucher reviewed Dec 9, 2022
View reviewed changes
Comment thread Python/bytecodes.c
Comment on lines 92 to 95
#define _COMPARE_OP_FLOAT 1003
#define _COMPARE_OP_INT 1004
#define _COMPARE_OP_STR 1005
#define _JUMP_IF 1006

@brandtbucher brandtbucher Dec 8, 2022

Copy link
Copy Markdown
Member

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 these just be zeroes, too? Or even -1, just to emphasize that they aren't real?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@gvanrossum gvanrossum Dec 9, 2022

Copy link
Copy Markdown
Member Author

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, they should all be zeros. Since the value is never used I'm not sure what the point of -1 would be.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/generated_cases.c.h
TARGET(LOAD_FAST__LOAD_FAST) {
PyObject *_tmp_1;
PyObject *_tmp_2;
{

@brandtbucher brandtbucher Dec 8, 2022

Copy link
Copy Markdown
Member

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.

Random idea... any chance we could annotate the output of macros to make it easier to see what the different parts correspond to? So, like, this line would be:

Suggested change
{
{ // LOAD_FAST

And we would have { // JOIN and another { // LOAD_FAST below? Not sure how hard this is.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/bytecodes.c

// BEGIN BYTECODES //

op(JOIN, (word/1 --)) {

@brandtbucher brandtbucher Dec 8, 2022

Copy link
Copy Markdown
Member

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.

Hmmm. It feels weird to treat the next instruction as a cache entry.

Why don't all macro components generate code to reload the incremented opcodes/opargs unconditionally? That way we wouldn't need JOIN at all. Or are we worried the compiler can't optimize it out when it's unused (or that garbage values could be too confusing)? Or does it mess up something else?

Perhaps there's a clean way of expressing in the DSL whether an op corresponds to a real instruction or not? Then we can just reload the opcode/oparg if that's true, and get rid of JOIN.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@gvanrossum gvanrossum Dec 9, 2022

Copy link
Copy Markdown
Member Author

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.

Hmmm. It feels weird to treat the next instruction as a cache entry.

It's only weird if you think of the instruction stream as alternating instructions and cache entries. In the discussion about registers it was already proposed to use a "cache" entry to encode the operation (ADD, MUL, etc.) for BINARY_OP, so it's really just a stream of variable-length instructions. But yeah, this op is definitely full of internal hackery.

Why don't all macro components generate code to reload the incremented opcodes/opargs unconditionally? That way we wouldn't need JOIN at all. Or are we worried the compiler can't optimize it out when it's unused (or that garbage values could be too confusing)? Or does it mess up something else?

I worry more about where the next oparg would be loaded from. The code generator makes assumption about where next_instr points (for macros it keeps pointing just past the original instruction until the end, for supers it gets bumped for each component).

Perhaps there's a clean way of expressing in the DSL whether an op corresponds to a real instruction or not? Then we can just reload the opcode/oparg if that's true, and get rid of JOIN.

That's not a bad idea -- because we actually have that way: inst vs op. The main downside would then be that there would no longer be a clue in the macro whether it defines a super or not.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Tools/cases_generator/parser.py
Comment on lines -229 to -234
if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "super":
if self.expect(lx.LPAREN):
if tkn := self.expect(lx.IDENTIFIER):
if self.expect(lx.RPAREN):
if self.expect(lx.EQUALS):
if ops := self.ops():

@brandtbucher brandtbucher Dec 9, 2022

Copy link
Copy Markdown
Member

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.

Kill it with fire! ;)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@python python deleted a comment from netlify Bot Dec 9, 2022
gvanrossum
gvanrossum commented Dec 9, 2022
View reviewed changes

@gvanrossum gvanrossum left a comment

Copy link
Copy Markdown
Member Author

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'm feeling a lot of hesitation about this PR. Maybe we should just leave things as they were and focus on other work (e.g. finish converting more instructions to the explicit stack/cache effects form, and adding arrays).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/bytecodes.c
Comment on lines 92 to 95
#define _COMPARE_OP_FLOAT 1003
#define _COMPARE_OP_INT 1004
#define _COMPARE_OP_STR 1005
#define _JUMP_IF 1006

@gvanrossum gvanrossum Dec 9, 2022

Copy link
Copy Markdown
Member Author

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, they should all be zeros. Since the value is never used I'm not sure what the point of -1 would be.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/bytecodes.c

// BEGIN BYTECODES //

op(JOIN, (word/1 --)) {

@gvanrossum gvanrossum Dec 9, 2022

Copy link
Copy Markdown
Member Author

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.

Hmmm. It feels weird to treat the next instruction as a cache entry.

It's only weird if you think of the instruction stream as alternating instructions and cache entries. In the discussion about registers it was already proposed to use a "cache" entry to encode the operation (ADD, MUL, etc.) for BINARY_OP, so it's really just a stream of variable-length instructions. But yeah, this op is definitely full of internal hackery.

Why don't all macro components generate code to reload the incremented opcodes/opargs unconditionally? That way we wouldn't need JOIN at all. Or are we worried the compiler can't optimize it out when it's unused (or that garbage values could be too confusing)? Or does it mess up something else?

I worry more about where the next oparg would be loaded from. The code generator makes assumption about where next_instr points (for macros it keeps pointing just past the original instruction until the end, for supers it gets bumped for each component).

Perhaps there's a clean way of expressing in the DSL whether an op corresponds to a real instruction or not? Then we can just reload the opcode/oparg if that's true, and get rid of JOIN.

That's not a bad idea -- because we actually have that way: inst vs op. The main downside would then be that there would no longer be a clue in the macro whether it defines a super or not.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@gvanrossum

gvanrossum commented Dec 12, 2022

Copy link
Copy Markdown
Member Author

Off-line we decided not to do this. Super-instructions may eventually disappear (when we have a register VM).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum gvanrossum closed this Dec 12, 2022
@gvanrossum
gvanrossum deleted the remove-supers branch June 13, 2023 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@brandtbucher brandtbucher brandtbucher left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting core review skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@gvanrossum @brandtbucher @bedevere-bot
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.