Skip to content

Commit e82764d

Browse files
committed
Add support for analysing tuples
1 parent 219db3d commit e82764d

File tree

5 files changed

+82
-5
lines changed

5 files changed

+82
-5
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ extern bool _Py_uop_sym_is_bottom(JitOptSymbol *sym);
296296
extern int _Py_uop_sym_truthiness(JitOptSymbol *sym);
297297
extern PyTypeObject *_Py_uop_sym_get_type(JitOptSymbol *sym);
298298

299+
extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args);
300+
extern JitOptSymbol *_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item);
301+
extern int _Py_uop_sym_tuple_length(JitOptSymbol *sym);
299302

300303
extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
301304
extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);

Python/optimizer_analysis.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
368368
#define sym_truthiness _Py_uop_sym_truthiness
369369
#define frame_new _Py_uop_frame_new
370370
#define frame_pop _Py_uop_frame_pop
371+
#define sym_new_tuple _Py_uop_sym_new_tuple
372+
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
373+
#define sym_tuple_length _Py_uop_sym_tuple_length
371374

372375
static int
373376
optimize_to_bool(

Python/optimizer_bytecodes.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
3030
#define sym_is_bottom _Py_uop_sym_is_bottom
3131
#define frame_new _Py_uop_frame_new
3232
#define frame_pop _Py_uop_frame_pop
33+
#define sym_new_tuple _Py_uop_sym_new_tuple
34+
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
35+
#define sym_tuple_length _Py_uop_sym_tuple_length
3336

3437
extern int
3538
optimize_to_bool(
@@ -947,6 +950,22 @@ dummy_func(void) {
947950
res = sym_new_const(ctx, Py_True);
948951
}
949952

953+
op(_BUILD_TUPLE, (values[oparg] -- tup)) {
954+
tup = sym_new_tuple(ctx, oparg, values);
955+
}
956+
957+
op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0)) {
958+
val0 = sym_tuple_getitem(ctx, seq, 0);
959+
val1 = sym_tuple_getitem(ctx, seq, 1);
960+
}
961+
962+
op(_UNPACK_SEQUENCE_TUPLE, (seq -- values[oparg])) {
963+
for (int i = 0; i < oparg; i++) {
964+
values[i] = sym_tuple_getitem(ctx, seq, i);
965+
}
966+
}
967+
968+
950969
// END BYTECODES //
951970

952971
}

Python/optimizer_cases.c.h

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

Python/optimizer_symbols.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,52 @@ _Py_uop_sym_truthiness(JitOptSymbol *sym)
431431
return -1;
432432
}
433433

434+
static JitOptSymbol *
435+
allocation_base(JitOptContext *ctx)
436+
{
437+
return ctx->t_arena.arena;
438+
}
439+
440+
JitOptSymbol *
441+
_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args)
442+
{
443+
JitOptSymbol *res = sym_new(ctx);
444+
if (res == NULL) {
445+
return out_of_space(ctx);
446+
}
447+
if (size > 6) {
448+
res->tag = JIT_SYM_KNOWN_CLASS_TAG;
449+
res->cls.type = &PyTuple_Type;
450+
}
451+
else {
452+
res->tag = JIT_SYM_TUPLE_TAG;
453+
res->tuple.length = size;
454+
for (int i = 0; i < size; i++) {
455+
res->tuple.items[i] = (uint16_t)(args[i] - allocation_base(ctx));
456+
}
457+
}
458+
return res;
459+
}
460+
461+
JitOptSymbol *
462+
_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item)
463+
{
464+
465+
if (sym->tag != JIT_SYM_TUPLE_TAG || item < 0 || item >= sym->tuple.length) {
466+
return _Py_uop_sym_new_unknown(ctx);
467+
}
468+
return allocation_base(ctx) + sym->tuple.items[item];
469+
}
470+
471+
int
472+
_Py_uop_sym_tuple_length(JitOptSymbol *sym)
473+
{
474+
if (sym->tag != JIT_SYM_TUPLE_TAG) {
475+
return -1;
476+
}
477+
return sym->tuple.length;
478+
}
479+
434480

435481
// 0 on success, -1 on error.
436482
_Py_UOpsAbstractFrame *

0 commit comments

Comments
 (0)