8000 Specialize STORE_FAST by reference and type in JIT · python/cpython@4b415f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4b415f5

Browse files
Specialize STORE_FAST by reference and type in JIT
1 parent c825b5d commit 4b415f5

File tree

11 files changed

+350
-159
lines changed

11 files changed

+350
-159
lines changed

Include/internal/pycore_opcode_metadata.h

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

Include/internal/pycore_uop_ids.h

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

Include/internal/pycore_uop_metadata.h

Lines changed: 44 additions & 28 deletions
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: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,6 +2349,66 @@ def testfunc(n):
23492349
assert ex is not None
23502350
"""))
23512351

2352+
def test_store_fast_pop_top_specialize_immortal(self):
2353+
def testfunc(n):
2354+
for _ in range(n):
2355+
x = None # _POP_TOP, as x's type is not yet known by optimizer.
2356+
x = None # _POP_TOP_NOP, as x = None
2357+
2358+
testfunc(TIER2_THRESHOLD)
2359+
2360+
ex = get_first_executor(testfunc)
2361+
self.assertIsNotNone(ex)
2362+
uops = get_opnames(ex)
2363+
2364+
self.assertIn("_POP_TOP_NOP", uops)
2365+
2366+
def test_store_fast_pop_top_specialize_int(self):
2367+
def testfunc(n):
2368+
y = int(1e6) # Big number so no int caching
2369+
for _ in range(n):
2370+
x = y + y # _POP_TOP, as x's type is not yet known by optimizer.
2371+
x = None # _POP_TOP_INT, as x = int
2372+
2373+
testfunc(TIER2_THRESHOLD)
2374+
2375+
ex = get_first_executor(testfunc)
2376+
self.assertIsNotNone(ex)
2377+
uops = get_opnames(ex)
2378+
2379+
self.assertIn("_POP_TOP_INT", uops)
2380+
2381+
def test_store_fast_pop_top_specialize_float(self):
2382+
def testfunc(n):
2383+
y = 1.0
2384+
for _ in range(n):
2385+
x = y + y # _POP_TOP, as x's type is not yet known by optimizer.
2386+
x = None # _POP_TOP_FLOAT, as x = int
2387+
2388+
testfunc(TIER2_THRESHOLD)
2389+
2390+
ex = get_first_executor(testfunc)
2391+
self.assertIsNotNone(ex)
2392+
uops = get_opnames(ex)
2393+
2394+
self.assertIn("_POP_TOP_FLOAT", uops)
2395+
2396+
def test_store_fast_pop_top_specialize_unicode(self):
2397+
def testfunc(n):
2398+
y = "hi"
2399+
for _ in range(n):
2400+
x = y + y # _POP_TOP, as x's type is not yet known by optimizer.
2401+
x = None # _POP_TOP_STR, as x = int
2402+
2403+
testfunc(TIER2_THRESHOLD)
2404+
2405+
ex = get_first_executor(testfunc)
2406+
self.assertIsNotNone(ex)
2407+
uops = get_opnames(ex)
2408+
2409+
self.assertIn("_POP_TOP_UNICODE", uops)
2410+
2411+
23522412

23532413
def global_identity(x):
23542414
return x

Python/bytecodes.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,14 @@ dummy_func(
306306
value = PyStackRef_FromPyObjectBorrow(obj);
307307
}
308308

309-
replicate(8) inst(STORE_FAST, (value --)) {
310-
_PyStackRef tmp = GETLOCAL(oparg);
309+
replicate(8) op(_SWAP_FAST, (value -- trash)) {
310+
trash = GETLOCAL(oparg);
311311
GETLOCAL(oparg) = value;
312312
DEAD(value);
313-
57AE PyStackRef_XCLOSE(tmp);
314313
}
315314

315+
macro(STORE_FAST) = _SWAP_FAST + POP_TOP;
316+
316317
pseudo(STORE_FAST_MAYBE_NULL, (unused --)) = {
317318
STORE_FAST,
318319
};
@@ -344,6 +345,31 @@ dummy_func(
344345
PyStackRef_XCLOSE(value);
345346
}
346347

348+
op(_POP_TOP_NOP, (value --)) {
349+
// TODO (gh-134584): Consider moving this to a function pointer table and replicate.
350+
assert(!PyStackRef_RefcountOnObject(value) ||
351+
_Py_IsImmortal((PyStackRef_AsPyObjectBorrow(value))));
352+
DEAD(value);
353+
}
354+
355+
op(_POP_TOP_INT, (value --)) {
356+
// TODO (gh-134584): Consider moving this to a function pointer table and replicate.
357+
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
358+
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
359+
}
360+
361+
op(_POP_TOP_FLOAT, (value --)) {
362+
// TODO (gh-134584): Consider moving this to a function pointer table and replicate.
363+
assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
364+
PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
365+
}
366+
367+
op(_POP_TOP_UNICODE, (value --)) {
368+
// TODO (gh-134584): Consider moving this to a function pointer table and replicate.
369+
assert(PyUnicode_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
370+
PyStackRef_CLOSE_SPECIALIZED(value, _PyUnicode_ExactDealloc);
371+
}
372+
347373
tier2 op(_POP_TWO, (nos, tos --)) {
348374
PyStackRef_CLOSE(tos);
349375
PyStackRef_CLOSE(nos);

0 commit comments

Comments
 (0)
0