[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