[Python-checkins] Issue #11244: The peephole optimizer is now able to constant-fold (original) (raw)

antoine.pitrou python-checkins at python.org
Fri Mar 11 17:27:57 CET 2011


http://hg.python.org/cpython/rev/14205d0fee45 changeset: 68375:14205d0fee45 user: Antoine Pitrou <solipsis at pitrou.net> date: Fri Mar 11 17:27:02 2011 +0100 summary: Issue #11244: The peephole optimizer is now able to constant-fold arbitrarily complex expressions. This also fixes a 3.2 regression where operations involving negative numbers were not constant-folded.

files: Lib/test/test_peepholer.py Misc/NEWS Python/peephole.c

diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -8,8 +8,10 @@ f = StringIO() tmp = sys.stdout sys.stdout = f - dis.dis(func) - sys.stdout = tmp + try: + dis.dis(func) + finally: + sys.stdout = tmp result = f.getvalue() f.close() return result @@ -99,6 +101,12 @@ self.assertIn(elem, asm) self.assertNotIn('BUILD_TUPLE', asm) + # Long tuples should be folded too. + asm = dis_single(repr(tuple(range(10000)))) + # One LOAD_CONST for the tuple, one for the None return value + self.assertEqual(asm.count('LOAD_CONST'), 2) + self.assertNotIn('BUILD_TUPLE', asm) + # Bug 1053819: Tuple of constants misidentified when presented with: # . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . . # The following would segfault upon compilation @@ -267,6 +275,25 @@ asm = disassemble(f) self.assertNotIn('BINARY_ADD', asm) + def test_constant_folding(self): + # Issue #11244: aggressive constant folding. + exprs = [ + "3 * -5", + "-3 * 5", + "2 * (3 * 4)", + "(2 * 3) * 4", + "(-1, 2, 3)", + "(1, -2, 3)", + "(1, 2, -3)", + "(1, 2, -3) * 6", + "lambda x: x in {(3 * -5) + (-1 - 6), (1, -2, 3) * 2, None}", + ] + for e in exprs: + asm = dis_single(e) + self.assertNotIn('UNARY_', asm, e) + self.assertNotIn('BINARY_', asm, e) + self.assertNotIn('BUILD_', asm, e) + def test_main(verbose=None): import sys diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins

+- Issue #11244: The peephole optimizer is now able to constant-fold

diff --git a/Python/peephole.c b/Python/peephole.c --- a/Python/peephole.c +++ b/Python/peephole.c @@ -23,6 +23,64 @@ #define ISBASICBLOCK(blocks, start, bytes)
(blocks[start]==blocks[start+bytes-1])

{ PyObject *newconst, *constant;

@@ -51,16 +106,14 @@ return 0; len_consts = PyList_GET_SIZE(consts); for (i=0 ; i<n ; i++) {

@@ -77,9 +130,8 @@

 /* Write NOPs over old LOAD_CONSTS and
    add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */

@@ -87,14 +139,14 @@ with LOAD_CONST binop(c1,c2) The consts table must still be in list form so that the new constant can be appended.

@@ -180,16 +230,15 @@ Py_DECREF(newconst);

 /* Write NOP NOP NOP NOP LOAD_CONST newconst */

static int -fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts) +fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts, PyObject *v) {

@@ -198,7 +247,6 @@ assert(codestr[0] == LOAD_CONST);

 /* Create new constant */

@@ -340,7 +388,11 @@ unsigned char *lineno; int *addrmap = NULL; int new_line, cum_orig_line, last_line, tabsiz;

@@ -386,12 +438,16 @@ goto exitError; assert(PyList_Check(consts));

@@ -432,21 +488,21 @@ goto exitError; else if (h == 0) continue;

@@ -458,19 +514,23 @@ case BUILD_LIST: case BUILD_SET: j = GETARG(codestr, i);

@@ -482,10 +542,12 @@ } else if (j == 2) { codestr[i] = ROT_TWO; memset(codestr+i+1, NOP, 5);

@@ -504,12 +566,18 @@ case BINARY_AND: case BINARY_XOR: case BINARY_OR:

@@ -518,12 +586,15 @@ case UNARY_NEGATIVE: case UNARY_INVERT: case UNARY_POSITIVE:

@@ -680,6 +751,7 @@ assert(h + nops == codelen);

 code = PyBytes_FromStringAndSize((char *)codestr, h);

exitUnchanged:

-- Repository URL: http://hg.python.org/cpython



More information about the Python-checkins mailing list