Skip to content

Commit f12573f

Browse files
committed
Test optimize_load_fast as part of OptimizeCfg
1 parent ac8940b commit f12573f

File tree

5 files changed

+33
-117
lines changed

5 files changed

+33
-117
lines changed

Include/internal/pycore_flowgraph.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg(
4141
PyObject *consts,
4242
int nlocals);
4343

44-
// Export for '_testinternalcapi' shared extension
45-
PyAPI_FUNC(PyObject*) _PyCompile_OptimizeLoadFast(PyObject *instructions);
46-
4744
#ifdef __cplusplus
4845
}
4946
#endif

Lib/test/test_peepholer.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,9 +2435,9 @@ def test_list_to_tuple_get_iter(self):
24352435
]
24362436
expected_insts = [
24372437
("BUILD_LIST", 0, 1),
2438-
("LOAD_FAST", 0, 2),
2438+
("LOAD_FAST_BORROW", 0, 2),
24392439
("LIST_EXTEND", 1, 3),
2440-
("LOAD_FAST", 1, 4),
2440+
("LOAD_FAST_BORROW", 1, 4),
24412441
("LIST_EXTEND", 1, 5),
24422442
("NOP", None, 6), # ("CALL_INTRINSIC_1", INTRINSIC_LIST_TO_TUPLE, 6),
24432443
("GET_ITER", None, 7),
@@ -2463,15 +2463,24 @@ def test_list_to_tuple_get_iter_is_safe(self):
24632463
self.assertEqual(items, [])
24642464

24652465

2466-
@unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
2467-
class OptimizeLoadFastTestCase(CompilationStepTestCase):
2468-
def check(self, insts, expected_insts):
2469-
self.check_instructions(insts)
2470-
self.check_instructions(expected_insts)
2471-
seq = self.seq_from_insts(insts)
2472-
opt_insts = _testinternalcapi.optimize_load_fast(seq)
2473-
expected_insts = self.seq_from_insts(expected_insts).get_instructions()
2474-
self.assertInstructionsMatch(opt_insts, expected_insts)
2466+
class OptimizeLoadFastTestCase(DirectCfgOptimizerTests):
2467+
def make_bb(self, insts):
2468+
last_loc = insts[-1][2]
2469+
maxconst = 0
2470+
for op, arg, _ in insts:
2471+
if op == "LOAD_CONST":
2472+
maxconst = max(maxconst, arg)
2473+
consts = [None for _ in range(maxconst + 1)]
2474+
return insts + [
2475+
("LOAD_CONST", 0, last_loc + 1),
2476+
("RETURN_VALUE", None, last_loc + 2),
2477+
], consts
2478+
2479+
def check(self, insts, expected_insts, consts=None):
2480+
insts_bb, insts_consts = self.make_bb(insts)
2481+
expected_insts_bb, exp_consts = self.make_bb(expected_insts)
2482+
self.cfg_optimization_test(insts_bb, expected_insts_bb,
2483+
consts=insts_consts, expected_consts=exp_consts)
24752484

24762485
def test_optimized(self):
24772486
insts = [
@@ -2518,7 +2527,12 @@ def test_unoptimized_if_unconsumed(self):
25182527
("COPY", 1, 2),
25192528
("POP_TOP", None, 3),
25202529
]
2521-
self.check(insts, insts)
2530+
expected = [
2531+
("LOAD_FAST", 0, 1),
2532+
("NOP", None, 2),
2533+
("NOP", None, 3),
2534+
]
2535+
self.check(insts, expected)
25222536

25232537
def test_unoptimized_if_support_killed(self):
25242538
insts = [

Modules/_testinternalcapi.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -751,23 +751,6 @@ _testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions,
751751
return _PyCompile_OptimizeCfg(instructions, consts, nlocals);
752752
}
753753

754-
/*[clinic input]
755-
756-
_testinternalcapi.optimize_load_fast -> object
757-
758-
instructions: object
759-
760-
Optimize LOAD_FAST{_LOAD_FAST} instructions.
761-
[clinic start generated code]*/
762-
763-
static PyObject *
764-
_testinternalcapi_optimize_load_fast_impl(PyObject *module,
765-
PyObject *instructions)
766-
/*[clinic end generated code: output=6f975349c976d017 input=c59f3eac68308c01]*/
767-
{
768-
return _PyCompile_OptimizeLoadFast(instructions);
769-
}
770-
771754
static int
772755
get_nonnegative_int_from_dict(PyObject *dict, const char *key) {
773756
PyObject *obj = PyDict_GetItemString(dict, key);
@@ -2043,7 +2026,6 @@ static PyMethodDef module_functions[] = {
20432026
_TESTINTERNALCAPI_NEW_INSTRUCTION_SEQUENCE_METHODDEF
20442027
_TESTINTERNALCAPI_COMPILER_CODEGEN_METHODDEF
20452028
_TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF
2046-
_TESTINTERNALCAPI_OPTIMIZE_LOAD_FAST_METHODDEF
20472029
_TESTINTERNALCAPI_ASSEMBLE_CODE_OBJECT_METHODDEF
20482030
{"get_interp_settings", get_interp_settings, METH_VARARGS, NULL},
20492031
{"clear_extension", clear_extension, METH_VARARGS, NULL},

Modules/clinic/_testinternalcapi.c.h

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

Python/flowgraph.c

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,7 +2717,7 @@ load_fast_push_block(basicblock ***sp, basicblock *target,
27172717
*
27182718
* 2. Locals live until they are either killed by an instruction
27192719
* (e.g. STORE_FAST) or the frame is unwound. Any local that is overwritten
2720-
* via `f_locals` is added to a list owned by the frame object.
2720+
* via `f_locals` is added to a tuple owned by the frame object.
27212721
*
27222722
* To simplify the problem of detecting which supporting references in the
27232723
* frame are killed by instructions that overwrite locals, we only allow
@@ -3965,38 +3965,18 @@ _PyCompile_OptimizeCfg(PyObject *seq, PyObject *consts, int nlocals)
39653965
nparams, firstlineno) < 0) {
39663966
goto error;
39673967
}
3968-
res = cfg_to_instruction_sequence(g);
3969-
error:
3970-
Py_DECREF(const_cache);
3971-
_PyCfgBuilder_Free(g);
3972-
return res;
3973-
}
3974-
3975-
PyObject *
3976-
_PyCompile_OptimizeLoadFast(PyObject *seq)
3977-
{
3978-
if (!_PyInstructionSequence_Check(seq)) {
3979-
PyErr_SetString(PyExc_ValueError, "expected an instruction sequence");
3980-
return NULL;
3981-
}
3982-
3983-
cfg_builder *g =
3984-
_PyCfg_FromInstructionSequence((_PyInstructionSequence *)seq);
3985-
if (g == NULL) {
3986-
return NULL;
3987-
}
39883968

39893969
if (calculate_stackdepth(g) == ERROR) {
3990-
_PyCfgBuilder_Free(g);
3991-
return NULL;
3970+
goto error;
39923971
}
39933972

39943973
if (optimize_load_fast(g) != SUCCESS) {
3995-
_PyCfgBuilder_Free(g);
3996-
return NULL;
3974+
goto error;
39973975
}
39983976

3999-
PyObject *res = cfg_to_instruction_sequence(g);
3977+
res = cfg_to_instruction_sequence(g);
3978+
error:
3979+
Py_DECREF(const_cache);
40003980
_PyCfgBuilder_Free(g);
40013981
return res;
40023982
}

0 commit comments

Comments
 (0)