mirror of https://github.com/python/cpython
gh-120367: fix removal of redundant NOPs and jumps after reordering hot-cold blocks (#120425)
This commit is contained in:
parent
c2d5df5787
commit
21866c8ed2
|
@ -502,6 +502,33 @@ class TestSpecifics(unittest.TestCase):
|
||||||
with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"):
|
with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"):
|
||||||
compile(ast.fix_missing_locations(m), "<file>", "exec")
|
compile(ast.fix_missing_locations(m), "<file>", "exec")
|
||||||
|
|
||||||
|
def test_compile_redundant_jumps_and_nops_after_moving_cold_blocks(self):
|
||||||
|
# See gh-120367
|
||||||
|
code=textwrap.dedent("""
|
||||||
|
try:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
match name_2:
|
||||||
|
case b'':
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
something
|
||||||
|
""")
|
||||||
|
|
||||||
|
tree = ast.parse(code)
|
||||||
|
|
||||||
|
# make all instructions locations the same to create redundancies
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
if hasattr(node,"lineno"):
|
||||||
|
del node.lineno
|
||||||
|
del node.end_lineno
|
||||||
|
del node.col_offset
|
||||||
|
del node.end_col_offset
|
||||||
|
|
||||||
|
compile(ast.fix_missing_locations(tree), "<file>", "exec")
|
||||||
|
|
||||||
def test_compile_ast(self):
|
def test_compile_ast(self):
|
||||||
fname = __file__
|
fname = __file__
|
||||||
if fname.lower().endswith('pyc'):
|
if fname.lower().endswith('pyc'):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crash in compiler on code with redundant NOPs and JUMPs which show up
|
||||||
|
after exception handlers are moved to the end of the code.
|
|
@ -1857,6 +1857,22 @@ error:
|
||||||
|
|
||||||
static int resolve_line_numbers(cfg_builder *g, int firstlineno);
|
static int resolve_line_numbers(cfg_builder *g, int firstlineno);
|
||||||
|
|
||||||
|
static int
|
||||||
|
remove_redundant_nops_and_jumps(cfg_builder *g)
|
||||||
|
{
|
||||||
|
int removed_nops, removed_jumps;
|
||||||
|
do {
|
||||||
|
/* Convergence is guaranteed because the number of
|
||||||
|
* redundant jumps and nops only decreases.
|
||||||
|
*/
|
||||||
|
removed_nops = remove_redundant_nops(g);
|
||||||
|
RETURN_IF_ERROR(removed_nops);
|
||||||
|
removed_jumps = remove_redundant_jumps(g);
|
||||||
|
RETURN_IF_ERROR(removed_jumps);
|
||||||
|
} while(removed_nops + removed_jumps > 0);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform optimizations on a control flow graph.
|
/* Perform optimizations on a control flow graph.
|
||||||
The consts object should still be in list form to allow new constants
|
The consts object should still be in list form to allow new constants
|
||||||
to be appended.
|
to be appended.
|
||||||
|
@ -1878,17 +1894,7 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache, int firstl
|
||||||
}
|
}
|
||||||
RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock));
|
RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock));
|
||||||
RETURN_IF_ERROR(remove_unreachable(g->g_entryblock));
|
RETURN_IF_ERROR(remove_unreachable(g->g_entryblock));
|
||||||
|
RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g));
|
||||||
int removed_nops, removed_jumps;
|
|
||||||
do {
|
|
||||||
/* Convergence is guaranteed because the number of
|
|
||||||
* redundant jumps and nops only decreases.
|
|
||||||
*/
|
|
||||||
removed_nops = remove_redundant_nops(g);
|
|
||||||
RETURN_IF_ERROR(removed_nops);
|
|
||||||
removed_jumps = remove_redundant_jumps(g);
|
|
||||||
RETURN_IF_ERROR(removed_jumps);
|
|
||||||
} while(removed_nops + removed_jumps > 0);
|
|
||||||
assert(no_redundant_jumps(g));
|
assert(no_redundant_jumps(g));
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2358,7 +2364,7 @@ push_cold_blocks_to_end(cfg_builder *g) {
|
||||||
b->b_next = cold_blocks;
|
b->b_next = cold_blocks;
|
||||||
|
|
||||||
if (cold_blocks != NULL) {
|
if (cold_blocks != NULL) {
|
||||||
RETURN_IF_ERROR(remove_redundant_jumps(g));
|
RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g));
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue