Skip to content

Commit 70e387c

Browse files
authored
GH-129709: Clean up tier two (GH-129710)
1 parent fbaa6c8 commit 70e387c

12 files changed

+97
-348
lines changed

Include/internal/pycore_uop_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,6 +3526,7 @@ dummy_func(
35263526
}
35273527

35283528
op(_MAYBE_EXPAND_METHOD, (callable[1], self_or_null[1], args[oparg] -- func[1], maybe_self[1], args[oparg])) {
3529+
(void)args;
35293530
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
35303531
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
35313532
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
@@ -3892,6 +3893,7 @@ dummy_func(
38923893
_CHECK_PERIODIC;
38933894

38943895
op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable[1], null[1], args[oparg] -- init[1], self[1], args[oparg])) {
3896+
(void)args;
38953897
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
38963898
DEOPT_IF(!PyStackRef_IsNull(null[0]));
38973899
DEOPT_IF(!PyType_Check(callable_o));
@@ -4119,7 +4121,7 @@ dummy_func(
41194121
PyObject *res_o = PyLong_FromSsize_t(len_i);
41204122
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
41214123
if (res_o == NULL) {
4122-
GOTO_ERROR(error);
4124+
ERROR_NO_POP();
41234125
}
41244126
PyStackRef_CLOSE(arg_stackref);
41254127
DEAD(args);
@@ -4364,6 +4366,7 @@ dummy_func(
43644366
}
43654367

43664368
op(_MAYBE_EXPAND_METHOD_KW, (callable[1], self_or_null[1], args[oparg], kwnames_in -- func[1], maybe_self[1], args[oparg], kwnames_out)) {
4369+
(void)args;
43674370
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
43684371
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
43694372
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
@@ -5022,7 +5025,7 @@ dummy_func(
50225025
if (frame->lltrace >= 2) {
50235026
printf("SIDE EXIT: [UOp ");
50245027
_PyUOpPrint(&next_uop[-1]);
5025-
printf(", exit %u, temp %d, target %d -> %s]\n",
5028+
printf(", exit %lu, temp %d, target %d -> %s]\n",
50265029
exit - current_executor->exits, exit->temperature.value_and_backoff,
50275030
(int)(target - _PyFrame_GetBytecode(frame)),
50285031
_PyOpcode_OpName[target->op.code]);
@@ -5032,11 +5035,11 @@ dummy_func(
50325035
exit->temperature = initial_temperature_backoff_counter();
50335036
Py_CLEAR(exit->executor);
50345037
}
5038+
tstate->previous_executor = (PyObject *)current_executor;
50355039
if (exit->executor == NULL) {
50365040
_Py_BackoffCounter temperature = exit->temperature;
50375041
if (!backoff_counter_triggers(temperature)) {
50385042
exit->temperature = advance_backoff_counter(temperature);
5039-
tstate->previous_executor = (PyObject *)current_executor;
50405043
GOTO_TIER_ONE(target);
50415044
}
50425045
_PyExecutorObject *executor;
@@ -5049,20 +5052,13 @@ dummy_func(
50495052
int optimized = _PyOptimizer_Optimize(frame, target, &executor, chain_depth);
50505053
if (optimized <= 0) {
50515054
exit->temperature = restart_backoff_counter(temperature);
5052-
if (optimized < 0) {
5053-
GOTO_UNWIND();
5054-
}
5055-
tstate->previous_executor = (PyObject *)current_executor;
5056-
GOTO_TIER_ONE(target);
5057-
}
5058-
else {
5059-
exit->temperature = initial_temperature_backoff_counter();
5055+
GOTO_TIER_ONE(optimized < 0 ? NULL : target);
50605056
}
5057+
exit->temperature = initial_temperature_backoff_counter();
50615058
}
50625059
exit->executor = executor;
50635060
}
50645061
Py_INCREF(exit->executor);
5065-
tstate->previous_executor = (PyObject *)current_executor;
50665062
GOTO_TIER_TWO(exit->executor);
50675063
}
50685064

@@ -5130,7 +5126,7 @@ dummy_func(
51305126
if (frame->lltrace >= 2) {
51315127
printf("DYNAMIC EXIT: [UOp ");
51325128
_PyUOpPrint(&next_uop[-1]);
5133-
printf(", exit %u, temp %d, target %d -> %s]\n",
5129+
printf(", exit %lu, temp %d, target %d -> %s]\n",
51345130
exit - current_executor->exits, exit->temperature.value_and_backoff,
51355131
(int)(target - _PyFrame_GetBytecode(frame)),
51365132
_PyOpcode_OpName[target->op.code]);
@@ -5150,21 +5146,15 @@ dummy_func(
51505146
int optimized = _PyOptimizer_Optimize(frame, target, &executor, 0);
51515147
if (optimized <= 0) {
51525148
exit->temperature = restart_backoff_counter(exit->temperature);
5153-
if (optimized < 0) {
5154-
GOTO_UNWIND();
5155-
}
5156-
GOTO_TIER_ONE(target);
5157-
}
5158-
else {
5159-
exit->temperature = initial_temperature_backoff_counter();
5149+
GOTO_TIER_ONE(optimized < 0 ? NULL : target);
51605150
}
5151+
exit->temperature = initial_temperature_backoff_counter();
51615152
}
51625153
GOTO_TIER_TWO(executor);
51635154
}
51645155

51655156
tier2 op(_START_EXECUTOR, (executor/4 --)) {
5166-
Py_DECREF(tstate->previous_executor);
5167-
tstate->previous_executor = NULL;
5157+
Py_CLEAR(tstate->previous_executor);
51685158
#ifndef _Py_JIT
51695159
current_executor = (_PyExecutorObject*)executor;
51705160
#endif
@@ -5190,14 +5180,16 @@ dummy_func(
51905180
}
51915181

51925182
tier2 op(_DEOPT, (--)) {
5193-
EXIT_TO_TIER1();
5183+
tstate->previous_executor = (PyObject *)current_executor;
5184+
GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET());
51945185
}
51955186

51965187
tier2 op(_ERROR_POP_N, (target/2 --)) {
5188+
tstate->previous_executor = (PyObject *)current_executor;
51975189
assert(oparg == 0);
51985190
frame->instr_ptr = _PyFrame_GetBytecode(frame) + target;
51995191
SYNC_SP();
5200-
GOTO_UNWIND();
5192+
GOTO_TIER_ONE(NULL);
52015193
}
52025194

52035195
/* Progress is guaranteed if we DEOPT on the eval breaker, because

Python/ceval.c

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -879,9 +879,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
879879
#undef LOAD_IP
880880
#define LOAD_IP(UNUSED) (void)0
881881

882-
#undef GOTO_ERROR
883-
#define GOTO_ERROR(LABEL) goto LABEL ## _tier_two
884-
885882
#ifdef Py_STATS
886883
// Disable these macros that apply to Tier 1 stats when we are in Tier 2
887884
#undef STAT_INC
@@ -957,46 +954,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
957954
_PyOpcode_OpName[frame->instr_ptr->op.code]);
958955
}
959956
#endif
960-
assert (next_uop[-1].format == UOP_FORMAT_JUMP);
957+
assert(next_uop[-1].format == UOP_FORMAT_JUMP);
961958
uint16_t target = uop_get_error_target(&next_uop[-1]);
962959
next_uop = current_executor->trace + target;
963960
goto tier2_dispatch;
964961

965-
error_tier_two:
966-
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
967-
assert(next_uop[-1].format == UOP_FORMAT_TARGET);
968-
frame->return_offset = 0; // Don't leave this random
969-
Py_DECREF(current_executor);
970-
tstate->previous_executor = NULL;
971-
next_instr = frame->instr_ptr;
972-
goto error;
973-
974962
jump_to_jump_target:
975963
assert(next_uop[-1].format == UOP_FORMAT_JUMP);
976964
target = uop_get_jump_target(&next_uop[-1]);
977965
next_uop = current_executor->trace + target;
978966
goto tier2_dispatch;
979967

980-
exit_to_tier1_dynamic:
981-
next_instr = frame->instr_ptr;
982-
goto goto_to_tier1;
983-
exit_to_tier1:
984-
assert(next_uop[-1].format == UOP_FORMAT_TARGET);
985-
next_instr = next_uop[-1].target + _PyFrame_GetBytecode(frame);
986-
goto_to_tier1:
987-
#ifdef Py_DEBUG
988-
if (frame->lltrace >= 2) {
989-
printf("DEOPT: [UOp ");
990-
_PyUOpPrint(&next_uop[-1]);
991-
printf(" -> %s]\n",
992-
_PyOpcode_OpName[next_instr->op.code]);
993-
}
994-
#endif
995-
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
996-
Py_DECREF(current_executor);
997-
tstate->previous_executor = NULL;
998-
DISPATCH();
999-
1000968
#endif // _Py_JIT
1001969

1002970
#endif // _Py_TIER2

Python/ceval_macros.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,6 @@ do { \
161161
JUMP_TO_LABEL(start_frame); \
162162
} while (0)
163163

164-
// Use this instead of 'goto error' so Tier 2 can go to a different label
165-
#define GOTO_ERROR(LABEL) JUMP_TO_LABEL(LABEL)
166-
167164
/* Tuple access macros */
168165

169166
#ifndef Py_DEBUG
@@ -387,17 +384,19 @@ _PyFrame_SetStackPointer(frame, stack_pointer)
387384
#define GOTO_TIER_TWO(EXECUTOR) \
388385
do { \
389386
OPT_STAT_INC(traces_executed); \
390-
jit_func jitted = (EXECUTOR)->jit_code; \
387+
_PyExecutorObject *_executor = (EXECUTOR); \
388+
jit_func jitted = _executor->jit_code; \
389+
/* Keep the shim frame alive via the executor: */ \
390+
Py_INCREF(_executor); \
391391
next_instr = jitted(frame, stack_pointer, tstate); \
392-
Py_DECREF(tstate->previous_executor); \
393-
tstate->previous_executor = NULL; \
392+
Py_DECREF(_executor); \
393+
Py_CLEAR(tstate->previous_executor); \
394394
frame = tstate->current_frame; \
395+
stack_pointer = _PyFrame_GetStackPointer(frame); \
395396
if (next_instr == NULL) { \
396397
next_instr = frame->instr_ptr; \
397-
stack_pointer = _PyFrame_GetStackPointer(frame); \
398398
goto error; \
399399
} \
400-
stack_pointer = _PyFrame_GetStackPointer(frame); \
401400
DISPATCH(); \
402401
} while (0)
403402
#else
@@ -410,24 +409,25 @@ do { \
410409
} while (0)
411410
#endif
412411

413-
#define GOTO_TIER_ONE(TARGET) \
414-
do { \
415-
Py_DECREF(tstate->previous_executor); \
416-
tstate->previous_executor = NULL; \
417-
next_instr = target; \
418-
DISPATCH(); \
412+
#define GOTO_TIER_ONE(TARGET) \
413+
do { \
414+
next_instr = (TARGET); \
415+
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); \
416+
Py_CLEAR(tstate->previous_executor); \
417+
if (next_instr == NULL) { \
418+
next_instr = frame->instr_ptr; \
419+
goto error; \
420+
} \
421+
DISPATCH(); \
419422
} while (0)
420423

421-
#define CURRENT_OPARG() (next_uop[-1].oparg)
422-
424+
#define CURRENT_OPARG() (next_uop[-1].oparg)
423425
#define CURRENT_OPERAND0() (next_uop[-1].operand0)
424426
#define CURRENT_OPERAND1() (next_uop[-1].operand1)
427+
#define CURRENT_TARGET() (next_uop[-1].target)
425428

426429
#define JUMP_TO_JUMP_TARGET() goto jump_to_jump_target
427430
#define JUMP_TO_ERROR() goto jump_to_error_target
428-
#define GOTO_UNWIND() goto error_tier_two
429-
#define EXIT_TO_TIER1() goto exit_to_tier1
430-
#define EXIT_TO_TIER1_DYNAMIC() goto exit_to_tier1_dynamic;
431431

432432
/* Stackref macros */
433433

0 commit comments

Comments
 (0)