Kaydet (Commit) 9c18e81f authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Install two code generation optimizations that depend on NOP.

Reduces the cost of "not" to almost zero.
üst 2c9f8891
......@@ -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
......
......@@ -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)
......
......@@ -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) {
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment