Skip to content

Commit 3e1b870

Browse files
committed
Add tier 2 support for YIELD_VALUE
1 parent ab6eda0 commit 3e1b870

9 files changed

+80
-16
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 0 deletions
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 & 0 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: 4 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: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,32 +1089,34 @@ dummy_func(
10891089
goto resume_frame;
10901090
}
10911091

1092-
tier1 inst(YIELD_VALUE, (retval -- unused)) {
1092+
inst(YIELD_VALUE, (retval -- value)) {
10931093
// NOTE: It's important that YIELD_VALUE never raises an exception!
10941094
// The compiler treats any exception raised here as a failed close()
10951095
// or throw() call.
10961096
assert(frame != &entry_frame);
1097-
frame->instr_ptr = next_instr;
1097+
frame->instr_ptr++;
10981098
PyGenObject *gen = _PyFrame_GetGenerator(frame);
10991099
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
11001100
assert(oparg == 0 || oparg == 1);
11011101
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
1102-
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
1102+
SYNC_SP();
1103+
_PyFrame_SetStackPointer(frame, stack_pointer);
11031104
tstate->exc_info = gen->gi_exc_state.previous_item;
11041105
gen->gi_exc_state.previous_item = NULL;
11051106
_Py_LeaveRecursiveCallPy(tstate);
11061107
_PyInterpreterFrame *gen_frame = frame;
11071108
frame = tstate->current_frame = frame->previous;
11081109
gen_frame->previous = NULL;
1109-
_PyFrame_StackPush(frame, retval);
11101110
/* We don't know which of these is relevant here, so keep them equal */
11111111
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
11121112
assert(_PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND ||
11131113
_PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER ||
11141114
_PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT ||
11151115
_PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR);
11161116
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
1117-
goto resume_frame;
1117+
LOAD_SP();
1118+
value = retval;
1119+
LLTRACE_RESUME_FRAME();
11181120
}
11191121

11201122
inst(POP_EXCEPT, (exc_value -- )) {

Python/executor_cases.c.h

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

Python/optimizer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ translate_bytecode_to_trace(
704704
int nuops = expansion->nuops;
705705
RESERVE(nuops + 1); /* One extra for exit */
706706
int16_t last_op = expansion->uops[nuops-1].uop;
707-
if (last_op == _POP_FRAME || last_op == _RETURN_GENERATOR) {
707+
if (last_op == _POP_FRAME || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) {
708708
// Check for trace stack underflow now:
709709
// We can't bail e.g. in the middle of
710710
// LOAD_CONST + _POP_FRAME.
@@ -763,7 +763,7 @@ translate_bytecode_to_trace(
763763
Py_FatalError("garbled expansion");
764764
}
765765

766-
if (uop == _POP_FRAME || uop == _RETURN_GENERATOR) {
766+
if (uop == _POP_FRAME || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) {
767767
TRACE_STACK_POP();
768768
/* Set the operand to the function or code object returned to,
769769
* to assist optimization passes. (See _PUSH_FRAME below.)

Python/optimizer_bytecodes.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,15 @@ dummy_func(void) {
673673
}
674674
}
675675

676+
op(_YIELD_VALUE, (unused -- res)) {
677+
OUT_OF_SPACE_IF_NULL(res = sym_new_unknown(ctx));
678+
}
679+
680+
op(_FOR_ITER_GEN_FRAME, ( -- )) {
681+
/* We are about to hit the end of the trace */
682+
goto done;
683+
}
684+
676685
op(_CHECK_STACK_SPACE, ( --)) {
677686
assert(corresponding_check_stack == NULL);
678687
corresponding_check_stack = this_instr;

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)