Skip to content

gh-106706: Streamline family syntax #106716

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

Merged
merged 39 commits into from
Jul 16, 2023

Conversation

kgdiem
Copy link
Contributor

@kgdiem kgdiem commented Jul 13, 2023

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@@ -321,13 +321,13 @@ def test_macro_instruction():
_tmp_3 = res;
}
next_instr += 5;
static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size");
Copy link
Contributor Author

@kgdiem kgdiem Jul 13, 2023

Choose a reason for hiding this comment

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

It isn't clear to me how/where the INLINE_CACHE_ENTRIES_OP instruction is generated.

Changing the test to pass w/o understanding doesn't inspire confidence on my end so any guidance or explanation here is greatly appreciated.

Copy link
Member

Choose a reason for hiding this comment

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

It is the second parameter to family.

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@gvanrossum gvanrossum self-requested a review July 14, 2023 00:50
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

Thank you! I hope I've given you enough hints on what to do about the static assert -- if not, let me know.

@@ -183,6 +182,7 @@
}

case TO_BOOL_ALWAYS_TRUE: {
static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size");
Copy link
Member

Choose a reason for hiding this comment

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

While it works, I think it's better to keep the static assert in the "family head".

Copy link
Member

Choose a reason for hiding this comment

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

This still isn't resolved?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I think this might be related to the change in Lib/_opcode_metadata.pyas well; the op from the family name isn't getting inserted into instrs

I'm having some trouble getting the name into instrs / parsed as an instruction. Any advice?

@@ -321,13 +321,13 @@ def test_macro_instruction():
_tmp_3 = res;
}
next_instr += 5;
static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size");
Copy link
Member

Choose a reason for hiding this comment

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

It is the second parameter to family.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

I think you pushed a rebase? Please don't do that once review is in progress -- everything will be squashed when we merge into main.

Can you look into moving the static_assert back to the family head?

And I'm unsure why the metadata file was truncated. (Let me know if you need help figuring this out.)

@@ -31,75 +31,3 @@
"STORE_SUBSCR_DICT",
"STORE_SUBSCR_LIST_INT",
],
"SEND": [
Copy link
Member

Choose a reason for hiding this comment

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

That this file changed surprises me. Maybe this points to a problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It didn't change originally, I think only after 178e300 ?

@@ -183,6 +182,7 @@
}

case TO_BOOL_ALWAYS_TRUE: {
static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size");
Copy link
Member

Choose a reason for hiding this comment

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

This still isn't resolved?

Comment on lines +858 to +862
if family.name not in self.macro_instrs and family.name not in self.instrs:
self.error(
f"Family {family.name!r} has unknown instruction {family.name!r}",
family,
)
Copy link
Member

Choose a reason for hiding this comment

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

Good catch!

@kgdiem
Copy link
Contributor Author

kgdiem commented Jul 15, 2023

I think you pushed a rebase? Please don't do that once review is in progress -- everything will be squashed when we merge into main.

Can you look into moving the static_assert back to the family head?

And I'm unsure why the metadata file was truncated. (Let me know if you need help figuring this out.)

Ya there was a conflict in one of the header files so I rebased and re-generated it. Will keep that in mind next time.

@gvanrossum
Copy link
Member

Ya there was a conflict in one of the header files so I rebased and re-generated it. Will keep that in mind next time.

The missing part of the metadata will be reconstructed if you simply run make regen-cases and then commit the resulting changes to Lib/_opcode_metadata.py.

Not sure yet why the stat asserts moved, will look into it later. (Did you find where they are generated?)

@kgdiem
Copy link
Contributor Author

kgdiem commented Jul 15, 2023

Ya there was a conflict in one of the header files so I rebased and re-generated it. Will keep that in mind next time.

The missing part of the metadata will be reconstructed if you simply run make regen-cases and then commit the resulting changes to Lib/_opcode_metadata.py.

Not sure yet why the stat asserts moved, will look into it later. (Did you find where they are generated?)

Yes, https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L1555

I had changed this on my local from .members[0] to family.name but:

This condition is always falsy because last_instr.family is None on the instruction used as family.name.

That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

I'm thinking that there would be far fewer changes to generate_cases while keeping the desired syntax for a family template if the family name was added to the members here https://github.com/python/cpython/blob/main/Tools/cases_generator/parser.py#L347

eg ..., [tkn.txt] + members

I considered just starting fresh from there but thought I would check given we've been back and forth on this implementation for a couple days.

@barneygale barneygale removed their request for review July 15, 2023 16:25
@gvanrossum
Copy link
Member

I'm thinking that there would be far fewer changes to generate_cases while keeping the desired syntax for a family template if the family name was added to the members here https://github.com/python/cpython/blob/main/Tools/cases_generator/parser.py#L347

eg ..., [tkn.txt] + members

I considered just starting fresh from there but thought I would check given we've been back and forth on this implementation for a couple days.

Interesting idea. It would mean fewer changes, but some of the ugliness would remain as well (e.g. the several places where you have to slice .members[1:]).

As you point out, the problem is that the family head doesn't have self.family set to the family whose head it is. I think this will fix it:

diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index 48c082a429..4756f50b8f 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -438,7 +438,7 @@ def write(self, out: Formatter, tier: Tiers = TIER_ONE) -> None:
         """Write one instruction, sans prologue and epilogue."""
         # Write a static assertion that a family's cache size is correct
         if family := self.family:
-            if self.name == family.members[0]:
+            if self.name == family.name:
                 if cache_size := family.size:
                     out.emit(
                         f"static_assert({cache_size} == "
@@ -831,7 +831,7 @@ def find_predictions(self) -> None:
     def map_families(self) -> None:
         """Link instruction names back to their family, if they have one."""
         for family in self.families.values():
-            for member in family.members:
+            for member in [family.name] + family.members:
                 if member_instr := self.instrs.get(member):
                     if member_instr.family not in (family, None):
                         self.error(

@kgdiem
Copy link
Contributor Author

kgdiem commented Jul 15, 2023 via email

@kgdiem
Copy link
Contributor Author

kgdiem commented Jul 16, 2023

This condition is always falsy because last_instr.family is None on the instruction used as family.name.

That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

I committed those changes but I'd actually outlined them in my previous comment:

This condition is always falsy because last_instr.family is None on the instruction used as family.name.

That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

family.name is never mapped because it isn't present in self.instrs; This results in the assertion never being emitted.

@kgdiem
Copy link
Contributor Author

kgdiem commented Jul 16, 2023

This condition is always falsy because last_instr.family is None on the instruction used as family.name.
That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

I committed those changes but I'd actually outlined them in my previous comment:

This condition is always falsy because last_instr.family is None on the instruction used as family.name.
That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

family.name is never mapped because it isn't present in self.instrs; This results in the assertion never being emitted.

Looks like the generated headers are now correct / unchanged and the test is testing for a macro instruction and what I described above is still missing here https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L1555

But the generated header files after that change are correct.

Makes a lot more sense now why the macro isn't in self.instrs, wasn't thinking about it correctly before. Still unsure of what to do or if the test is wrong.

@kgdiem
Copy link
Contributor Author

kgdiem commented Jul 16, 2023

This condition is always falsy because last_instr.family is None on the instruction used as family.name.
That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

I committed those changes but I'd actually outlined them in my previous comment:

This condition is always falsy because last_instr.family is None on the instruction used as family.name.
That instruction misses in map_families (https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L835) because it isn't added to the instrs in parse_file https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L787

family.name is never mapped because it isn't present in self.instrs; This results in the assertion never being emitted.

Looks like the generated headers are now correct / unchanged and the test is testing for a macro instruction and what I described above is still missing here https://github.com/python/cpython/blob/main/Tools/cases_generator/generate_cases.py#L1555

But the generated header files after that change are correct.

Makes a lot more sense now why the macro isn't in self.instrs, wasn't thinking about it correctly before. Still unsure of what to do or if the test is wrong.

Got it! Instead of checking the last instruction, get the family from self.families

@kgdiem kgdiem requested a review from gvanrossum July 16, 2023 11:15
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

Perfect! I'll merge.

@gvanrossum gvanrossum merged commit cc25ca1 into python:main Jul 16, 2023
gvanrossum added a commit that referenced this pull request Jul 18, 2023
These repair nits I found in PR gh-106798 (issue gh-106797) and in PR gh-106716 (issue gh-106706).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.