gh-146306: JIT: Optimize float operations by mutating uniquely-referenced operands in place (GH-146307)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pieter Eendebak 2026-03-24 14:16:02 +01:00 committed by GitHub
parent 68c7fad757
commit 951675c18a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 2349 additions and 1231 deletions

View file

@ -460,6 +460,20 @@ dummy_func(
DEAD(value);
}
// Inplace negation: negate a uniquely-referenced float in place.
// Tier 2 only.
tier2 op(_UNARY_NEGATIVE_FLOAT_INPLACE, (value -- res, v)) {
PyObject *val_o = PyStackRef_AsPyObjectBorrow(value);
assert(PyFloat_CheckExact(val_o));
assert(_PyObject_IsUniquelyReferenced(val_o));
STAT_INC(UNARY_NEGATIVE, hit);
double dres = -((PyFloatObject *)val_o)->ob_fval;
((PyFloatObject *)val_o)->ob_fval = dres;
res = value;
v = PyStackRef_NULL;
INPUTS_DEAD();
}
inst(UNARY_NOT, (value -- res)) {
assert(PyStackRef_BoolCheck(value));
res = PyStackRef_IsFalse(value)
@ -771,6 +785,59 @@ dummy_func(
macro(BINARY_OP_SUBTRACT_FLOAT) =
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_SUBTRACT_FLOAT + _POP_TOP_FLOAT + _POP_TOP_FLOAT;
// Inplace float ops: mutate the uniquely-referenced left operand
// instead of allocating a new float. Tier 2 only.
// The optimizer sets l to a borrowed value so the following _POP_TOP_FLOAT
// becomes _POP_TOP_NOP.
tier2 op(_BINARY_OP_ADD_FLOAT_INPLACE, (left, right -- res, l, r)) {
FLOAT_INPLACE_OP(left, right, left, +);
res = left;
l = PyStackRef_NULL;
r = right;
INPUTS_DEAD();
}
tier2 op(_BINARY_OP_SUBTRACT_FLOAT_INPLACE, (left, right -- res, l, r)) {
FLOAT_INPLACE_OP(left, right, left, -);
res = left;
l = PyStackRef_NULL;
r = right;
INPUTS_DEAD();
}
tier2 op(_BINARY_OP_MULTIPLY_FLOAT_INPLACE, (left, right -- res, l, r)) {
FLOAT_INPLACE_OP(left, right, left, *);
res = left;
l = PyStackRef_NULL;
r = right;
INPUTS_DEAD();
}
// Inplace RIGHT variants: mutate the uniquely-referenced right operand.
tier2 op(_BINARY_OP_ADD_FLOAT_INPLACE_RIGHT, (left, right -- res, l, r)) {
FLOAT_INPLACE_OP(left, right, right, +);
res = right;
l = left;
r = PyStackRef_NULL;
INPUTS_DEAD();
}
tier2 op(_BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT, (left, right -- res, l, r)) {
FLOAT_INPLACE_OP(left, right, right, *);
res = right;
l = left;
r = PyStackRef_NULL;
INPUTS_DEAD();
}
tier2 op(_BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT, (left, right -- res, l, r)) {
FLOAT_INPLACE_OP(left, right, right, -);
res = right;
l = left;
r = PyStackRef_NULL;
INPUTS_DEAD();
}
pure op(_BINARY_OP_ADD_UNICODE, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);