Skip to content

Commit a35904d

Browse files
committed
COMPARE_OP_FLOAT_JUMP
1 parent d59fb14 commit a35904d

File tree

2 files changed

+62
-53
lines changed

2 files changed

+62
-53
lines changed

Python/bytecodes.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,14 @@ static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub
8383
static PyObject *container, *start, *stop, *v, *lhs, *rhs;
8484
static PyObject *list, *tuple, *dict;
8585
static PyObject *exit_func, *lasti, *val;
86+
static PyObject *jump;
87+
// Dummy variables for stack effects
88+
static int when_to_jump_mask;
89+
// Dummy opcode names for 'op' opcodes
8690
#define _BINARY_OP_INPLACE_ADD_UNICODE_PART_1 1
8791
#define _BINARY_OP_INPLACE_ADD_UNICODE_PART_2 2
92+
#define _COMPARE_OP_FLOAT 3
93+
#define _JUMP_ON_SIGN 4
8894

8995
static PyObject *
9096
dummy_func(
@@ -2054,12 +2060,12 @@ dummy_func(
20542060
JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR);
20552061
}
20562062

2057-
// family(compare_op) = {
2058-
// COMPARE_OP,
2059-
// COMPARE_OP_FLOAT_JUMP,
2060-
// COMPARE_OP_INT_JUMP,
2061-
// COMPARE_OP_STR_JUMP,
2062-
// };
2063+
family(compare_op) = {
2064+
COMPARE_OP,
2065+
_COMPARE_OP_FLOAT,
2066+
// COMPARE_OP_INT_JUMP,
2067+
// COMPARE_OP_STR_JUMP,
2068+
};
20632069

20642070
inst(COMPARE_OP, (unused/1, left, right, unused/1 -- res)) {
20652071
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
@@ -2078,36 +2084,32 @@ dummy_func(
20782084
ERROR_IF(res == NULL, error);
20792085
}
20802086

2081-
// stack effect: (__0 -- )
2082-
inst(COMPARE_OP_FLOAT_JUMP) {
2087+
// The result is an int disguised as an object pointer.
2088+
op(_COMPARE_OP_FLOAT, (unused/1, left, right, when_to_jump_mask/1 -- jump)) {
20832089
assert(cframe.use_tracing == 0);
20842090
// Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false)
2085-
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
2086-
int when_to_jump_mask = cache->mask;
2087-
PyObject *right = TOP();
2088-
PyObject *left = SECOND();
20892091
DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP);
20902092
DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP);
20912093
double dleft = PyFloat_AS_DOUBLE(left);
20922094
double dright = PyFloat_AS_DOUBLE(right);
2093-
int sign = (dleft > dright) - (dleft < dright);
2095+
// 1 if <, 2 if ==, 4 if >; this matches when _to_jump_mask
2096+
int sign_ish = 2*(dleft > dright) + 2 - (dleft < dright);
20942097
DEOPT_IF(isnan(dleft), COMPARE_OP);
20952098
DEOPT_IF(isnan(dright), COMPARE_OP);
20962099
STAT_INC(COMPARE_OP, hit);
2097-
JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP);
2098-
NEXTOPARG();
2099-
STACK_SHRINK(2);
21002100
_Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
21012101
_Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
2102+
jump = (PyObject *)(size_t)(sign_ish & when_to_jump_mask);
2103+
}
2104+
// The input is an int disguised as an object pointer!
2105+
op(_JUMP_ON_SIGN, (jump --)) {
21022106
assert(opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_TRUE);
2103-
int jump = (1 << (sign + 1)) & when_to_jump_mask;
2104-
if (!jump) {
2105-
next_instr++;
2106-
}
2107-
else {
2108-
JUMPBY(1 + oparg);
2107+
if (jump) {
2108+
JUMPBY(oparg);
21092109
}
21102110
}
2111+
// We're praying that the compiler optimizes the flags manipuations.
2112+
super(COMPARE_OP_FLOAT_JUMP) = _COMPARE_OP_FLOAT + _JUMP_ON_SIGN;
21112113

21122114
// stack effect: (__0 -- )
21132115
inst(COMPARE_OP_INT_JUMP) {

Python/generated_cases.c.h

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

0 commit comments

Comments
 (0)