Skip to content

Commit 6d6263c

Browse files
Add 2-operand support
1 parent 6ac0cdf commit 6d6263c

File tree

11 files changed

+35
-15
lines changed

11 files changed

+35
-15
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ typedef struct {
5959
};
6060
};
6161
uint64_t operand; // A cache entry
62+
uint64_t operand1;
6263
} _PyUOpInstruction;
6364

6465
typedef struct {

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: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3442,8 +3442,7 @@ dummy_func(
34423442
EXIT_IF(func->func_version != func_version);
34433443
}
34443444

3445-
tier2 op(_CHECK_FUNCTION_VERSION_INLINE, (callable_o/4 --)) {
3446-
uint16_t func_version = oparg;
3445+
tier2 op(_CHECK_FUNCTION_VERSION_INLINE, (func_version/2, callable_o/4 --)) {
34473446
assert(PyFunction_Check(callable_o));
34483447
PyFunctionObject *func = (PyFunctionObject *)callable_o;
34493448
EXIT_IF(func->func_version != func_version);

Python/ceval_macros.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ do { \
410410
#define CURRENT_OPARG() (next_uop[-1].oparg)
411411

412412
#define CURRENT_OPERAND() (next_uop[-1].operand)
413+
#define CURRENT_OPERAND1() (next_uop[-1].operand1)
413414

414415
#define JUMP_TO_JUMP_TARGET() goto jump_to_jump_target
415416
#define JUMP_TO_ERROR() goto jump_to_error_target

Python/executor_cases.c.h

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

Python/optimizer_bytecodes.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -593,9 +593,8 @@ dummy_func(void) {
593593
(void)self_or_null;
594594
if (sym_is_const(callable) && sym_matches_type(callable, &PyFunction_Type)) {
595595
assert(PyFunction_Check(sym_get_const(callable)));
596-
if (func_version == (uint16_t)func_version) {
597-
REPLACE_OP(this_instr, _CHECK_FUNCTION_VERSION_INLINE, func_version, (uintptr_t)sym_get_const(callable));
598-
}
596+
REPLACE_OP(this_instr, _CHECK_FUNCTION_VERSION_INLINE, 0, func_version);
597+
this_instr->operand1 = (uintptr_t)sym_get_const(callable);
599598
}
600599
sym_set_type(callable, &PyFunction_Type);
601600
}

Python/optimizer_cases.c.h

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

Tools/cases_generator/analyzer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ def why_not_viable(self) -> str | None:
200200
return "has tier 1 control flow"
201201
if self.properties.needs_this:
202202
return "uses the 'this_instr' variable"
203-
if len([c for c in self.caches if c.name != "unused"]) > 1:
203+
if len([c for c in self.caches if c.name != "unused"]) > 2:
204204
return "has unused cache entries"
205205
if self.properties.error_with_pop and self.properties.error_without_pop:
206206
return "has both popping and not-popping errors"

Tools/cases_generator/tier2_generator.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,17 @@ def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> Stack:
181181
code_list, storage = Storage.for_uop(stack, uop)
182182
for code in code_list:
183183
emitter.emit(code)
184-
for cache in uop.caches:
184+
for idx, cache in enumerate(uop.caches):
185185
if cache.name != "unused":
186186
if cache.size == 4:
187187
type = cast = "PyObject *"
188188
else:
189189
type = f"uint{cache.size*16}_t "
190190
cast = f"uint{cache.size*16}_t"
191-
emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n")
191+
if idx == 0:
192+
emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n")
193+
else:
194+
emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND{idx}();\n")
192195
storage = emitter.emit_tokens(uop, storage, None)
193196
except StackError as ex:
194197
raise analysis_error(ex.args[0], uop.body[0]) from None

Tools/jit/_stencils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ class HoleValue(enum.Enum):
3434
# The current uop's operand on 32-bit platforms (exposed as _JIT_OPERAND_HI/LO):
3535
OPERAND_HI = enum.auto()
3636
OPERAND_LO = enum.auto()
37+
# The current uop's operand1 on 64-bit platforms (exposed as _JIT_OPERAND):
38+
OPERAND1 = enum.auto()
39+
# The current uop's operand1 on 32-bit platforms (exposed as _JIT_OPERAND_HI/LO):
40+
OPERAND1_HI = enum.auto()
41+
OPERAND1_LO = enum.auto()
3742
# The current uop's target (exposed as _JIT_TARGET):
3843
TARGET = enum.auto()
3944
# The base address of the machine code for the jump target (exposed as _JIT_JUMP_TARGET):
@@ -102,6 +107,9 @@ class HoleValue(enum.Enum):
102107
HoleValue.OPERAND: "instruction->operand",
103108
HoleValue.OPERAND_HI: "(instruction->operand >> 32)",
104109
HoleValue.OPERAND_LO: "(instruction->operand & UINT32_MAX)",
110+
HoleValue.OPERAND1: "instruction->operand1",
111+
HoleValue.OPERAND1_HI: "(instruction->operand1 >> 32)",
112+
HoleValue.OPERAND1_LO: "(instruction->operand1 & UINT32_MAX)",
105113
HoleValue.TARGET: "instruction->target",
106114
HoleValue.JUMP_TARGET: "state->instruction_starts[instruction->jump_target]",
107115
HoleValue.ERROR_TARGET: "state->instruction_starts[instruction->error_target]",

0 commit comments

Comments
 (0)