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

thomas.lee python-checkins at python.org
Sun Jun 8 10:46:48 CEST 2008


Author: thomas.lee
Date: Sun Jun  8 10:46:48 2008
New Revision: 64034

Log:
Finalize symtable-generation-before-compile. STEs are now available to the AST optimizer. Added an optimization for lists used as constants in for loops in the AST optimizer. Removed the corresponding code from the peepholer.

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	Sun Jun  8 10:46:48 2008
@@ -194,6 +194,17 @@
         self.assertEqual(_ast.Return, ast.body[0].body[0].__class__)
         self.assertEqual(None, ast.body[0].body[0].value)
 
+    def test_generators_work_even_if_yields_are_optimized_away(self):
+        code = """
+def mygen():
+    return
+    yield 5
+"""
+
+        ast = self.compileast(code)
+        self.assertEqual(_ast.Return, ast.body[0].body[0].__class__)
+        self.assertEqual(_ast.Pass, ast.body[0].body[1].__class__)
+
     def test_tuple_of_constants(self):
         tests = [
             (1, 2, 3),
@@ -211,6 +222,15 @@
             self.assertEqual(tuple, ast.body[0].value.value.__class__)
             self.assertEqual(obj, ast.body[0].value.value)
 
+    def test_folding_of_constant_list_in_for_loop(self):
+        code = """
+for i in [1, 2, 3]:
+    print i
+"""
+        ast = self.compileast(code)
+        self.assertEqual(_ast.Const, ast.body[0].iter.__class__)
+        self.assertEqual((1, 2, 3), ast.body[0].iter.value)
+
     def test_named_constants(self):
         tests = [None, True, False]
 

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	Sun Jun  8 10:46:48 2008
@@ -2,16 +2,24 @@
 #include "Python-ast.h"
 #include "pyarena.h"
 #include "pyerrors.h"
+#include "symtable.h"
 #include "node.h"
 #include "ast.h"
 
-static int optimize_expr(expr_ty* expr_ptr, PyArena* arena);
-static int optimize_stmt(stmt_ty* stmt_ptr, PyArena* arena);
-static int optimize_comprehension(comprehension_ty* comp_ptr, PyArena* arena);
-static int optimize_excepthandler(excepthandler_ty* exc_ptr, PyArena* arena);
-static int optimize_keyword(keyword_ty* kwd_ptr, PyArena* arena);
-static int optimize_arguments(arguments_ty* args_ptr, PyArena* arena);
-static int optimize_slice(slice_ty* slice_ptr, PyArena* arena);
+static int optimize_expr(expr_ty* expr_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_stmt(stmt_ty* stmt_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_comprehension(comprehension_ty* comp_ptr,
+                            PySTEntryObject* ste, PyArena* arena);
+static int optimize_excepthandler(excepthandler_ty* exc_ptr,
+                            PySTEntryObject* ste, PyArena* arena);
+static int optimize_keyword(keyword_ty* kwd_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_arguments(arguments_ty* args_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
+static int optimize_slice(slice_ty* slice_ptr, PySTEntryObject* ste,
+                            PyArena* arena);
 
 /**
  * Determine the constant value of a given expression. It's assumed that
@@ -133,12 +141,12 @@
  * Optimize a sequence of expressions.
  */
 static int
-optimize_expr_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_expr_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++)
-        if (!optimize_expr((expr_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_expr((expr_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
     return 1;
 }
@@ -199,13 +207,13 @@
  * Optimize a sequence of statements.
  */
 static int
-optimize_stmt_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_stmt_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++) {
         stmt_ty stmt = asdl_seq_GET(seq, n);
-        if (!optimize_stmt((stmt_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_stmt((stmt_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
 
         if (stmt->kind == If_kind) {
@@ -243,57 +251,59 @@
 }
 
 static int
-optimize_comprehension_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_comprehension_seq(asdl_seq** seq_ptr, PySTEntryObject* ste,
+                            PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++) {
         comprehension_ty* comp;
         comp = (comprehension_ty*)&asdl_seq_GET(seq, n);
-        if (!optimize_comprehension(comp, arena))
+        if (!optimize_comprehension(comp, ste, arena))
             return 0;
     }
     return 1;
 }
 
 static int
-optimize_excepthandler_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_excepthandler_seq(asdl_seq** seq_ptr, PySTEntryObject* ste,
+                            PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++) {
         excepthandler_ty* excepthandler;
         excepthandler = (excepthandler_ty*)&asdl_seq_GET(seq, n);
-        if (!optimize_excepthandler(excepthandler, arena))
+        if (!optimize_excepthandler(excepthandler, ste, arena))
             return 0;
     }
     return 1;
 }
 
 static int
-optimize_keyword_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_keyword_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++)
-        if (!optimize_keyword((keyword_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_keyword((keyword_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_slice_seq(asdl_seq** seq_ptr, PyArena* arena)
+optimize_slice_seq(asdl_seq** seq_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     int n;
     asdl_seq* seq = *seq_ptr;
     for (n = 0; n < asdl_seq_LEN(seq); n++)
-        if (!optimize_slice((slice_ty*)&asdl_seq_GET(seq, n), arena))
+        if (!optimize_slice((slice_ty*)&asdl_seq_GET(seq, n), ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_mod(mod_ty* mod_ptr, PyArena* arena)
+optimize_mod(mod_ty* mod_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     asdl_seq** body;
     mod_ty mod = *mod_ptr;
@@ -316,7 +326,7 @@
             }
         case Expression_kind:
             {
-                return optimize_expr(&mod->v.Expression.body, arena);
+                return optimize_expr(&mod->v.Expression.body, ste, arena);
             }
         default:
             PyErr_Format(PyExc_ValueError, "unknown mod_ty kind: %d",
@@ -324,28 +334,28 @@
             return 0;
     };
 
-    return optimize_stmt_seq(body, arena);
+    return optimize_stmt_seq(body, ste, arena);
 }
 
 static int
-optimize_bool_op(expr_ty* expr_ptr, PyArena* arena)
+optimize_bool_op(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr_seq(&expr->v.BoolOp.values, arena))
+    if (!optimize_expr_seq(&expr->v.BoolOp.values, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_bin_op(expr_ty* expr_ptr, PyArena* arena)
+optimize_bin_op(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     PyObject* left;
     PyObject* right;
     expr_ty expr = *expr_ptr;
 
-    if (!optimize_expr(&expr->v.BinOp.left, arena))
+    if (!optimize_expr(&expr->v.BinOp.left, ste, arena))
         return 0;
-    if (!optimize_expr(&expr->v.BinOp.right, arena))
+    if (!optimize_expr(&expr->v.BinOp.right, ste, arena))
         return 0;
 
     /* 
@@ -472,11 +482,11 @@
 }
 
 static int
-optimize_unary_op(expr_ty* expr_ptr, PyArena* arena)
+optimize_unary_op(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     PyObject* operand;
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.UnaryOp.operand, arena))
+    if (!optimize_expr(&expr->v.UnaryOp.operand, ste, arena))
         return 0;
     operand = _expr_constant_value(expr->v.UnaryOp.operand);
     if (operand != NULL) {
@@ -537,76 +547,83 @@
 }
 
 static int
-optimize_lambda(expr_ty* expr_ptr, PyArena* arena)
+optimize_lambda(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Lambda.body, arena))
+    if (!optimize_expr(&expr->v.Lambda.body, ste, arena))
         return 0;
     return 1;
 }
 
-static int optimize_if_exp(expr_ty* expr_ptr, PyArena* arena) {
+static int
+optimize_if_exp(expr_ty* expr_ptr, PySTEntryObject* ste,
+                            PyArena* arena)
+{
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.IfExp.test, arena))
+    if (!optimize_expr(&expr->v.IfExp.test, ste, arena))
         return 0;
-    if (!optimize_expr(&expr->v.IfExp.body, arena))
+    if (!optimize_expr(&expr->v.IfExp.body, ste, arena))
         return 0;
-    if (!optimize_expr(&expr->v.IfExp.orelse, arena))
+    if (!optimize_expr(&expr->v.IfExp.orelse, ste, arena))
         return 0;
     return 1;
 }
 
-static int optimize_dict(expr_ty* expr_ptr, PyArena* arena) {
+static int
+optimize_dict(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
+{
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr_seq(&expr->v.Dict.keys, arena))
+    if (!optimize_expr_seq(&expr->v.Dict.keys, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&expr->v.Dict.values, arena))
+    if (!optimize_expr_seq(&expr->v.Dict.values, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_comprehension(comprehension_ty* comp_ptr, PyArena* arena)
+optimize_comprehension(comprehension_ty* comp_ptr, PySTEntryObject* ste,
+                        PyArena* arena)
 {
     comprehension_ty comp = *comp_ptr;
-    if (!optimize_expr(&comp->target, arena))
+    if (!optimize_expr(&comp->target, ste, arena))
         return 0;
-    if (!optimize_expr(&comp->iter, arena))
+    if (!optimize_expr(&comp->iter, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&comp->ifs, arena))
+    if (!optimize_expr_seq(&comp->ifs, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_list_comp(expr_ty* expr_ptr, PyArena* arena)
+optimize_list_comp(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.ListComp.elt, arena))
+    if (!optimize_expr(&expr->v.ListComp.elt, ste, arena))
         return 0;
-    if (!optimize_comprehension_seq(&expr->v.ListComp.generators, arena))
+    if (!optimize_comprehension_seq(&expr->v.ListComp.generators, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_generator_exp(expr_ty* expr_ptr, PyArena* arena)
+optimize_generator_exp(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.GeneratorExp.elt, arena))
+    if (!optimize_expr(&expr->v.GeneratorExp.elt, ste, arena))
         return 0;
-    if (!optimize_comprehension_seq(&expr->v.GeneratorExp.generators, arena))
+    if (!optimize_comprehension_seq(&expr->v.GeneratorExp.generators, ste,
+                                    arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_yield(expr_ty* expr_ptr, PyArena* arena)
+optimize_yield(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
     if (expr->v.Yield.value != NULL) {
         expr_ty value;
-        if (!optimize_expr(&expr->v.Yield.value, arena))
+        if (!optimize_expr(&expr->v.Yield.value, ste, arena))
             return 0;
         value = expr->v.Yield.value;
         if (value->kind == Const_kind && value->v.Const.value == Py_None)
@@ -616,100 +633,101 @@
 }
 
 static int
-optimize_compare(expr_ty* expr_ptr, PyArena* arena)
+optimize_compare(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Compare.left, arena))
+    if (!optimize_expr(&expr->v.Compare.left, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&expr->v.Compare.comparators, arena))
+    if (!optimize_expr_seq(&expr->v.Compare.comparators, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_keyword(keyword_ty* keyword_ptr, PyArena* arena)
+optimize_keyword(keyword_ty* keyword_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     keyword_ty keyword = *keyword_ptr;
-    if (!optimize_expr(&keyword->value, arena))
+    if (!optimize_expr(&keyword->value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_arguments(arguments_ty* args_ptr, PyArena* arena)
+optimize_arguments(arguments_ty* args_ptr, PySTEntryObject* ste,
+                    PyArena* arena)
 {
     arguments_ty args = *args_ptr;
-    if (!optimize_expr_seq(&args->args, arena))
+    if (!optimize_expr_seq(&args->args, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&args->defaults, arena))
+    if (!optimize_expr_seq(&args->defaults, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_call(expr_ty* expr_ptr, PyArena* arena)
+optimize_call(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Call.func, arena))
+    if (!optimize_expr(&expr->v.Call.func, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&expr->v.Call.args, arena))
+    if (!optimize_expr_seq(&expr->v.Call.args, ste, arena))
         return 0;
-    if (!optimize_keyword_seq(&expr->v.Call.keywords, arena))
+    if (!optimize_keyword_seq(&expr->v.Call.keywords, ste, arena))
         return 0;
     if (expr->v.Call.starargs != NULL)
-        if (!optimize_expr(&expr->v.Call.starargs, arena))
+        if (!optimize_expr(&expr->v.Call.starargs, ste, arena))
             return 0;
     if (expr->v.Call.kwargs != NULL)
-        if (!optimize_expr(&expr->v.Call.kwargs, arena))
+        if (!optimize_expr(&expr->v.Call.kwargs, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_repr(expr_ty* expr_ptr, PyArena* arena)
+optimize_repr(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Repr.value, arena))
+    if (!optimize_expr(&expr->v.Repr.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_attribute(expr_ty* expr_ptr, PyArena* arena)
+optimize_attribute(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Attribute.value, arena))
+    if (!optimize_expr(&expr->v.Attribute.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_slice(slice_ty* slice_ptr, PyArena* arena)
+optimize_slice(slice_ty* slice_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     slice_ty slice = *slice_ptr;
     switch (slice->kind) {
         case Slice_kind:
             {
                 if (slice->v.Slice.lower != NULL)
-                    if (!optimize_expr(&slice->v.Slice.lower, arena))
+                    if (!optimize_expr(&slice->v.Slice.lower, ste, arena))
                         return 0;
                 if (slice->v.Slice.upper != NULL)
-                    if (!optimize_expr(&slice->v.Slice.upper, arena))
+                    if (!optimize_expr(&slice->v.Slice.upper, ste, arena))
                         return 0;
                 if (slice->v.Slice.step != NULL)
-                    if (!optimize_expr(&slice->v.Slice.step, arena))
+                    if (!optimize_expr(&slice->v.Slice.step, ste, arena))
                         return 0;
                 break;
             }
         case ExtSlice_kind:
             {
-                if (!optimize_slice_seq(&slice->v.ExtSlice.dims, arena))
+                if (!optimize_slice_seq(&slice->v.ExtSlice.dims, ste, arena))
                     return 0;
                 break;
             }
         case Index_kind:
             {
-                if (!optimize_expr(&slice->v.Index.value, arena))
+                if (!optimize_expr(&slice->v.Index.value, ste, arena))
                     return 0;
                 break;
             }
@@ -726,21 +744,21 @@
 }
 
 static int
-optimize_subscript(expr_ty* expr_ptr, PyArena* arena)
+optimize_subscript(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr(&expr->v.Subscript.value, arena))
+    if (!optimize_expr(&expr->v.Subscript.value, ste, arena))
         return 0;
-    if (!optimize_slice(&expr->v.Subscript.slice, arena))
+    if (!optimize_slice(&expr->v.Subscript.slice, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_tuple(expr_ty* expr_ptr, PyArena* arena)
+optimize_tuple(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
-    if (!optimize_expr_seq(&expr->v.Tuple.elts, arena))
+    if (!optimize_expr_seq(&expr->v.Tuple.elts, ste, arena))
         return 0;
 
     if (_is_sequence_of_constants(expr->v.Tuple.elts)) {
@@ -756,7 +774,7 @@
 }
 
 static int
-optimize_name(expr_ty* expr_ptr, PyArena* arena)
+optimize_name(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
     const char* id = PyString_AS_STRING(expr->v.Name.id);
@@ -783,77 +801,77 @@
 }
 
 static int
-optimize_expr(expr_ty* expr_ptr, PyArena* arena)
+optimize_expr(expr_ty* expr_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     expr_ty expr = *expr_ptr;
     switch (expr->kind) {
         case BoolOp_kind:
             {
-                return optimize_bool_op(expr_ptr, arena);
+                return optimize_bool_op(expr_ptr, ste, arena);
             }
         case BinOp_kind:
             {
-                return optimize_bin_op(expr_ptr, arena);
+                return optimize_bin_op(expr_ptr, ste, arena);
             }
         case UnaryOp_kind:
             {
-                return optimize_unary_op(expr_ptr, arena);
+                return optimize_unary_op(expr_ptr, ste, arena);
             }
         case Lambda_kind:
             {
-                return optimize_lambda(expr_ptr, arena);
+                return optimize_lambda(expr_ptr, ste, arena);
             }
         case IfExp_kind:
             {
-                return optimize_if_exp(expr_ptr, arena);
+                return optimize_if_exp(expr_ptr, ste, arena);
             }
         case Dict_kind:
             {
-                return optimize_dict(expr_ptr, arena);
+                return optimize_dict(expr_ptr, ste, arena);
             }
         case ListComp_kind:
             {
-                return optimize_list_comp(expr_ptr, arena);
+                return optimize_list_comp(expr_ptr, ste, arena);
             }
         case GeneratorExp_kind:
             {
-                return optimize_generator_exp(expr_ptr, arena);
+                return optimize_generator_exp(expr_ptr, ste, arena);
             }
         case Yield_kind:
             {
-                return optimize_yield(expr_ptr, arena);
+                return optimize_yield(expr_ptr, ste, arena);
             }
         case Compare_kind:
             {
-                return optimize_compare(expr_ptr, arena);
+                return optimize_compare(expr_ptr, ste, arena);
             }
         case Call_kind:
             {
-                return optimize_call(expr_ptr, arena);
+                return optimize_call(expr_ptr, ste, arena);
             }
         case Repr_kind:
             {
-                return optimize_repr(expr_ptr, arena);
+                return optimize_repr(expr_ptr, ste, arena);
             }
         case Attribute_kind:
             {
-                return optimize_attribute(expr_ptr, arena);
+                return optimize_attribute(expr_ptr, ste, arena);
             }
         case Subscript_kind:
             {
-                return optimize_subscript(expr_ptr, arena);
+                return optimize_subscript(expr_ptr, ste, arena);
             }
         case List_kind:
             {
-                return optimize_expr_seq(&expr->v.List.elts, arena);
+                return optimize_expr_seq(&expr->v.List.elts, ste, arena);
             }
         case Tuple_kind:
             {
-                return optimize_tuple(expr_ptr, arena);
+                return optimize_tuple(expr_ptr, ste, arena);
             }
         case Name_kind:
             {
-                return optimize_name(expr_ptr, arena);
+                return optimize_name(expr_ptr, ste, arena);
             }
         case Num_kind:
         case Str_kind:
@@ -869,38 +887,38 @@
 }
 
 static int
-optimize_function_def(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_function_def(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_arguments(&stmt->v.FunctionDef.args, arena))
+    if (!optimize_arguments(&stmt->v.FunctionDef.args, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&stmt->v.FunctionDef.decorator_list, arena))
+    if (!optimize_expr_seq(&stmt->v.FunctionDef.decorator_list, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.FunctionDef.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.FunctionDef.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_class_def(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_class_def(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr_seq(&stmt->v.ClassDef.bases, arena))
+    if (!optimize_expr_seq(&stmt->v.ClassDef.bases, ste, arena))
         return 0;
-    if (!optimize_expr_seq(&stmt->v.ClassDef.decorator_list, arena))
+    if (!optimize_expr_seq(&stmt->v.ClassDef.decorator_list, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.ClassDef.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.ClassDef.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_return(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_return(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
     if (stmt->v.Return.value != NULL) {
         expr_ty value;
-        if (!optimize_expr(&stmt->v.Return.value, arena))
+        if (!optimize_expr(&stmt->v.Return.value, ste, arena))
             return 0;
         value = stmt->v.Return.value;
         if (value->kind == Const_kind && value->v.Const.value == Py_None)
@@ -910,87 +928,105 @@
 }
 
 static int
-optimize_delete(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_delete(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr_seq(&stmt->v.Delete.targets, arena))
+    if (!optimize_expr_seq(&stmt->v.Delete.targets, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_assign(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_assign(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr_seq(&stmt->v.Assign.targets, arena))
+    if (!optimize_expr_seq(&stmt->v.Assign.targets, ste, arena))
         return 0;
-    if (!optimize_expr(&stmt->v.Assign.value, arena))
+    if (!optimize_expr(&stmt->v.Assign.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_aug_assign(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_aug_assign(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.AugAssign.target, arena))
+    if (!optimize_expr(&stmt->v.AugAssign.target, ste, arena))
         return 0;
-    if (!optimize_expr(&stmt->v.AugAssign.value, arena))
+    if (!optimize_expr(&stmt->v.AugAssign.value, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_print(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_print(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
 
     if (stmt->v.Print.dest != NULL)
-        if (!optimize_expr(&stmt->v.Print.dest, arena))
+        if (!optimize_expr(&stmt->v.Print.dest, ste, arena))
             return 0;
-    if (!optimize_expr_seq(&stmt->v.Print.values, arena))
+    if (!optimize_expr_seq(&stmt->v.Print.values, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_for(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_for(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.For.target, arena))
+    if (!optimize_expr(&stmt->v.For.target, ste, arena))
         return 0;
-    if (!optimize_expr(&stmt->v.For.iter, arena))
+    if (!optimize_expr(&stmt->v.For.iter, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.For.body, arena))
+    /* if the object we're iterating over is a list of constants,
+     * build the list at compile time. Note that this will actually
+     * transform the list into a tuple. This is safe because only
+     * the `for' loop can actually reference it.
+     */
+    if (stmt->v.For.iter->kind == List_kind) {
+        expr_ty list = stmt->v.For.iter;
+        if (_is_sequence_of_constants(list->v.List.elts)) {
+            PyObject* iter = _build_tuple_of_constants(list->v.List.elts,
+                                                        arena);
+            if (iter == NULL)
+                return 0;
+            stmt->v.For.iter = Const(iter, stmt->lineno, stmt->col_offset,
+                                        arena);
+            if (stmt->v.For.iter == NULL)
+                return 0;
+        }
+    }
+    if (!optimize_stmt_seq(&stmt->v.For.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.For.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.For.orelse, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_while(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_while(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.While.test, arena))
+    if (!optimize_expr(&stmt->v.While.test, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.While.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.While.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.While.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.While.orelse, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_if(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_if(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
 
-    if (!optimize_expr(&stmt->v.If.test, arena))
+    if (!optimize_expr(&stmt->v.If.test, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.If.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.If.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.If.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.If.orelse, ste, arena))
         return 0;
 
     if (stmt->v.If.test->kind == UnaryOp_kind &&
@@ -1020,174 +1056,187 @@
 }
 
 static int
-optimize_with(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_with(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.With.context_expr, arena))
+    if (!optimize_expr(&stmt->v.With.context_expr, ste, arena))
         return 0;
     if (stmt->v.With.optional_vars != NULL)
-        if (!optimize_expr(&stmt->v.With.optional_vars, arena))
+        if (!optimize_expr(&stmt->v.With.optional_vars, ste, arena))
             return 0;
-    if (!optimize_stmt_seq(&stmt->v.With.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.With.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_raise(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_raise(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
     if (stmt->v.Raise.type != NULL)
-        if (!optimize_expr(&stmt->v.Raise.type, arena))
+        if (!optimize_expr(&stmt->v.Raise.type, ste, arena))
             return 0;
     if (stmt->v.Raise.inst != NULL)
-        if (!optimize_expr(&stmt->v.Raise.inst, arena))
+        if (!optimize_expr(&stmt->v.Raise.inst, ste, arena))
             return 0;
     if (stmt->v.Raise.tback != NULL)
-        if (!optimize_expr(&stmt->v.Raise.tback, arena))
+        if (!optimize_expr(&stmt->v.Raise.tback, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_excepthandler(excepthandler_ty* exc_ptr, PyArena* arena)
+optimize_excepthandler(excepthandler_ty* exc_ptr, PySTEntryObject* ste,
+                        PyArena* arena)
 {
     excepthandler_ty exc = *exc_ptr;
     if (exc->v.ExceptHandler.type != NULL)
-        if (!optimize_expr(&exc->v.ExceptHandler.type, arena))
+        if (!optimize_expr(&exc->v.ExceptHandler.type, ste, arena))
             return 0;
     if (exc->v.ExceptHandler.name != NULL)
-        if (!optimize_expr(&exc->v.ExceptHandler.name, arena))
+        if (!optimize_expr(&exc->v.ExceptHandler.name, ste, arena))
             return 0;
-    if (!optimize_stmt_seq(&exc->v.ExceptHandler.body, arena))
+    if (!optimize_stmt_seq(&exc->v.ExceptHandler.body, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_try_except(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_try_except(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_stmt_seq(&stmt->v.TryExcept.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryExcept.body, ste, arena))
         return 0;
-    if (!optimize_excepthandler_seq(&stmt->v.TryExcept.handlers, arena))
+    if (!optimize_excepthandler_seq(&stmt->v.TryExcept.handlers, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.TryExcept.orelse, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryExcept.orelse, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_try_finally(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_try_finally(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_stmt_seq(&stmt->v.TryFinally.body, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryFinally.body, ste, arena))
         return 0;
-    if (!optimize_stmt_seq(&stmt->v.TryFinally.finalbody, arena))
+    if (!optimize_stmt_seq(&stmt->v.TryFinally.finalbody, ste, arena))
         return 0;
     return 1;
 }
 
 static int
-optimize_assert(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_assert(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.Assert.test, arena))
+    if (!optimize_expr(&stmt->v.Assert.test, ste, arena))
         return 0;
     if (stmt->v.Assert.msg != NULL)
-        if (!optimize_expr(&stmt->v.Assert.msg, arena))
+        if (!optimize_expr(&stmt->v.Assert.msg, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_exec(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_exec(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
-    if (!optimize_expr(&stmt->v.Exec.body, arena))
+    if (!optimize_expr(&stmt->v.Exec.body, ste, arena))
         return 0;
     if (stmt->v.Exec.globals != NULL)
-        if (!optimize_expr(&stmt->v.Exec.globals, arena))
+        if (!optimize_expr(&stmt->v.Exec.globals, ste, arena))
             return 0;
     if (stmt->v.Exec.locals != NULL)
-        if (!optimize_expr(&stmt->v.Exec.locals, arena))
+        if (!optimize_expr(&stmt->v.Exec.locals, ste, arena))
             return 0;
     return 1;
 }
 
 static int
-optimize_stmt(stmt_ty* stmt_ptr, PyArena* arena)
+optimize_stmt(stmt_ty* stmt_ptr, PySTEntryObject* ste, PyArena* arena)
 {
     stmt_ty stmt = *stmt_ptr;
 
     switch (stmt->kind) {
         case FunctionDef_kind:
             {
-                return optimize_function_def(stmt_ptr, arena);
+                int result;
+                ste = PySymtable_Lookup(ste->ste_table, stmt);
+                if (ste == NULL)
+                    return 0;
+                result = optimize_function_def(stmt_ptr, ste, arena);
+                Py_DECREF(ste);
+                return result;
             }
         case ClassDef_kind:
             {
-                return optimize_class_def(stmt_ptr, arena);
+                int result;
+                ste = PySymtable_Lookup(ste->ste_table, stmt);
+                if (ste == NULL)
+                    return 0;
+                result = optimize_class_def(stmt_ptr, ste, arena);
+                Py_DECREF(ste);
+                return result;
             }
         case Return_kind:
             {
-                return optimize_return(stmt_ptr, arena);
+                return optimize_return(stmt_ptr, ste, arena);
             }
         case Delete_kind:
             {
-                return optimize_delete(stmt_ptr, arena);
+                return optimize_delete(stmt_ptr, ste, arena);
             }
         case Assign_kind:
             {
-                return optimize_assign(stmt_ptr, arena);
+                return optimize_assign(stmt_ptr, ste, arena);
             }
         case AugAssign_kind:
             {
-                return optimize_aug_assign(stmt_ptr, arena);
+                return optimize_aug_assign(stmt_ptr, ste, arena);
             }
         case Print_kind:
             {
-                return optimize_print(stmt_ptr, arena);
+                return optimize_print(stmt_ptr, ste, arena);
             }
         case For_kind:
             {
-                return optimize_for(stmt_ptr, arena);
+                return optimize_for(stmt_ptr, ste, arena);
             }
         case While_kind:
             {
-                return optimize_while(stmt_ptr, arena);
+                return optimize_while(stmt_ptr, ste, arena);
             }
         case If_kind:
             {
-                return optimize_if(stmt_ptr, arena);
+                return optimize_if(stmt_ptr, ste, arena);
             }
         case With_kind:
             {
-                return optimize_with(stmt_ptr, arena);
+                return optimize_with(stmt_ptr, ste, arena);
             }
         case Raise_kind:
             {
-                return optimize_raise(stmt_ptr, arena);
+                return optimize_raise(stmt_ptr, ste, arena);
             }
         case TryExcept_kind:
             {
-                return optimize_try_except(stmt_ptr, arena);
+                return optimize_try_except(stmt_ptr, ste, arena);
             }
         case TryFinally_kind:
             {
-                return optimize_try_finally(stmt_ptr, arena);
+                return optimize_try_finally(stmt_ptr, ste, arena);
             }
         case Assert_kind:
             {
-                return optimize_assert(stmt_ptr, arena);
+                return optimize_assert(stmt_ptr, ste, arena);
             }
         case Exec_kind:
             {
-                return optimize_exec(stmt_ptr, arena);
+                return optimize_exec(stmt_ptr, ste, arena);
             }
         case Expr_kind:
             {
-                return optimize_expr(&stmt->v.Expr.value, arena);
+                return optimize_expr(&stmt->v.Expr.value, ste, arena);
             }
         case Import_kind:
         case ImportFrom_kind:
@@ -1213,7 +1262,14 @@
 int
 PyAST_Optimize(mod_ty* mod_ptr, struct symtable* st, PyArena* arena)
 {
-    /* TODO: update optimize_* functions to accept an ste */
-    return optimize_mod(mod_ptr, arena);
+    int result;
+    PySTEntryObject* ste;
+
+    ste = PySymtable_Lookup(st, *mod_ptr);
+    if (ste == NULL)
+        return 0;
+    result = optimize_mod(mod_ptr, ste, arena);
+    Py_DECREF(ste);
+    return 1;
 }
 

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	Sun Jun  8 10:46:48 2008
@@ -20,55 +20,6 @@
 #define ISBASICBLOCK(blocks, start, bytes) \
 	(blocks[start]==blocks[start+bytes-1])
 
-/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
-   with	   LOAD_CONST (c1, c2, ... cn).
-   The consts table must still be in list form so that the
-   new constant (c1, c2, ... cn) can be appended.
-   Called with codestr pointing to the first LOAD_CONST.
-   Bails out with no change if one or more of the LOAD_CONSTs is missing. 
-   Also works for BUILD_LIST when followed by an "in" or "not in" test.
-*/
-static int
-tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
-{
-	PyObject *newconst, *constant;
-	Py_ssize_t i, arg, len_consts;
-
-	/* Pre-conditions */
-	assert(PyList_CheckExact(consts));
-	assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
-	assert(GETARG(codestr, (n*3)) == n);
-	for (i=0 ; i<n ; i++)
-		assert(codestr[i*3] == LOAD_CONST);
-
-	/* Buildup new tuple of constants */
-	newconst = PyTuple_New(n);
-	if (newconst == NULL)
-		return 0;
-	len_consts = PyList_GET_SIZE(consts);
-	for (i=0 ; i<n ; i++) {
-		arg = GETARG(codestr, (i*3));
-		assert(arg < len_consts);
-		constant = PyList_GET_ITEM(consts, arg);
-		Py_INCREF(constant);
-		PyTuple_SET_ITEM(newconst, i, constant);
-	}
-
-	/* Append folded constant onto consts */
-	if (PyList_Append(consts, newconst)) {
-		Py_DECREF(newconst);
-		return 0;
-	}
-	Py_DECREF(newconst);
-
-	/* Write NOPs over old LOAD_CONSTS and
-	   add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
-	memset(codestr, NOP, n*3);
-	codestr[n*3] = LOAD_CONST;
-	SETARG(codestr, (n*3), len_consts);
-	return 1;
-}
-
 static unsigned int *
 markblocks(unsigned char *code, Py_ssize_t len)
 {
@@ -200,44 +151,6 @@
 				codestr[i+3] = NOP;
 				break;
 
-				/* Try to fold tuples of constants (includes a case for lists
-				   which are only used for "in" and "not in" tests).
-				   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_LIST:
-				j = GETARG(codestr, i);
-				h = i - 3 * j;
-				if (h >= 0  &&
-				    j <= lastlc	 &&
-				    ((opcode == BUILD_TUPLE && 
-				      ISBASICBLOCK(blocks, h, 3*(j+1))) ||
-				     (opcode == BUILD_LIST && 
-				      codestr[i+3]==COMPARE_OP && 
-				      ISBASICBLOCK(blocks, h, 3*(j+2)) &&
-				      (GETARG(codestr,i+3)==6 ||
-				       GETARG(codestr,i+3)==7))) &&
-				    tuple_of_constants(&codestr[h], j, consts)) {
-					assert(codestr[i] == LOAD_CONST);
-					cumlc = 1;
-					break;
-				}
-				if (codestr[i+3] != UNPACK_SEQUENCE  ||
-				    !ISBASICBLOCK(blocks,i,6) ||
-				    j != GETARG(codestr, i+3))
-					continue;
-				if (j == 1) {
-					memset(codestr+i, NOP, 6);
-				} else if (j == 2) {
-					codestr[i] = ROT_TWO;
-					memset(codestr+i+1, NOP, 5);
-				} else if (j == 3) {
-					codestr[i] = ROT_THREE;
-					codestr[i+1] = ROT_TWO;
-					memset(codestr+i+2, NOP, 4);
-				}
-				break;
-
 				/* Simplify conditional jump to conditional jump where the
 				   result of the first test implies the success of a similar
 				   test or the failure of the opposite test.


More information about the Python-checkins mailing list