Skip to content

Commit

Permalink
pythonGH-118095: Add tier 2 support for YIELD_VALUE (pythonGH-118380)
Browse files Browse the repository at this point in the history
  • Loading branch information
markshannon authored and SonicField committed May 8, 2024
1 parent 754ea49 commit 573070c
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 16 deletions.
1 change: 1 addition & 0 deletions Include/internal/pycore_opcode_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Include/internal/pycore_uop_ids.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Include/internal/pycore_uop_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,32 +1089,38 @@ dummy_func(
goto resume_frame;
}

tier1 inst(YIELD_VALUE, (retval -- unused)) {
inst(YIELD_VALUE, (retval -- value)) {
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed close()
// or throw() call.
#if TIER_ONE
assert(frame != &entry_frame);
frame->instr_ptr = next_instr;
#endif
frame->instr_ptr++;
PyGenObject *gen = _PyFrame_GetGenerator(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
assert(oparg == 0 || oparg == 1);
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
_PyFrame_SetStackPointer(frame, stack_pointer - 1);
SYNC_SP();
_PyFrame_SetStackPointer(frame, stack_pointer);
tstate->exc_info = gen->gi_exc_state.previous_item;
gen->gi_exc_state.previous_item = NULL;
_Py_LeaveRecursiveCallPy(tstate);
_PyInterpreterFrame *gen_frame = frame;
frame = tstate->current_frame = frame->previous;
gen_frame->previous = NULL;
_PyFrame_StackPush(frame, retval);
/* We don't know which of these is relevant here, so keep them equal */
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
#if TIER_ONE
assert(_PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND ||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER ||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT ||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR);
#endif
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
goto resume_frame;
LOAD_SP();
value = retval;
LLTRACE_RESUME_FRAME();
}

inst(POP_EXCEPT, (exc_value -- )) {
Expand Down
41 changes: 41 additions & 0 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Python/optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ translate_bytecode_to_trace(
int nuops = expansion->nuops;
RESERVE(nuops + 1); /* One extra for exit */
int16_t last_op = expansion->uops[nuops-1].uop;
if (last_op == _POP_FRAME || last_op == _RETURN_GENERATOR) {
if (last_op == _POP_FRAME || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) {
// Check for trace stack underflow now:
// We can't bail e.g. in the middle of
// LOAD_CONST + _POP_FRAME.
Expand Down Expand Up @@ -763,7 +763,7 @@ translate_bytecode_to_trace(
Py_FatalError("garbled expansion");
}

if (uop == _POP_FRAME || uop == _RETURN_GENERATOR) {
if (uop == _POP_FRAME || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) {
TRACE_STACK_POP();
/* Set the operand to the function or code object returned to,
* to assist optimization passes. (See _PUSH_FRAME below.)
Expand Down
9 changes: 9 additions & 0 deletions Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,15 @@ dummy_func(void) {
}
}

op(_YIELD_VALUE, (unused -- res)) {
OUT_OF_SPACE_IF_NULL(res = sym_new_unknown(ctx));
}

op(_FOR_ITER_GEN_FRAME, ( -- )) {
/* We are about to hit the end of the trace */
goto done;
}

op(_CHECK_STACK_SPACE, ( --)) {
assert(corresponding_check_stack == NULL);
corresponding_check_stack = this_instr;
Expand Down
14 changes: 9 additions & 5 deletions Python/optimizer_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 573070c

Please sign in to comment.