8000 Be smarter about opargs and operands · python/cpython@07fb485 · GitHub
[go: up one dir, main page]

Skip to content

Commit 07fb485

Browse files
committed
Be smarter about opargs and operands
1 parent 720878f commit 07fb485

File tree

6 files changed

+66
-49
lines changed

6 files changed

+66
-49
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 44 additions & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/jit.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,10 @@ _PyJIT_CompileTrace(_PyUOpInstruction *trace, int size)
200200
_PyUOpInstruction *instruction = &trace[i];
201201
const Stencil *stencil = &stencils[instruction->opcode];
202202
nbytes += stencil->nbytes;
203-
if (instruction->oparg) {
203+
if (OPCODE_HAS_ARG(instruction->opcode)) {
204204
nbytes += oparg_stencil.nbytes;
205205
}
206-
if (instruction->operand) {
206+
if (OPCODE_HAS_OPERAND(instruction->opcode)) {
207207
nbytes += operand_stencil.nbytes;
208208
}
209209
assert(stencil->nbytes);
@@ -251,7 +251,7 @@ _PyJIT_CompileTrace(_PyUOpInstruction *trace, int size)
251251
// as they are being used, clang *will* optimize the function as if the oparg
252252
// can never be zero and the operand always fits in 32 bits, for example. That's
253253
// bad, for obvious reasons:
254-
if (instruction->oparg) {
254+
if (OPCODE_HAS_ARG(instruction->opcode)) {
255255
const Stencil *stencil = &oparg_stencil;
256256
uint64_t patches[] = GET_PATCHES();
257257
patches[_JIT_BASE] = (uintptr_t)head;
@@ -261,7 +261,7 @@ _PyJIT_CompileTrace(_PyUOpInstruction *trace, int size)
261261
copy_and_patch(head, stencil, patches);
262262
head += stencil->nbytes;
263263
}
264-
if (instruction->operand) {
264+
if (OPCODE_HAS_OPERAND(instruction->opcode)) {
265265
const Stencil *stencil = &operand_stencil;
266266
uint64_t patches[] = GET_PATCHES();
267267
patches[_JIT_BASE] = (uintptr_t)head;

Tools/cases_generator/flags.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class InstructionFlags:
1919
HAS_EVAL_BREAK_FLAG: bool = False
2020
HAS_DEOPT_FLAG: bool = False
2121
HAS_ERROR_FLAG: bool = False
22+
HAS_OPERAND_FLAG: bool = False
2223

2324
def __post_init__(self) -> None:
2425
self.bitmask = {name: (1 << i) for i, name in enumerate(self.names())}

Tools/cases_generator/instructions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ def __init__(self, inst: parsing.InstDef):
107107
if effect.name != UNUSED:
108108
self.active_caches.append(ActiveCacheEffect(effect, offset))
109109
offset += effect.size
110-
110+
if self.active_caches:
111+
self.instr_flags.HAS_OPERAND_FLAG = True
111112
if self.instr_flags.HAS_ARG_FLAG:
112113
fmt = "IB"
113114
else:

Tools/jit/deoptimize.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "Python.h"
2+
3+
#include "pycore_frame.h"
4+
5+
_PyInterpreterFrame *
6+
_JIT_ENTRY(_PyInterpreterFrame *frame, PyObject **stack_pointer, PyThreadState *tstate, int32_t oparg, uint64_t operand)
7+
{
8+
frame->prev_instr--;
9+
_PyFrame_SetStackPointer(frame, stack_pointer);
10+
return frame;
11+
}

Tools/jit/template.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@ _JIT_ENTRY(_PyInterpreterFrame *frame, PyObject **stack_pointer,
4545
default:
4646
Py_UNREACHABLE();
4747
}
48+
// Trick clang into not caring what's passed to the continuation:
49+
asm inline ("" : "=r"(oparg), "=r"(operand));
4850
if (pc != -1) {
4951
assert(pc == oparg);
5052
assert(opcode == _JUMP_TO_TOP || opcode == _POP_JUMP_IF_FALSE || opcode == _POP_JUMP_IF_TRUE);
5153
__attribute__((musttail))
52-
return _JIT_JUMP(frame, stack_pointer, tstate, 0, 0);
54+
return _JIT_JUMP(frame, stack_pointer, tstate, oparg, operand);
5355
}
5456
__attribute__((musttail))
55-
return _JIT_CONTINUE(frame, stack_pointer, tstate, 0, 0);
57+
return _JIT_CONTINUE(frame, stack_pointer, tstate, oparg, operand);
5658
// Labels that the instruction implementations expect to exist:
5759
unbound_local_error:
5860
_PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg));

0 commit comments

Comments
 (0)
0