Skip to content

Commit 7405745

Browse files
authored
Various small improvements to uop debug output (#112218)
- Show uop name in Error/DEOPT messages - Add target to some messages - Expose uop_name() as _PyUopName()
1 parent be0bd54 commit 7405745

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

Python/ceval.c

+11-4
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,8 @@ static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = {
647647

648648
extern const struct _PyCode_DEF(8) _Py_InitCleanup;
649649

650+
extern const char *_PyUopName(int index);
651+
650652
/* Disable unused label warnings. They are handy for debugging, even
651653
if computed gotos aren't used. */
652654

@@ -1002,11 +1004,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10021004
oparg = next_uop->oparg;
10031005
operand = next_uop->operand;
10041006
DPRINTF(3,
1005-
"%4d: uop %s, oparg %d, operand %" PRIu64 ", stack_level %d\n",
1007+
"%4d: uop %s, oparg %d, operand %" PRIu64 ", target %d, stack_level %d\n",
10061008
(int)(next_uop - current_executor->trace),
1007-
opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode],
1009+
_PyUopName(opcode),
10081010
oparg,
10091011
operand,
1012+
next_uop->target,
10101013
(int)(stack_pointer - _PyFrame_Stackbase(frame)));
10111014
next_uop++;
10121015
OPT_STAT_INC(uops_executed);
@@ -1051,7 +1054,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10511054
pop_1_error_tier_two:
10521055
STACK_SHRINK(1);
10531056
error_tier_two:
1054-
DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
1057+
DPRINTF(2, "Error: [Uop %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d]\n",
1058+
opcode, _PyUopName(opcode), oparg, operand, next_uop[-1].target,
1059+
(int)(next_uop - current_executor->trace - 1));
10551060
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
10561061
frame->return_offset = 0; // Don't leave this random
10571062
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -1062,7 +1067,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10621067
deoptimize:
10631068
// On DEOPT_IF we just repeat the last instruction.
10641069
// This presumes nothing was popped from the stack (nor pushed).
1065-
DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 " @ %d]\n", opcode, operand, (int)(next_uop-current_executor->trace-1));
1070+
DPRINTF(2, "DEOPT: [Uop %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d]\n",
1071+
opcode, _PyUopName(opcode), oparg, operand, next_uop[-1].target,
1072+
(int)(next_uop - current_executor->trace - 1));
10661073
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
10671074
UOP_STAT_INC(opcode, miss);
10681075
frame->return_offset = 0; // Dispatch to frame->instr_ptr

Python/optimizer.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ uop_dealloc(_PyUOpExecutorObject *self) {
324324
PyObject_Free(self);
325325
}
326326

327-
static const char *
328-
uop_name(int index)
327+
const char *
328+
_PyUopName(int index)
329329
{
330330
if (index <= MAX_REAL_OPCODE) {
331331
return _PyOpcode_OpName[index];
@@ -347,7 +347,7 @@ uop_item(_PyUOpExecutorObject *self, Py_ssize_t index)
347347
PyErr_SetNone(PyExc_IndexError);
348348
return NULL;
349349
}
350-
const char *name = uop_name(self->trace[index].opcode);
350+
const char *name = _PyUopName(self->trace[index].opcode);
351351
if (name == NULL) {
352352
name = "<nil>";
353353
}
@@ -451,7 +451,7 @@ translate_bytecode_to_trace(
451451
#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \
452452
DPRINTF(2, \
453453
" ADD_TO_TRACE(%s, %d, %" PRIu64 ")\n", \
454-
uop_name(OPCODE), \
454+
_PyUopName(OPCODE), \
455455
(OPARG), \
456456
(uint64_t)(OPERAND)); \
457457
assert(trace_length < max_length); \
@@ -477,7 +477,7 @@ translate_bytecode_to_trace(
477477
reserved = (n); // Keep ADD_TO_TRACE honest
478478

479479
// Reserve space for main+stub uops, plus 3 for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
480-
#define RESERVE(main, stub) RESERVE_RAW((main) + (stub) + 3, uop_name(opcode))
480+
#define RESERVE(main, stub) RESERVE_RAW((main) + (stub) + 3, _PyUopName(opcode))
481481

482482
// Trace stack operations (used by _PUSH_FRAME, _POP_FRAME)
483483
#define TRACE_STACK_PUSH() \
@@ -549,8 +549,8 @@ translate_bytecode_to_trace(
549549
uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely];
550550
_Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]];
551551
DPRINTF(4, "%s(%d): counter=%x, bitcount=%d, likely=%d, uopcode=%s\n",
552-
uop_name(opcode), oparg,
553-
counter, bitcount, jump_likely, uop_name(uopcode));
552+
_PyUopName(opcode), oparg,
553+
counter, bitcount, jump_likely, _PyUopName(uopcode));
554554
ADD_TO_TRACE(uopcode, max_length, 0, target);
555555
if (jump_likely) {
556556
_Py_CODEUNIT *target_instr = next_instr + oparg;
@@ -710,7 +710,7 @@ translate_bytecode_to_trace(
710710
}
711711
break;
712712
}
713-
DPRINTF(2, "Unsupported opcode %s\n", uop_name(opcode));
713+
DPRINTF(2, "Unsupported opcode %s\n", _PyUopName(opcode));
714714
OPT_UNSUPPORTED_OPCODE(opcode);
715715
goto done; // Break out of loop
716716
} // End default
@@ -844,7 +844,7 @@ make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies)
844844
for (int i = 0; i < length; i++) {
845845
printf("%4d %s(%d, %d, %" PRIu64 ")\n",
846846
i,
847-
uop_name(executor->trace[i].opcode),
847+
_PyUopName(executor->trace[i].opcode),
848848
executor->trace[i].oparg,
849849
executor->trace[i].target,
850850
executor->trace[i].operand);

0 commit comments

Comments
 (0)