Skip to content

Commit 76d0868

Browse files
authored
Cleanup tier2 debug output (#116920)
Various tweaks, including a slight refactor of the special cases for `_PUSH_FRAME`/`_POP_FRAME` to show the actual operand emitted.
1 parent 849e071 commit 76d0868

File tree

5 files changed

+50
-22
lines changed

5 files changed

+50
-22
lines changed

Python/ceval.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10171017
uopcode = next_uop->opcode;
10181018
#ifdef Py_DEBUG
10191019
if (lltrace >= 3) {
1020-
printf("%4d uop: ", (int)(next_uop - (current_executor == NULL ? next_uop : current_executor->trace)));
1020+
if (next_uop->opcode == _START_EXECUTOR || next_uop->opcode == _COLD_EXIT) {
1021+
printf("%4d uop: ", 0);
1022+
}
1023+
else {
1024+
printf("%4d uop: ", (int)(next_uop - current_executor->trace));
1025+
}
10211026
_PyUOpPrint(next_uop);
10221027
printf(" stack_level=%d\n",
10231028
(int)(stack_pointer - _PyFrame_Stackbase(frame)));
@@ -1113,7 +1118,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11131118
_PyUOpPrint(&next_uop[-1]);
11141119
printf(", exit %u, temp %d, target %d -> %s]\n",
11151120
exit_index, exit->temperature, exit->target,
1116-
_PyOpcode_OpName[frame->instr_ptr->op.code]);
1121+
_PyOpcode_OpName[_PyCode_CODE(_PyFrame_GetCode(frame))[exit->target].op.code]);
11171122
}
11181123
#endif
11191124
Py_INCREF(exit->executor);

Python/optimizer.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ _PyUOpPrint(const _PyUOpInstruction *uop)
313313
else {
314314
printf("%s", name);
315315
}
316-
printf(" (%d, target=%d, operand=%" PRIx64 ")",
316+
printf(" (%d, target=%d, operand=%#" PRIx64 ")",
317317
uop->oparg,
318318
uop->target,
319319
(uint64_t)uop->operand);
@@ -528,7 +528,7 @@ translate_bytecode_to_trace(
528528
}
529529
#endif
530530

531-
DPRINTF(4,
531+
DPRINTF(2,
532532
"Optimizing %s (%s:%d) at byte offset %d\n",
533533
PyUnicode_AsUTF8(code->co_qualname),
534534
PyUnicode_AsUTF8(code->co_filename),
@@ -546,7 +546,7 @@ translate_bytecode_to_trace(
546546
uint32_t oparg = instr->op.arg;
547547
uint32_t extended = 0;
548548

549-
DPRINTF(3, "%d: %s(%d)\n", target, _PyOpcode_OpName[opcode], oparg);
549+
DPRINTF(2, "%d: %s(%d)\n", target, _PyOpcode_OpName[opcode], oparg);
550550

551551
if (opcode == ENTER_EXECUTOR) {
552552
assert(oparg < 256);
@@ -606,7 +606,7 @@ translate_bytecode_to_trace(
606606
confidence = confidence * (18 - bitcount) / 20;
607607
}
608608
uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely];
609-
DPRINTF(2, "%d: %s(%d): counter=%x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n",
609+
DPRINTF(2, "%d: %s(%d): counter=%04x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n",
610610
target, _PyOpcode_OpName[opcode], oparg,
611611
counter, bitcount, jump_likely, confidence, _PyUOpName(uopcode));
612612
if (confidence < CONFIDENCE_CUTOFF) {
@@ -617,7 +617,7 @@ translate_bytecode_to_trace(
617617
_Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]];
618618
_Py_CODEUNIT *target_instr = next_instr + oparg;
619619
if (jump_likely) {
620-
DPRINTF(2, "Jump likely (%x = %d bits), continue at byte offset %d\n",
620+
DPRINTF(2, "Jump likely (%04x = %d bits), continue at byte offset %d\n",
621621
instr[1].cache, bitcount, 2 * INSTR_IP(target_instr, code));
622622
instr = target_instr;
623623
ADD_TO_TRACE(uopcode, max_length, 0, INSTR_IP(next_instr, code));
@@ -716,12 +716,12 @@ translate_bytecode_to_trace(
716716
expansion->uops[i].offset);
717717
Py_FatalError("garbled expansion");
718718
}
719-
ADD_TO_TRACE(uop, oparg, operand, target);
719+
720720
if (uop == _POP_FRAME) {
721721
TRACE_STACK_POP();
722722
/* Set the operand to the function object returned to,
723723
* to assist optimization passes */
724-
trace[trace_length-1].operand = (uintptr_t)func;
724+
ADD_TO_TRACE(uop, oparg, (uintptr_t)func, target);
725725
DPRINTF(2,
726726
"Returning to %s (%s:%d) at byte offset %d\n",
727727
PyUnicode_AsUTF8(code->co_qualname),
@@ -730,6 +730,7 @@ translate_bytecode_to_trace(
730730
2 * INSTR_IP(instr, code));
731731
goto top;
732732
}
733+
733734
if (uop == _PUSH_FRAME) {
734735
assert(i + 1 == nuops);
735736
int func_version_offset =
@@ -738,7 +739,7 @@ translate_bytecode_to_trace(
738739
+ 1;
739740
uint32_t func_version = read_u32(&instr[func_version_offset].cache);
740741
PyFunctionObject *new_func = _PyFunction_LookupByVersion(func_version);
741-
DPRINTF(3, "Function object: %p\n", func);
742+
DPRINTF(2, "Function: version=%#x; object=%p\n", (int)func_version, new_func);
742743
if (new_func != NULL) {
743744
PyCodeObject *new_code = (PyCodeObject *)PyFunction_GET_CODE(new_func);
744745
if (new_code == code) {
@@ -748,6 +749,7 @@ translate_bytecode_to_trace(
748749
PyUnicode_AsUTF8(new_code->co_filename),
749750
new_code->co_firstlineno);
750751
OPT_STAT_INC(recursive_call);
752+
ADD_TO_TRACE(uop, oparg, 0, target);
751753
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
752754
goto done;
753755
}
@@ -756,16 +758,17 @@ translate_bytecode_to_trace(
756758
// Perhaps it may happen again, so don't bother tracing.
757759
// TODO: Reason about this -- is it better to bail or not?
758760
DPRINTF(2, "Bailing because co_version != func_version\n");
761+
ADD_TO_TRACE(uop, oparg, 0, target);
759762
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
760763
goto done;
761764
}
762765
// Increment IP to the return address
763766
instr += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + 1;
764767
TRACE_STACK_PUSH();
765768
_Py_BloomFilter_Add(dependencies, new_code);
766-
/* Set the operand to the callee's code object,
767-
* to assist optimization passes */
768-
trace[trace_length-1].operand = (uintptr_t)new_func;
769+
/* Set the operand to the callee's function object,
770+
* to assist optimization passes */
771+
ADD_TO_TRACE(uop, oparg, (uintptr_t)new_func, target);
769772
code = new_code;
770773
func = new_func;
771774
instr = _PyCode_CODE(code);
@@ -777,9 +780,14 @@ translate_bytecode_to_trace(
777780
2 * INSTR_IP(instr, code));
778781
goto top;
779782
}
783+
DPRINTF(2, "Bail, new_func == NULL\n");
784+
ADD_TO_TRACE(uop, oparg, operand, target);
780785
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
781786
goto done;
782787
}
788+
789+
// All other instructions
790+
ADD_TO_TRACE(uop, oparg, operand, target);
783791
}
784792
break;
785793
}
@@ -803,17 +811,18 @@ translate_bytecode_to_trace(
803811
// Skip short traces like _SET_IP, LOAD_FAST, _SET_IP, _EXIT_TRACE
804812
if (progress_needed || trace_length < 5) {
805813
OPT_STAT_INC(trace_too_short);
806-
DPRINTF(4,
807-
"No trace for %s (%s:%d) at byte offset %d\n",
814+
DPRINTF(2,
815+
"No trace for %s (%s:%d) at byte offset %d (%s)\n",
808816
PyUnicode_AsUTF8(code->co_qualname),
809817
PyUnicode_AsUTF8(code->co_filename),
810818
code->co_firstlineno,
811-
2 * INSTR_IP(initial_instr, code));
819+
2 * INSTR_IP(initial_instr, code),
820+
progress_needed ? "no progress" : "too short");
812821
return 0;
813822
}
814823
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, target);
815824
DPRINTF(1,
816-
"Created a trace for %s (%s:%d) at byte offset %d -- length %d\n",
825+
"Created a proto-trace for %s (%s:%d) at byte offset %d -- length %d\n",
817826
PyUnicode_AsUTF8(code->co_qualname),
818827
PyUnicode_AsUTF8(code->co_filename),
819828
code->co_firstlineno,
@@ -938,6 +947,8 @@ make_executor_from_uops(_PyUOpInstruction *buffer, const _PyBloomFilter *depende
938947
assert(next_exit == -1);
939948
assert(dest == executor->trace);
940949
dest->opcode = _START_EXECUTOR;
950+
dest->oparg = 0;
951+
dest->target = 0;
941952
dest->operand = (uintptr_t)executor;
942953
_Py_ExecutorInit(executor, dependencies);
943954
#ifdef Py_DEBUG
@@ -947,7 +958,7 @@ make_executor_from_uops(_PyUOpInstruction *buffer, const _PyBloomFilter *depende
947958
lltrace = *python_lltrace - '0'; // TODO: Parse an int and all that
948959
}
949960
if (lltrace >= 2) {
950-
printf("Optimized executor (length %d):\n", length);
961+
printf("Optimized trace (length %d):\n", length);
951962
for (int i = 0; i < length; i++) {
952963
printf("%4d OPTIMIZED: ", i);
953964
_PyUOpPrint(&executor->trace[i]);

Python/optimizer_analysis.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#ifdef Py_DEBUG
3737
extern const char *_PyUOpName(int index);
38+
extern void _PyUOpPrint(const _PyUOpInstruction *uop);
3839
static const char *const DEBUG_ENV = "PYTHON_OPT_DEBUG";
3940
static inline int get_lltrace(void) {
4041
char *uop_debug = Py_GETENV(DEBUG_ENV);
@@ -377,14 +378,20 @@ optimize_uops(
377378

378379
_Py_UopsSymbol **stack_pointer = ctx->frame->stack_pointer;
379380

380-
DPRINTF(3, "Abstract interpreting %s:%d ",
381-
_PyUOpName(opcode),
382-
oparg);
381+
#ifdef Py_DEBUG
382+
if (get_lltrace() >= 3) {
383+
printf("%4d abs: ", (int)(this_instr - trace));
384+
_PyUOpPrint(this_instr);
385+
printf(" ");
386+
}
387+
#endif
388+
383389
switch (opcode) {
390+
384391
#include "optimizer_cases.c.h"
385392

386393
default:
387-
DPRINTF(1, "Unknown opcode in abstract interpreter\n");
394+
DPRINTF(1, "\nUnknown opcode in abstract interpreter\n");
388395
Py_UNREACHABLE();
389396
}
390397
assert(ctx->frame != NULL);
@@ -397,11 +404,13 @@ optimize_uops(
397404
return 1;
398405

399406
out_of_space:
407+
DPRINTF(3, "\n");
400408
DPRINTF(1, "Out of space in abstract interpreter\n");
401409
_Py_uop_abstractcontext_fini(ctx);
402410
return 0;
403411

404412
error:
413+
DPRINTF(3, "\n");
405414
DPRINTF(1, "Encountered error in abstract interpreter\n");
406415
_Py_uop_abstractcontext_fini(ctx);
407416
return 0;
@@ -411,6 +420,7 @@ optimize_uops(
411420
// This means that the abstract interpreter has hit unreachable code.
412421
// We *could* generate an _EXIT_TRACE or _FATAL_ERROR here, but it's
413422
// simpler to just admit failure and not create the executor.
423+
DPRINTF(3, "\n");
414424
DPRINTF(1, "Hit bottom in abstract interpreter\n");
415425
_Py_uop_abstractcontext_fini(ctx);
416426
return 0;

Python/optimizer_bytecodes.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ dummy_func(void) {
544544
(void)callable;
545545

546546
PyFunctionObject *func = (PyFunctionObject *)(this_instr + 2)->operand;
547+
DPRINTF(3, "func: %p ", func);
547548
if (func == NULL) {
548549
goto error;
549550
}

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)