[Python-checkins] python/dist/src/Python compile.c,2.337,2.338
rhettinger at users.sourceforge.net
rhettinger at users.sourceforge.net
Sun Jan 2 07:17:37 CET 2005
Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7497/Python
Modified Files:
compile.c
Log Message:
Teach the peephole optimizer to fold simple constant expressions.
Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.337
retrieving revision 2.338
diff -u -d -r2.337 -r2.338
--- compile.c 7 Nov 2004 14:04:00 -0000 2.337
+++ compile.c 2 Jan 2005 06:17:33 -0000 2.338
@@ -439,6 +439,99 @@
return 1;
}
+/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
+ with LOAD_CONST binop(c1,c2)
+ The consts table must still be in list form so that the
+ new constant can be appended.
+ Called with codestr pointing to the first LOAD_CONST.
+ Abandons the transformation if the folding fails (i.e. 1+'a'). */
+static int
+fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
+{
+ PyObject *newconst, *v, *w;
+ int len_consts, opcode;
+
+ /* Pre-conditions */
+ assert(PyList_CheckExact(consts));
+ assert(codestr[0] == LOAD_CONST);
+ assert(codestr[3] == LOAD_CONST);
+
+ /* Create new constant */
+ v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
+ w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
+ opcode = codestr[6];
+ switch (opcode) {
+ case BINARY_POWER:
+ newconst = PyNumber_Power(v, w, Py_None);
+ break;
+ case BINARY_MULTIPLY:
+ newconst = PyNumber_Multiply(v, w);
+ break;
+ case BINARY_DIVIDE:
+ if (!_Py_QnewFlag) {
+ newconst = PyNumber_Divide(v, w);
+ break;
+ }
+ /* -Qnew is in effect: fall through to
+ BINARY_TRUE_DIVIDE */
+ case BINARY_TRUE_DIVIDE:
+ newconst = PyNumber_TrueDivide(v, w);
+ break;
+ case BINARY_FLOOR_DIVIDE:
+ newconst = PyNumber_FloorDivide(v, w);
+ break;
+ case BINARY_MODULO:
+ newconst = PyNumber_Remainder(v, w);
+ break;
+ case BINARY_ADD:
+ newconst = PyNumber_Add(v, w);
+ break;
+ case BINARY_SUBTRACT:
+ newconst = PyNumber_Subtract(v, w);
+ break;
+ case BINARY_SUBSCR:
+ newconst = PyObject_GetItem(v, w);
+ break;
+ case BINARY_LSHIFT:
+ newconst = PyNumber_Lshift(v, w);
+ break;
+ case BINARY_RSHIFT:
+ newconst = PyNumber_Rshift(v, w);
+ break;
+ case BINARY_AND:
+ newconst = PyNumber_And(v, w);
+ break;
+ case BINARY_XOR:
+ newconst = PyNumber_Xor(v, w);
+ break;
+ case BINARY_OR:
+ newconst = PyNumber_Or(v, w);
+ 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 NOP NOP NOP LOAD_CONST newconst */
+ memset(codestr, NOP, 4);
+ codestr[4] = LOAD_CONST;
+ SETARG(codestr, 4, len_consts);
+ return 1;
+}
+
static unsigned int *
markblocks(unsigned char *code, int len)
{
@@ -614,7 +707,6 @@
h = i - 3 * j;
if (h >= 0 &&
j <= lastlc &&
- codestr[h] == LOAD_CONST &&
ISBASICBLOCK(blocks, h, 3*(j+1)) &&
tuple_of_constants(&codestr[h], j, consts)) {
assert(codestr[i] == LOAD_CONST);
@@ -640,6 +732,31 @@
}
break;
+ /* Fold binary ops on constants.
+ LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
+ case BINARY_POWER:
+ case BINARY_MULTIPLY:
+ case BINARY_DIVIDE:
+ case BINARY_TRUE_DIVIDE:
+ case BINARY_FLOOR_DIVIDE:
+ case BINARY_MODULO:
+ case BINARY_ADD:
+ case BINARY_SUBTRACT:
+ case BINARY_SUBSCR:
+ case BINARY_LSHIFT:
+ case BINARY_RSHIFT:
+ case BINARY_AND:
+ case BINARY_XOR:
+ case BINARY_OR:
+ if (lastlc >= 2 &&
+ ISBASICBLOCK(blocks, i-6, 7) &&
+ fold_binops_on_constants(&codestr[i-6], 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