Mercurial > cpython-lru_cache-weakref
diff Python/compile.c @ 33860:3467288089a1 legacy-trunk
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.
| author | Raymond Hettinger <python@rcn.com> |
|---|---|
| date | Sat, 30 Oct 2004 08:55:08 +0000 |
| parents | fdce3d39bec1 |
| children | 4a3eaa1aa3af |
line wrap: on
line diff
--- a/Python/compile.c Fri Oct 29 19:47:52 2004 +0000 +++ b/Python/compile.c Sat Oct 30 08:55:08 2004 +0000 @@ -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)
