blob: 359eda833b2c63fdfad7d15857ab03dc09395caf [file] [log] [blame]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001/* Peephole optimizations for bytecode compiler. */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002
3#include "Python.h"
4
5#include "Python-ast.h"
6#include "node.h"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00007#include "ast.h"
8#include "code.h"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00009#include "symtable.h"
10#include "opcode.h"
11
12#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
Jeffrey Yasskin9de7ec72009-02-25 02:25:04 +000014#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000015 || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
Jeffrey Yasskin9de7ec72009-02-25 02:25:04 +000016#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
18 || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
Jeffrey Yasskin9de7ec72009-02-25 02:25:04 +000019#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000020#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
21#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
22#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1)
23#define ISBASICBLOCK(blocks, start, bytes) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000024 (blocks[start]==blocks[start+bytes-1])
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000025
26/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 with LOAD_CONST (c1, c2, ... cn).
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000028 The consts table must still be in list form so that the
29 new constant (c1, c2, ... cn) can be appended.
30 Called with codestr pointing to the first LOAD_CONST.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 Bails out with no change if one or more of the LOAD_CONSTs is missing.
Antoine Pitroub7fbcd32010-01-16 18:37:38 +000032 Also works for BUILD_LIST and BUILT_SET when followed by an "in" or "not in"
33 test; for BUILD_SET it assembles a frozenset rather than a tuple.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000034*/
35static int
Christian Heimescc47b052008-03-25 14:56:36 +000036tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000037{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 PyObject *newconst, *constant;
39 Py_ssize_t i, arg, len_consts;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 /* Pre-conditions */
42 assert(PyList_CheckExact(consts));
43 assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST || codestr[n*3] == BUILD_SET);
44 assert(GETARG(codestr, (n*3)) == n);
45 for (i=0 ; i<n ; i++)
46 assert(codestr[i*3] == LOAD_CONST);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000048 /* Buildup new tuple of constants */
49 newconst = PyTuple_New(n);
50 if (newconst == NULL)
51 return 0;
52 len_consts = PyList_GET_SIZE(consts);
53 for (i=0 ; i<n ; i++) {
54 arg = GETARG(codestr, (i*3));
55 assert(arg < len_consts);
56 constant = PyList_GET_ITEM(consts, arg);
57 Py_INCREF(constant);
58 PyTuple_SET_ITEM(newconst, i, constant);
59 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 /* If it's a BUILD_SET, use the PyTuple we just built to create a
62 PyFrozenSet, and use that as the constant instead: */
63 if (codestr[n*3] == BUILD_SET) {
64 PyObject *tuple = newconst;
65 newconst = PyFrozenSet_New(tuple);
66 Py_DECREF(tuple);
67 if (newconst == NULL)
68 return 0;
69 }
Antoine Pitroub7fbcd32010-01-16 18:37:38 +000070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 /* Append folded constant onto consts */
72 if (PyList_Append(consts, newconst)) {
73 Py_DECREF(newconst);
74 return 0;
75 }
76 Py_DECREF(newconst);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 /* Write NOPs over old LOAD_CONSTS and
79 add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
80 memset(codestr, NOP, n*3);
81 codestr[n*3] = LOAD_CONST;
82 SETARG(codestr, (n*3), len_consts);
83 return 1;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000084}
85
86/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 with LOAD_CONST binop(c1,c2)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000088 The consts table must still be in list form so that the
89 new constant can be appended.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 Called with codestr pointing to the first LOAD_CONST.
91 Abandons the transformation if the folding fails (i.e. 1+'a').
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000092 If the new constant is a sequence, only folds when the size
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 is below a threshold value. That keeps pyc files from
94 becoming large in the presence of code like: (None,)*1000.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000095*/
96static int
97fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
98{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 PyObject *newconst, *v, *w;
100 Py_ssize_t len_consts, size;
101 int opcode;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 /* Pre-conditions */
104 assert(PyList_CheckExact(consts));
105 assert(codestr[0] == LOAD_CONST);
106 assert(codestr[3] == LOAD_CONST);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000108 /* Create new constant */
109 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
110 w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
111 opcode = codestr[6];
112 switch (opcode) {
113 case BINARY_POWER:
114 newconst = PyNumber_Power(v, w, Py_None);
115 break;
116 case BINARY_MULTIPLY:
117 newconst = PyNumber_Multiply(v, w);
118 break;
119 case BINARY_TRUE_DIVIDE:
120 newconst = PyNumber_TrueDivide(v, w);
121 break;
122 case BINARY_FLOOR_DIVIDE:
123 newconst = PyNumber_FloorDivide(v, w);
124 break;
125 case BINARY_MODULO:
126 newconst = PyNumber_Remainder(v, w);
127 break;
128 case BINARY_ADD:
129 newconst = PyNumber_Add(v, w);
130 break;
131 case BINARY_SUBTRACT:
132 newconst = PyNumber_Subtract(v, w);
133 break;
134 case BINARY_SUBSCR:
135 newconst = PyObject_GetItem(v, w);
Ezio Melotti2df6a932011-04-15 16:38:34 +0300136 /* #5057: if v is unicode, there might be differences between
137 wide and narrow builds in cases like '\U00012345'[0].
138 Wide builds will return a non-BMP char, whereas narrow builds
139 will return a surrogate. In both the cases skip the
140 optimization in order to produce compatible pycs.
141 */
142 if (newconst != NULL &&
143 PyUnicode_Check(v) && PyUnicode_Check(newconst)) {
144 Py_UNICODE ch = PyUnicode_AS_UNICODE(newconst)[0];
145#ifdef Py_UNICODE_WIDE
146 if (ch > 0xFFFF) {
147#else
148 if (ch >= 0xD800 && ch <= 0xDFFF) {
149#endif
150 Py_DECREF(newconst);
151 return 0;
152 }
153 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 break;
155 case BINARY_LSHIFT:
156 newconst = PyNumber_Lshift(v, w);
157 break;
158 case BINARY_RSHIFT:
159 newconst = PyNumber_Rshift(v, w);
160 break;
161 case BINARY_AND:
162 newconst = PyNumber_And(v, w);
163 break;
164 case BINARY_XOR:
165 newconst = PyNumber_Xor(v, w);
166 break;
167 case BINARY_OR:
168 newconst = PyNumber_Or(v, w);
169 break;
170 default:
171 /* Called with an unknown opcode */
172 PyErr_Format(PyExc_SystemError,
173 "unexpected binary operation %d on a constant",
174 opcode);
175 return 0;
176 }
177 if (newconst == NULL) {
Raymond Hettinger819a0642010-08-22 08:39:49 +0000178 if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt))
179 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 return 0;
181 }
182 size = PyObject_Size(newconst);
Raymond Hettinger819a0642010-08-22 08:39:49 +0000183 if (size == -1) {
184 if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt))
185 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 PyErr_Clear();
Raymond Hettinger819a0642010-08-22 08:39:49 +0000187 } else if (size > 20) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 Py_DECREF(newconst);
189 return 0;
190 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000191
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 /* Append folded constant into consts table */
193 len_consts = PyList_GET_SIZE(consts);
194 if (PyList_Append(consts, newconst)) {
195 Py_DECREF(newconst);
196 return 0;
197 }
198 Py_DECREF(newconst);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 /* Write NOP NOP NOP NOP LOAD_CONST newconst */
201 memset(codestr, NOP, 4);
202 codestr[4] = LOAD_CONST;
203 SETARG(codestr, 4, len_consts);
204 return 1;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000205}
206
207static int
208fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 PyObject *newconst=NULL, *v;
211 Py_ssize_t len_consts;
212 int opcode;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 /* Pre-conditions */
215 assert(PyList_CheckExact(consts));
216 assert(codestr[0] == LOAD_CONST);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 /* Create new constant */
219 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
220 opcode = codestr[3];
221 switch (opcode) {
222 case UNARY_NEGATIVE:
223 /* Preserve the sign of -0.0 */
224 if (PyObject_IsTrue(v) == 1)
225 newconst = PyNumber_Negative(v);
226 break;
227 case UNARY_INVERT:
228 newconst = PyNumber_Invert(v);
229 break;
230 case UNARY_POSITIVE:
231 newconst = PyNumber_Positive(v);
232 break;
233 default:
234 /* Called with an unknown opcode */
235 PyErr_Format(PyExc_SystemError,
236 "unexpected unary operation %d on a constant",
237 opcode);
238 return 0;
239 }
240 if (newconst == NULL) {
Raymond Hettinger819a0642010-08-22 08:39:49 +0000241 if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt))
242 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 return 0;
244 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 /* Append folded constant into consts table */
247 len_consts = PyList_GET_SIZE(consts);
248 if (PyList_Append(consts, newconst)) {
249 Py_DECREF(newconst);
250 return 0;
251 }
252 Py_DECREF(newconst);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 /* Write NOP LOAD_CONST newconst */
255 codestr[0] = NOP;
256 codestr[1] = LOAD_CONST;
257 SETARG(codestr, 1, len_consts);
258 return 1;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000259}
260
261static unsigned int *
Christian Heimescc47b052008-03-25 14:56:36 +0000262markblocks(unsigned char *code, Py_ssize_t len)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000263{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
265 int i,j, opcode, blockcnt = 0;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 if (blocks == NULL) {
268 PyErr_NoMemory();
269 return NULL;
270 }
271 memset(blocks, 0, len*sizeof(int));
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 /* Mark labels in the first pass */
274 for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
275 opcode = code[i];
276 switch (opcode) {
277 case FOR_ITER:
278 case JUMP_FORWARD:
279 case JUMP_IF_FALSE_OR_POP:
280 case JUMP_IF_TRUE_OR_POP:
281 case POP_JUMP_IF_FALSE:
282 case POP_JUMP_IF_TRUE:
283 case JUMP_ABSOLUTE:
284 case CONTINUE_LOOP:
285 case SETUP_LOOP:
286 case SETUP_EXCEPT:
287 case SETUP_FINALLY:
288 case SETUP_WITH:
289 j = GETJUMPTGT(code, i);
290 blocks[j] = 1;
291 break;
292 }
293 }
294 /* Build block numbers in the second pass */
295 for (i=0 ; i<len ; i++) {
296 blockcnt += blocks[i]; /* increment blockcnt over labels */
297 blocks[i] = blockcnt;
298 }
299 return blocks;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000300}
301
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000302/* Helper to replace LOAD_NAME None/True/False with LOAD_CONST
303 Returns: 0 if no change, 1 if change, -1 if error */
304static int
305load_global(unsigned char *codestr, Py_ssize_t i, char *name, PyObject *consts)
306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 Py_ssize_t j;
308 PyObject *obj;
309 if (name == NULL)
310 return 0;
311 if (strcmp(name, "None") == 0)
312 obj = Py_None;
313 else if (strcmp(name, "True") == 0)
314 obj = Py_True;
315 else if (strcmp(name, "False") == 0)
316 obj = Py_False;
317 else
318 return 0;
319 for (j = 0; j < PyList_GET_SIZE(consts); j++) {
320 if (PyList_GET_ITEM(consts, j) == obj)
321 break;
322 }
323 if (j == PyList_GET_SIZE(consts)) {
324 if (PyList_Append(consts, obj) < 0)
325 return -1;
326 }
327 assert(PyList_GET_ITEM(consts, j) == obj);
328 codestr[i] = LOAD_CONST;
329 SETARG(codestr, i, j);
330 return 1;
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000331}
332
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000333/* Perform basic peephole optimizations to components of a code object.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 The consts object should still be in list form to allow new constants
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000335 to be appended.
336
Guido van Rossum0240b922007-02-26 21:23:50 +0000337 To keep the optimizer simple, it bails out (does nothing) for code that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 has a length over 32,700, and does not calculate extended arguments.
Guido van Rossum0240b922007-02-26 21:23:50 +0000339 That allows us to avoid overflow and sign issues. Likewise, it bails when
340 the lineno table has complex encoding for gaps >= 255. EXTENDED_ARG can
341 appear before MAKE_FUNCTION; in this case both opcodes are skipped.
342 EXTENDED_ARG preceding any other opcode causes the optimizer to bail.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000343
344 Optimizations are restricted to simple transformations occuring within a
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 single basic block. All transformations keep the code size the same or
346 smaller. For those that reduce size, the gaps are initially filled with
347 NOPs. Later those NOPs are removed and the jump addresses retargeted in
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000348 a single pass. Line numbering is adjusted accordingly. */
349
350PyObject *
351PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
352 PyObject *lineno_obj)
353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 Py_ssize_t i, j, codelen;
355 int nops, h, adj;
356 int tgt, tgttgt, opcode;
357 unsigned char *codestr = NULL;
358 unsigned char *lineno;
359 int *addrmap = NULL;
360 int new_line, cum_orig_line, last_line, tabsiz;
361 int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
362 unsigned int *blocks = NULL;
363 char *name;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 /* Bail out if an exception is set */
366 if (PyErr_Occurred())
367 goto exitError;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 /* Bypass optimization when the lineno table is too complex */
370 assert(PyBytes_Check(lineno_obj));
371 lineno = (unsigned char*)PyBytes_AS_STRING(lineno_obj);
372 tabsiz = PyBytes_GET_SIZE(lineno_obj);
373 if (memchr(lineno, 255, tabsiz) != NULL)
374 goto exitUnchanged;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 /* Avoid situations where jump retargeting could overflow */
377 assert(PyBytes_Check(code));
378 codelen = PyBytes_GET_SIZE(code);
379 if (codelen > 32700)
380 goto exitUnchanged;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 /* Make a modifiable copy of the code string */
383 codestr = (unsigned char *)PyMem_Malloc(codelen);
384 if (codestr == NULL)
385 goto exitError;
386 codestr = (unsigned char *)memcpy(codestr,
387 PyBytes_AS_STRING(code), codelen);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 /* Verify that RETURN_VALUE terminates the codestring. This allows
390 the various transformation patterns to look ahead several
391 instructions without additional checks to make sure they are not
392 looking beyond the end of the code string.
393 */
394 if (codestr[codelen-1] != RETURN_VALUE)
395 goto exitUnchanged;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 /* Mapping to new jump targets after NOPs are removed */
398 addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
399 if (addrmap == NULL)
400 goto exitError;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 blocks = markblocks(codestr, codelen);
403 if (blocks == NULL)
404 goto exitError;
405 assert(PyList_Check(consts));
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
408 reoptimize_current:
409 opcode = codestr[i];
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 lastlc = cumlc;
412 cumlc = 0;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 switch (opcode) {
415 /* Replace UNARY_NOT POP_JUMP_IF_FALSE
416 with POP_JUMP_IF_TRUE */
417 case UNARY_NOT:
418 if (codestr[i+1] != POP_JUMP_IF_FALSE
419 || !ISBASICBLOCK(blocks,i,4))
420 continue;
421 j = GETARG(codestr, i+1);
422 codestr[i] = POP_JUMP_IF_TRUE;
423 SETARG(codestr, i, j);
424 codestr[i+3] = NOP;
425 goto reoptimize_current;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 /* not a is b --> a is not b
428 not a in b --> a not in b
429 not a is not b --> a is b
430 not a not in b --> a in b
431 */
432 case COMPARE_OP:
433 j = GETARG(codestr, i);
434 if (j < 6 || j > 9 ||
435 codestr[i+3] != UNARY_NOT ||
436 !ISBASICBLOCK(blocks,i,4))
437 continue;
438 SETARG(codestr, i, (j^1));
439 codestr[i+3] = NOP;
440 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 /* Replace LOAD_GLOBAL/LOAD_NAME None/True/False
443 with LOAD_CONST None/True/False */
444 case LOAD_NAME:
445 case LOAD_GLOBAL:
446 j = GETARG(codestr, i);
447 name = _PyUnicode_AsString(PyTuple_GET_ITEM(names, j));
448 h = load_global(codestr, i, name, consts);
449 if (h < 0)
450 goto exitError;
451 else if (h == 0)
452 continue;
453 cumlc = lastlc + 1;
454 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 /* Skip over LOAD_CONST trueconst
457 POP_JUMP_IF_FALSE xx. This improves
458 "while 1" performance. */
459 case LOAD_CONST:
460 cumlc = lastlc + 1;
461 j = GETARG(codestr, i);
462 if (codestr[i+3] != POP_JUMP_IF_FALSE ||
463 !ISBASICBLOCK(blocks,i,6) ||
464 !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
465 continue;
466 memset(codestr+i, NOP, 6);
467 cumlc = 0;
468 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 /* Try to fold tuples of constants (includes a case for lists and sets
471 which are only used for "in" and "not in" tests).
472 Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
473 Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
474 Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
475 case BUILD_TUPLE:
476 case BUILD_LIST:
477 case BUILD_SET:
478 j = GETARG(codestr, i);
479 h = i - 3 * j;
480 if (h >= 0 &&
481 j <= lastlc &&
482 ((opcode == BUILD_TUPLE &&
483 ISBASICBLOCK(blocks, h, 3*(j+1))) ||
484 ((opcode == BUILD_LIST || opcode == BUILD_SET) &&
485 codestr[i+3]==COMPARE_OP &&
486 ISBASICBLOCK(blocks, h, 3*(j+2)) &&
487 (GETARG(codestr,i+3)==6 ||
488 GETARG(codestr,i+3)==7))) &&
489 tuple_of_constants(&codestr[h], j, consts)) {
490 assert(codestr[i] == LOAD_CONST);
491 cumlc = 1;
492 break;
493 }
494 if (codestr[i+3] != UNPACK_SEQUENCE ||
495 !ISBASICBLOCK(blocks,i,6) ||
Raymond Hettinger29dcaad2011-03-15 14:50:16 -0700496 j != GETARG(codestr, i+3) ||
497 opcode == BUILD_SET)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 continue;
499 if (j == 1) {
500 memset(codestr+i, NOP, 6);
501 } else if (j == 2) {
502 codestr[i] = ROT_TWO;
503 memset(codestr+i+1, NOP, 5);
504 } else if (j == 3) {
505 codestr[i] = ROT_THREE;
506 codestr[i+1] = ROT_TWO;
507 memset(codestr+i+2, NOP, 4);
508 }
509 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 /* Fold binary ops on constants.
512 LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
513 case BINARY_POWER:
514 case BINARY_MULTIPLY:
515 case BINARY_TRUE_DIVIDE:
516 case BINARY_FLOOR_DIVIDE:
517 case BINARY_MODULO:
518 case BINARY_ADD:
519 case BINARY_SUBTRACT:
520 case BINARY_SUBSCR:
521 case BINARY_LSHIFT:
522 case BINARY_RSHIFT:
523 case BINARY_AND:
524 case BINARY_XOR:
525 case BINARY_OR:
526 if (lastlc >= 2 &&
527 ISBASICBLOCK(blocks, i-6, 7) &&
528 fold_binops_on_constants(&codestr[i-6], consts)) {
529 i -= 2;
530 assert(codestr[i] == LOAD_CONST);
531 cumlc = 1;
532 }
533 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 /* Fold unary ops on constants.
536 LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
537 case UNARY_NEGATIVE:
538 case UNARY_INVERT:
539 case UNARY_POSITIVE:
540 if (lastlc >= 1 &&
541 ISBASICBLOCK(blocks, i-3, 4) &&
542 fold_unaryops_on_constants(&codestr[i-3], consts)) {
543 i -= 2;
544 assert(codestr[i] == LOAD_CONST);
545 cumlc = 1;
546 }
547 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 /* Simplify conditional jump to conditional jump where the
550 result of the first test implies the success of a similar
551 test or the failure of the opposite test.
552 Arises in code like:
553 "if a and b:"
554 "if a or b:"
555 "a and b or c"
556 "(a and b) and c"
557 x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z
558 --> x:JUMP_IF_FALSE_OR_POP z
559 x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z
560 --> x:POP_JUMP_IF_FALSE y+3
561 where y+3 is the instruction following the second test.
562 */
563 case JUMP_IF_FALSE_OR_POP:
564 case JUMP_IF_TRUE_OR_POP:
565 tgt = GETJUMPTGT(codestr, i);
566 j = codestr[tgt];
567 if (CONDITIONAL_JUMP(j)) {
568 /* NOTE: all possible jumps here are
569 absolute! */
570 if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
571 /* The second jump will be
572 taken iff the first is. */
573 tgttgt = GETJUMPTGT(codestr, tgt);
574 /* The current opcode inherits
575 its target's stack behaviour */
576 codestr[i] = j;
577 SETARG(codestr, i, tgttgt);
578 goto reoptimize_current;
579 } else {
580 /* The second jump is not taken
581 if the first is (so jump past
582 it), and all conditional
583 jumps pop their argument when
584 they're not taken (so change
585 the first jump to pop its
586 argument when it's taken). */
587 if (JUMPS_ON_TRUE(opcode))
588 codestr[i] = POP_JUMP_IF_TRUE;
589 else
590 codestr[i] = POP_JUMP_IF_FALSE;
591 SETARG(codestr, i, (tgt + 3));
592 goto reoptimize_current;
593 }
594 }
595 /* Intentional fallthrough */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 /* Replace jumps to unconditional jumps */
598 case POP_JUMP_IF_FALSE:
599 case POP_JUMP_IF_TRUE:
600 case FOR_ITER:
601 case JUMP_FORWARD:
602 case JUMP_ABSOLUTE:
603 case CONTINUE_LOOP:
604 case SETUP_LOOP:
605 case SETUP_EXCEPT:
606 case SETUP_FINALLY:
607 case SETUP_WITH:
608 tgt = GETJUMPTGT(codestr, i);
609 /* Replace JUMP_* to a RETURN into just a RETURN */
610 if (UNCONDITIONAL_JUMP(opcode) &&
611 codestr[tgt] == RETURN_VALUE) {
612 codestr[i] = RETURN_VALUE;
613 memset(codestr+i+1, NOP, 2);
614 continue;
615 }
616 if (!UNCONDITIONAL_JUMP(codestr[tgt]))
617 continue;
618 tgttgt = GETJUMPTGT(codestr, tgt);
619 if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
620 opcode = JUMP_ABSOLUTE;
621 if (!ABSOLUTE_JUMP(opcode))
622 tgttgt -= i + 3; /* Calc relative jump addr */
623 if (tgttgt < 0) /* No backward relative jumps */
624 continue;
625 codestr[i] = opcode;
626 SETARG(codestr, i, tgttgt);
627 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 case EXTENDED_ARG:
630 if (codestr[i+3] != MAKE_FUNCTION)
631 goto exitUnchanged;
632 /* don't visit MAKE_FUNCTION as GETARG will be wrong */
633 i += 3;
634 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
637 /* Remove unreachable JUMPs after RETURN */
638 case RETURN_VALUE:
639 if (i+4 >= codelen)
640 continue;
641 if (codestr[i+4] == RETURN_VALUE &&
642 ISBASICBLOCK(blocks,i,5))
643 memset(codestr+i+1, NOP, 4);
644 else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
645 ISBASICBLOCK(blocks,i,4))
646 memset(codestr+i+1, NOP, 3);
647 break;
648 }
649 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 /* Fixup linenotab */
652 for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
653 addrmap[i] = i - nops;
654 if (codestr[i] == NOP)
655 nops++;
656 }
657 cum_orig_line = 0;
658 last_line = 0;
659 for (i=0 ; i < tabsiz ; i+=2) {
660 cum_orig_line += lineno[i];
661 new_line = addrmap[cum_orig_line];
662 assert (new_line - last_line < 255);
663 lineno[i] =((unsigned char)(new_line - last_line));
664 last_line = new_line;
665 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 /* Remove NOPs and fixup jump targets */
668 for (i=0, h=0 ; i<codelen ; ) {
669 opcode = codestr[i];
670 switch (opcode) {
671 case NOP:
672 i++;
673 continue;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 case JUMP_ABSOLUTE:
676 case CONTINUE_LOOP:
677 case POP_JUMP_IF_FALSE:
678 case POP_JUMP_IF_TRUE:
679 case JUMP_IF_FALSE_OR_POP:
680 case JUMP_IF_TRUE_OR_POP:
681 j = addrmap[GETARG(codestr, i)];
682 SETARG(codestr, i, j);
683 break;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 case FOR_ITER:
686 case JUMP_FORWARD:
687 case SETUP_LOOP:
688 case SETUP_EXCEPT:
689 case SETUP_FINALLY:
690 case SETUP_WITH:
691 j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
692 SETARG(codestr, i, j);
693 break;
694 }
695 adj = CODESIZE(opcode);
696 while (adj--)
697 codestr[h++] = codestr[i++];
698 }
699 assert(h + nops == codelen);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 code = PyBytes_FromStringAndSize((char *)codestr, h);
702 PyMem_Free(addrmap);
703 PyMem_Free(codestr);
704 PyMem_Free(blocks);
705 return code;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000706
Alexandre Vassalotti6f828182009-07-21 02:51:58 +0000707 exitError:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 code = NULL;
Alexandre Vassalotti6f828182009-07-21 02:51:58 +0000709
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000710 exitUnchanged:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 if (blocks != NULL)
712 PyMem_Free(blocks);
713 if (addrmap != NULL)
714 PyMem_Free(addrmap);
715 if (codestr != NULL)
716 PyMem_Free(codestr);
717 Py_XINCREF(code);
718 return code;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000719}