Skip to content

Commit 422f55e

Browse files
brandtbucheraisk
authored andcommitted
pythonGH-109214: _SET_IP before _PUSH_FRAME (but not _POP_FRAME) (pythonGH-111001)
1 parent 29090d0 commit 422f55e

File tree

5 files changed

+28
-44
lines changed

5 files changed

+28
-44
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove unnecessary instruction pointer updates before returning from frames.

Python/bytecodes.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,6 @@ dummy_func(
803803
}
804804

805805
macro(RETURN_VALUE) =
806-
_SAVE_CURRENT_IP + // Sets frame->prev_instr
807806
_POP_FRAME;
808807

809808
inst(INSTRUMENTED_RETURN_VALUE, (retval --)) {
@@ -827,7 +826,6 @@ dummy_func(
827826

828827
macro(RETURN_CONST) =
829828
LOAD_CONST +
830-
_SAVE_CURRENT_IP + // Sets frame->prev_instr
831829
_POP_FRAME;
832830

833831
inst(INSTRUMENTED_RETURN_CONST, (--)) {

Python/generated_cases.c.h

Lines changed: 19 additions & 32 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 & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,9 @@ translate_bytecode_to_trace(
701701
case OPARG_BOTTOM: // Second half of super-instr
702702
oparg = orig_oparg & 0xF;
703703
break;
704-
case OPARG_SET_IP: // op==_SET_IP; oparg=next instr
704+
case OPARG_SET_IP: // uop=_SET_IP; oparg=next_instr-1
705+
// The number of caches is smuggled in via offset:
706+
assert(offset == _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]);
705707
oparg = INSTR_IP(instr + offset, code);
706708
uop = _SET_IP;
707709
break;
@@ -850,11 +852,7 @@ remove_unneeded_uops(_PyUOpInstruction *trace, int trace_length)
850852
bool need_ip = true;
851853
for (int pc = 0; pc < trace_length; pc++) {
852854
int opcode = trace[pc].opcode;
853-
if (opcode == _SAVE_CURRENT_IP) {
854-
// Special case: never remove preceding _SET_IP
855-
last_set_ip = -1;
856-
}
857-
else if (opcode == _SET_IP) {
855+
if (opcode == _SET_IP) {
858856
if (!need_ip && last_set_ip >= 0) {
859857
trace[last_set_ip].opcode = NOP;
860858
}
@@ -866,8 +864,8 @@ remove_unneeded_uops(_PyUOpInstruction *trace, int trace_length)
866864
break;
867865
}
868866
else {
869-
// If opcode has ERROR or DEOPT, set need_up to true
870-
if (_PyOpcode_opcode_metadata[opcode].flags & (HAS_ERROR_FLAG | HAS_DEOPT_FLAG)) {
867+
// If opcode has ERROR or DEOPT, set need_ip to true
868+
if (_PyOpcode_opcode_metadata[opcode].flags & (HAS_ERROR_FLAG | HAS_DEOPT_FLAG) || opcode == _PUSH_FRAME) {
871869
need_ip = true;
872870
}
873871
}

0 commit comments

Comments
 (0)