annotate Python/peephole.c @ 54294:dba767bc3155 legacy-trunk

remove mention of old ctypes version
author Benjamin Peterson <benjamin@python.org>
date Sat, 23 May 2009 20:59:09 +0000
parents ef8fe9088696
children ba305fe8e831
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40998
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
1 /* Peephole optimizations for bytecode compiler. */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
2
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
3 #include "Python.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
4
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
5 #include "Python-ast.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
6 #include "node.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
7 #include "pyarena.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
8 #include "ast.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
9 #include "code.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
10 #include "compile.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
11 #include "symtable.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
12 #include "opcode.h"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
13
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
14 #define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
15 #define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
16 #define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
17 || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
18 #define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP \
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
19 || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
20 || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
21 #define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP)
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
22 #define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
23 #define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
24 #define CODESIZE(op) (HAS_ARG(op) ? 3 : 1)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
25 #define ISBASICBLOCK(blocks, start, bytes) \
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
26 (blocks[start]==blocks[start+bytes-1])
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
27
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
28 /* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
29 with LOAD_CONST (c1, c2, ... cn).
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
30 The consts table must still be in list form so that the
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
31 new constant (c1, c2, ... cn) can be appended.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
32 Called with codestr pointing to the first LOAD_CONST.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
33 Bails out with no change if one or more of the LOAD_CONSTs is missing.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
34 Also works for BUILD_LIST when followed by an "in" or "not in" test.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
35 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
36 static int
46062
09adff3d6691 Try to fix a bunch of compiler warnings on Win64.
Neal Norwitz <nnorwitz@gmail.com>
parents: 45511
diff changeset
37 tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
38 {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
39 PyObject *newconst, *constant;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
40 Py_ssize_t i, arg, len_consts;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
41
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
42 /* Pre-conditions */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
43 assert(PyList_CheckExact(consts));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
44 assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
45 assert(GETARG(codestr, (n*3)) == n);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
46 for (i=0 ; i<n ; i++)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
47 assert(codestr[i*3] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
48
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
49 /* Buildup new tuple of constants */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
50 newconst = PyTuple_New(n);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
51 if (newconst == NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
52 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
53 len_consts = PyList_GET_SIZE(consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
54 for (i=0 ; i<n ; i++) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
55 arg = GETARG(codestr, (i*3));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
56 assert(arg < len_consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
57 constant = PyList_GET_ITEM(consts, arg);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
58 Py_INCREF(constant);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
59 PyTuple_SET_ITEM(newconst, i, constant);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
60 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
61
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
62 /* Append folded constant onto consts */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
63 if (PyList_Append(consts, newconst)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
64 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
65 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
66 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
67 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
68
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
69 /* Write NOPs over old LOAD_CONSTS and
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
70 add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
71 memset(codestr, NOP, n*3);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
72 codestr[n*3] = LOAD_CONST;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
73 SETARG(codestr, (n*3), len_consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
74 return 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
75 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
76
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
77 /* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
78 with LOAD_CONST binop(c1,c2)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
79 The consts table must still be in list form so that the
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
80 new constant can be appended.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
81 Called with codestr pointing to the first LOAD_CONST.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
82 Abandons the transformation if the folding fails (i.e. 1+'a').
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
83 If the new constant is a sequence, only folds when the size
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
84 is below a threshold value. That keeps pyc files from
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
85 becoming large in the presence of code like: (None,)*1000.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
86 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
87 static int
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
88 fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
89 {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
90 PyObject *newconst, *v, *w;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
91 Py_ssize_t len_consts, size;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
92 int opcode;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
93
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
94 /* Pre-conditions */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
95 assert(PyList_CheckExact(consts));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
96 assert(codestr[0] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
97 assert(codestr[3] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
98
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
99 /* Create new constant */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
100 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
101 w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
102 opcode = codestr[6];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
103 switch (opcode) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
104 case BINARY_POWER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
105 newconst = PyNumber_Power(v, w, Py_None);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
106 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
107 case BINARY_MULTIPLY:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
108 newconst = PyNumber_Multiply(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
109 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
110 case BINARY_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
111 /* Cannot fold this operation statically since
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
112 the result can depend on the run-time presence
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
113 of the -Qnew flag */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
114 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
115 case BINARY_TRUE_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
116 newconst = PyNumber_TrueDivide(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
117 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
118 case BINARY_FLOOR_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
119 newconst = PyNumber_FloorDivide(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
120 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
121 case BINARY_MODULO:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
122 newconst = PyNumber_Remainder(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
123 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
124 case BINARY_ADD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
125 newconst = PyNumber_Add(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
126 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
127 case BINARY_SUBTRACT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
128 newconst = PyNumber_Subtract(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
129 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
130 case BINARY_SUBSCR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
131 newconst = PyObject_GetItem(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
132 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
133 case BINARY_LSHIFT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
134 newconst = PyNumber_Lshift(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
135 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
136 case BINARY_RSHIFT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
137 newconst = PyNumber_Rshift(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
138 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
139 case BINARY_AND:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
140 newconst = PyNumber_And(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
141 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
142 case BINARY_XOR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
143 newconst = PyNumber_Xor(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
144 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
145 case BINARY_OR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
146 newconst = PyNumber_Or(v, w);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
147 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
148 default:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
149 /* Called with an unknown opcode */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
150 PyErr_Format(PyExc_SystemError,
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
151 "unexpected binary operation %d on a constant",
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
152 opcode);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
153 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
154 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
155 if (newconst == NULL) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
156 PyErr_Clear();
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
157 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
158 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
159 size = PyObject_Size(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
160 if (size == -1)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
161 PyErr_Clear();
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
162 else if (size > 20) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
163 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
164 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
165 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
166
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
167 /* Append folded constant into consts table */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
168 len_consts = PyList_GET_SIZE(consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
169 if (PyList_Append(consts, newconst)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
170 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
171 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
172 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
173 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
174
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
175 /* Write NOP NOP NOP NOP LOAD_CONST newconst */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
176 memset(codestr, NOP, 4);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
177 codestr[4] = LOAD_CONST;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
178 SETARG(codestr, 4, len_consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
179 return 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
180 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
181
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
182 static int
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
183 fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
184 {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
185 PyObject *newconst=NULL, *v;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
186 Py_ssize_t len_consts;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
187 int opcode;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
188
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
189 /* Pre-conditions */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
190 assert(PyList_CheckExact(consts));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
191 assert(codestr[0] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
192
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
193 /* Create new constant */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
194 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
195 opcode = codestr[3];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
196 switch (opcode) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
197 case UNARY_NEGATIVE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
198 /* Preserve the sign of -0.0 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
199 if (PyObject_IsTrue(v) == 1)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
200 newconst = PyNumber_Negative(v);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
201 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
202 case UNARY_CONVERT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
203 newconst = PyObject_Repr(v);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
204 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
205 case UNARY_INVERT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
206 newconst = PyNumber_Invert(v);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
207 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
208 default:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
209 /* Called with an unknown opcode */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
210 PyErr_Format(PyExc_SystemError,
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
211 "unexpected unary operation %d on a constant",
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
212 opcode);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
213 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
214 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
215 if (newconst == NULL) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
216 PyErr_Clear();
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
217 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
218 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
219
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
220 /* Append folded constant into consts table */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
221 len_consts = PyList_GET_SIZE(consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
222 if (PyList_Append(consts, newconst)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
223 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
224 return 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
225 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
226 Py_DECREF(newconst);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
227
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
228 /* Write NOP LOAD_CONST newconst */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
229 codestr[0] = NOP;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
230 codestr[1] = LOAD_CONST;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
231 SETARG(codestr, 1, len_consts);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
232 return 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
233 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
234
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
235 static unsigned int *
46062
09adff3d6691 Try to fix a bunch of compiler warnings on Win64.
Neal Norwitz <nnorwitz@gmail.com>
parents: 45511
diff changeset
236 markblocks(unsigned char *code, Py_ssize_t len)
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
237 {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
238 unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
239 int i,j, opcode, blockcnt = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
240
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
241 if (blocks == NULL) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
242 PyErr_NoMemory();
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
243 return NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
244 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
245 memset(blocks, 0, len*sizeof(int));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
246
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
247 /* Mark labels in the first pass */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
248 for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
249 opcode = code[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
250 switch (opcode) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
251 case FOR_ITER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
252 case JUMP_FORWARD:
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
253 case JUMP_IF_FALSE_OR_POP:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
254 case JUMP_IF_TRUE_OR_POP:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
255 case POP_JUMP_IF_FALSE:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
256 case POP_JUMP_IF_TRUE:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
257 case JUMP_ABSOLUTE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
258 case CONTINUE_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
259 case SETUP_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
260 case SETUP_EXCEPT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
261 case SETUP_FINALLY:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
262 j = GETJUMPTGT(code, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
263 blocks[j] = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
264 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
265 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
266 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
267 /* Build block numbers in the second pass */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
268 for (i=0 ; i<len ; i++) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
269 blockcnt += blocks[i]; /* increment blockcnt over labels */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
270 blocks[i] = blockcnt;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
271 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
272 return blocks;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
273 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
274
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
275 /* Perform basic peephole optimizations to components of a code object.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
276 The consts object should still be in list form to allow new constants
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
277 to be appended.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
278
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
279 To keep the optimizer simple, it bails out (does nothing) for code
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
280 containing extended arguments or that has a length over 32,700. That
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
281 allows us to avoid overflow and sign issues. Likewise, it bails when
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
282 the lineno table has complex encoding for gaps >= 255.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
283
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
284 Optimizations are restricted to simple transformations occuring within a
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
285 single basic block. All transformations keep the code size the same or
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
286 smaller. For those that reduce size, the gaps are initially filled with
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
287 NOPs. Later those NOPs are removed and the jump addresses retargeted in
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
288 a single pass. Line numbering is adjusted accordingly. */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
289
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
290 PyObject *
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
291 PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
292 PyObject *lineno_obj)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
293 {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
294 Py_ssize_t i, j, codelen;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
295 int nops, h, adj;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
296 int tgt, tgttgt, opcode;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
297 unsigned char *codestr = NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
298 unsigned char *lineno;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
299 int *addrmap = NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
300 int new_line, cum_orig_line, last_line, tabsiz;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
301 int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
302 unsigned int *blocks = NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
303 char *name;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
304
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
305 /* Bail out if an exception is set */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
306 if (PyErr_Occurred())
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
307 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
308
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
309 /* Bypass optimization when the lineno table is too complex */
47527
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
310 assert(PyString_Check(lineno_obj));
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
311 lineno = (unsigned char*)PyString_AS_STRING(lineno_obj);
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
312 tabsiz = PyString_GET_SIZE(lineno_obj);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
313 if (memchr(lineno, 255, tabsiz) != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
314 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
315
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
316 /* Avoid situations where jump retargeting could overflow */
47527
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
317 assert(PyString_Check(code));
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
318 codelen = PyString_GET_SIZE(code);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
319 if (codelen > 32700)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
320 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
321
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
322 /* Make a modifiable copy of the code string */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
323 codestr = (unsigned char *)PyMem_Malloc(codelen);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
324 if (codestr == NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
325 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
326 codestr = (unsigned char *)memcpy(codestr,
47527
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
327 PyString_AS_STRING(code), codelen);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
328
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
329 /* Verify that RETURN_VALUE terminates the codestring. This allows
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
330 the various transformation patterns to look ahead several
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
331 instructions without additional checks to make sure they are not
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
332 looking beyond the end of the code string.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
333 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
334 if (codestr[codelen-1] != RETURN_VALUE)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
335 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
336
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
337 /* Mapping to new jump targets after NOPs are removed */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
338 addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
339 if (addrmap == NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
340 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
341
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
342 blocks = markblocks(codestr, codelen);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
343 if (blocks == NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
344 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
345 assert(PyList_Check(consts));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
346
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
347 for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
348 reoptimize_current:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
349 opcode = codestr[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
350
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
351 lastlc = cumlc;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
352 cumlc = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
353
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
354 switch (opcode) {
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
355 /* Replace UNARY_NOT POP_JUMP_IF_FALSE
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
356 with POP_JUMP_IF_TRUE */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
357 case UNARY_NOT:
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
358 if (codestr[i+1] != POP_JUMP_IF_FALSE
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
359 || !ISBASICBLOCK(blocks,i,4))
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
360 continue;
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
361 j = GETARG(codestr, i+1);
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
362 codestr[i] = POP_JUMP_IF_TRUE;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
363 SETARG(codestr, i, j);
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
364 codestr[i+3] = NOP;
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
365 goto reoptimize_current;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
366
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
367 /* not a is b --> a is not b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
368 not a in b --> a not in b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
369 not a is not b --> a is b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
370 not a not in b --> a in b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
371 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
372 case COMPARE_OP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
373 j = GETARG(codestr, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
374 if (j < 6 || j > 9 ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
375 codestr[i+3] != UNARY_NOT ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
376 !ISBASICBLOCK(blocks,i,4))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
377 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
378 SETARG(codestr, i, (j^1));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
379 codestr[i+3] = NOP;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
380 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
381
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
382 /* Replace LOAD_GLOBAL/LOAD_NAME None
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
383 with LOAD_CONST None */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
384 case LOAD_NAME:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
385 case LOAD_GLOBAL:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
386 j = GETARG(codestr, i);
47527
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
387 name = PyString_AsString(PyTuple_GET_ITEM(names, j));
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
388 if (name == NULL || strcmp(name, "None") != 0)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
389 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
390 for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
40998
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
391 if (PyList_GET_ITEM(consts, j) == Py_None)
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
392 break;
40998
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
393 }
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
394 if (j == PyList_GET_SIZE(consts)) {
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
395 if (PyList_Append(consts, Py_None) == -1)
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
396 goto exitUnchanged;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
397 }
40998
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
398 assert(PyList_GET_ITEM(consts, j) == Py_None);
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
399 codestr[i] = LOAD_CONST;
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
400 SETARG(codestr, i, j);
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
401 cumlc = lastlc + 1;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
402 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
403
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
404 /* Skip over LOAD_CONST trueconst
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
405 POP_JUMP_IF_FALSE xx. This improves
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
406 "while 1" performance. */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
407 case LOAD_CONST:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
408 cumlc = lastlc + 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
409 j = GETARG(codestr, i);
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
410 if (codestr[i+3] != POP_JUMP_IF_FALSE ||
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
411 !ISBASICBLOCK(blocks,i,6) ||
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
412 !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
413 continue;
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
414 memset(codestr+i, NOP, 6);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
415 cumlc = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
416 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
417
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
418 /* Try to fold tuples of constants (includes a case for lists
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
419 which are only used for "in" and "not in" tests).
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
420 Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
421 Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
422 Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
423 case BUILD_TUPLE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
424 case BUILD_LIST:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
425 j = GETARG(codestr, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
426 h = i - 3 * j;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
427 if (h >= 0 &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
428 j <= lastlc &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
429 ((opcode == BUILD_TUPLE &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
430 ISBASICBLOCK(blocks, h, 3*(j+1))) ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
431 (opcode == BUILD_LIST &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
432 codestr[i+3]==COMPARE_OP &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
433 ISBASICBLOCK(blocks, h, 3*(j+2)) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
434 (GETARG(codestr,i+3)==6 ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
435 GETARG(codestr,i+3)==7))) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
436 tuple_of_constants(&codestr[h], j, consts)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
437 assert(codestr[i] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
438 cumlc = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
439 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
440 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
441 if (codestr[i+3] != UNPACK_SEQUENCE ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
442 !ISBASICBLOCK(blocks,i,6) ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
443 j != GETARG(codestr, i+3))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
444 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
445 if (j == 1) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
446 memset(codestr+i, NOP, 6);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
447 } else if (j == 2) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
448 codestr[i] = ROT_TWO;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
449 memset(codestr+i+1, NOP, 5);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
450 } else if (j == 3) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
451 codestr[i] = ROT_THREE;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
452 codestr[i+1] = ROT_TWO;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
453 memset(codestr+i+2, NOP, 4);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
454 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
455 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
456
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
457 /* Fold binary ops on constants.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
458 LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
459 case BINARY_POWER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
460 case BINARY_MULTIPLY:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
461 case BINARY_TRUE_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
462 case BINARY_FLOOR_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
463 case BINARY_MODULO:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
464 case BINARY_ADD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
465 case BINARY_SUBTRACT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
466 case BINARY_SUBSCR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
467 case BINARY_LSHIFT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
468 case BINARY_RSHIFT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
469 case BINARY_AND:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
470 case BINARY_XOR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
471 case BINARY_OR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
472 if (lastlc >= 2 &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
473 ISBASICBLOCK(blocks, i-6, 7) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
474 fold_binops_on_constants(&codestr[i-6], consts)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
475 i -= 2;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
476 assert(codestr[i] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
477 cumlc = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
478 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
479 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
480
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
481 /* Fold unary ops on constants.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
482 LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
483 case UNARY_NEGATIVE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
484 case UNARY_CONVERT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
485 case UNARY_INVERT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
486 if (lastlc >= 1 &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
487 ISBASICBLOCK(blocks, i-3, 4) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
488 fold_unaryops_on_constants(&codestr[i-3], consts)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
489 i -= 2;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
490 assert(codestr[i] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
491 cumlc = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
492 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
493 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
494
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
495 /* Simplify conditional jump to conditional jump where the
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
496 result of the first test implies the success of a similar
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
497 test or the failure of the opposite test.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
498 Arises in code like:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
499 "if a and b:"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
500 "if a or b:"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
501 "a and b or c"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
502 "(a and b) and c"
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
503 x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
504 --> x:JUMP_IF_FALSE_OR_POP z
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
505 x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
506 --> x:POP_JUMP_IF_FALSE y+3
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
507 where y+3 is the instruction following the second test.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
508 */
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
509 case JUMP_IF_FALSE_OR_POP:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
510 case JUMP_IF_TRUE_OR_POP:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
511 tgt = GETJUMPTGT(codestr, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
512 j = codestr[tgt];
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
513 if (CONDITIONAL_JUMP(j)) {
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
514 /* NOTE: all possible jumps here are
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
515 absolute! */
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
516 if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
517 /* The second jump will be
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
518 taken iff the first is. */
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
519 tgttgt = GETJUMPTGT(codestr, tgt);
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
520 /* The current opcode inherits
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
521 its target's stack behaviour */
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
522 codestr[i] = j;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
523 SETARG(codestr, i, tgttgt);
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
524 goto reoptimize_current;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
525 } else {
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
526 /* The second jump is not taken
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
527 if the first is (so jump past
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
528 it), and all conditional
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
529 jumps pop their argument when
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
530 they're not taken (so change
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
531 the first jump to pop its
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
532 argument when it's taken). */
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
533 if (JUMPS_ON_TRUE(opcode))
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
534 codestr[i] = POP_JUMP_IF_TRUE;
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
535 else
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
536 codestr[i] = POP_JUMP_IF_FALSE;
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
537 SETARG(codestr, i, (tgt + 3));
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
538 goto reoptimize_current;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
539 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
540 }
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
541 /* Intentional fallthrough */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
542
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
543 /* Replace jumps to unconditional jumps */
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
544 case POP_JUMP_IF_FALSE:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
545 case POP_JUMP_IF_TRUE:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
546 case FOR_ITER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
547 case JUMP_FORWARD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
548 case JUMP_ABSOLUTE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
549 case CONTINUE_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
550 case SETUP_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
551 case SETUP_EXCEPT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
552 case SETUP_FINALLY:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
553 tgt = GETJUMPTGT(codestr, i);
40116
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
554 /* Replace JUMP_* to a RETURN into just a RETURN */
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
555 if (UNCONDITIONAL_JUMP(opcode) &&
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
556 codestr[tgt] == RETURN_VALUE) {
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
557 codestr[i] = RETURN_VALUE;
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
558 memset(codestr+i+1, NOP, 2);
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
559 continue;
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
560 }
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
561 if (!UNCONDITIONAL_JUMP(codestr[tgt]))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
562 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
563 tgttgt = GETJUMPTGT(codestr, tgt);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
564 if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
565 opcode = JUMP_ABSOLUTE;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
566 if (!ABSOLUTE_JUMP(opcode))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
567 tgttgt -= i + 3; /* Calc relative jump addr */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
568 if (tgttgt < 0) /* No backward relative jumps */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
569 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
570 codestr[i] = opcode;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
571 SETARG(codestr, i, tgttgt);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
572 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
573
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
574 case EXTENDED_ARG:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
575 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
576
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
577 /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
40116
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
578 /* Remove unreachable JUMPs after RETURN */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
579 case RETURN_VALUE:
40116
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
580 if (i+4 >= codelen)
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
581 continue;
40116
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
582 if (codestr[i+4] == RETURN_VALUE &&
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
583 ISBASICBLOCK(blocks,i,5))
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
584 memset(codestr+i+1, NOP, 4);
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
585 else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
586 ISBASICBLOCK(blocks,i,4))
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
587 memset(codestr+i+1, NOP, 3);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
588 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
589 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
590 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
591
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
592 /* Fixup linenotab */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
593 for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
594 addrmap[i] = i - nops;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
595 if (codestr[i] == NOP)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
596 nops++;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
597 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
598 cum_orig_line = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
599 last_line = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
600 for (i=0 ; i < tabsiz ; i+=2) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
601 cum_orig_line += lineno[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
602 new_line = addrmap[cum_orig_line];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
603 assert (new_line - last_line < 255);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
604 lineno[i] =((unsigned char)(new_line - last_line));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
605 last_line = new_line;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
606 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
607
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
608 /* Remove NOPs and fixup jump targets */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
609 for (i=0, h=0 ; i<codelen ; ) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
610 opcode = codestr[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
611 switch (opcode) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
612 case NOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
613 i++;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
614 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
615
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
616 case JUMP_ABSOLUTE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
617 case CONTINUE_LOOP:
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
618 case POP_JUMP_IF_FALSE:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
619 case POP_JUMP_IF_TRUE:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
620 case JUMP_IF_FALSE_OR_POP:
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
621 case JUMP_IF_TRUE_OR_POP:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
622 j = addrmap[GETARG(codestr, i)];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
623 SETARG(codestr, i, j);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
624 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
625
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
626 case FOR_ITER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
627 case JUMP_FORWARD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
628 case SETUP_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
629 case SETUP_EXCEPT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
630 case SETUP_FINALLY:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
631 j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
632 SETARG(codestr, i, j);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
633 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
634 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
635 adj = CODESIZE(opcode);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
636 while (adj--)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
637 codestr[h++] = codestr[i++];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
638 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
639 assert(h + nops == codelen);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
640
47527
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
641 code = PyString_FromStringAndSize((char *)codestr, h);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
642 PyMem_Free(addrmap);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
643 PyMem_Free(codestr);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
644 PyMem_Free(blocks);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
645 return code;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
646
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
647 exitUnchanged:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
648 if (blocks != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
649 PyMem_Free(blocks);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
650 if (addrmap != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
651 PyMem_Free(addrmap);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
652 if (codestr != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
653 PyMem_Free(codestr);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
654 Py_INCREF(code);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
655 return code;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
656 }