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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
294750d
gh-106706 Streamline family syntax
kgdiem Jul 13, 2023
7dc364c
Update syntax in interpreter_definition.md
kgdiem Jul 13, 2023
dac8eb5
Further refactor bytecodes.c
kgdiem Jul 13, 2023
b05a7f8
Update test
kgdiem Jul 13, 2023
47f2491
Update syntax in interpreter_definition.md
kgdiem Jul 13, 2023
d499926
Update interpreter_definition to new syntax
kgdiem Jul 13, 2023
6fee03d
Use family name as first instruction
kgdiem Jul 13, 2023
d13dbf2
stop using slice in iters
kgdiem Jul 13, 2023
105871c
Remove formatting in interpreter_definition.md
kgdiem Jul 13, 2023
945f09d
Change test
kgdiem Jul 13, 2023
c4ffdc5
Merge branch 'main' into streamline-family-syntax
kgdiem Jul 13, 2023
b588c72
Fix check
kgdiem Jul 13, 2023
e091ca3
Fix assertion
kgdiem Jul 13, 2023
59dedfe
📜🤖 Added by blurb_it.
blurb-it[bot] Jul 13, 2023
868ae1b
lint blurb
kgdiem Jul 13, 2023
ae5cd52
Merge branch 'main' into streamline-family-syntax
kgdiem Jul 13, 2023
843880d
Update Misc/NEWS.d/next/Tools-Demos/2023-07-13-12-08-35.gh-issue-1067…
kgdiem Jul 14, 2023
906c8b2
Remove redundant checks for family member length
kgdiem Jul 14, 2023
c367600
Reword documentation
kgdiem Jul 14, 2023
d31258c
Update test, regenerate headers
kgdiem Jul 14, 2023
9986c2e
keep formatting in interpreter_definiton
kgdiem Jul 14, 2023
1601141
GH-104909: Split `LOAD_ATTR_INSTANCE_VALUE` into micro-ops (GH-106678)
markshannon Jul 13, 2023
8ce84bc
gh-106690: Add a .coveragerc file to the CPython repository (#8150)
ammaraskar Jul 13, 2023
ca8147a
gh-106701: Move the hand-written Tier 2 uops to bytecodes.c (#106702)
gvanrossum Jul 13, 2023
58025d6
gh-106664: selectors: add get() method to _SelectorMapping (#106665)
bdraco Jul 13, 2023
fd9f8d6
docs: clarify Path.suffix (GH-106650)
nedbat Jul 13, 2023
9acddfa
gh-106368: Increase Argument Clinic test coverage (#106728)
erlend-aasland Jul 13, 2023
0941a94
gh-104683: Argument clinic: use an enum to describe the different kin…
AlexWaygood Jul 13, 2023
c15f572
gh-106529: Split FOR_ITER_{LIST,TUPLE} into uops (#106696)
gvanrossum Jul 14, 2023
656c5bc
gh-105626: Change the default return value of `HTTPConnection.get_pro…
sobolevn Jul 14, 2023
642cc0e
gh-105293: Do not call SSL_CTX_set_session_id_context on client side …
grantramsay Jul 14, 2023
2dd5049
gh-106446: Fix failed doctest in stdtypes (#106447)
CharlieZhao95 Jul 14, 2023
ea05f4d
Fix check
kgdiem Jul 13, 2023
178e300
Merge branch 'main' into streamline-family-syntax
erlend-aasland Jul 14, 2023
eab1974
Regen cases
kgdiem Jul 15, 2023
1e68564
Check against family name when emitting cache size check, add family.…
kgdiem Jul 16, 2023
85cbbed
update family syntax in test
kgdiem Jul 16, 2023
82a9927
Regenerate cases
kgdiem Jul 16, 2023
b05e24d
Check families for mac.name instead of last_instr.family
kgdiem Jul 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Change bytecode syntax for families
to remove redundant name matching
pseudo syntax.
39 changes: 13 additions & 26 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,7 @@ dummy_func(
res = Py_IsFalse(value) ? Py_True : Py_False;
}

family(to_bool, INLINE_CACHE_ENTRIES_TO_BOOL) = {
TO_BOOL,
family(TO_BOOL, INLINE_CACHE_ENTRIES_TO_BOOL) = {
TO_BOOL_ALWAYS_TRUE,
TO_BOOL_BOOL,
TO_BOOL_INT,
Expand Down Expand Up @@ -372,8 +371,7 @@ dummy_func(
ERROR_IF(res == NULL, error);
}

family(binary_op, INLINE_CACHE_ENTRIES_BINARY_OP) = {
BINARY_OP,
family(BINARY_OP, INLINE_CACHE_ENTRIES_BINARY_OP) = {
BINARY_OP_MULTIPLY_INT,
BINARY_OP_ADD_INT,
BINARY_OP_SUBTRACT_INT,
Expand Down Expand Up @@ -507,8 +505,7 @@ dummy_func(
macro(BINARY_OP_INPLACE_ADD_UNICODE) =
_GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE;

family(binary_subscr, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
BINARY_SUBSCR,
family(BINARY_SUBSCR, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
BINARY_SUBSCR_DICT,
BINARY_SUBSCR_GETITEM,
BINARY_SUBSCR_LIST_INT,
Expand Down Expand Up @@ -643,8 +640,7 @@ dummy_func(
ERROR_IF(err, error);
}

family(store_subscr, INLINE_CACHE_ENTRIES_STORE_SUBSCR) = {
STORE_SUBSCR,
family(STORE_SUBSCR, INLINE_CACHE_ENTRIES_STORE_SUBSCR) = {
STORE_SUBSCR_DICT,
STORE_SUBSCR_LIST_INT,
};
Expand Down Expand Up @@ -921,8 +917,7 @@ dummy_func(
ERROR_IF(iter == NULL, error);
}

family(send, INLINE_CACHE_ENTRIES_SEND) = {
SEND,
family(SEND, INLINE_CACHE_ENTRIES_SEND) = {
SEND_GEN,
};

Expand Down Expand Up @@ -1134,8 +1129,7 @@ dummy_func(
}
}

family(unpack_sequence, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = {
UNPACK_SEQUENCE,
family(UNPACK_SEQUENCE, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = {
UNPACK_SEQUENCE_TWO_TUPLE,
UNPACK_SEQUENCE_TUPLE,
UNPACK_SEQUENCE_LIST,
Expand Down Expand Up @@ -1198,8 +1192,7 @@ dummy_func(
ERROR_IF(res == 0, error);
}

family(store_attr, INLINE_CACHE_ENTRIES_STORE_ATTR) = {
STORE_ATTR,
family(STORE_ATTR, INLINE_CACHE_ENTRIES_STORE_ATTR) = {
STORE_ATTR_INSTANCE_VALUE,
STORE_ATTR_SLOT,
STORE_ATTR_WITH_HINT,
Expand Down Expand Up @@ -1298,8 +1291,7 @@ dummy_func(

macro(LOAD_FROM_DICT_OR_GLOBALS) = _LOAD_FROM_DICT_OR_GLOBALS;

family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
LOAD_GLOBAL,
family(LOAD_GLOBAL, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
LOAD_GLOBAL_MODULE,
LOAD_GLOBAL_BUILTIN,
};
Expand Down Expand Up @@ -1647,8 +1639,7 @@ dummy_func(
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}

family(load_super_attr, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR,
family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR_ATTR,
LOAD_SUPER_ATTR_METHOD,
};
Expand Down Expand Up @@ -1750,8 +1741,7 @@ dummy_func(
}
}

family(load_attr, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {
LOAD_ATTR,
family(LOAD_ATTR, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {
LOAD_ATTR_INSTANCE_VALUE,
LOAD_ATTR_MODULE,
LOAD_ATTR_WITH_HINT,
Expand Down Expand Up @@ -2048,8 +2038,7 @@ dummy_func(
Py_DECREF(owner);
}

family(compare_op, INLINE_CACHE_ENTRIES_COMPARE_OP) = {
COMPARE_OP,
family(COMPARE_OP, INLINE_CACHE_ENTRIES_COMPARE_OP) = {
COMPARE_OP_FLOAT,
COMPARE_OP_INT,
COMPARE_OP_STR,
Expand Down Expand Up @@ -2350,8 +2339,7 @@ dummy_func(
// This is optimized by skipping that instruction and combining
// its effect (popping 'iter' instead of pushing 'next'.)

family(for_iter, INLINE_CACHE_ENTRIES_FOR_ITER) = {
FOR_ITER,
family(FOR_ITER, INLINE_CACHE_ENTRIES_FOR_ITER) = {
FOR_ITER_LIST,
FOR_ITER_TUPLE,
FOR_ITER_RANGE,
Expand Down Expand Up @@ -2800,8 +2788,7 @@ dummy_func(

// Cache layout: counter/1, func_version/2
// Neither CALL_INTRINSIC_1/2 nor CALL_FUNCTION_EX are members!
family(call, INLINE_CACHE_ENTRIES_CALL) = {
CALL,
family(CALL, INLINE_CACHE_ENTRIES_CALL) = {
CALL_BOUND_METHOD_EXACT_ARGS,
CALL_PY_EXACT_ARGS,
CALL_PY_WITH_DEFAULTS,
Expand Down
27 changes: 13 additions & 14 deletions Tools/cases_generator/generate_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -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} == "
Expand Down Expand Up @@ -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(
Expand All @@ -855,8 +855,11 @@ def check_families(self) -> None:
- All members must have the same cache, input and output effects
"""
for family in self.families.values():
if len(family.members) < 2:
self.error(f"Family {family.name!r} has insufficient members", family)
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,
)
Comment on lines +858 to +862
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!

members = [
member
for member in family.members
Expand All @@ -867,10 +870,8 @@ def check_families(self) -> None:
self.error(
f"Family {family.name!r} has unknown members: {unknown}", family
)
if len(members) < 2:
continue
expected_effects = self.effect_counts(members[0])
for member in members[1:]:
expected_effects = self.effect_counts(family.name)
for member in members:
member_effects = self.effect_counts(member)
if member_effects != expected_effects:
self.error(
Expand Down Expand Up @@ -1293,11 +1294,10 @@ def write_metadata(self) -> None:
self.out.emit("")
self.out.emit("_specializations = {")
for name, family in self.families.items():
assert len(family.members) > 1
with self.out.indent():
self.out.emit(f"\"{family.members[0]}\": [")
self.out.emit(f"\"{family.name}\": [")
with self.out.indent():
for m in family.members[1:]:
for m in family.members:
self.out.emit(f"\"{m}\",")
self.out.emit(f"],")
self.out.emit("}")
Expand Down Expand Up @@ -1533,9 +1533,8 @@ def write_macro(self, mac: MacroInstruction) -> None:
self.out.emit(f"next_instr += {cache_adjust};")

if (
last_instr
and (family := last_instr.family)
and mac.name == family.members[0]
(family := self.families.get(mac.name))
and mac.name == family.name
and (cache_size := family.size)
):
self.out.emit(
Expand Down
2 changes: 1 addition & 1 deletion Tools/cases_generator/interpreter_definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ For explanations see "Generating the interpreter" below.)

### Defining an instruction family

A _family_ represents a specializable instruction and its specializations.
A _family_ maps a specializable instruction to its specializations.

Example: These opcodes all share the same instruction format):
```C
Expand Down
2 changes: 1 addition & 1 deletion Tools/cases_generator/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def test_macro_instruction():
inst(OP3, (unused/5, arg2, left, right -- res)) {
res = op3(arg2, left, right);
}
family(op, INLINE_CACHE_ENTRIES_OP) = { OP, OP3 };
family(OP, INLINE_CACHE_ENTRIES_OP) = { OP3 };
"""
output = """
TARGET(OP1) {
Expand Down