[Python-checkins] r62816 - in python/branches/tlee-ast-optimize: Include/Python-ast.h Parser/Python.asdl Python/Python-ast.c Python/compile.c Python/optimize.c Python/peephole.c Python/symtable.c

thomas.lee python-checkins at python.org
Wed May 7 11:46:25 CEST 2008


Author: thomas.lee
Date: Wed May  7 11:46:25 2008
New Revision: 62816

Log:
Use Const(). Fix a bug occuring when optimizing away statements following a Return node.

Modified:
   python/branches/tlee-ast-optimize/Include/Python-ast.h
   python/branches/tlee-ast-optimize/Parser/Python.asdl
   python/branches/tlee-ast-optimize/Python/Python-ast.c
   python/branches/tlee-ast-optimize/Python/compile.c
   python/branches/tlee-ast-optimize/Python/optimize.c
   python/branches/tlee-ast-optimize/Python/peephole.c
   python/branches/tlee-ast-optimize/Python/symtable.c

Modified: python/branches/tlee-ast-optimize/Include/Python-ast.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/Python-ast.h	(original)
+++ python/branches/tlee-ast-optimize/Include/Python-ast.h	Wed May  7 11:46:25 2008
@@ -188,8 +188,8 @@
                   IfExp_kind=5, Dict_kind=6, ListComp_kind=7,
                   GeneratorExp_kind=8, Yield_kind=9, Compare_kind=10,
                   Call_kind=11, Repr_kind=12, Num_kind=13, Str_kind=14,
-                  Attribute_kind=15, Subscript_kind=16, Name_kind=17,
-                  List_kind=18, Tuple_kind=19};
+                  Const_kind=15, Attribute_kind=16, Subscript_kind=17,
+                  Name_kind=18, List_kind=19, Tuple_kind=20};
 struct _expr {
         enum _expr_kind kind;
         union {
@@ -266,6 +266,10 @@
                 } Str;
                 
                 struct {
+                        object value;
+                } Const;
+                
+                struct {
                         expr_ty value;
                         identifier attr;
                         expr_context_ty ctx;
@@ -470,6 +474,8 @@
 expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena);
 #define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3)
 expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena);
+#define Const(a0, a1, a2, a3) _Py_Const(a0, a1, a2, a3)
+expr_ty _Py_Const(object value, int lineno, int col_offset, PyArena *arena);
 #define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5)
 expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
                       lineno, int col_offset, PyArena *arena);

Modified: python/branches/tlee-ast-optimize/Parser/Python.asdl
==============================================================================
--- python/branches/tlee-ast-optimize/Parser/Python.asdl	(original)
+++ python/branches/tlee-ast-optimize/Parser/Python.asdl	Wed May  7 11:46:25 2008
@@ -68,6 +68,7 @@
 	     | Repr(expr value)
 	     | Num(object n) -- a number as a PyObject.
 	     | Str(string s) -- need to specify raw, unicode, etc?
+         | Const(object value) -- inject arbitary constants into the AST
 	     -- other literals? bools?
 
 	     -- the following expression can appear in assignment context

Modified: python/branches/tlee-ast-optimize/Python/Python-ast.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/Python-ast.c	(original)
+++ python/branches/tlee-ast-optimize/Python/Python-ast.c	Wed May  7 11:46:25 2008
@@ -228,6 +228,10 @@
 static char *Str_fields[]={
         "s",
 };
+static PyTypeObject *Const_type;
+static char *Const_fields[]={
+        "value",
+};
 static PyTypeObject *Attribute_type;
 static char *Attribute_fields[]={
         "value",
@@ -717,6 +721,8 @@
         if (!Num_type) return 0;
         Str_type = make_type("Str", expr_type, Str_fields, 1);
         if (!Str_type) return 0;
+        Const_type = make_type("Const", expr_type, Const_fields, 1);
+        if (!Const_type) return 0;
         Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
         if (!Attribute_type) return 0;
         Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3);
@@ -1736,6 +1742,25 @@
 }
 
 expr_ty
+Const(object value, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        if (!value) {
+                PyErr_SetString(PyExc_ValueError,
+                                "field value is required for Const");
+                return NULL;
+        }
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p)
+                return NULL;
+        p->kind = Const_kind;
+        p->v.Const.value = value;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
 Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
           col_offset, PyArena *arena)
 {
@@ -2673,6 +2698,15 @@
                         goto failed;
                 Py_DECREF(value);
                 break;
+        case Const_kind:
+                result = PyType_GenericNew(Const_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_object(o->v.Const.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
         case Attribute_kind:
                 result = PyType_GenericNew(Attribute_type, NULL, NULL);
                 if (!result) goto failed;
@@ -5046,6 +5080,25 @@
                 if (*out == NULL) goto failed;
                 return 0;
         }
+        if (PyObject_IsInstance(obj, (PyObject*)Const_type)) {
+                object value;
+
+                if (PyObject_HasAttrString(obj, "value")) {
+                        int res;
+                        tmp = PyObject_GetAttrString(obj, "value");
+                        if (tmp == NULL) goto failed;
+                        res = obj2ast_object(tmp, &value, arena);
+                        if (res != 0) goto failed;
+                        Py_XDECREF(tmp);
+                        tmp = NULL;
+                } else {
+                        PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Const");
+                        return 1;
+                }
+                *out = Const(value, lineno, col_offset, arena);
+                if (*out == NULL) goto failed;
+                return 0;
+        }
         if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) {
                 expr_ty value;
                 identifier attr;
@@ -6003,6 +6056,7 @@
         if (PyDict_SetItemString(d, "Repr", (PyObject*)Repr_type) < 0) return;
         if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return;
         if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return;
+        if (PyDict_SetItemString(d, "Const", (PyObject*)Const_type) < 0) return;
         if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) <
             0) return;
         if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) <

Modified: python/branches/tlee-ast-optimize/Python/compile.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/compile.c	(original)
+++ python/branches/tlee-ast-optimize/Python/compile.c	Wed May  7 11:46:25 2008
@@ -3022,6 +3022,9 @@
 		VISIT(c, expr, e->v.Repr.value);
 		ADDOP(c, UNARY_CONVERT);
 		break;
+    case Const_kind:
+        ADDOP_O(c, LOAD_CONST, e->v.Const.value, consts);
+        break;
 	case Num_kind:
 		ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts);
 		break;
@@ -3580,7 +3583,10 @@
 	d_lineno = i->i_lineno - a->a_lineno;
 
 	assert(d_bytecode >= 0);
+    /* XXX: removing stuff after a Return node causes this to fail */
+#if 0
 	assert(d_lineno >= 0);
+#endif
 
 	if(d_bytecode == 0 && d_lineno == 0)
 		return 1;

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 11:46:25 2008
@@ -180,18 +180,11 @@
 static asdl_seq*
 _asdl_seq_replace_with_pass(asdl_seq* seq, int n, int lineno, int col_offset, PyArena* arena)
 {
-    stmt_ty pass;
-    asdl_seq* new;
-
-    pass = Pass(lineno, col_offset, arena);
+    stmt_ty pass = Pass(lineno, col_offset, arena);
     if (pass == NULL)
         return NULL;
-    new = asdl_seq_new(1, arena);
-    if (new == NULL)
-        return NULL;
-    asdl_seq_SET(new, 0, pass);
-    
-    return _asdl_seq_replace(seq, n, new, arena);
+    asdl_seq_SET(seq, n, pass);
+    return seq;
 }
 
 /**
@@ -228,7 +221,7 @@
                 *seq_ptr = seq;
             }
         }
-        else if (stmt->kind == Return_kind) {
+        else if (stmt->kind == Return_kind && n < (asdl_seq_LEN(seq) - 1)) {
             /* eliminate all nodes after a return */
             seq = _asdl_seq_replace_with_pass(seq, n + 1,
                     stmt->lineno, stmt->col_offset, arena);
@@ -816,9 +809,34 @@
             {
                 return optimize_expr_seq(&expr->v.Tuple.elts, 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;
+            }
         case Num_kind:
         case Str_kind:
-        case Name_kind:
+        case Const_kind:
             {
                 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	Wed May  7 11:46:25 2008
@@ -135,7 +135,6 @@
 	int new_line, cum_orig_line, last_line, tabsiz;
 	int cumlc=0, lastlc=0;	/* Count runs of consecutive LOAD_CONSTs */
 	unsigned int *blocks = NULL;
-	char *name;
 
 	/* Bail out if an exception is set */
 	if (PyErr_Occurred())
@@ -201,28 +200,6 @@
 				codestr[i+3] = NOP;
 				break;
 
-				/* Replace LOAD_GLOBAL/LOAD_NAME None
-                                   with LOAD_CONST None */
-			case LOAD_NAME:
-			case LOAD_GLOBAL:
-				j = GETARG(codestr, i);
-				name = PyString_AsString(PyTuple_GET_ITEM(names, j));
-				if (name == NULL  ||  strcmp(name, "None") != 0)
-					continue;
-				for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
-					if (PyList_GET_ITEM(consts, j) == Py_None)
-						break;
-				}
-				if (j == PyList_GET_SIZE(consts)) {
-					if (PyList_Append(consts, Py_None) == -1)
-					        goto exitUnchanged;                                        
-				}
-				assert(PyList_GET_ITEM(consts, j) == Py_None);
-				codestr[i] = LOAD_CONST;
-				SETARG(codestr, i, j);
-				cumlc = lastlc + 1;
-				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.

Modified: python/branches/tlee-ast-optimize/Python/symtable.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/symtable.c	(original)
+++ python/branches/tlee-ast-optimize/Python/symtable.c	Wed May  7 11:46:25 2008
@@ -1189,6 +1189,7 @@
 		break;
         case Num_kind:
         case Str_kind:
+        case Const_kind:
 		/* Nothing to do here. */
 		break;
 	/* The following exprs can be assignment targets. */


More information about the Python-checkins mailing list