mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
GH-135379: Specialize int operations for compact ints only (GH-135668)
Some checks are pending
JIT / Interpreter (Debug) (push) Waiting to run
Lint / lint (push) Waiting to run
Tail calling interpreter / x86_64-pc-windows-msvc/msvc (push) Waiting to run
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
JIT / aarch64-pc-windows-msvc/msvc (Release) (push) Blocked by required conditions
JIT / aarch64-pc-windows-msvc/msvc (Debug) (push) Blocked by required conditions
JIT / i686-pc-windows-msvc/msvc (Release) (push) Blocked by required conditions
JIT / i686-pc-windows-msvc/msvc (Debug) (push) Blocked by required conditions
JIT / aarch64-apple-darwin/clang (Release) (push) Blocked by required conditions
JIT / aarch64-unknown-linux-gnu/gcc (Release) (push) Blocked by required conditions
JIT / aarch64-apple-darwin/clang (Debug) (push) Blocked by required conditions
JIT / aarch64-unknown-linux-gnu/gcc (Debug) (push) Blocked by required conditions
JIT / x86_64-pc-windows-msvc/msvc (Release) (push) Blocked by required conditions
JIT / x86_64-pc-windows-msvc/msvc (Debug) (push) Blocked by required conditions
JIT / x86_64-apple-darwin/clang (Release) (push) Blocked by required conditions
JIT / x86_64-unknown-linux-gnu/gcc (Release) (push) Blocked by required conditions
JIT / x86_64-apple-darwin/clang (Debug) (push) Blocked by required conditions
JIT / x86_64-unknown-linux-gnu/gcc (Debug) (push) Blocked by required conditions
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
Tail calling interpreter / aarch64-unknown-linux-gnu/gcc (push) Waiting to run
Tail calling interpreter / x86_64-apple-darwin/clang (push) Waiting to run
Tail calling interpreter / free-threading (push) Waiting to run
Tail calling interpreter / x86_64-unknown-linux-gnu/gcc (push) Waiting to run
Tail calling interpreter / aarch64-apple-darwin/clang (push) Waiting to run
Some checks are pending
JIT / Interpreter (Debug) (push) Waiting to run
Lint / lint (push) Waiting to run
Tail calling interpreter / x86_64-pc-windows-msvc/msvc (push) Waiting to run
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
JIT / aarch64-pc-windows-msvc/msvc (Release) (push) Blocked by required conditions
JIT / aarch64-pc-windows-msvc/msvc (Debug) (push) Blocked by required conditions
JIT / i686-pc-windows-msvc/msvc (Release) (push) Blocked by required conditions
JIT / i686-pc-windows-msvc/msvc (Debug) (push) Blocked by required conditions
JIT / aarch64-apple-darwin/clang (Release) (push) Blocked by required conditions
JIT / aarch64-unknown-linux-gnu/gcc (Release) (push) Blocked by required conditions
JIT / aarch64-apple-darwin/clang (Debug) (push) Blocked by required conditions
JIT / aarch64-unknown-linux-gnu/gcc (Debug) (push) Blocked by required conditions
JIT / x86_64-pc-windows-msvc/msvc (Release) (push) Blocked by required conditions
JIT / x86_64-pc-windows-msvc/msvc (Debug) (push) Blocked by required conditions
JIT / x86_64-apple-darwin/clang (Release) (push) Blocked by required conditions
JIT / x86_64-unknown-linux-gnu/gcc (Release) (push) Blocked by required conditions
JIT / x86_64-apple-darwin/clang (Debug) (push) Blocked by required conditions
JIT / x86_64-unknown-linux-gnu/gcc (Debug) (push) Blocked by required conditions
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
Tail calling interpreter / aarch64-unknown-linux-gnu/gcc (push) Waiting to run
Tail calling interpreter / x86_64-apple-darwin/clang (push) Waiting to run
Tail calling interpreter / free-threading (push) Waiting to run
Tail calling interpreter / x86_64-unknown-linux-gnu/gcc (push) Waiting to run
Tail calling interpreter / aarch64-apple-darwin/clang (push) Waiting to run
This commit is contained in:
parent
5c25c884b9
commit
9731dd2c8d
17 changed files with 515 additions and 283 deletions
|
@ -569,12 +569,24 @@ dummy_func(
|
|||
|
||||
op(_GUARD_NOS_INT, (left, unused -- left, unused)) {
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
EXIT_IF(!PyLong_CheckExact(left_o));
|
||||
EXIT_IF(!PyLong_CheckCompact(left_o));
|
||||
}
|
||||
|
||||
op(_GUARD_TOS_INT, (value -- value)) {
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
EXIT_IF(!PyLong_CheckExact(value_o));
|
||||
EXIT_IF(!PyLong_CheckCompact(value_o));
|
||||
}
|
||||
|
||||
op(_GUARD_NOS_OVERFLOWED, (left, unused -- left, unused)) {
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
assert(Py_TYPE(left_o) == &PyLong_Type);
|
||||
EXIT_IF(!_PyLong_IsCompact((PyLongObject *)left_o));
|
||||
}
|
||||
|
||||
op(_GUARD_TOS_OVERFLOWED, (value -- value)) {
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
assert(Py_TYPE(value_o) == &PyLong_Type);
|
||||
EXIT_IF(!_PyLong_IsCompact((PyLongObject *)value_o));
|
||||
}
|
||||
|
||||
pure op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
|
||||
|
@ -582,15 +594,14 @@ dummy_func(
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
DEOPT_IF(!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
res = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
EXIT_IF(PyStackRef_IsNull(res));
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
INPUTS_DEAD();
|
||||
ERROR_IF(res_o == NULL);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
|
||||
pure op(_BINARY_OP_ADD_INT, (left, right -- res)) {
|
||||
|
@ -598,15 +609,14 @@ dummy_func(
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
DEOPT_IF(!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
res = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
EXIT_IF(PyStackRef_IsNull(res));
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
INPUTS_DEAD();
|
||||
ERROR_IF(res_o == NULL);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
|
||||
pure op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
|
||||
|
@ -614,21 +624,22 @@ dummy_func(
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
DEOPT_IF(!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
res = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
EXIT_IF(PyStackRef_IsNull(res));
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
INPUTS_DEAD();
|
||||
ERROR_IF(res_o == NULL);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
|
||||
macro(BINARY_OP_MULTIPLY_INT) =
|
||||
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_MULTIPLY_INT;
|
||||
|
||||
macro(BINARY_OP_ADD_INT) =
|
||||
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_ADD_INT;
|
||||
|
||||
macro(BINARY_OP_SUBTRACT_INT) =
|
||||
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_SUBTRACT_INT;
|
||||
|
||||
|
@ -2737,8 +2748,8 @@ dummy_func(
|
|||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
|
||||
DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left_o));
|
||||
DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right_o));
|
||||
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);
|
||||
|
|
77
Python/executor_cases.c.h
generated
77
Python/executor_cases.c.h
generated
|
@ -852,7 +852,7 @@
|
|||
_PyStackRef left;
|
||||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
if (!PyLong_CheckExact(left_o)) {
|
||||
if (!PyLong_CheckCompact(left_o)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
|
@ -863,7 +863,31 @@
|
|||
_PyStackRef value;
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_OVERFLOWED: {
|
||||
_PyStackRef left;
|
||||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
assert(Py_TYPE(left_o) == &PyLong_Type);
|
||||
if (!_PyLong_IsCompact((PyLongObject *)left_o)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_TOS_OVERFLOWED: {
|
||||
_PyStackRef value;
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
assert(Py_TYPE(value_o) == &PyLong_Type);
|
||||
if (!_PyLong_IsCompact((PyLongObject *)value_o)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
|
@ -880,20 +904,15 @@
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
if (!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o)) {
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
res = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
if (PyStackRef_IsNull(res)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
if (res_o == NULL) {
|
||||
stack_pointer += -2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
JUMP_TO_ERROR();
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -910,20 +929,15 @@
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
if (!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o)) {
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
res = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
if (PyStackRef_IsNull(res)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
if (res_o == NULL) {
|
||||
stack_pointer += -2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
JUMP_TO_ERROR();
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -940,20 +954,15 @@
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
if (!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o)) {
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
res = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
if (PyStackRef_IsNull(res)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
if (res_o == NULL) {
|
||||
stack_pointer += -2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
JUMP_TO_ERROR();
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -3807,14 +3816,8 @@
|
|||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
if (!_PyLong_IsCompact((PyLongObject *)left_o)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (!_PyLong_IsCompact((PyLongObject *)right_o)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
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);
|
||||
|
|
69
Python/generated_cases.c.h
generated
69
Python/generated_cases.c.h
generated
|
@ -158,7 +158,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -168,7 +168,7 @@
|
|||
{
|
||||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
if (!PyLong_CheckExact(left_o)) {
|
||||
if (!PyLong_CheckCompact(left_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -182,19 +182,16 @@
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
if (!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o)) {
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
res = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
if (PyStackRef_IsNull(res)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
}
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
if (res_o == NULL) {
|
||||
JUMP_TO_LABEL(pop_2_error);
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
|
@ -486,7 +483,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -496,7 +493,7 @@
|
|||
{
|
||||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
if (!PyLong_CheckExact(left_o)) {
|
||||
if (!PyLong_CheckCompact(left_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -510,19 +507,16 @@
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
if (!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o)) {
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
res = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
if (PyStackRef_IsNull(res)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
}
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
if (res_o == NULL) {
|
||||
JUMP_TO_LABEL(pop_2_error);
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
|
@ -700,7 +694,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -862,7 +856,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -940,7 +934,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -1070,7 +1064,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -1080,7 +1074,7 @@
|
|||
{
|
||||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
if (!PyLong_CheckExact(left_o)) {
|
||||
if (!PyLong_CheckCompact(left_o)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
@ -1094,19 +1088,16 @@
|
|||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
assert(PyLong_CheckExact(left_o));
|
||||
assert(PyLong_CheckExact(right_o));
|
||||
if (!_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o)) {
|
||||
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
res = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
if (PyStackRef_IsNull(res)) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
}
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
|
||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
|
||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
|
||||
if (res_o == NULL) {
|
||||
JUMP_TO_LABEL(pop_2_error);
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
|
@ -4902,7 +4893,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(COMPARE_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (COMPARE_OP));
|
||||
JUMP_TO_PREDICTED(COMPARE_OP);
|
||||
|
@ -4912,7 +4903,7 @@
|
|||
{
|
||||
left = stack_pointer[-2];
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
if (!PyLong_CheckExact(left_o)) {
|
||||
if (!PyLong_CheckCompact(left_o)) {
|
||||
UPDATE_MISS_STATS(COMPARE_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (COMPARE_OP));
|
||||
JUMP_TO_PREDICTED(COMPARE_OP);
|
||||
|
@ -4924,16 +4915,8 @@
|
|||
right = value;
|
||||
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
|
||||
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
|
||||
if (!_PyLong_IsCompact((PyLongObject *)left_o)) {
|
||||
UPDATE_MISS_STATS(COMPARE_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (COMPARE_OP));
|
||||
JUMP_TO_PREDICTED(COMPARE_OP);
|
||||
}
|
||||
if (!_PyLong_IsCompact((PyLongObject *)right_o)) {
|
||||
UPDATE_MISS_STATS(COMPARE_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (COMPARE_OP));
|
||||
JUMP_TO_PREDICTED(COMPARE_OP);
|
||||
}
|
||||
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);
|
||||
|
@ -11490,7 +11473,7 @@
|
|||
{
|
||||
value = stack_pointer[-1];
|
||||
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
|
||||
if (!PyLong_CheckExact(value_o)) {
|
||||
if (!PyLong_CheckCompact(value_o)) {
|
||||
UPDATE_MISS_STATS(STORE_SUBSCR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR));
|
||||
JUMP_TO_PREDICTED(STORE_SUBSCR);
|
||||
|
|
|
@ -333,6 +333,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
|
|||
#define sym_set_type(SYM, TYPE) _Py_uop_sym_set_type(ctx, SYM, TYPE)
|
||||
#define sym_set_type_version(SYM, VERSION) _Py_uop_sym_set_type_version(ctx, SYM, VERSION)
|
||||
#define sym_set_const(SYM, CNST) _Py_uop_sym_set_const(ctx, SYM, CNST)
|
||||
#define sym_set_compact_int(SYM) _Py_uop_sym_set_compact_int(ctx, SYM)
|
||||
#define sym_is_bottom _Py_uop_sym_is_bottom
|
||||
#define sym_truthiness _Py_uop_sym_truthiness
|
||||
#define frame_new _Py_uop_frame_new
|
||||
|
@ -341,6 +342,8 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
|
|||
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
|
||||
#define sym_tuple_length _Py_uop_sym_tuple_length
|
||||
#define sym_is_immortal _Py_uop_sym_is_immortal
|
||||
#define sym_is_compact_int _Py_uop_sym_is_compact_int
|
||||
#define sym_new_compact_int _Py_uop_sym_new_compact_int
|
||||
#define sym_new_truthiness _Py_uop_sym_new_truthiness
|
||||
|
||||
static int
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
|
|||
#define sym_set_type(SYM, TYPE) _Py_uop_sym_set_type(ctx, SYM, TYPE)
|
||||
#define sym_set_type_version(SYM, VERSION) _Py_uop_sym_set_type_version(ctx, SYM, VERSION)
|
||||
#define sym_set_const(SYM, CNST) _Py_uop_sym_set_const(ctx, SYM, CNST)
|
||||
#define sym_set_compact_int(SYM) _Py_uop_sym_set_compact_int(ctx, SYM)
|
||||
#define sym_is_bottom _Py_uop_sym_is_bottom
|
||||
#define frame_new _Py_uop_frame_new
|
||||
#define frame_pop _Py_uop_frame_pop
|
||||
|
@ -34,6 +35,8 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
|
|||
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
|
||||
#define sym_tuple_length _Py_uop_sym_tuple_length
|
||||
#define sym_is_immortal _Py_uop_sym_is_immortal
|
||||
#define sym_new_compact_int _Py_uop_sym_new_compact_int
|
||||
#define sym_is_compact_int _Py_uop_sym_is_compact_int
|
||||
#define sym_new_truthiness _Py_uop_sym_new_truthiness
|
||||
|
||||
extern int
|
||||
|
@ -105,17 +108,27 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_GUARD_TOS_INT, (value -- value)) {
|
||||
if (sym_matches_type(value, &PyLong_Type)) {
|
||||
if (sym_is_compact_int(value)) {
|
||||
REPLACE_OP(this_instr, _NOP, 0, 0);
|
||||
}
|
||||
sym_set_type(value, &PyLong_Type);
|
||||
else {
|
||||
if (sym_get_type(value) == &PyLong_Type) {
|
||||
REPLACE_OP(this_instr, _GUARD_TOS_OVERFLOWED, 0, 0);
|
||||
}
|
||||
sym_set_compact_int(value);
|
||||
}
|
||||
}
|
||||
|
||||
op(_GUARD_NOS_INT, (left, unused -- left, unused)) {
|
||||
if (sym_matches_type(left, &PyLong_Type)) {
|
||||
if (sym_is_compact_int(left)) {
|
||||
REPLACE_OP(this_instr, _NOP, 0, 0);
|
||||
}
|
||||
sym_set_type(left, &PyLong_Type);
|
||||
else {
|
||||
if (sym_get_type(left) == &PyLong_Type) {
|
||||
REPLACE_OP(this_instr, _GUARD_NOS_OVERFLOWED, 0, 0);
|
||||
}
|
||||
sym_set_compact_int(left);
|
||||
}
|
||||
}
|
||||
|
||||
op(_CHECK_ATTR_CLASS, (type_version/2, owner -- owner)) {
|
||||
|
@ -222,15 +235,15 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_BINARY_OP_ADD_INT, (left, right -- res)) {
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
|
||||
|
@ -434,6 +447,15 @@ dummy_func(void) {
|
|||
res = sym_new_truthiness(ctx, value, false);
|
||||
}
|
||||
|
||||
op(_UNARY_NEGATIVE, (value -- res)) {
|
||||
if (sym_is_compact_int(value)) {
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
else {
|
||||
res = sym_new_not_null(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
op(_UNARY_INVERT, (value -- res)) {
|
||||
if (sym_matches_type(value, &PyLong_Type)) {
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
|
|
41
Python/optimizer_cases.c.h
generated
41
Python/optimizer_cases.c.h
generated
|
@ -142,8 +142,15 @@
|
|||
}
|
||||
|
||||
case _UNARY_NEGATIVE: {
|
||||
JitOptRef value;
|
||||
JitOptRef res;
|
||||
res = sym_new_not_null(ctx);
|
||||
value = stack_pointer[-1];
|
||||
if (sym_is_compact_int(value)) {
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
else {
|
||||
res = sym_new_not_null(ctx);
|
||||
}
|
||||
stack_pointer[-1] = res;
|
||||
break;
|
||||
}
|
||||
|
@ -301,26 +308,44 @@
|
|||
case _GUARD_NOS_INT: {
|
||||
JitOptRef left;
|
||||
left = stack_pointer[-2];
|
||||
if (sym_matches_type(left, &PyLong_Type)) {
|
||||
if (sym_is_compact_int(left)) {
|
||||
REPLACE_OP(this_instr, _NOP, 0, 0);
|
||||
}
|
||||
sym_set_type(left, &PyLong_Type);
|
||||
else {
|
||||
if (sym_get_type(left) == &PyLong_Type) {
|
||||
REPLACE_OP(this_instr, _GUARD_NOS_OVERFLOWED, 0, 0);
|
||||
}
|
||||
sym_set_compact_int(left);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_TOS_INT: {
|
||||
JitOptRef value;
|
||||
value = stack_pointer[-1];
|
||||
if (sym_matches_type(value, &PyLong_Type)) {
|
||||
if (sym_is_compact_int(value)) {
|
||||
REPLACE_OP(this_instr, _NOP, 0, 0);
|
||||
}
|
||||
sym_set_type(value, &PyLong_Type);
|
||||
else {
|
||||
if (sym_get_type(value) == &PyLong_Type) {
|
||||
REPLACE_OP(this_instr, _GUARD_TOS_OVERFLOWED, 0, 0);
|
||||
}
|
||||
sym_set_compact_int(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_OVERFLOWED: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_TOS_OVERFLOWED: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _BINARY_OP_MULTIPLY_INT: {
|
||||
JitOptRef res;
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
res = sym_new_compact_int(ctx);
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -329,7 +354,7 @@
|
|||
|
||||
case _BINARY_OP_ADD_INT: {
|
||||
JitOptRef res;
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
res = sym_new_compact_int(ctx);
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
@ -338,7 +363,7 @@
|
|||
|
||||
case _BINARY_OP_SUBTRACT_INT: {
|
||||
JitOptRef res;
|
||||
res = sym_new_type(ctx, &PyLong_Type);
|
||||
res = sym_new_compact_int(ctx);
|
||||
stack_pointer[-2] = res;
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
|
|
|
@ -30,17 +30,19 @@ we often skip in-between states for convenience:
|
|||
| |
|
||||
NULL |
|
||||
| | <- Anything below this level is an object.
|
||||
| NON_NULL
|
||||
| | | <- Anything below this level has a known type version.
|
||||
| TYPE_VERSION |
|
||||
| | | <- Anything below this level has a known type.
|
||||
| KNOWN_CLASS |
|
||||
| | | | <- Anything below this level has a known truthiness.
|
||||
| | | TRUTHINESS
|
||||
| | | |
|
||||
| TUPLE | |
|
||||
| | | | <- Anything below this level is a known constant.
|
||||
| KNOWN_VALUE
|
||||
| NON_NULL-+
|
||||
| | | <- Anything below this level has a known type version.
|
||||
| TYPE_VERSION |
|
||||
| | | <- Anything below this level has a known type.
|
||||
| KNOWN_CLASS |
|
||||
| | | | | |
|
||||
| | | INT* | |
|
||||
| | | | | | <- Anything below this level has a known truthiness.
|
||||
| | | | | TRUTHINESS
|
||||
| | | | | |
|
||||
| TUPLE | | | |
|
||||
| | | | | | <- Anything below this level is a known constant.
|
||||
| KNOWN_VALUE--+
|
||||
| | <- Anything below this level is unreachable.
|
||||
BOTTOM
|
||||
|
||||
|
@ -52,6 +54,8 @@ result of a truth test, which would allow us to narrow the symbol to KNOWN_VALUE
|
|||
the same symbol, that would be a contradiction, and the symbol would be set to
|
||||
BOTTOM (indicating that the code is unreachable).
|
||||
|
||||
INT* is a limited range int, currently a "compact" int.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
|
@ -229,6 +233,11 @@ _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef ref, PyTypeObject *typ)
|
|||
sym_set_bottom(ctx, sym);
|
||||
}
|
||||
return;
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
if (typ != &PyLong_Type) {
|
||||
sym_set_bottom(ctx, sym);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,6 +295,12 @@ _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef ref, unsigned int ver
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
if (version != PyLong_Type.tp_version_tag) {
|
||||
sym_set_bottom(ctx, sym);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Py_UNREACHABLE();
|
||||
}
|
||||
|
@ -370,6 +385,14 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef ref, PyObject *const_val)
|
|||
// TODO: More types (GH-130415)!
|
||||
make_const(sym, const_val);
|
||||
return;
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
if (PyLong_CheckCompact(const_val)) {
|
||||
make_const(sym, const_val);
|
||||
}
|
||||
else {
|
||||
sym_set_bottom(ctx, sym);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,6 +500,9 @@ _Py_uop_sym_get_type(JitOptRef ref)
|
|||
return &PyTuple_Type;
|
||||
case JIT_SYM_TRUTHINESS_TAG:
|
||||
return &PyBool_Type;
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
return &PyLong_Type;
|
||||
|
||||
}
|
||||
Py_UNREACHABLE();
|
||||
}
|
||||
|
@ -502,6 +528,8 @@ _Py_uop_sym_get_type_version(JitOptRef ref)
|
|||
return PyTuple_Type.tp_version_tag;
|
||||
case JIT_SYM_TRUTHINESS_TAG:
|
||||
return PyBool_Type.tp_version_tag;
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
return PyLong_Type.tp_version_tag;
|
||||
}
|
||||
Py_UNREACHABLE();
|
||||
}
|
||||
|
@ -535,6 +563,7 @@ _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef ref)
|
|||
case JIT_SYM_BOTTOM_TAG:
|
||||
case JIT_SYM_NON_NULL_TAG:
|
||||
case JIT_SYM_UNKNOWN_TAG:
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
return -1;
|
||||
case JIT_SYM_KNOWN_CLASS_TAG:
|
||||
/* TODO :
|
||||
|
@ -645,6 +674,16 @@ _Py_uop_symbol_is_immortal(JitOptSymbol *sym)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
_Py_uop_sym_is_compact_int(JitOptRef ref)
|
||||
{
|
||||
JitOptSymbol *sym = PyJitRef_Unwrap(ref);
|
||||
if (sym->tag == JIT_SYM_KNOWN_VALUE_TAG) {
|
||||
return (bool)PyLong_CheckCompact(sym->value.value);
|
||||
}
|
||||
return sym->tag == JIT_SYM_COMPACT_INT;
|
||||
}
|
||||
|
||||
bool
|
||||
_Py_uop_sym_is_immortal(JitOptRef ref)
|
||||
{
|
||||
|
@ -652,6 +691,50 @@ _Py_uop_sym_is_immortal(JitOptRef ref)
|
|||
return _Py_uop_symbol_is_immortal(sym);
|
||||
}
|
||||
|
||||
void
|
||||
_Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref)
|
||||
{
|
||||
JitOptSymbol *sym = PyJitRef_Unwrap(ref);
|
||||
JitSymType tag = sym->tag;
|
||||
switch(tag) {
|
||||
case JIT_SYM_NULL_TAG:
|
||||
sym_set_bottom(ctx, sym);
|
||||
return;
|
||||
case JIT_SYM_KNOWN_CLASS_TAG:
|
||||
if (sym->cls.type == &PyLong_Type) {
|
||||
sym->tag = JIT_SYM_COMPACT_INT;
|
||||
} else {
|
||||
sym_set_bottom(ctx, sym);
|
||||
}
|
||||
return;
|
||||
case JIT_SYM_TYPE_VERSION_TAG:
|
||||
if (sym->version.version == PyLong_Type.tp_version_tag) {
|
||||
sym->tag = JIT_SYM_COMPACT_INT;
|
||||
}
|
||||
else {
|
||||
sym_set_bottom(ctx, sym);
|
||||
}
|
||||
return;
|
||||
case JIT_SYM_KNOWN_VALUE_TAG:
|
||||
if (!PyLong_CheckCompact(sym->value.value)) {
|
||||
Py_CLEAR(sym->value.value);
|
||||
sym_set_bottom(ctx, sym);
|
||||
}
|
||||
return;
|
||||
case JIT_SYM_TUPLE_TAG:
|
||||
case JIT_SYM_TRUTHINESS_TAG:
|
||||
sym_set_bottom(ctx, sym);
|
||||
return;
|
||||
case JIT_SYM_BOTTOM_TAG:
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
return;
|
||||
case JIT_SYM_NON_NULL_TAG:
|
||||
case JIT_SYM_UNKNOWN_TAG:
|
||||
sym->tag = JIT_SYM_COMPACT_INT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JitOptRef
|
||||
_Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptRef ref, bool truthy)
|
||||
{
|
||||
|
@ -677,6 +760,17 @@ _Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptRef ref, bool truthy)
|
|||
return PyJitRef_Wrap(res);
|
||||
}
|
||||
|
||||
JitOptRef
|
||||
_Py_uop_sym_new_compact_int(JitOptContext *ctx)
|
||||
{
|
||||
JitOptSymbol *sym = sym_new(ctx);
|
||||
if (sym == NULL) {
|
||||
return out_of_space_ref(ctx);
|
||||
}
|
||||
sym->tag = JIT_SYM_COMPACT_INT;
|
||||
return PyJitRef_Wrap(sym);
|
||||
}
|
||||
|
||||
// 0 on success, -1 on error.
|
||||
_Py_UOpsAbstractFrame *
|
||||
_Py_uop_frame_new(
|
||||
|
@ -796,6 +890,7 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
|
|||
_Py_uop_abstractcontext_init(ctx);
|
||||
PyObject *val_42 = NULL;
|
||||
PyObject *val_43 = NULL;
|
||||
PyObject *val_big = NULL;
|
||||
PyObject *tuple = NULL;
|
||||
|
||||
// Use a single 'sym' variable so copy-pasting tests is easier.
|
||||
|
@ -926,9 +1021,38 @@ _Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
|
|||
TEST_PREDICATE(_Py_uop_sym_get_const(ctx, ref) == Py_False, "truthiness is not False");
|
||||
TEST_PREDICATE(_Py_uop_sym_is_const(ctx, value) == true, "value is not constant");
|
||||
TEST_PREDICATE(_Py_uop_sym_get_const(ctx, value) == Py_True, "value is not True");
|
||||
|
||||
|
||||
val_big = PyNumber_Lshift(_PyLong_GetOne(), PyLong_FromLong(66));
|
||||
if (val_big == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
JitOptRef ref_42 = _Py_uop_sym_new_const(ctx, val_42);
|
||||
JitOptRef ref_big = _Py_uop_sym_new_const(ctx, val_big);
|
||||
JitOptRef ref_int = _Py_uop_sym_new_compact_int(ctx);
|
||||
TEST_PREDICATE(_Py_uop_sym_is_compact_int(ref_42), "42 is not a compact int");
|
||||
TEST_PREDICATE(!_Py_uop_sym_is_compact_int(ref_big), "(1 << 66) is a compact int");
|
||||
TEST_PREDICATE(_Py_uop_sym_is_compact_int(ref_int), "compact int is not a compact int");
|
||||
TEST_PREDICATE(_Py_uop_sym_matches_type(ref_int, &PyLong_Type), "compact int is not an int");
|
||||
|
||||
_Py_uop_sym_set_type(ctx, ref_int, &PyLong_Type); // Should have no effect
|
||||
TEST_PREDICATE(_Py_uop_sym_is_compact_int(ref_int), "compact int is not a compact int after cast");
|
||||
TEST_PREDICATE(_Py_uop_sym_matches_type(ref_int, &PyLong_Type), "compact int is not an int after cast");
|
||||
|
||||
_Py_uop_sym_set_type(ctx, ref_int, &PyFloat_Type); // Should make it bottom
|
||||
TEST_PREDICATE(_Py_uop_sym_is_bottom(ref_int), "compact int cast to float isn't bottom");
|
||||
|
||||
ref_int = _Py_uop_sym_new_compact_int(ctx);
|
||||
_Py_uop_sym_set_const(ctx, ref_int, val_43);
|
||||
TEST_PREDICATE(_Py_uop_sym_is_compact_int(ref_int), "43 is not a compact int");
|
||||
TEST_PREDICATE(_Py_uop_sym_matches_type(ref_int, &PyLong_Type), "43 is not an int");
|
||||
TEST_PREDICATE(_Py_uop_sym_get_const(ctx, ref_int) == val_43, "43 isn't 43");
|
||||
|
||||
_Py_uop_abstractcontext_fini(ctx);
|
||||
Py_DECREF(val_42);
|
||||
Py_DECREF(val_43);
|
||||
Py_DECREF(val_big);
|
||||
Py_DECREF(tuple);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
|
@ -936,6 +1060,7 @@ fail:
|
|||
_Py_uop_abstractcontext_fini(ctx);
|
||||
Py_XDECREF(val_42);
|
||||
Py_XDECREF(val_43);
|
||||
Py_XDECREF(val_big);
|
||||
Py_DECREF(tuple);
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue