Skip to content

Commit 6a00a58

Browse files
authored
gh-111786: Use separate opcode vars for Tier 1 and Tier 2 (#112289)
This makes Windows about 3% faster on pyperformance benchmarks.
1 parent 8deb8bc commit 6a00a58

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

Python/ceval.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
689689
#ifdef Py_STATS
690690
int lastopcode = 0;
691691
#endif
692-
int opcode; /* Current opcode */
692+
uint8_t opcode; /* Current opcode */
693693
int oparg; /* Current opcode argument, if any */
694694
#ifdef LLTRACE
695695
int lltrace = 0;
@@ -776,9 +776,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
776776
/* Start instructions */
777777
#if !USE_COMPUTED_GOTOS
778778
dispatch_opcode:
779-
// Cast to an 8-bit value to improve the code generated by MSVC
780-
// (in combination with the EXTRA_CASES macro).
781-
switch ((uint8_t)opcode)
779+
switch (opcode)
782780
#endif
783781
{
784782

@@ -822,7 +820,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
822820
#if USE_COMPUTED_GOTOS
823821
_unknown_opcode:
824822
#else
825-
EXTRA_CASES // From pycore_opcode.h, a 'case' for each unused opcode
823+
EXTRA_CASES // From pycore_opcode_metadata.h, a 'case' for each unused opcode
826824
#endif
827825
/* Tell C compilers not to hold the opcode variable in the loop.
828826
next_instr points the current instruction without TARGET(). */
@@ -994,28 +992,29 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
994992

995993
OPT_STAT_INC(traces_executed);
996994
_PyUOpInstruction *next_uop = current_executor->trace;
995+
uint16_t uopcode;
997996
#ifdef Py_STATS
998997
uint64_t trace_uop_execution_counter = 0;
999998
#endif
1000999

10011000
for (;;) {
1002-
opcode = next_uop->opcode;
1001+
uopcode = next_uop->opcode;
10031002
DPRINTF(3,
10041003
"%4d: uop %s, oparg %d, operand %" PRIu64 ", target %d, stack_level %d\n",
10051004
(int)(next_uop - current_executor->trace),
1006-
_PyUopName(opcode),
1005+
_PyUopName(uopcode),
10071006
next_uop->oparg,
10081007
next_uop->operand,
10091008
next_uop->target,
10101009
(int)(stack_pointer - _PyFrame_Stackbase(frame)));
10111010
next_uop++;
10121011
OPT_STAT_INC(uops_executed);
1013-
UOP_STAT_INC(opcode, execution_count);
1012+
UOP_STAT_INC(uopcode, execution_count);
10141013
#ifdef Py_STATS
10151014
trace_uop_execution_counter++;
10161015
#endif
10171016

1018-
switch (opcode) {
1017+
switch (uopcode) {
10191018

10201019
#include "executor_cases.c.h"
10211020

@@ -1053,7 +1052,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10531052
STACK_SHRINK(1);
10541053
error_tier_two:
10551054
DPRINTF(2, "Error: [Uop %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d]\n",
1056-
opcode, _PyUopName(opcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target,
1055+
uopcode, _PyUopName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target,
10571056
(int)(next_uop - current_executor->trace - 1));
10581057
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
10591058
frame->return_offset = 0; // Don't leave this random
@@ -1066,10 +1065,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10661065
// On DEOPT_IF we just repeat the last instruction.
10671066
// This presumes nothing was popped from the stack (nor pushed).
10681067
DPRINTF(2, "DEOPT: [Uop %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d]\n",
1069-
opcode, _PyUopName(opcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target,
1068+
uopcode, _PyUopName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target,
10701069
(int)(next_uop - current_executor->trace - 1));
10711070
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
1072-
UOP_STAT_INC(opcode, miss);
1071+
UOP_STAT_INC(uopcode, miss);
10731072
frame->return_offset = 0; // Dispatch to frame->instr_ptr
10741073
_PyFrame_SetStackPointer(frame, stack_pointer);
10751074
frame->instr_ptr = next_uop[-1].target + _PyCode_CODE(_PyFrame_GetCode(frame));

0 commit comments

Comments
 (0)