mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
GH-130415: Improve the JIT's unneeded uop removal pass (GH-132333)
This commit is contained in:
parent
9be3645688
commit
4f7f72ce34
5 changed files with 46 additions and 18 deletions
|
@ -1283,7 +1283,7 @@ class TestUopsOptimization(unittest.TestCase):
|
|||
load_attr_top = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", 0, call)
|
||||
load_attr_bottom = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", call)
|
||||
self.assertEqual(opnames[:load_attr_top].count("_GUARD_TYPE_VERSION"), 1)
|
||||
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 1)
|
||||
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 2)
|
||||
|
||||
def test_guard_type_version_removed_escaping(self):
|
||||
|
||||
|
@ -1306,7 +1306,7 @@ class TestUopsOptimization(unittest.TestCase):
|
|||
load_attr_top = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", 0, call)
|
||||
load_attr_bottom = opnames.index("_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", call)
|
||||
self.assertEqual(opnames[:load_attr_top].count("_GUARD_TYPE_VERSION"), 1)
|
||||
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 1)
|
||||
self.assertEqual(opnames[call:load_attr_bottom].count("_CHECK_VALIDITY"), 2)
|
||||
|
||||
def test_guard_type_version_executor_invalidated(self):
|
||||
"""
|
||||
|
@ -1601,7 +1601,7 @@ class TestUopsOptimization(unittest.TestCase):
|
|||
self.assertIsNotNone(ex)
|
||||
uops = get_opnames(ex)
|
||||
self.assertNotIn("_COMPARE_OP_INT", uops)
|
||||
self.assertIn("_POP_TWO_LOAD_CONST_INLINE_BORROW", uops)
|
||||
self.assertNotIn("_POP_TWO_LOAD_CONST_INLINE_BORROW", uops)
|
||||
|
||||
def test_to_bool_bool_contains_op_set(self):
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Improve the JIT's ability to remove unused constant and local variable
|
||||
loads, and fix an issue where deallocating unused values could cause JIT
|
||||
code to crash or behave incorrectly.
|
|
@ -555,28 +555,47 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
|
|||
}
|
||||
break;
|
||||
case _POP_TOP:
|
||||
case _POP_TOP_LOAD_CONST_INLINE:
|
||||
case _POP_TOP_LOAD_CONST_INLINE_BORROW:
|
||||
case _POP_TWO_LOAD_CONST_INLINE_BORROW:
|
||||
optimize_pop_top_again:
|
||||
{
|
||||
_PyUOpInstruction *last = &buffer[pc-1];
|
||||
while (last->opcode == _NOP) {
|
||||
last--;
|
||||
}
|
||||
if (last->opcode == _LOAD_CONST_INLINE ||
|
||||
last->opcode == _LOAD_CONST_INLINE_BORROW ||
|
||||
last->opcode == _LOAD_FAST ||
|
||||
last->opcode == _LOAD_FAST_BORROW ||
|
||||
last->opcode == _COPY
|
||||
) {
|
||||
last->opcode = _NOP;
|
||||
buffer[pc].opcode = _NOP;
|
||||
switch (last->opcode) {
|
||||
case _POP_TWO_LOAD_CONST_INLINE_BORROW:
|
||||
last->opcode = _POP_TOP;
|
||||
break;
|
||||
case _POP_TOP_LOAD_CONST_INLINE:
|
||||
case _POP_TOP_LOAD_CONST_INLINE_BORROW:
|
||||
last->opcode = _NOP;
|
||||
goto optimize_pop_top_again;
|
||||
case _COPY:
|
||||
case _LOAD_CONST_INLINE:
|
||||
case _LOAD_CONST_INLINE_BORROW:
|
||||
case _LOAD_FAST:
|
||||
case _LOAD_FAST_BORROW:
|
||||
case _LOAD_SMALL_INT:
|
||||
last->opcode = _NOP;
|
||||
if (opcode == _POP_TOP) {
|
||||
opcode = buffer[pc].opcode = _NOP;
|
||||
}
|
||||
else if (opcode == _POP_TOP_LOAD_CONST_INLINE) {
|
||||
opcode = buffer[pc].opcode = _LOAD_CONST_INLINE;
|
||||
}
|
||||
else if (opcode == _POP_TOP_LOAD_CONST_INLINE_BORROW) {
|
||||
opcode = buffer[pc].opcode = _LOAD_CONST_INLINE_BORROW;
|
||||
}
|
||||
else {
|
||||
assert(opcode == _POP_TWO_LOAD_CONST_INLINE_BORROW);
|
||||
opcode = buffer[pc].opcode = _POP_TOP_LOAD_CONST_INLINE_BORROW;
|
||||
goto optimize_pop_top_again;
|
||||
}
|
||||
}
|
||||
if (last->opcode == _REPLACE_WITH_TRUE) {
|
||||
last->opcode = _NOP;
|
||||
}
|
||||
break;
|
||||
_Py_FALLTHROUGH;
|
||||
}
|
||||
case _JUMP_TO_TOP:
|
||||
case _EXIT_TRACE:
|
||||
return pc + 1;
|
||||
default:
|
||||
{
|
||||
/* _PUSH_FRAME doesn't escape or error, but it
|
||||
|
@ -591,7 +610,11 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
|
|||
buffer[last_set_ip].opcode = _SET_IP;
|
||||
last_set_ip = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case _JUMP_TO_TOP:
|
||||
case _EXIT_TRACE:
|
||||
return pc + 1;
|
||||
}
|
||||
}
|
||||
Py_UNREACHABLE();
|
||||
|
|
|
@ -912,6 +912,7 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_REPLACE_WITH_TRUE, (value -- res)) {
|
||||
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_True);
|
||||
res = sym_new_const(ctx, Py_True);
|
||||
}
|
||||
|
||||
|
|
1
Python/optimizer_cases.c.h
generated
1
Python/optimizer_cases.c.h
generated
|
@ -274,6 +274,7 @@
|
|||
|
||||
case _REPLACE_WITH_TRUE: {
|
||||
JitOptSymbol *res;
|
||||
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)Py_True);
|
||||
res = sym_new_const(ctx, Py_True);
|
||||
stack_pointer[-1] = res;
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue