Skip to content

Commit 00a506a

Browse files
committed
gh-111786: Use separate opcode vars for Tier 1 and Tier 2
Suggested by @neonene: #111786 (comment) This makes Windows about 3% faster on pyperformance benchmarks.
1 parent 7e8f4fc commit 00a506a

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

Python/ceval.c

+10-11
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
678678
#ifdef Py_STATS
679679
int lastopcode = 0;
680680
#endif
681-
uint16_t opcode; /* Current opcode */
681+
uint8_t opcode; /* Current opcode */
682682
int oparg; /* Current opcode argument, if any */
683683
#ifdef LLTRACE
684684
int lltrace = 0;
@@ -765,9 +765,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
765765
/* Start instructions */
766766
#if !USE_COMPUTED_GOTOS
767767
dispatch_opcode:
768-
// Cast to an 8-bit value to improve the code generated by MSVC
769-
// (in combination with the EXTRA_CASES macro).
770-
switch ((uint8_t)opcode)
768+
switch (opcode)
771769
#endif
772770
{
773771

@@ -983,30 +981,31 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
983981

984982
OPT_STAT_INC(traces_executed);
985983
_PyUOpInstruction *next_uop = current_executor->trace;
984+
uint16_t uopcode;
986985
uint64_t operand;
987986
#ifdef Py_STATS
988987
uint64_t trace_uop_execution_counter = 0;
989988
#endif
990989

991990
for (;;) {
992-
opcode = next_uop->opcode;
991+
uopcode = next_uop->opcode;
993992
oparg = next_uop->oparg;
994993
operand = next_uop->operand;
995994
DPRINTF(3,
996995
"%4d: uop %s, oparg %d, operand %" PRIu64 ", stack_level %d\n",
997996
(int)(next_uop - current_executor->trace),
998-
opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode],
997+
uopcode < 256 ? _PyOpcode_OpName[uopcode] : _PyOpcode_uop_name[uopcode],
999998
oparg,
1000999
operand,
10011000
(int)(stack_pointer - _PyFrame_Stackbase(frame)));
10021001
next_uop++;
10031002
OPT_STAT_INC(uops_executed);
1004-
UOP_STAT_INC(opcode, execution_count);
1003+
UOP_STAT_INC(uopcode, execution_count);
10051004
#ifdef Py_STATS
10061005
trace_uop_execution_counter++;
10071006
#endif
10081007

1009-
switch (opcode) {
1008+
switch (uopcode) {
10101009

10111010
#include "executor_cases.c.h"
10121011

@@ -1042,7 +1041,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10421041
pop_1_error_tier_two:
10431042
STACK_SHRINK(1);
10441043
error_tier_two:
1045-
DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
1044+
DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", uopcode, operand);
10461045
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
10471046
frame->return_offset = 0; // Don't leave this random
10481047
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -1053,9 +1052,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10531052
deoptimize:
10541053
// On DEOPT_IF we just repeat the last instruction.
10551054
// This presumes nothing was popped from the stack (nor pushed).
1056-
DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 " @ %d]\n", opcode, operand, (int)(next_uop-current_executor->trace-1));
1055+
DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 " @ %d]\n", uopcode, operand, (int)(next_uop-current_executor->trace-1));
10571056
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
1058-
UOP_STAT_INC(opcode, miss);
1057+
UOP_STAT_INC(uopcode, miss);
10591058
frame->return_offset = 0; // Dispatch to frame->instr_ptr
10601059
_PyFrame_SetStackPointer(frame, stack_pointer);
10611060
frame->instr_ptr = next_uop[-1].target + _PyCode_CODE((PyCodeObject *)frame->f_executable);

0 commit comments

Comments
 (0)