[Python-checkins] python/dist/src/Python compile.c,2.299,2.300

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sun Mar 21 10:12:03 EST 2004


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

Modified Files:
	compile.c 
Log Message:
Improve byte coding for multiple assignments.
Gives 30% speedup on "a,b=1,2" and 25% on "a,b,c=1,2,3".



Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.299
retrieving revision 2.300
diff -C2 -d -r2.299 -r2.300
*** compile.c	7 Mar 2004 07:31:06 -0000	2.299
--- compile.c	21 Mar 2004 15:12:00 -0000	2.300
***************
*** 328,331 ****
--- 328,368 ----
  #define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
  #define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
+ #define CODESIZE(op)  (HAS_ARG(op) ? 3 : 1)
+ #define ISBASICBLOCK(blocks, start, bytes) (blocks[start]==blocks[start+bytes-1])
+ 
+ static unsigned int *
+ markblocks(unsigned char *code, int len)
+ {
+ 	unsigned int *blocks = PyMem_Malloc(len*sizeof(int));
+ 	int i,j, opcode, oldblock, newblock, blockcnt = 0;
+ 
+ 	if (blocks == NULL)
+ 		return NULL;
+ 	memset(blocks, 0, len*sizeof(int));
+ 	for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
+ 		opcode = code[i];
+ 		switch (opcode) {
+ 			case FOR_ITER:
+ 			case JUMP_FORWARD:
+ 			case JUMP_IF_FALSE:
+ 			case JUMP_IF_TRUE:
+ 			case JUMP_ABSOLUTE:
+ 			case CONTINUE_LOOP:
+ 			case SETUP_LOOP:
+ 			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;
+ 				}
+ 			break;
+ 		}
+ 	}
+ 	return blocks;
+ }
  
  static PyObject *
***************
*** 335,338 ****
--- 372,376 ----
  	int tgt, tgttgt, opcode;
  	unsigned char *codestr;
+ 	unsigned int *blocks;
  
  	/* Make a modifiable copy of the code string */
***************
*** 341,350 ****
  	codelen = PyString_Size(code);
  	codestr = PyMem_Malloc(codelen);
! 	if (codestr == NULL) 
  		goto exitUnchanged;
  	codestr = memcpy(codestr, PyString_AS_STRING(code), codelen);
  	assert(PyTuple_Check(consts));
  
! 	for (i=0 ; i<codelen-7 ; i += HAS_ARG(codestr[i]) ? 3 : 1) {
  		opcode = codestr[i];
  		switch (opcode) {
--- 379,393 ----
  	codelen = PyString_Size(code);
  	codestr = PyMem_Malloc(codelen);
! 	if (codestr == NULL)
  		goto exitUnchanged;
  	codestr = memcpy(codestr, PyString_AS_STRING(code), codelen);
+ 	blocks = markblocks(codestr, codelen);
+ 	if (blocks == NULL) {
+ 		PyMem_Free(codestr);
+ 		goto exitUnchanged;
+ 	}
  	assert(PyTuple_Check(consts));
  
! 	for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
  		opcode = codestr[i];
  		switch (opcode) {
***************
*** 363,366 ****
--- 406,436 ----
  			break;
  
+ 		/* Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2 JMP+2 NOP NOP.
+ 		   Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2 JMP+1 NOP. */
+ 		case BUILD_TUPLE:
+ 		case BUILD_LIST:
+ 			if (codestr[i+3] != UNPACK_SEQUENCE)
+ 				continue;
+ 			if (!ISBASICBLOCK(blocks,i,6))
+ 				continue;
+ 			if (GETARG(codestr, i) == 2 && \
+ 			    GETARG(codestr, i+3) == 2) {
+ 				codestr[i] = ROT_TWO;
+ 				codestr[i+1] = JUMP_FORWARD;
+ 				SETARG(codestr, i+1, 2);
+ 				codestr[i+4] = DUP_TOP;  /* Filler codes used as NOPs */
+ 				codestr[i+5] = POP_TOP;
+ 				continue;
+ 			} 
+ 			if (GETARG(codestr, i) == 3 && \
+ 			    GETARG(codestr, i+3) == 3) {
+ 				codestr[i] = ROT_THREE;
+ 				codestr[i+1] = ROT_TWO;
+ 				codestr[i+2] = JUMP_FORWARD;
+ 				SETARG(codestr, i+2, 1);
+ 				codestr[i+5] = DUP_TOP;
+ 			}
+ 			break;
+ 
  		/* Replace jumps to unconditional jumps */
  		case FOR_ITER:
***************
*** 374,378 ****
  		case SETUP_FINALLY:
  			tgt = GETJUMPTGT(codestr, i);
! 			if (!UNCONDITIONAL_JUMP(codestr[tgt])) 
  				continue;
  			tgttgt = GETJUMPTGT(codestr, tgt);
--- 444,448 ----
  		case SETUP_FINALLY:
  			tgt = GETJUMPTGT(codestr, i);
! 			if (!UNCONDITIONAL_JUMP(codestr[tgt]))
  				continue;
  			tgttgt = GETJUMPTGT(codestr, tgt);
***************
*** 394,397 ****
--- 464,468 ----
  	code = PyString_FromStringAndSize((char *)codestr, codelen);
  	PyMem_Free(codestr);
+ 	PyMem_Free(blocks);
  	return code;
  




More information about the Python-checkins mailing list