FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GH-130415: Improve the JIT's unneeded uop removal pass by brandtbucher · Pull Request #132333 · python/cpython · GitHub

Repository navigation

GH-130415: Improve the JIT's unneeded uop removal pass - #132333

Merged
brandtbucher merged 5 commits into
python:mainfrom
brandtbucher:jit-peephole
Apr 21, 2025
Merged

brandtbucher merged 5 commits into
python:mainfrom
brandtbucher:jit-peephole

Conversation

brandtbucher commented Apr 9, 2025 •
edited by bedevere-app Bot
Loading

Copy link
Copy Markdown
Member

This improves our ability to remove unused constant and local variable loads during the remove_unneeded_uops pass in the JIT's optimizer.

It now handles all combinations of:

  • _COPY
  • _LOAD_CONST_INLINE
  • _LOAD_CONST_INLINE_BORROW
  • _LOAD_FAST
  • _LOAD_FAST_BORROW
  • _LOAD_SMALL_INT

...followed by...

  • _POP_TOP
  • _POP_TOP_LOAD_CONST_INLINE
  • _POP_TOP_LOAD_CONST_INLINE_BORROW
  • _POP_TWO_LOAD_CONST_INLINE_BORROW

(It also fixes an issue where CHECK_VALIDITY wasn't being added after these latter four instructions, due to how the old switch-case was structured.)

According to the stats, this results in:

  • 1% reduction in _LOAD_FAST
  • 94% reduction in _POP_TOP_LOAD_CONST_INLINE_BORROW
  • 100% reduction in _POP_TOP_LOAD_CONST_INLINE

@savannahostrowski: We should see even more impact once you start using _POP_TWO_LOAD_CONST_INLINE_BORROW in more places. I'm currently working on turning basically all cached class attribute/method loads into constants too, which should help here as well.

brandtbucher added performance Performance or resource usage interpreter-core (Objects, Python, Grammar, and Parser dirs) topic-JIT labels Apr 9, 2025
brandtbucher self-assigned this Apr 9, 2025
bedevere-app Bot mentioned this pull request Apr 9, 2025
13 of 17 tasks

Fidget-Spinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I think this should be fine? optimize_pop_top_again should reach a fixpoint (there are only a finite number of last we can change to _NOP).

markshannon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I have a few questions.
The overall design looks good.

load_attr_bottom = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", call)
self.assertEqual(opnames[:load_attr_top].count("_GUARD_TYPE_VERSION"), 1)
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 1)
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 2)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Why do we have two _CHECK_VALIDITYs now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

There used to be one validity check, after the setattr call. This adds an additional one after the _POP_TOP following the call, since in theory the function could return an object with a destructor that invalidates the JIT code when it's popped.

Because of the old structure of this optimization pass, we weren't actually treating _POP_TOP as escaping, even though it is (this is handled in the default case, which we fall through to now).

Comment thread Python/optimizer_analysis.c Outdated
switch (last->opcode) {
case _POP_TWO_LOAD_CONST_INLINE_BORROW:
last->opcode = _POP_TOP;
goto optimize_pop_top_again;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Do we want to optimize again here?
If the previous instruction is _POP_TOP I see no further optimization to apply here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Nice catch. We might want to combine smaller ops into larger ones later (for example, turn _POP_TOP; _POP_TOP_LOAD_CONST_INLINE_BORROW into _NOP; _POP_TWO_LOAD_CONST_INLINE_BORROW), which is where I think I was going with this. But that can come later.

last->opcode = _NOP;
buffer[pc].opcode = _NOP;
}
if (last->opcode == _REPLACE_WITH_TRUE) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Are we not optimizing this any more? I would have thought it would go in the same case as _POP_TOP_LOAD_CONST_INLINE_BORROW.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Nice catch. Though these should probably just be turned into _POP_TOP_LOAD_CONST_INLINE_BORROW by the optimizer instead.

I'll leave it this way and open up another PR for that. Having the hardcoded constant makes things more difficult, since we'd need to start writing operands instead of operating purely on opcodes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Actually, I just added that change as part of this PR.

brandtbucher merged commit 4f7f72c into python:main Apr 21, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

interpreter-core (Objects, Python, Grammar, and Parser dirs) performance Performance or resource usage topic-JIT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants


Back | FazBrowse Home | New Git URL