Skip to content

Commit a7c92fc

Browse files
committed
Specialize int operations for compact ints only. Deopts before allocation in case of overflow
1 parent 8dd8b5c commit a7c92fc

File tree

16 files changed

+479
-283
lines changed

16 files changed

+479
-283
lines changed

Include/cpython/longintrepr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ _PyLong_IsCompact(const PyLongObject* op) {
124124
return op->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS);
125125
}
126126

127+
static inline int
128+
PyLong_CheckCompact(const PyObject *op)
129+
{
130+
return PyLong_CheckExact(op) && _PyLong_IsCompact((PyLongObject *)op);
131+
}
132+
127133
#define PyUnstable_Long_IsCompact _PyLong_IsCompact
128134

129135
static inline Py_ssize_t

Include/internal/pycore_long.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, int64_t);
112112
// Export for 'math' shared extension
113113
PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, int64_t);
114114

115-
PyAPI_FUNC(PyObject*) _PyCompactLong_Add(PyLongObject *left, PyLongObject *right);
116-
PyAPI_FUNC(PyObject*) _PyCompactLong_Multiply(PyLongObject *left, PyLongObject *right);
117-
PyAPI_FUNC(PyObject*) _PyCompactLong_Subtract(PyLongObject *left, PyLongObject *right);
115+
PyAPI_FUNC(_PyStackRef) _PyCompactLong_Add(PyLongObject *left, PyLongObject *right);
116+
PyAPI_FUNC(_PyStackRef) _PyCompactLong_Multiply(PyLongObject *left, PyLongObject *right);
117+
PyAPI_FUNC(_PyStackRef) _PyCompactLong_Subtract(PyLongObject *left, PyLongObject *right);
118118

119119
// Export for 'binascii' shared extension.
120120
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
@@ -213,7 +213,6 @@ _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) {
213213
assert(PyLong_Check(b));
214214
return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS);
215215
}
216-
217216
static inline bool
218217
_PyLong_IsZero(const PyLongObject *op)
219218
{

Include/internal/pycore_opcode_metadata.h

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_optimizer.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ typedef enum _JitSymType {
178178
JIT_SYM_KNOWN_VALUE_TAG = 7,
179179
JIT_SYM_TUPLE_TAG = 8,
180180
JIT_SYM_TRUTHINESS_TAG = 9,
181+
JIT_SYM_COMPACT_INT = 10,
181182
} JitSymType;
182183

183184
typedef struct _jit_opt_known_class {
@@ -210,13 +211,18 @@ typedef struct {
210211
uint16_t value;
211212
} JitOptTruthiness;
212213

214+
typedef struct {
215+
uint8_t tag;
216+
} JitOptCompactInt;
217+
213218
typedef union _jit_opt_symbol {
214219
uint8_t tag;
215220
JitOptKnownClass cls;
216221
JitOptKnownValue value;
217222
JitOptKnownVersion version;
218223
JitOptTuple tuple;
219224
JitOptTruthiness truthiness;
225+
JitOptCompactInt compact;
220226
} JitOptSymbol;
221227

222228

@@ -282,6 +288,10 @@ extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptS
282288
extern JitOptSymbol *_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item);
283289
extern int _Py_uop_sym_tuple_length(JitOptSymbol *sym);
284290
extern JitOptSymbol *_Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptSymbol *value, bool truthy);
291+
extern bool _Py_uop_sym_is_compact_int(JitOptSymbol *sym);
292+
extern JitOptSymbol *_Py_uop_sym_new_compact_int(JitOptContext *ctx);
293+
extern void _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptSymbol *value);
294+
285295

286296
extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
287297
extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);

0 commit comments

Comments
 (0)