[Python-checkins] r62827 - in python/branches/tlee-ast-optimize: Lib/test/test_optimizer.py Python/optimize.c Python/peephole.c

thomas.lee python-checkins at python.org
Wed May 7 17:11:06 CEST 2008


Author: thomas.lee
Date: Wed May  7 17:11:06 2008
New Revision: 62827

Log:
Refactored a little bit of code living in switch statements. Added constant tuple folding.

Modified:
   python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py
   python/branches/tlee-ast-optimize/Python/optimize.c
   python/branches/tlee-ast-optimize/Python/peephole.c

Modified: python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py	(original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py	Wed May  7 17:11:06 2008
@@ -194,6 +194,34 @@
         self.assertEqual(_ast.Return, ast.body[0].body[0].__class__)
         self.assertEqual(None, ast.body[0].body[0].value)
 
+    def test_tuple_of_constants(self):
+        tests = [
+            (1, 2, 3),
+            ("a", "b", "c"),
+            (1+3, 5, 8-2),
+            ((1, 2), (3, 4), 5)
+        ]
+
+        for obj in tests:
+            code = repr(obj)
+
+            ast = self.compileast(code)
+            self.assertEqual(_ast.Expr, ast.body[0].__class__)
+            self.assertEqual(_ast.Const, ast.body[0].value.__class__)
+            self.assertEqual(tuple, ast.body[0].value.value.__class__)
+            self.assertEqual(obj, ast.body[0].value.value)
+
+    def test_named_constants(self):
+        tests = [None, True, False]
+
+        for obj in tests:
+            code = repr(obj)
+
+            ast = self.compileast(code)
+            self.assertEqual(_ast.Expr, ast.body[0].__class__)
+            self.assertEqual(_ast.Const, ast.body[0].value.__class__)
+            self.assertEqual(obj, ast.body[0].value.value)
+
 def test_main():
     test_support.run_unittest(AstOptimizerTest)
 

Modified: python/branches/tlee-ast-optimize/Python/optimize.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/optimize.c	(original)
+++ python/branches/tlee-ast-optimize/Python/optimize.c	Wed May  7 17:11:06 2008
@@ -41,6 +41,9 @@
     return NULL;
 }
 
+/**
+ * Construct an expr_ty instance from the given constant PyObject value.
+ */
 static expr_ty
 _expr_from_object(PyObject* object, int lineno, int col_offset, PyArena* arena)
 {
@@ -54,7 +57,10 @@
         Py_INCREF(object);
         expr = Num(object, lineno, col_offset, arena);
     }
-    else if (object == Py_None || object == Py_True || object == Py_False) {
+    else if (object == Py_None ||
+                object == Py_True ||
+                object == Py_False ||
+                PyTuple_Check(object)) {
         Py_INCREF(object);
         expr = Const(object, lineno, col_offset, arena);
     }
@@ -76,6 +82,53 @@
     return expr;
 }
 
+static int
+_is_sequence_of_constants(asdl_seq* seq)
+{
+    int i;
+    int length = asdl_seq_LEN(seq);
+    for (i = 0; i < length; i++) {
+        PyObject* value;
+        expr_ty expr;
+        
+        expr = (expr_ty)asdl_seq_GET(seq, i);
+        value = _expr_constant_value(expr);
+        if (value == NULL)
+            return 0;
+    }
+    return 1;
+}
+
+/**
+ * Build a tuple of constants from an expression sequence.
+ */
+static PyObject*
+_build_tuple_of_constants(asdl_seq* seq, PyArena* arena)
+{
+    PyObject* result;
+    int i;
+    int length = asdl_seq_LEN(seq);
+
+    result = PyTuple_New(length);
+    if (result == NULL)
+        return NULL;
+
+    if (PyArena_AddPyObject(arena, result) == -1) {
+        Py_DECREF(result);
+        return NULL;
+    }
+
+    for (i = 0; i < length; i++) {
+        PyObject* value;
+        expr_ty expr = (expr_ty)asdl_seq_GET(seq, i);
+        value = _expr_constant_value(expr);
+        Py_INCREF(value);
+        PyTuple_SetItem(result, i, value);
+    }
+
+    return result;
+}
+
 /**
  * Optimize a sequence of expressions.
  */
@@ -684,6 +737,52 @@
 }
 
 static int
+optimize_tuple(expr_ty* expr_ptr, PyArena* arena)
+{
+    expr_ty expr = *expr_ptr;
+    if (!optimize_expr_seq(&expr->v.Tuple.elts, arena))
+        return 0;
+
+    if (_is_sequence_of_constants(expr->v.Tuple.elts)) {
+        PyObject* tuple = _build_tuple_of_constants(expr->v.Tuple.elts, arena);
+        if (tuple == NULL)
+            return 0;
+        *expr_ptr = Const(tuple, expr->lineno, expr->col_offset, arena);
+        if (*expr_ptr == NULL)
+            return 0;
+    }
+
+    return 1;
+}
+
+static int
+optimize_name(expr_ty* expr_ptr, PyArena* arena)
+{
+    expr_ty expr = *expr_ptr;
+    const char* id = PyString_AS_STRING(expr->v.Name.id);
+    PyObject* constvalue = NULL;
+
+    if (strcmp(id, "None") == 0) {
+        Py_INCREF(Py_None);
+        constvalue = Py_None;
+    }
+    else if (strcmp(id, "True") == 0) {
+        Py_INCREF(Py_True);
+        constvalue = Py_True;
+    }
+    else if (strcmp(id, "False") == 0) {
+        Py_INCREF(Py_False);
+        constvalue = Py_False;
+    }
+
+    if (constvalue != NULL)
+        *expr_ptr = Const(constvalue, expr->lineno,
+                            expr->col_offset, arena);
+
+    return 1;
+}
+
+static int
 optimize_expr(expr_ty* expr_ptr, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
@@ -750,32 +849,11 @@
             }
         case Tuple_kind:
             {
-                return optimize_expr_seq(&expr->v.Tuple.elts, arena);
+                return optimize_tuple(expr_ptr, arena);
             }
         case Name_kind:
             {
-                const char* id = PyString_AS_STRING(expr->v.Name.id);
-                PyObject* constvalue = NULL;
-                /* XXX: dunno if we need to incref these or if Const()
-                 * takes care of that */
-                if (strcmp(id, "None") == 0) {
-                    Py_INCREF(Py_None);
-                    constvalue = Py_None;
-                }
-                else if (strcmp(id, "True") == 0) {
-                    Py_INCREF(Py_True);
-                    constvalue = Py_True;
-                }
-                else if (strcmp(id, "False") == 0) {
-                    Py_INCREF(Py_False);
-                    constvalue = Py_False;
-                }
-
-                if (constvalue != NULL)
-                    *expr_ptr = Const(constvalue, expr->lineno,
-                                        expr->col_offset, arena);
-
-                return 1;
+                return optimize_name(expr_ptr, arena);
             }
         case Num_kind:
         case Str_kind:

Modified: python/branches/tlee-ast-optimize/Python/peephole.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/peephole.c	(original)
+++ python/branches/tlee-ast-optimize/Python/peephole.c	Wed May  7 17:11:06 2008
@@ -205,7 +205,6 @@
 				   Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
 				   Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
 				   Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
-			case BUILD_TUPLE:
 			case BUILD_LIST:
 				j = GETARG(codestr, i);
 				h = i - 3 * j;


More information about the Python-checkins mailing list