Skip to content

Commit cf18981

Browse files
Remove opcode
1 parent 85d5fc3 commit cf18981

7 files changed

+699
-254
lines changed

Lib/test/test_generated_cases.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,8 @@ def test_basic(self):
18861886
output = """
18871887
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_OP(TAIL_CALL_PARAMS) {
18881888
{
1889+
int opcode = next_instr->op.code;
1890+
(void)(opcode);
18891891
frame->instr_ptr = next_instr;
18901892
next_instr += 1;
18911893
INSTRUCTION_STATS(OP);
@@ -1927,6 +1929,8 @@ def test_label_transformed(self):
19271929
19281930
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_OP(TAIL_CALL_PARAMS) {
19291931
{
1932+
int opcode = next_instr->op.code;
1933+
(void)(opcode);
19301934
frame->instr_ptr = next_instr;
19311935
next_instr += 1;
19321936
INSTRUCTION_STATS(OP);
@@ -1944,7 +1948,7 @@ def test_label_transformed(self):
19441948
if (x) {
19451949
goto baz;
19461950
}
1947-
return _TAIL_CALL_entry(frame, stack_pointer, tstate, next_instr, 0, 0);
1951+
return _TAIL_CALL_entry(frame, stack_pointer, tstate, next_instr, 0);
19481952
}
19491953
"""
19501954
self.run_cases_test(input, output, output_labels)

Python/ceval.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch)
772772
static inline PyObject *
773773
_TAIL_CALL_entry(TAIL_CALL_PARAMS)
774774
{
775-
opcode = next_instr->op.code;
775+
int opcode = next_instr->op.code;
776776
oparg = next_instr->op.arg;
777777
return (INSTRUCTION_TABLE[opcode])(TAIL_CALL_ARGS);
778778
}

Python/ceval_macros.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@
7070
#define INSTRUCTION_STATS(op) ((void)0)
7171
#endif
7272

73-
#define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int opcode, int oparg
74-
#define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, opcode, oparg
73+
#define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg
74+
#define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg
7575

7676
#ifdef Py_TAIL_CALL_INTERP
7777
// Note: [[clang::musttail]] works for GCC 15, but not __attribute__((musttail)) at the moment.
@@ -125,8 +125,15 @@ do { \
125125

126126

127127
/* Do interpreter dispatch accounting for tracing and instrumentation */
128+
#ifdef Py_TAIL_CALL_INTERP
129+
# define DEFINE_OPCODE_IF_NEEDED() int opcode;
130+
#else
131+
# define DEFINE_OPCODE_IF_NEEDED()
132+
#endif
133+
128134
#define DISPATCH() \
129135
{ \
136+
DEFINE_OPCODE_IF_NEEDED(); \
130137
assert(frame->stackpointer == NULL); \
131138
NEXTOPARG(); \
132139
PRE_DISPATCH_GOTO(); \

Python/generated_tail_call_handlers.c.h

+671-226
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_tail_call_labels.c.h

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/tier1_generator.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,12 @@ def write_single_inst(
137137
emitter: Emitter,
138138
name: str,
139139
inst: Instruction,
140-
uses_this: Callable[[Instruction], bool]
140+
uses_this: Callable[[Instruction], bool],
141+
is_in_tail_call: bool = False
141142
) -> None:
143+
if is_in_tail_call:
144+
out.emit("int opcode = next_instr->op.code;\n")
145+
out.emit("(void)(opcode);\n")
142146
needs_this = uses_this(inst)
143147
unused_guard = "(void)this_instr;\n"
144148
if inst.properties.needs_prev:

Tools/cases_generator/tier1_tail_call_generator.py

+6-21
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,6 @@ def __init__(self, out: CWriter, analysis: Analysis):
5454
super().__init__(out)
5555
self.analysis = analysis
5656

57-
def go_to_instruction(
58-
self,
59-
tkn: Token,
60-
tkn_iter: TokenIterator,
61-
uop: Uop | Label,
62-
storage: Storage,
63-
inst: Instruction | None,
64-
) -> bool:
65-
next(tkn_iter)
66-
name = next(tkn_iter)
67-
next(tkn_iter)
68-
next(tkn_iter)
69-
assert name.kind == "IDENTIFIER"
70-
self.out.start_line()
71-
self.emit(f"Py_MUSTTAIL return (INSTRUCTION_TABLE[{name.text}])(frame, stack_pointer, tstate, this_instr, opcode, oparg);\n")
72-
return True
73-
7457
def deopt_if(
7558
self,
7659
tkn: Token,
@@ -92,7 +75,8 @@ def deopt_if(
9275
family_name = inst.family.name
9376
self.emit(f"UPDATE_MISS_STATS({family_name});\n")
9477
self.emit(f"assert(_PyOpcode_Deopt[opcode] == ({family_name}));\n")
95-
self.emit(f"Py_MUSTTAIL return _TAIL_CALL_{family_name}(frame, stack_pointer, tstate, this_instr, opcode, oparg);\n")
78+
# Note it's not TAIL_CALL_ARGS, it passes this_instr instead of next_instr.
79+
self.emit(f"Py_MUSTTAIL return _TAIL_CALL_{family_name}(frame, stack_pointer, tstate, this_instr, oparg);\n")
9680
self.emit("}\n")
9781
return not always_true(first_tkn)
9882

@@ -145,7 +129,7 @@ def dispatch(
145129
next(tkn_iter)
146130
next(tkn_iter)
147131
self.out.start_line()
148-
self.emit("return _TAIL_CALL_entry(frame, stack_pointer, tstate, next_instr, 0, 0);\n")
132+
self.emit("return _TAIL_CALL_entry(frame, stack_pointer, tstate, next_instr, 0);\n")
149133
return True
150134

151135

@@ -165,7 +149,6 @@ def generate_label_handlers(
165149
for name, label in analysis.labels.items():
166150
emitter.emit(f"{function_proto(name)}\n")
167151
emitter.emit_label(label)
168-
169152
emitter.emit("\n")
170153
emitter.emit("\n")
171154

@@ -195,6 +178,7 @@ def generate_tier1(
195178
emitter = TailCallCevalLabelsEmitter(out)
196179
generate_tier1_labels(analysis, emitter)
197180
labels_outfile.write(FOOTER)
181+
198182
write_header(__file__, filenames, outfile)
199183
outfile.write(PRELUDE)
200184
out = CWriter(outfile, 0, lines)
@@ -214,7 +198,7 @@ def generate_tier1(
214198
# escaping locals.
215199
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118430#c1
216200
out.emit("{\n")
217-
write_single_inst(out, emitter, name, inst, uses_this)
201+
write_single_inst(out, emitter, name, inst, uses_this, is_in_tail_call=True)
218202
out.emit("}\n")
219203
if not inst.parts[-1].properties.always_exits:
220204
out.emit("DISPATCH();\n")
@@ -234,6 +218,7 @@ def generate_tier1(
234218
out.emit(function_proto("UNKNOWN_OPCODE"))
235219
out.emit(" {\n")
236220
out.emit("{\n")
221+
out.emit("int opcode = next_instr->op.code;\n")
237222
out.emit("""
238223
_PyErr_Format(tstate, PyExc_SystemError,
239224
"%U:%d: unknown opcode %d",

0 commit comments

Comments
 (0)