Skip to content

Commit 9831dea

Browse files
authored
gh-148211: decompose _POP_TWO/_POP_CALL(_ONE/_TWO) in JIT (GH-148377)
1 parent 72006a7 commit 9831dea

File tree

9 files changed

+1027
-1280
lines changed

9 files changed

+1027
-1280
lines changed

Include/internal/pycore_uop_ids.h

Lines changed: 1010 additions & 1018 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 0 additions & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_capi/test_opt.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,6 @@ def testfunc(n):
16431643
self.assertIsNotNone(ex)
16441644
uops = get_opnames(ex)
16451645
self.assertNotIn("_BINARY_OP_ADD_INT", uops)
1646-
self.assertNotIn("_POP_TWO", uops)
16471646
self.assertNotIn("_GUARD_NOS_INT", uops)
16481647
self.assertNotIn("_GUARD_TOS_INT", uops)
16491648

@@ -1862,7 +1861,6 @@ def testfunc(n):
18621861
self.assertIsNotNone(ex)
18631862
uops = get_opnames(ex)
18641863
self.assertNotIn("_COMPARE_OP", uops)
1865-
self.assertNotIn("_POP_TWO", uops)
18661864

18671865
def test_compare_op_int_insert_two_load_const_inline_borrow(self):
18681866
def testfunc(n):
@@ -1930,7 +1928,6 @@ def testfunc(n):
19301928
self.assertIsNotNone(ex)
19311929
uops = get_opnames(ex)
19321930
self.assertNotIn("_CONTAINS_OP", uops)
1933-
self.assertNotIn("_POP_TWO", uops)
19341931

19351932
def test_to_bool_bool_contains_op_set(self):
19361933
"""

Python/bytecodes.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,6 @@ dummy_func(
381381
PyStackRef_CLOSE_SPECIALIZED(value, _PyUnicode_ExactDealloc);
382382
}
383383

384-
tier2 op(_POP_TWO, (nos, tos --)) {
385-
PyStackRef_CLOSE(tos);
386-
PyStackRef_CLOSE(nos);
387-
}
388-
389384
op(_POP_TOP_OPARG, (args[oparg] -- )) {
390385
_PyStackRef_CloseStack(args, oparg);
391386
DEAD(args);
@@ -5922,27 +5917,6 @@ dummy_func(
59225917
value = PyStackRef_FromPyObjectBorrow(ptr);
59235918
}
59245919

5925-
tier2 op(_POP_CALL, (callable, null --)) {
5926-
(void)null; // Silence compiler warnings about unused variables
5927-
DEAD(null);
5928-
PyStackRef_CLOSE(callable);
5929-
}
5930-
5931-
tier2 op(_POP_CALL_ONE, (callable, null, pop --)) {
5932-
PyStackRef_CLOSE(pop);
5933-
(void)null; // Silence compiler warnings about unused variables
5934-
DEAD(null);
5935-
PyStackRef_CLOSE(callable);
5936-
}
5937-
5938-
tier2 op(_POP_CALL_TWO, (callable, null, pop1, pop2 --)) {
5939-
PyStackRef_CLOSE(pop2);
5940-
PyStackRef_CLOSE(pop1);
5941-
(void)null; // Silence compiler warnings about unused variables
5942-
DEAD(null);
5943-
PyStackRef_CLOSE(callable);
5944-
}
5945-
59465920
tier2 op(_SHUFFLE_3_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null, arg -- res, a, c)) {
59475921
res = PyStackRef_FromPyObjectBorrow(ptr);
59485922
a = arg;

Python/executor_cases.c.h

Lines changed: 0 additions & 122 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer_analysis.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ const uint16_t op_without_push[MAX_UOP_ID + 1] = {
677677
[_LOAD_FAST] = _NOP,
678678
[_LOAD_FAST_BORROW] = _NOP,
679679
[_LOAD_SMALL_INT] = _NOP,
680+
[_PUSH_NULL] = _NOP,
680681
};
681682

682683
const bool op_skip[MAX_UOP_ID + 1] = {
@@ -692,13 +693,6 @@ const uint16_t op_without_pop[MAX_UOP_ID + 1] = {
692693
[_POP_TOP_INT] = _NOP,
693694
[_POP_TOP_FLOAT] = _NOP,
694695
[_POP_TOP_UNICODE] = _NOP,
695-
[_POP_TWO] = _POP_TOP,
696-
[_POP_CALL_TWO] = _POP_CALL_ONE,
697-
[_POP_CALL_ONE] = _POP_CALL,
698-
};
699-
700-
const uint16_t op_without_pop_null[MAX_UOP_ID + 1] = {
701-
[_POP_CALL] = _POP_TOP,
702696
};
703697

704698

@@ -733,10 +727,10 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
733727
default:
734728
{
735729
// Cancel out pushes and pops, repeatedly. So:
736-
// _LOAD_FAST + _POP_TWO + _LOAD_CONST_INLINE_BORROW + _POP_TOP
730+
// _LOAD_FAST + _POP_TOP + _POP_TOP + _LOAD_CONST_INLINE_BORROW + _POP_TOP
737731
// ...becomes:
738-
// _NOP + _POP_TOP + _NOP + _NOP
739-
while (op_without_pop[opcode] || op_without_pop_null[opcode]) {
732+
// _NOP + _NOP + _POP_TOP + _NOP + _NOP
733+
while (op_without_pop[opcode]) {
740734
_PyUOpInstruction *last = &buffer[pc - 1];
741735
while (op_skip[last->opcode]) {
742736
last--;
@@ -749,14 +743,6 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
749743
pc = (int)(last - buffer);
750744
}
751745
}
752-
else if (last->opcode == _PUSH_NULL) {
753-
// Handle _POP_CALL separately.
754-
// This looks for a preceding _PUSH_NULL instruction and
755-
// simplifies to _POP_TOP.
756-
last->opcode = _NOP;
757-
opcode = buffer[pc].opcode = op_without_pop_null[opcode];
758-
assert(opcode);
759-
}
760746
else {
761747
break;
762748
}

Python/optimizer_bytecodes.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,10 @@ dummy_func(void) {
12721272
out = Py_True;
12731273
}
12741274
sym_set_const(res, out);
1275-
ADD_OP(_POP_CALL_TWO, 0, 0);
1275+
ADD_OP(_POP_TOP, 0, 0);
1276+
ADD_OP(_POP_TOP, 0, 0);
1277+
ADD_OP(_POP_TOP_NOP, 0, 0);
1278+
ADD_OP(_POP_TOP, 0, 0);
12761279
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)out);
12771280
}
12781281
}

0 commit comments

Comments
 (0)