Skip to content

Commit 484e003

Browse files
authored
GH-131798: Optimize away isinstance calls in the JIT (GH-134369)
1 parent fade146 commit 484e003

File tree

9 files changed

+312
-61
lines changed

9 files changed

+312
-61
lines changed

Include/internal/pycore_uop_ids.h

Lines changed: 48 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: 23 additions & 3 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: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,7 +2002,10 @@ def testfunc(n):
20022002
self.assertNotIn("_CALL_ISINSTANCE", uops)
20032003
self.assertNotIn("_GUARD_THIRD_NULL", uops)
20042004
self.assertNotIn("_GUARD_CALLABLE_ISINSTANCE", uops)
2005-
self.assertIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
2005+
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
2006+
self.assertNotIn("_POP_CALL_LOAD_CONST_INLINE_BORROW", uops)
2007+
self.assertNotIn("_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW", uops)
2008+
self.assertNotIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
20062009

20072010
def test_call_list_append(self):
20082011
def testfunc(n):
@@ -2035,7 +2038,10 @@ def testfunc(n):
20352038
self.assertNotIn("_CALL_ISINSTANCE", uops)
20362039
self.assertNotIn("_TO_BOOL_BOOL", uops)
20372040
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
2038-
self.assertIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
2041+
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
2042+
self.assertNotIn("_POP_CALL_LOAD_CONST_INLINE_BORROW", uops)
2043+
self.assertNotIn("_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW", uops)
2044+
self.assertNotIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
20392045

20402046
def test_call_isinstance_is_false(self):
20412047
def testfunc(n):
@@ -2053,7 +2059,10 @@ def testfunc(n):
20532059
self.assertNotIn("_CALL_ISINSTANCE", uops)
20542060
self.assertNotIn("_TO_BOOL_BOOL", uops)
20552061
self.assertNotIn("_GUARD_IS_FALSE_POP", uops)
2056-
self.assertIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
2062+
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
2063+
self.assertNotIn("_POP_CALL_LOAD_CONST_INLINE_BORROW", uops)
2064+
self.assertNotIn("_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW", uops)
2065+
self.assertNotIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
20572066

20582067
def test_call_isinstance_subclass(self):
20592068
def testfunc(n):
@@ -2071,7 +2080,10 @@ def testfunc(n):
20712080
self.assertNotIn("_CALL_ISINSTANCE", uops)
20722081
self.assertNotIn("_TO_BOOL_BOOL", uops)
20732082
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
2074-
self.assertIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
2083+
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
2084+
self.assertNotIn("_POP_CALL_LOAD_CONST_INLINE_BORROW", uops)
2085+
self.assertNotIn("_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW", uops)
2086+
self.assertNotIn("_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", uops)
20752087

20762088
def test_call_isinstance_unknown_object(self):
20772089
def testfunc(n):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Optimize ``_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW``.

Python/bytecodes.c

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5287,18 +5287,54 @@ dummy_func(
52875287
value = PyStackRef_FromPyObjectBorrow(ptr);
52885288
}
52895289

5290-
tier2 pure op (_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) {
5290+
tier2 op(_POP_CALL, (callable, null --)) {
5291+
(void)null; // Silence compiler warnings about unused variables
5292+
DEAD(null);
5293+
PyStackRef_CLOSE(callable);
5294+
}
5295+
5296+
tier2 op(_POP_CALL_ONE, (callable, null, pop --)) {
5297+
PyStackRef_CLOSE(pop);
5298+
(void)null; // Silence compiler warnings about unused variables
5299+
DEAD(null);
5300+
PyStackRef_CLOSE(callable);
5301+
}
5302+
5303+
tier2 op(_POP_CALL_TWO, (callable, null, pop1, pop2 --)) {
5304+
PyStackRef_CLOSE(pop2);
5305+
PyStackRef_CLOSE(pop1);
5306+
(void)null; // Silence compiler warnings about unused variables
5307+
DEAD(null);
5308+
PyStackRef_CLOSE(callable);
5309+
}
5310+
5311+
tier2 op(_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) {
52915312
PyStackRef_CLOSE(pop);
52925313
value = PyStackRef_FromPyObjectBorrow(ptr);
52935314
}
52945315

5295-
tier2 pure op(_POP_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, pop1, pop2 -- value)) {
5316+
tier2 op(_POP_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, pop1, pop2 -- value)) {
52965317
PyStackRef_CLOSE(pop2);
52975318
PyStackRef_CLOSE(pop1);
52985319
value = PyStackRef_FromPyObjectBorrow(ptr);
52995320
}
53005321

5301-
tier2 pure op(_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null, pop1, pop2 -- value)) {
5322+
tier2 op(_POP_CALL_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null -- value)) {
5323+
(void)null; // Silence compiler warnings about unused variables
5324+
DEAD(null);
5325+
PyStackRef_CLOSE(callable);
5326+
value = PyStackRef_FromPyObjectBorrow(ptr);
5327+
}
5328+
5329+
tier2 op(_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null, pop -- value)) {
5330+
PyStackRef_CLOSE(pop);
5331+
(void)null; // Silence compiler warnings about unused variables
5332+
DEAD(null);
5333+
PyStackRef_CLOSE(callable);
5334+
value = PyStackRef_FromPyObjectBorrow(ptr);
5335+
}
5336+
5337+
tier2 op(_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null, pop1, pop2 -- value)) {
53025338
PyStackRef_CLOSE(pop2);
53035339
PyStackRef_CLOSE(pop1);
53045340
(void)null; // Silence compiler warnings about unused variables

0 commit comments

Comments
 (0)