PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
}
case _COMPARE_OP_FLOAT: {
+ JitOptRef right;
+ JitOptRef left;
JitOptRef res;
+ right = stack_pointer[-1];
+ left = stack_pointer[-2];
+ if (
+ sym_is_safe_const(ctx, left) &&
+ sym_is_safe_const(ctx, right)
+ ) {
+ JitOptRef left_sym = left;
+ JitOptRef right_sym = right;
+ _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
+ _PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
+ _PyStackRef res_stackref;
+ /* Start of uop copied from bytecodes for constant evaluation */
+ PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
+ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
+ STAT_INC(COMPARE_OP, hit);
+ double dleft = PyFloat_AS_DOUBLE(left_o);
+ double dright = PyFloat_AS_DOUBLE(right_o);
+ int sign_ish = COMPARISON_BIT(dleft, dright);
+ PyStackRef_CLOSE_SPECIALIZED(left, _PyFloat_ExactDealloc);
+ PyStackRef_CLOSE_SPECIALIZED(right, _PyFloat_ExactDealloc);
+ res_stackref = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
+ /* End of uop copied from bytecodes for constant evaluation */
+ res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
+ stack_pointer[-2] = res;
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
res = sym_new_type(ctx, &PyBool_Type);
stack_pointer[-2] = res;
stack_pointer += -1;
JitOptRef res;
right = stack_pointer[-1];
left = stack_pointer[-2];
- if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
- assert(PyLong_CheckExact(sym_get_const(ctx, left)));
- assert(PyLong_CheckExact(sym_get_const(ctx, right)));
- PyObject *tmp = PyObject_RichCompare(sym_get_const(ctx, left),
- sym_get_const(ctx, right),
- oparg >> 5);
- if (tmp == NULL) {
- goto error;
+ if (
+ sym_is_safe_const(ctx, left) &&
+ sym_is_safe_const(ctx, right)
+ ) {
+ JitOptRef left_sym = left;
+ JitOptRef right_sym = right;
+ _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
+ _PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
+ _PyStackRef res_stackref;
+ /* Start of uop copied from bytecodes for constant evaluation */
+ PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
+ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
+ assert(_PyLong_IsCompact((PyLongObject *)left_o));
+ assert(_PyLong_IsCompact((PyLongObject *)right_o));
+ STAT_INC(COMPARE_OP, hit);
+ assert(_PyLong_DigitCount((PyLongObject *)left_o) <= 1 &&
+ _PyLong_DigitCount((PyLongObject *)right_o) <= 1);
+ Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left_o);
+ Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o);
+ int sign_ish = COMPARISON_BIT(ileft, iright);
+ PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
+ PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
+ res_stackref = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
+ /* End of uop copied from bytecodes for constant evaluation */
+ res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
}
- assert(PyBool_Check(tmp));
- assert(_Py_IsImmortal(tmp));
- REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp);
- res = sym_new_const(ctx, tmp);
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
- Py_DECREF(tmp);
- }
- else {
- res = sym_new_type(ctx, &PyBool_Type);
- stack_pointer += -1;
+ break;
}
- stack_pointer[-1] = res;
+ res = sym_new_type(ctx, &PyBool_Type);
+ stack_pointer[-2] = res;
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
break;
}
case _COMPARE_OP_STR: {
+ JitOptRef right;
+ JitOptRef left;
JitOptRef res;
+ right = stack_pointer[-1];
+ left = stack_pointer[-2];
+ if (
+ sym_is_safe_const(ctx, left) &&
+ sym_is_safe_const(ctx, right)
+ ) {
+ JitOptRef left_sym = left;
+ JitOptRef right_sym = right;
+ _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
+ _PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
+ _PyStackRef res_stackref;
+ /* Start of uop copied from bytecodes for constant evaluation */
+ PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
+ PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
+ STAT_INC(COMPARE_OP, hit);
+ int eq = _PyUnicode_Equal(left_o, right_o);
+ assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE);
+ PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
+ PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
+ assert(eq == 0 || eq == 1);
+ assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS);
+ assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS);
+ res_stackref = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? PyStackRef_True : PyStackRef_False;
+ /* End of uop copied from bytecodes for constant evaluation */
+ res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
+ stack_pointer[-2] = res;
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
res = sym_new_type(ctx, &PyBool_Type);
stack_pointer[-2] = res;
stack_pointer += -1;
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
+
+ if (sym_is_const(ctx, res)) {
+ PyObject *result = sym_get_const(ctx, res);
+ if (_Py_IsImmortal(result)) {
+ // Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
+ REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
+ }
+ }
stack_pointer[-2] = res;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());