Skip to content

Commit 46b423f

Browse files
committed
WIP
1 parent d5afe15 commit 46b423f

File tree

11 files changed

+130
-21
lines changed

11 files changed

+130
-21
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_capi/test_opt.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import unittest
66
import gc
77
import os
8+
import random
9+
import string
810

911
import _opcode
1012

@@ -2362,6 +2364,23 @@ def testfunc(n):
23622364
self.assertNotIn("_GUARD_TOS_INT", uops)
23632365
self.assertNotIn("_GUARD_NOS_INT", uops)
23642366

2367+
def test_store_fast_pop_top_specialize_unicode(self):
2368+
def random_str(n):
2369+
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(n))
2370+
def testfunc(n):
2371+
y = random_str(32)
2372+
for _ in range(n):
2373+
x = y + y # _POP_TOP
2374+
x = None # _POP_TOP_NOP
2375+
2376+
testfunc(TIER2_THRESHOLD)
2377+
2378+
ex = get_first_executor(testfunc)
2379+
self.assertIsNotNone(ex)
2380+
uops = get_opnames(ex)
2381+
2382+
self.assertIn("_POP_TOP_NOP", uops)
2383+
23652384
def test_attr_promotion_failure(self):
23662385
# We're not testing for any specific uops here, just
23672386
# testing it doesn't crash.

Lib/test/test_sys.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,7 +1671,7 @@ def func():
16711671
INTERPRETER_FRAME = '9PihcP'
16721672
else:
16731673
INTERPRETER_FRAME = '9PhcP'
1674-
check(x, size('3PiccPPP' + INTERPRETER_FRAME + 'P'))
1674+
check(x, size('3PiccPPP' + INTERPRETER_FRAME + 'PP'))
16751675
# function
16761676
def func(): pass
16771677
check(func, size('16Pi'))
@@ -1688,7 +1688,7 @@ def bar(cls):
16881688
check(bar, size('PP'))
16891689
# generator
16901690
def get_gen(): yield 1
1691-
check(get_gen(), size('6P4c' + INTERPRETER_FRAME + 'P'))
1691+
check(get_gen(), size('6P4c' + INTERPRETER_FRAME + 'PP'))
16921692
# iterator
16931693
check(iter('abc'), size('lP'))
16941694
# callable-iterator

Programs/test_frozenmain.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/bytecodes.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,23 +773,23 @@ dummy_func(
773773
macro(BINARY_OP_SUBTRACT_FLOAT) =
774774
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/5 + _BINARY_OP_SUBTRACT_FLOAT;
775775

776-
pure op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
776+
pure op(_BINARY_OP_ADD_UNICODE, (left, right -- res, l, r)) {
777777
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
778778
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
779779
assert(PyUnicode_CheckExact(left_o));
780780
assert(PyUnicode_CheckExact(right_o));
781781

782782
STAT_INC(BINARY_OP, hit);
783783
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
784-
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
785-
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
786784
INPUTS_DEAD();
787785
ERROR_IF(res_o == NULL);
786+
l = left;
787+
r = right;
788788
res = PyStackRef_FromPyObjectSteal(res_o);
789789
}
790790

791791
macro(BINARY_OP_ADD_UNICODE) =
792-
_GUARD_TOS_UNICODE + _GUARD_NOS_UNICODE + unused/5 + _BINARY_OP_ADD_UNICODE;
792+
_GUARD_TOS_UNICODE + _GUARD_NOS_UNICODE + unused/5 + _BINARY_OP_ADD_UNICODE + _POP_TOP_UNICODE + _POP_TOP_UNICODE;
793793

794794
// This is a subtle one. It's a super-instruction for
795795
// BINARY_OP_ADD_UNICODE followed by STORE_FAST

Python/compile.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,10 @@ optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
14311431
&optimized_instrs) < 0) {
14321432
goto error;
14331433
}
1434+
/* Reserve an extra word on the stack to ensure there is space for uops to
1435+
pass at least one item on the stack to a subsequent uop.
1436+
*/
1437+
stackdepth++;
14341438

14351439
/** Assembly **/
14361440
co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts,

Python/executor_cases.c.h

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

Python/generated_cases.c.h

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

Python/optimizer_analysis.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
345345
#define sym_new_tuple _Py_uop_sym_new_tuple
346346
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
347347
#define sym_tuple_length _Py_uop_sym_tuple_length
348-
#define sym_is_immortal _Py_uop_sym_is_immortal
348+
#define sym_is_immortal _Py_uop_symbol_is_immortal
349349
#define sym_is_compact_int _Py_uop_sym_is_compact_int
350350
#define sym_new_compact_int _Py_uop_sym_new_compact_int
351351
#define sym_new_truthiness _Py_uop_sym_new_truthiness

Python/optimizer_bytecodes.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
3434
#define sym_new_tuple _Py_uop_sym_new_tuple
3535
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
3636
#define sym_tuple_length _Py_uop_sym_tuple_length
37-
#define sym_is_immortal _Py_uop_sym_is_immortal
37+
#define sym_is_immortal _Py_uop_symbol_is_immortal
3838
#define sym_new_compact_int _Py_uop_sym_new_compact_int
3939
#define sym_is_compact_int _Py_uop_sym_is_compact_int
4040
#define sym_new_truthiness _Py_uop_sym_new_truthiness
@@ -318,7 +318,7 @@ dummy_func(void) {
318318
}
319319
}
320320

321-
op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
321+
op(_BINARY_OP_ADD_UNICODE, (left, right -- res, l, r)) {
322322
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
323323
assert(PyUnicode_CheckExact(sym_get_const(ctx, left)));
324324
assert(PyUnicode_CheckExact(sym_get_const(ctx, right)));
@@ -327,10 +327,14 @@ dummy_func(void) {
327327
goto error;
328328
}
329329
res = sym_new_const(ctx, temp);
330+
l = left;
331+
r = right;
330332
Py_DECREF(temp);
331333
}
332334
else {
333335
res = sym_new_type(ctx, &PyUnicode_Type);
336+
l = left;
337+
r = right;
334338
}
335339
}
336340

@@ -561,11 +565,39 @@ dummy_func(void) {
561565
value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
562566
}
563567

568+
op(_POP_TOP_UNICODE, (value -- )) {
569+
if (PyJitRef_IsBorrowed(value) ||
570+
sym_is_immortal(PyJitRef_Unwrap(value))) {
571+
REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
572+
}
573+
}
574+
564575
op(_COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
565576
assert(oparg > 0);
566577
top = bottom;
567578
}
568579

580+
op(_POP_TOP, (value -- )) {
581+
PyTypeObject *typ = sym_get_type(value);
582+
PyObject *const_val = sym_get_const(ctx, value);
583+
if (PyJitRef_IsBorrowed(value) ||
584+
(const_val != NULL && _Py_IsImmortal(const_val))) {
585+
REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
586+
}
587+
else if (typ == &PyLong_Type) {
588+
REPLACE_OP(this_instr, _POP_TOP_INT, 0, 0);
589+
}
590+
else if (typ == &PyFloat_Type) {
591+
REPLACE_OP(this_instr, _POP_TOP_FLOAT, 0, 0);
592+
}
593+
else if (typ == &PyUnicode_Type) {
594+
REPLACE_OP(this_instr, _POP_TOP_UNICODE, 0, 0);
595+
}
596+
else if (typ == &PyBool_Type) {
597+
REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
598+
}
599+
}
600+
569601
op(_SWAP, (bottom, unused[oparg-2], top -- bottom, unused[oparg-2], top)) {
570602
JitOptRef temp = bottom;
571603
bottom = top;
@@ -803,7 +835,7 @@ dummy_func(void) {
803835
}
804836

805837
op(_RETURN_VALUE, (retval -- res)) {
806-
JitOptRef temp = retval;
838+
JitOptRef temp = PyJitRef_Wrap(PyJitRef_Unwrap(retval));
807839
DEAD(retval);
808840
SAVE_STACK();
809841
ctx->frame->stack_pointer = stack_pointer;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy