mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
gh-99761: Add _PyLong_IsPositiveSingleDigit
function to check for single digit integers (#100064)
This commit is contained in:
parent
68981578ec
commit
2b82c36f17
3 changed files with 25 additions and 10 deletions
|
@ -110,6 +110,25 @@ PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
|
|||
int base,
|
||||
int alternate);
|
||||
|
||||
/* Return 1 if the argument is positive single digit int */
|
||||
static inline int
|
||||
_PyLong_IsPositiveSingleDigit(PyObject* sub) {
|
||||
/* For a positive single digit int, the value of Py_SIZE(sub) is 0 or 1.
|
||||
|
||||
We perform a fast check using a single comparison by casting from int
|
||||
to uint which casts negative numbers to large positive numbers.
|
||||
For details see Section 14.2 "Bounds Checking" in the Agner Fog
|
||||
optimization manual found at:
|
||||
https://www.agner.org/optimize/optimizing_cpp.pdf
|
||||
|
||||
The function is not affected by -fwrapv, -fno-wrapv and -ftrapv
|
||||
compiler options of GCC and clang
|
||||
*/
|
||||
assert(PyLong_CheckExact(sub));
|
||||
Py_ssize_t signed_size = Py_SIZE(sub);
|
||||
return ((size_t)signed_size) <= 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -391,8 +391,7 @@ dummy_func(
|
|||
DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR);
|
||||
|
||||
// Deopt unless 0 <= sub < PyList_Size(list)
|
||||
Py_ssize_t signed_magnitude = Py_SIZE(sub);
|
||||
DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR);
|
||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
||||
|
@ -410,8 +409,7 @@ dummy_func(
|
|||
DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
|
||||
|
||||
// Deopt unless 0 <= sub < PyTuple_Size(list)
|
||||
Py_ssize_t signed_magnitude = Py_SIZE(sub);
|
||||
DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR);
|
||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
||||
|
@ -508,7 +506,7 @@ dummy_func(
|
|||
DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR);
|
||||
|
||||
// Ensure nonnegative, zero-or-one-digit ints.
|
||||
DEOPT_IF(((size_t)Py_SIZE(sub)) > 1, STORE_SUBSCR);
|
||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR);
|
||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
// Ensure index < len(list)
|
||||
DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR);
|
||||
|
|
8
Python/generated_cases.c.h
generated
8
Python/generated_cases.c.h
generated
|
@ -491,8 +491,7 @@
|
|||
DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR);
|
||||
|
||||
// Deopt unless 0 <= sub < PyList_Size(list)
|
||||
Py_ssize_t signed_magnitude = Py_SIZE(sub);
|
||||
DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR);
|
||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR);
|
||||
|
@ -517,8 +516,7 @@
|
|||
DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
|
||||
|
||||
// Deopt unless 0 <= sub < PyTuple_Size(list)
|
||||
Py_ssize_t signed_magnitude = Py_SIZE(sub);
|
||||
DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR);
|
||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR);
|
||||
assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0);
|
||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR);
|
||||
|
@ -642,7 +640,7 @@
|
|||
DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR);
|
||||
|
||||
// Ensure nonnegative, zero-or-one-digit ints.
|
||||
DEOPT_IF(((size_t)Py_SIZE(sub)) > 1, STORE_SUBSCR);
|
||||
DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR);
|
||||
Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0];
|
||||
// Ensure index < len(list)
|
||||
DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue