[Python-checkins] python/dist/src/Python compile.c,2.344,2.345

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sun Feb 20 13:41:48 CET 2005


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2403

Modified Files:
	compile.c 
Log Message:
Teach the peepholer to fold unary operations on constants.

Afterwards, -0.5 loads in a single step and no longer requires a runtime
UNARY_NEGATIVE operation.



Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.344
retrieving revision 2.345
diff -u -d -r2.344 -r2.345
--- compile.c	10 Feb 2005 01:42:32 -0000	2.344
+++ compile.c	20 Feb 2005 12:41:32 -0000	2.345
@@ -542,6 +542,54 @@
 	return 1;
 }
 
+static int
+fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
+{
+	PyObject *newconst, *v;
+	int len_consts, opcode;
+
+	/* Pre-conditions */
+	assert(PyList_CheckExact(consts));
+	assert(codestr[0] == LOAD_CONST);
+
+	/* Create new constant */
+	v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
+	opcode = codestr[3];
+	switch (opcode) {
+	case UNARY_NEGATIVE:
+		newconst = PyNumber_Negative(v);
+		break;
+	case UNARY_CONVERT:
+		newconst = PyObject_Repr(v);
+		break;
+	case UNARY_INVERT:
+		newconst = PyNumber_Invert(v);
+		break;
+	default:
+		/* Called with an unknown opcode */
+		assert(0);
+		return 0;
+	}
+	if (newconst == NULL) {
+		PyErr_Clear();
+		return 0;
+	}
+
+	/* Append folded constant into consts table */
+	len_consts = PyList_GET_SIZE(consts);
+	if (PyList_Append(consts, newconst)) {
+		Py_DECREF(newconst);
+		return 0;
+	}
+	Py_DECREF(newconst);
+
+	/* Write NOP LOAD_CONST newconst */
+	codestr[0] = NOP;
+	codestr[1] = LOAD_CONST;
+	SETARG(codestr, 1, len_consts);
+	return 1;
+}
+
 static unsigned int *
 markblocks(unsigned char *code, int len)
 {
@@ -771,6 +819,20 @@
 			}
 			break;
 
+		/* Fold unary ops on constants.
+		   LOAD_CONST c1  UNARY_OP -->  LOAD_CONST unary_op(c) */
+		case UNARY_NEGATIVE:
+		case UNARY_CONVERT:
+		case UNARY_INVERT:
+			if (lastlc >= 1  &&
+			    ISBASICBLOCK(blocks, i-3, 4)  &&
+			    fold_unaryops_on_constants(&codestr[i-3], consts))  {
+				i -= 2;
+				assert(codestr[i] == LOAD_CONST);
+				cumlc = 1;
+			}
+			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