Skip to content

Commit 880b48d

Browse files
Remove _BINARY_OP_INPLACE_ADD_UNICODE super instruction
1 parent 9ad32cc commit 880b48d

File tree

11 files changed

+65
-95
lines changed

11 files changed

+65
-95
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_uop_ids.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_uop_metadata.h

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

Lib/_opcode_metadata.py

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

Python/bytecodes.c

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ dummy_func(
588588
BINARY_OP_SUBSCR_STR_INT,
589589
BINARY_OP_SUBSCR_DICT,
590590
BINARY_OP_SUBSCR_GETITEM,
591-
// BINARY_OP_INPLACE_ADD_UNICODE, // See comments at that opcode.
591+
BINARY_OP_INPLACE_ADD_UNICODE,
592592
BINARY_OP_EXTEND,
593593
};
594594

@@ -762,13 +762,10 @@ dummy_func(
762762
macro(BINARY_OP_ADD_UNICODE) =
763763
_GUARD_TOS_UNICODE + _GUARD_NOS_UNICODE + unused/5 + _BINARY_OP_ADD_UNICODE + _POP_TOP_UNICODE + _POP_TOP_UNICODE;
764764

765-
// This is a subtle one. It's a super-instruction for
766-
// BINARY_OP_ADD_UNICODE followed by STORE_FAST
767-
// where the store goes into the left argument.
768-
// So the inputs are the same as for all BINARY_OP
769-
// specializations, but there is no output.
770-
// At the end we just skip over the STORE_FAST.
771-
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
765+
// This is a subtle one. We write NULL to the local
766+
// of the following STORE_FAST and leave the result for STORE_FAST
767+
// later to store.
768+
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- res)) {
772769
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
773770
assert(PyUnicode_CheckExact(left_o));
774771
assert(PyUnicode_CheckExact(PyStackRef_AsPyObjectBorrow(right)));
@@ -796,20 +793,16 @@ dummy_func(
796793
* that the string is safe to mutate.
797794
*/
798795
assert(Py_REFCNT(left_o) >= 2 || !PyStackRef_IsHeapSafe(left));
799-
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
800-
DEAD(left);
801796
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
802-
PyObject *right_o = PyStackRef_AsPyObjectSteal(right);
797+
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
803798
PyUnicode_Append(&temp, right_o);
804-
*target_local = PyStackRef_FromPyObjectSteal(temp);
805-
Py_DECREF(right_o);
806-
ERROR_IF(PyStackRef_IsNull(*target_local));
807-
#if TIER_ONE
808-
// The STORE_FAST is already done. This is done here in tier one,
809-
// and during trace projection in tier two:
810-
assert(next_instr->op.code == STORE_FAST);
811-
SKIP_OVER(1);
812-
#endif
799+
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
800+
DEAD(right);
801+
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
802+
DEAD(left);
803+
ERROR_IF(temp == NULL);
804+
res = PyStackRef_FromPyObjectSteal(temp);
805+
*target_local = PyStackRef_NULL;
813806
}
814807

815808
op(_GUARD_BINARY_OP_EXTEND, (descr/4, left, right -- left, right)) {
@@ -5594,7 +5587,6 @@ dummy_func(
55945587
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
55955588
// JIT should have disabled super instructions, as we can
55965589
// do these optimizations ourselves in the JIT.
5597-
assert(opcode != BINARY_OP_INPLACE_ADD_UNICODE);
55985590
_tstate->jit_tracer_state.prev_state.instr = next_instr;
55995591
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
56005592
if (_tstate->jit_tracer_state.prev_state.instr_code != (PyCodeObject *)prev_code) {

Python/executor_cases.c.h

Lines changed: 18 additions & 15 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: 11 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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,12 @@ _PyJit_translate_single_bytecode_to_trace(
951951
trace[trace_length - 1].operand1 = PyStackRef_IsNone(frame->f_executable) ? 2 : ((int)(frame->stackpointer - _PyFrame_Stackbase(frame)));
952952
break;
953953
}
954+
if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) {
955+
assert(i + 1 == nuops);
956+
_Py_CODEUNIT *next = target_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]];
957+
assert(next->op.code == STORE_FAST);
958+
operand = next->op.arg;
959+
}
954960
// All other instructions
955961
ADD_TO_TRACE(uop, oparg, operand, target);
956962
}

Python/optimizer_bytecodes.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -300,26 +300,11 @@ dummy_func(void) {
300300

301301
op(_BINARY_OP_ADD_UNICODE, (left, right -- res, l, r)) {
302302
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-
}
317303
l = left;
318304
r = right;
319305
}
320306

321-
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) {
322-
JitOptRef res;
307+
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- res)) {
323308
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
324309
assert(PyUnicode_CheckExact(sym_get_const(ctx, left)));
325310
assert(PyUnicode_CheckExact(sym_get_const(ctx, right)));
@@ -333,8 +318,7 @@ dummy_func(void) {
333318
else {
334319
res = sym_new_type(ctx, &PyUnicode_Type);
335320
}
336-
// _STORE_FAST:
337-
GETLOCAL(this_instr->operand0) = res;
321+
GETLOCAL(this_instr->operand0) = sym_new_null(ctx);
338322
}
339323

340324
op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) {

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)