diff Python/compile.c @ 32395:6bc6abba8659 legacy-trunk

Install two code generation optimizations that depend on NOP. Reduces the cost of "not" to almost zero.
author Raymond Hettinger <python@rcn.com>
date Mon, 21 Jun 2004 16:31:15 +0000
parents 13656d58d450
children 1c2baae14828
line wrap: on
line diff
--- a/Python/compile.c	Mon Jun 21 16:15:22 2004 +0000
+++ b/Python/compile.c	Mon Jun 21 16:31:15 2004 +0000
@@ -392,6 +392,33 @@
 		opcode = codestr[i];
 		switch (opcode) {
 
+		/* Replace UNARY_NOT JUMP_IF_FALSE with NOP JUMP_IF_TRUE */
+		case UNARY_NOT:
+			if (codestr[i+1] != JUMP_IF_FALSE  ||
+			    codestr[i+4] != POP_TOP  ||
+			    !ISBASICBLOCK(blocks,i,5))
+				continue;
+			tgt = GETJUMPTGT(codestr, (i+1));
+			if (codestr[tgt] != POP_TOP)
+				continue;
+			codestr[i] = NOP;
+			codestr[i+1] = JUMP_IF_TRUE;
+			break;
+
+		/* not a is b -->  a is not b
+		   not a in b -->  a not in b
+		   not a is not b -->  a is b
+		   not a not in b -->  a in b */
+		case COMPARE_OP:
+			j = GETARG(codestr, i);
+			if (j < 6  ||  j > 9  ||
+			    codestr[i+3] != UNARY_NOT  || 
+			    !ISBASICBLOCK(blocks,i,4))
+  			 continue;
+			SETARG(codestr, i, (j^1));
+			codestr[i+3] = NOP;
+			break;
+
 		/* Skip over LOAD_CONST trueconst  JUMP_IF_FALSE xx  POP_TOP. 
 		   Note, only the first opcode is changed, the others still
 		   perform normally if they happen to be jump targets. */
@@ -418,8 +445,8 @@
 				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;
+				codestr[i+4] = NOP;
+				codestr[i+5] = NOP;
 				continue;
 			} 
 			if (GETARG(codestr, i) == 3 && \
@@ -428,7 +455,7 @@
 				codestr[i+1] = ROT_TWO;
 				codestr[i+2] = JUMP_FORWARD;
 				SETARG(codestr, i+2, 1);
-				codestr[i+5] = DUP_TOP;
+				codestr[i+5] = NOP;
 			}
 			break;