[Python-checkins] python/dist/src/Python compile.c,2.332,2.333

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sat Oct 30 10:55:11 CEST 2004


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

Modified Files:
	compile.c 
Log Message:
Adopt some peepholer suggestions from Armin Rigo:

* Use simpler, faster two pass algorithm for markblocks().
* Free the blocks variable if not NULL and exiting without change.
* Verify that the rest of the compiler has not set an exception.
* Make the test for tuple of constants less restrictive.
* Embellish the comment for chained conditional jumps.



Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.332
retrieving revision 2.333
diff -u -d -r2.332 -r2.333
--- compile.c	26 Oct 2004 08:59:13 -0000	2.332
+++ compile.c	30 Oct 2004 08:55:08 -0000	2.333
@@ -406,14 +406,10 @@
 
 	/* Pre-conditions */
 	assert(PyList_CheckExact(consts));
-	assert(codestr[0] == LOAD_CONST);
 	assert(codestr[n*3] == BUILD_TUPLE);
 	assert(GETARG(codestr, (n*3)) == n);
-
-	/* Verify chain of n load_constants */
 	for (i=0 ; i<n ; i++)
-		if (codestr[i*3] != LOAD_CONST)
-			return 0;
+		assert(codestr[i*3] == LOAD_CONST);
 
 	/* Buildup new tuple of constants */
 	newconst = PyTuple_New(n);
@@ -447,11 +443,13 @@
 markblocks(unsigned char *code, int len)
 {
 	unsigned int *blocks = PyMem_Malloc(len*sizeof(int));
-	int i,j, opcode, oldblock, newblock, blockcnt = 0;
+	int i,j, opcode, blockcnt = 0;
 
 	if (blocks == NULL)
 		return NULL;
 	memset(blocks, 0, len*sizeof(int));
+
+	/* Mark labels in the first pass */
 	for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
 		opcode = code[i];
 		switch (opcode) {
@@ -465,16 +463,15 @@
 			case SETUP_EXCEPT:
 			case SETUP_FINALLY:
 				j = GETJUMPTGT(code, i);
-				oldblock = blocks[j];
-				newblock = ++blockcnt;
-				for (; j<len ; j++) {
-					if (blocks[j] != (unsigned)oldblock)
-						break;
-					blocks[j] = newblock;
-				}
+				blocks[j] = 1;
 			break;
 		}
 	}
+	/* Build block numbers in the second pass */
+	for (i=0 ; i<len ; i++) {
+		blockcnt += blocks[i];  /* increment blockcnt over labels */
+		blocks[i] = blockcnt;
+	}
 	return blocks;
 }
 
@@ -503,9 +500,13 @@
 	int *addrmap = NULL;
 	int new_line, cum_orig_line, last_line, tabsiz;
 	int cumlc=0, lastlc=0;	/* Count runs of consecutive LOAD_CONST codes */
-	unsigned int *blocks;
+	unsigned int *blocks = NULL;
 	char *name;
 
+	/* Bail out if an exception is set */
+	if (PyErr_Occurred())
+		goto exitUnchanged;
+
 	/* Bypass optimization when the lineno table is too complex */
 	assert(PyString_Check(lineno_obj));
 	lineno = PyString_AS_STRING(lineno_obj);
@@ -614,7 +615,7 @@
 			j = GETARG(codestr, i);
 			h = i - 3 * j;
 			if (h >= 0  &&
-			    j == lastlc  &&
+			    j <= lastlc  &&
 			    codestr[h] == LOAD_CONST  && 
 			    ISBASICBLOCK(blocks, h, 3*(j+1))  &&
 			    tuple_of_constants(&codestr[h], j, consts)) {
@@ -647,6 +648,8 @@
 		   result of the first test implies the success of a similar
 		   test or the failure of the opposite test.
 		   Arises in code like:
+		        "if a and b:"
+			"if a or b:"
 		        "a and b or c"
 			"a and b and c"
 		   x:JUMP_IF_FALSE y   y:JUMP_IF_FALSE z  -->  x:JUMP_IF_FALSE z
@@ -755,6 +758,8 @@
 	return code;
 
 exitUnchanged:
+	if (blocks != NULL)
+		PyMem_Free(blocks);
 	if (addrmap != NULL)
 		PyMem_Free(addrmap);
 	if (codestr != NULL)



More information about the Python-checkins mailing list