mirror of
https://github.com/python/cpython.git
synced 2026-04-20 02:40:59 +00:00
gh-146393: Optimize float division operations by mutating uniquely-referenced operands in place (JIT only) (GH-146397)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bdb0b36192
commit
95cbd4a232
13 changed files with 1940 additions and 1263 deletions
|
|
@ -289,7 +289,56 @@ dummy_func(void) {
|
|||
bool rhs_int = sym_matches_type(rhs, &PyLong_Type);
|
||||
bool lhs_float = sym_matches_type(lhs, &PyFloat_Type);
|
||||
bool rhs_float = sym_matches_type(rhs, &PyFloat_Type);
|
||||
if (!((lhs_int || lhs_float) && (rhs_int || rhs_float))) {
|
||||
bool is_truediv = (oparg == NB_TRUE_DIVIDE
|
||||
|| oparg == NB_INPLACE_TRUE_DIVIDE);
|
||||
bool is_remainder = (oparg == NB_REMAINDER
|
||||
|| oparg == NB_INPLACE_REMAINDER);
|
||||
// Promote probable-float operands to known floats via speculative
|
||||
// guards. _RECORD_TOS / _RECORD_NOS in the BINARY_OP macro record
|
||||
// the observed operand during tracing, which sym_get_probable_type
|
||||
// reads here. Applied only to ops where narrowing unlocks a
|
||||
// meaningful downstream win:
|
||||
// - NB_TRUE_DIVIDE: enables the specialized float path below.
|
||||
// - NB_REMAINDER: lets the float result type propagate.
|
||||
// NB_POWER is excluded — speculative guards there regressed
|
||||
// test_power_type_depends_on_input_values (GH-127844).
|
||||
if (is_truediv || is_remainder) {
|
||||
if (!sym_has_type(rhs)
|
||||
&& sym_get_probable_type(rhs) == &PyFloat_Type) {
|
||||
ADD_OP(_GUARD_TOS_FLOAT, 0, 0);
|
||||
sym_set_type(rhs, &PyFloat_Type);
|
||||
rhs_float = true;
|
||||
}
|
||||
if (!sym_has_type(lhs)
|
||||
&& sym_get_probable_type(lhs) == &PyFloat_Type) {
|
||||
ADD_OP(_GUARD_NOS_FLOAT, 0, 0);
|
||||
sym_set_type(lhs, &PyFloat_Type);
|
||||
lhs_float = true;
|
||||
}
|
||||
}
|
||||
if (is_truediv && lhs_float && rhs_float) {
|
||||
if (PyJitRef_IsUnique(lhs)) {
|
||||
ADD_OP(_BINARY_OP_TRUEDIV_FLOAT_INPLACE, 0, 0);
|
||||
l = sym_new_null(ctx);
|
||||
r = rhs;
|
||||
}
|
||||
else if (PyJitRef_IsUnique(rhs)) {
|
||||
ADD_OP(_BINARY_OP_TRUEDIV_FLOAT_INPLACE_RIGHT, 0, 0);
|
||||
l = lhs;
|
||||
r = sym_new_null(ctx);
|
||||
}
|
||||
else {
|
||||
ADD_OP(_BINARY_OP_TRUEDIV_FLOAT, 0, 0);
|
||||
l = lhs;
|
||||
r = rhs;
|
||||
}
|
||||
res = PyJitRef_MakeUnique(sym_new_type(ctx, &PyFloat_Type));
|
||||
}
|
||||
else if (is_truediv
|
||||
&& (lhs_int || lhs_float) && (rhs_int || rhs_float)) {
|
||||
res = PyJitRef_MakeUnique(sym_new_type(ctx, &PyFloat_Type));
|
||||
}
|
||||
else if (!((lhs_int || lhs_float) && (rhs_int || rhs_float))) {
|
||||
// There's something other than an int or float involved:
|
||||
res = sym_new_unknown(ctx);
|
||||
}
|
||||
|
|
@ -312,7 +361,7 @@ dummy_func(void) {
|
|||
}
|
||||
else if (lhs_float) {
|
||||
// Case C:
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
res = PyJitRef_MakeUnique(sym_new_type(ctx, &PyFloat_Type));
|
||||
}
|
||||
else if (!sym_is_const(ctx, rhs)) {
|
||||
// Case A or B... can't know without the sign of the RHS:
|
||||
|
|
@ -320,21 +369,18 @@ dummy_func(void) {
|
|||
}
|
||||
else if (_PyLong_IsNegative((PyLongObject *)sym_get_const(ctx, rhs))) {
|
||||
// Case B:
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
res = PyJitRef_MakeUnique(sym_new_type(ctx, &PyFloat_Type));
|
||||
}
|
||||
else {
|
||||
// Case A:
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
}
|
||||
}
|
||||
else if (oparg == NB_TRUE_DIVIDE || oparg == NB_INPLACE_TRUE_DIVIDE) {
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
}
|
||||
else if (lhs_int && rhs_int) {
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
}
|
||||
else {
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
res = PyJitRef_MakeUnique(sym_new_type(ctx, &PyFloat_Type));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue