Install two code generation optimizations that depend on NOP.

Reduces the cost of "not" to almost zero.
This commit is contained in:
Raymond Hettinger 2004-06-21 16:31:15 +00:00
parent 2c9f889122
commit 9c18e81fb2
4 changed files with 35 additions and 3 deletions

View File

@ -13,6 +13,7 @@ extern "C" {
#define ROT_THREE 3
#define DUP_TOP 4
#define ROT_FOUR 5
#define NOP 9
#define UNARY_POSITIVE 10
#define UNARY_NEGATIVE 11

View File

@ -49,6 +49,7 @@ def_op('ROT_THREE', 3)
def_op('DUP_TOP', 4)
def_op('ROT_FOUR', 5)
def_op('NOP', 9)
def_op('UNARY_POSITIVE', 10)
def_op('UNARY_NEGATIVE', 11)
def_op('UNARY_NOT', 12)

View File

@ -849,6 +849,9 @@ eval_frame(PyFrameObject *f)
/* case STOP_CODE: this is an error! */
case NOP:
goto fast_next_opcode;
case LOAD_FAST:
x = GETLOCAL(oparg);
if (x != NULL) {

View File

@ -392,6 +392,33 @@ optimize_code(PyObject *code, PyObject* consts)
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 @@ optimize_code(PyObject *code, PyObject* consts)
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 @@ optimize_code(PyObject *code, PyObject* consts)
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;