Skip to content

gh-118423: Add INSTRUCTION_SIZE macro to code generator - #125467

Merged
markshannon merged 34 commits into
python:mainfrom
tomasr8:instr-size
Oct 29, 2024
Merged

gh-118423: Add INSTRUCTION_SIZE macro to code generator#125467
markshannon merged 34 commits into
python:mainfrom
tomasr8:instr-size

Conversation

@tomasr8

@tomasr8tomasr8 commented Oct 14, 2024

Copy link
Copy Markdown
Member

I am not that familiar with the tier 1 interpreter (yet 😄 ) so I'd appreciate if someone could double check that for all
the places that use the new INSTRUCTION_SIZE macro, it is actually safe to do so.

I replaced all examples of next_instr - this_instr. There are still a few examples of 1 + INLINE_CACHE_ENTRIES_... but I wasn't sure whether those were safe to change as well.

I named the new macro INSTRUCTION_SIZE, but I'm happy to change it to INSTRUCTION_LENGTH if you prefer.

Feedback welcome :)

@tomasr8

Copy link
Copy Markdown
MemberAuthor

cc @iritkatriel since you asked for this in #118380 (comment) :)

Comment threadTools/cases_generator/generators_common.py Outdated

@Fidget-SpinnerFidget-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.

This is really close to what I was thinking of. Great work!

Comment threadTools/cases_generator/lexer.py Outdated
inst: Instruction | None
) -> bool:
"""Replace the INSTRUCTION_SIZE macro with the size of the current instruction."""
size = inst.size if inst else 1 + uop.size

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

tier2 does not have access to the instruction here so I calculate the size as 1 + uop.size. Does that make sense?

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.

Sorry this seems wrong, you need to emit the 1 + inline cache size not uop size

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Indeed, I see when comparing the output of generated_cases.c.h with executor_cases.c.h that the latter has the wrong instruction size. I fixed it (I think) by looking up the instructions for each uop in tier2 and passing it to the emitter.
Let me know if it's correct like that :)

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.

INSTRUCTION_SIZE is the size of the tier 1 instruction. This must be true even in tier 2.

I fixed it (I think) by looking up the instructions for each uop in tier2 and passing it to the emitter.

That is correct, but it would be nice if we also checked that all matching tier 1 instructions are the same size.

Comment threadTools/cases_generator/generators_common.py Outdated
@tomasr8

Copy link
Copy Markdown
MemberAuthor

It looks like there are not tests for tier2 yet so I only added tests for tier1

@markshannonmarkshannon 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.

Thanks for doing this.

The general approach looks good, but I think we need to check that all the instructions containing the uop with INSTRUCTION_LENGTH are the same length.

}
"""
self.run_cases_test(input, output)

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.

Add a test for another instruction that is a different length, but uses OP:

macro(OP2) = unused/1 + OP;

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Added!

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.

That test should fail, as the INSTRUCTION_SIZE is inconsistent.
The tier 2 INSTRUCTION_SIZE cannot be both 1 and 2.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Right, sorry I mistakenly thought it should only fail for tier 2 hence I was only checking the instruction in the tier 2 generator. I extended the check to tier 1 as well and the test now fails as expected.

Comment threadTools/cases_generator/generators_common.py Outdated


def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> Stack:
def write_uop(uop: Uop, emitter: Emitter, stack: Stack, inst: Instruction | None) -> Stack:

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.

Maybe pass the size, not the instruction. A uop can occur in many instructions, so picking one is arbitrary.
However, if it uses INSTRUCTION_SIZE, than all instructions must be the same size.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I added the check for the instruction size, which actually pointed out one place where we cannot use INSTRUCTION_SIZE instead of next_instr - this_instr:

frame->return_offset= (uint16_t)(next_instr-this_instr);

@bedevere-app

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@tomasr8

Copy link
Copy Markdown
MemberAuthor

Friendly ping @markshannon 🙂 I think I addressed all of your points.

@markshannon
markshannon self-requested a review October 28, 2024 09:40

@markshannonmarkshannon 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.

The assertion needs to be changed to explicitly raise. Otherwise it won't work with -O enabled.

Comment threadLib/test/test_generated_cases.py Outdated
Comment threadLib/test/test_generated_cases.py Outdated
Comment threadTools/cases_generator/analyzer.py Outdated
Comment threadTools/cases_generator/analyzer.py Outdated
Comment threadTools/cases_generator/analyzer.py Outdated
@bedevere-app

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@tomasr8

Copy link
Copy Markdown
MemberAuthor

Thanks again for the review!

I have made the requested changes; please review again 🙂

@bedevere-app

Copy link
Copy Markdown

Thanks for making the requested changes!

@markshannon: please review the changes made to this pull request.

@markshannonmarkshannon 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.

This looks good and correct now. Thanks.

I have a few suggestions, but they are mostly cosmetic.

Comment threadTools/cases_generator/analyzer.py Outdated
Comment threadTools/cases_generator/analyzer.py Outdated
if uop in inst.parts:
if size is None:
size = inst.size
if size != inst.size:

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.

Suggested change
ifsize!=inst.size:
elifsize!=inst.size:

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I changed this to an if because otherwise mypy complains that the elif is unreachable:

Tools/cases_generator/analyzer.py:1103: error: Statement is unreachable [unreachable]

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.

OK, leave it then.

@markshannonmarkshannon 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.

Looks good.
Thanks for doing this.

@markshannon
markshannon enabled auto-merge (squash) October 29, 2024 17:17
@markshannon
markshannon merged commit aab58a9 into python:mainOct 29, 2024
@tomasr8
tomasr8 deleted the instr-size branch October 29, 2024 21:19
@tomasr8

Copy link
Copy Markdown
MemberAuthor

Thanks for all the reviews! :)

picnixz pushed a commit to picnixz/cpython that referenced this pull request Dec 8, 2024
ebonnal pushed a commit to ebonnal/cpython that referenced this pull request Jan 12, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@tomasr8@markshannon@Fidget-Spinner