Skip to content

Commit cbc3d9a

Browse files
Make CALL_LIST_APPEND a normal instruction, disable superinstructions in the JIT
1 parent cbe0cb7 commit cbc3d9a

File tree

11 files changed

+96
-146
lines changed

11 files changed

+96
-146
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_tstate.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ typedef struct _PyJitTracerInitialState {
3737

3838
typedef struct _PyJitTracerPreviousState {
3939
bool dependencies_still_valid;
40-
bool instr_is_super;
4140
int code_max_size;
4241
int code_curr_size;
4342
int instr_oparg;

Include/internal/pycore_uop_ids.h

Lines changed: 4 additions & 4 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: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4329,8 +4329,7 @@ dummy_func(
43294329
DEOPT_IF(callable_o != interp->callable_cache.list_append);
43304330
}
43314331

4332-
// This is secretly a super-instruction
4333-
op(_CALL_LIST_APPEND, (callable, self, arg -- c, s)) {
4332+
op(_CALL_LIST_APPEND, (callable, self, arg -- none, c, s)) {
43344333
assert(oparg == 1);
43354334
PyObject *self_o = PyStackRef_AsPyObjectBorrow(self);
43364335

@@ -4343,13 +4342,9 @@ dummy_func(
43434342
}
43444343
c = callable;
43454344
s = self;
4346-
INPUTS_DEAD();
4347-
#if TIER_ONE
4348-
// Skip the following POP_TOP. This is done here in tier one, and
4349-
// during trace projection in tier two:
4350-
assert(next_instr->op.code == POP_TOP);
4351-
SKIP_OVER(1);
4352-
#endif
4345+
DEAD(callable);
4346+
DEAD(self);
4347+
none = PyStackRef_None;
43534348
}
43544349

43554350
op(_CALL_METHOD_DESCRIPTOR_O, (callable, self_or_null, args[oparg] -- res)) {
@@ -5597,15 +5592,10 @@ dummy_func(
55975592
// Super instructions. Instruction deopted. There's a mismatch in what the stack expects
55985593
// in the optimizer. So we have to reflect in the trace correctly.
55995594
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
5600-
if ((_tstate->jit_tracer_state.prev_state.instr->op.code == CALL_LIST_APPEND &&
5601-
opcode == POP_TOP) ||
5602-
(_tstate->jit_tracer_state.prev_state.instr->op.code == BINARY_OP_INPLACE_ADD_UNICODE &&
5603-
opcode == STORE_FAST)) {
5604-
_tstate->jit_tracer_state.prev_state.instr_is_super = true;
5605-
}
5606-
else {
5607-
_tstate->jit_tracer_state.prev_state.instr = next_instr;
5608-
}
5595+
// JIT should have disabled super instructions, as we can
5596+
// do these optimizations ourselves in the JIT.
5597+
assert(opcode != BINARY_OP_INPLACE_ADD_UNICODE);
5598+
_tstate->jit_tracer_state.prev_state.instr = next_instr;
56095599
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
56105600
if (_tstate->jit_tracer_state.prev_state.instr_code != (PyCodeObject *)prev_code) {
56115601
Py_SETREF(_tstate->jit_tracer_state.prev_state.instr_code, (PyCodeObject*)Py_NewRef((prev_code)));

Python/executor_cases.c.h

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

Python/generated_cases.c.h

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

Python/optimizer.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,6 @@ _PyJit_translate_single_bytecode_to_trace(
703703
}
704704
#endif
705705

706-
// Skip over super instructions.
707-
if (_tstate->jit_tracer_state.prev_state.instr_is_super) {
708-
_tstate->jit_tracer_state.prev_state.instr_is_super = false;
709-
return 1;
710-
}
711-
712706
if (opcode == ENTER_EXECUTOR) {
713707
goto full;
714708
}
@@ -957,12 +951,6 @@ _PyJit_translate_single_bytecode_to_trace(
957951
trace[trace_length - 1].operand1 = PyStackRef_IsNone(frame->f_executable) ? 2 : ((int)(frame->stackpointer - _PyFrame_Stackbase(frame)));
958952
break;
959953
}
960-
if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) {
961-
assert(i + 1 == nuops);
962-
_Py_CODEUNIT *next = target_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]];
963-
assert(next->op.code == STORE_FAST);
964-
operand = next->op.arg;
965-
}
966954
// All other instructions
967955
ADD_TO_TRACE(uop, oparg, operand, target);
968956
}
@@ -1077,7 +1065,6 @@ _PyJit_TryInitializeTracing(
10771065
_tstate->jit_tracer_state.prev_state.instr_frame = frame;
10781066
_tstate->jit_tracer_state.prev_state.instr_oparg = oparg;
10791067
_tstate->jit_tracer_state.prev_state.instr_stacklevel = curr_stackdepth;
1080-
_tstate->jit_tracer_state.prev_state.instr_is_super = false;
10811068
assert(curr_instr->op.code == JUMP_BACKWARD_JIT || (exit != NULL));
10821069
_tstate->jit_tracer_state.initial_state.jump_backward_instr = curr_instr;
10831070

Python/optimizer_bytecodes.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,21 @@ dummy_func(void) {
299299
}
300300

301301
op(_BINARY_OP_ADD_UNICODE, (left, right -- res, l, r)) {
302-
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
303302
res = sym_new_type(ctx, &PyUnicode_Type);
303+
// Re-implement the BINARY_OP_INPLACE_ADD_UNICODE super-instruction.
304+
if ((this_instr + 5)->opcode == _STORE_FAST) {
305+
assert((this_instr + 1)->opcode == _POP_TOP_UNICODE);
306+
assert((this_instr + 2)->opcode == _POP_TOP_UNICODE);
307+
assert((this_instr + 3)->opcode == _CHECK_VALIDITY);
308+
assert((this_instr + 4)->opcode == _SET_IP);
309+
int local_slot = (this_instr + 5)->oparg;
310+
if (PyJitRef_Unwrap(left) == PyJitRef_Unwrap(GETLOCAL(local_slot))) {
311+
REPLACE_OP(this_instr, _BINARY_OP_INPLACE_ADD_UNICODE, oparg, local_slot);
312+
REPLACE_OP(this_instr + 1, _NOP, 0, 0);
313+
REPLACE_OP(this_instr + 2, _NOP, 0, 0);
314+
REPLACE_OP(this_instr + 5, _NOP, 0, 0);
315+
}
316+
}
304317
l = left;
305318
r = right;
306319
}
@@ -1041,10 +1054,11 @@ dummy_func(void) {
10411054
sym_set_const(flag, Py_True);
10421055
}
10431056

1044-
op(_CALL_LIST_APPEND, (callable, self, arg -- c, s)) {
1057+
op(_CALL_LIST_APPEND, (callable, self, arg -- none, c, s)) {
10451058
(void)(arg);
10461059
c = callable;
10471060
s = self;
1061+
none = sym_new_const(ctx, Py_None);
10481062
}
10491063

10501064
op(_GUARD_IS_FALSE_POP, (flag -- )) {

0 commit comments

Comments
 (0)