blob: ae84efa996e8ce7ff6d7a6e9e26369789860f619 [file] [log] [blame]
Raymond Hettinger20e11992007-03-02 19:20:46 +00001/* Peephole optimizations for bytecode compiler. */
Jeremy Hylton644dddc2006-08-21 16:19:37 +00002
3#include "Python.h"
4
5#include "Python-ast.h"
6#include "node.h"
7#include "pyarena.h"
8#include "ast.h"
9#include "code.h"
10#include "compile.h"
11#include "symtable.h"
12#include "opcode.h"
13
14#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
Antoine Pitrouc83ea132010-05-09 14:46:46 +000015#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +000016#define CONDITIONAL_JUMP(op) (op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
Antoine Pitrouc83ea132010-05-09 14:46:46 +000017 || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +000018#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP \
Antoine Pitrouc83ea132010-05-09 14:46:46 +000019 || op==POP_JUMP_IF_FALSE || op==POP_JUMP_IF_TRUE \
20 || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +000021#define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP)
Jeremy Hylton644dddc2006-08-21 16:19:37 +000022#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
23#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
24#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1)
25#define ISBASICBLOCK(blocks, start, bytes) \
Antoine Pitrouc83ea132010-05-09 14:46:46 +000026 (blocks[start]==blocks[start+bytes-1])
Jeremy Hylton644dddc2006-08-21 16:19:37 +000027
28/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
Antoine Pitrouc83ea132010-05-09 14:46:46 +000029 with LOAD_CONST (c1, c2, ... cn).
Jeremy Hylton644dddc2006-08-21 16:19:37 +000030 The consts table must still be in list form so that the
31 new constant (c1, c2, ... cn) can be appended.
32 Called with codestr pointing to the first LOAD_CONST.
Antoine Pitrouc83ea132010-05-09 14:46:46 +000033 Bails out with no change if one or more of the LOAD_CONSTs is missing.
Jeremy Hylton644dddc2006-08-21 16:19:37 +000034 Also works for BUILD_LIST when followed by an "in" or "not in" test.
35*/
36static int
Neal Norwitz4677fbf72008-03-25 04:18:18 +000037tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)
Jeremy Hylton644dddc2006-08-21 16:19:37 +000038{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000039 PyObject *newconst, *constant;
40 Py_ssize_t i, arg, len_consts;
Jeremy Hylton644dddc2006-08-21 16:19:37 +000041
Antoine Pitrouc83ea132010-05-09 14:46:46 +000042 /* Pre-conditions */
43 assert(PyList_CheckExact(consts));
44 assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
45 assert(GETARG(codestr, (n*3)) == n);
46 for (i=0 ; i<n ; i++)
47 assert(codestr[i*3] == LOAD_CONST);
Jeremy Hylton644dddc2006-08-21 16:19:37 +000048
Antoine Pitrouc83ea132010-05-09 14:46:46 +000049 /* Buildup new tuple of constants */
50 newconst = PyTuple_New(n);
51 if (newconst == NULL)
52 return 0;
53 len_consts = PyList_GET_SIZE(consts);
54 for (i=0 ; i<n ; i++) {
55 arg = GETARG(codestr, (i*3));
56 assert(arg < len_consts);
57 constant = PyList_GET_ITEM(consts, arg);
58 Py_INCREF(constant);
59 PyTuple_SET_ITEM(newconst, i, constant);
60 }
Jeremy Hylton644dddc2006-08-21 16:19:37 +000061
Antoine Pitrouc83ea132010-05-09 14:46:46 +000062 /* Append folded constant onto consts */
63 if (PyList_Append(consts, newconst)) {
64 Py_DECREF(newconst);
65 return 0;
66 }
67 Py_DECREF(newconst);
Jeremy Hylton644dddc2006-08-21 16:19:37 +000068
Antoine Pitrouc83ea132010-05-09 14:46:46 +000069 /* Write NOPs over old LOAD_CONSTS and
70 add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
71 memset(codestr, NOP, n*3);
72 codestr[n*3] = LOAD_CONST;
73 SETARG(codestr, (n*3), len_consts);
74 return 1;
Jeremy Hylton644dddc2006-08-21 16:19:37 +000075}
76
77/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
Antoine Pitrouc83ea132010-05-09 14:46:46 +000078 with LOAD_CONST binop(c1,c2)
Jeremy Hylton644dddc2006-08-21 16:19:37 +000079 The consts table must still be in list form so that the
80 new constant can be appended.
Antoine Pitrouc83ea132010-05-09 14:46:46 +000081 Called with codestr pointing to the first LOAD_CONST.
82 Abandons the transformation if the folding fails (i.e. 1+'a').
Jeremy Hylton644dddc2006-08-21 16:19:37 +000083 If the new constant is a sequence, only folds when the size
Antoine Pitrouc83ea132010-05-09 14:46:46 +000084 is below a threshold value. That keeps pyc files from
85 becoming large in the presence of code like: (None,)*1000.
Jeremy Hylton644dddc2006-08-21 16:19:37 +000086*/
87static int
88fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
89{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000090 PyObject *newconst, *v, *w;
91 Py_ssize_t len_consts, size;
92 int opcode;
Jeremy Hylton644dddc2006-08-21 16:19:37 +000093
Antoine Pitrouc83ea132010-05-09 14:46:46 +000094 /* Pre-conditions */
95 assert(PyList_CheckExact(consts));
96 assert(codestr[0] == LOAD_CONST);
97 assert(codestr[3] == LOAD_CONST);
Jeremy Hylton644dddc2006-08-21 16:19:37 +000098
Antoine Pitrouc83ea132010-05-09 14:46:46 +000099 /* Create new constant */
100 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
101 w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
102 opcode = codestr[6];
103 switch (opcode) {
104 case BINARY_POWER:
105 newconst = PyNumber_Power(v, w, Py_None);
106 break;
107 case BINARY_MULTIPLY:
108 newconst = PyNumber_Multiply(v, w);
109 break;
110 case BINARY_DIVIDE:
111 /* Cannot fold this operation statically since
112 the result can depend on the run-time presence
113 of the -Qnew flag */
114 return 0;
115 case BINARY_TRUE_DIVIDE:
116 newconst = PyNumber_TrueDivide(v, w);
117 break;
118 case BINARY_FLOOR_DIVIDE:
119 newconst = PyNumber_FloorDivide(v, w);
120 break;
121 case BINARY_MODULO:
122 newconst = PyNumber_Remainder(v, w);
123 break;
124 case BINARY_ADD:
125 newconst = PyNumber_Add(v, w);
126 break;
127 case BINARY_SUBTRACT:
128 newconst = PyNumber_Subtract(v, w);
129 break;
130 case BINARY_SUBSCR:
131 newconst = PyObject_GetItem(v, w);
Ezio Melottic283a852011-04-15 16:14:04 +0300132 /* #5057: if v is unicode, there might be differences between
133 wide and narrow builds in cases like u'\U00012345'[0].
134 Wide builds will return a non-BMP char, whereas narrow builds
135 will return a surrogate. In both the cases skip the
136 optimization in order to produce compatible pycs.
137 */
Martin v. Löwised11a5d2012-05-20 10:42:17 +0200138#ifdef Py_USING_UNICODE
Ezio Melottic283a852011-04-15 16:14:04 +0300139 if (newconst != NULL &&
140 PyUnicode_Check(v) && PyUnicode_Check(newconst)) {
141 Py_UNICODE ch = PyUnicode_AS_UNICODE(newconst)[0];
142#ifdef Py_UNICODE_WIDE
143 if (ch > 0xFFFF) {
144#else
145 if (ch >= 0xD800 && ch <= 0xDFFF) {
146#endif
147 Py_DECREF(newconst);
148 return 0;
149 }
150 }
Martin v. Löwised11a5d2012-05-20 10:42:17 +0200151#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000152 break;
153 case BINARY_LSHIFT:
154 newconst = PyNumber_Lshift(v, w);
155 break;
156 case BINARY_RSHIFT:
157 newconst = PyNumber_Rshift(v, w);
158 break;
159 case BINARY_AND:
160 newconst = PyNumber_And(v, w);
161 break;
162 case BINARY_XOR:
163 newconst = PyNumber_Xor(v, w);
164 break;
165 case BINARY_OR:
166 newconst = PyNumber_Or(v, w);
167 break;
168 default:
169 /* Called with an unknown opcode */
170 PyErr_Format(PyExc_SystemError,
171 "unexpected binary operation %d on a constant",
172 opcode);
173 return 0;
174 }
175 if (newconst == NULL) {
176 PyErr_Clear();
177 return 0;
178 }
179 size = PyObject_Size(newconst);
180 if (size == -1)
181 PyErr_Clear();
182 else if (size > 20) {
183 Py_DECREF(newconst);
184 return 0;
185 }
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000186
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000187 /* Append folded constant into consts table */
188 len_consts = PyList_GET_SIZE(consts);
189 if (PyList_Append(consts, newconst)) {
190 Py_DECREF(newconst);
191 return 0;
192 }
193 Py_DECREF(newconst);
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000194
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000195 /* Write NOP NOP NOP NOP LOAD_CONST newconst */
196 memset(codestr, NOP, 4);
197 codestr[4] = LOAD_CONST;
198 SETARG(codestr, 4, len_consts);
199 return 1;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000200}
201
202static int
203fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
204{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000205 PyObject *newconst=NULL, *v;
206 Py_ssize_t len_consts;
207 int opcode;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000208
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000209 /* Pre-conditions */
210 assert(PyList_CheckExact(consts));
211 assert(codestr[0] == LOAD_CONST);
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000212
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000213 /* Create new constant */
214 v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
215 opcode = codestr[3];
216 switch (opcode) {
217 case UNARY_NEGATIVE:
218 /* Preserve the sign of -0.0 */
219 if (PyObject_IsTrue(v) == 1)
220 newconst = PyNumber_Negative(v);
221 break;
222 case UNARY_CONVERT:
223 newconst = PyObject_Repr(v);
224 break;
225 case UNARY_INVERT:
226 newconst = PyNumber_Invert(v);
227 break;
228 default:
229 /* Called with an unknown opcode */
230 PyErr_Format(PyExc_SystemError,
231 "unexpected unary operation %d on a constant",
232 opcode);
233 return 0;
234 }
235 if (newconst == NULL) {
236 PyErr_Clear();
237 return 0;
238 }
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000239
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000240 /* Append folded constant into consts table */
241 len_consts = PyList_GET_SIZE(consts);
242 if (PyList_Append(consts, newconst)) {
243 Py_DECREF(newconst);
244 return 0;
245 }
246 Py_DECREF(newconst);
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000247
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000248 /* Write NOP LOAD_CONST newconst */
249 codestr[0] = NOP;
250 codestr[1] = LOAD_CONST;
251 SETARG(codestr, 1, len_consts);
252 return 1;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000253}
254
255static unsigned int *
Neal Norwitz4677fbf72008-03-25 04:18:18 +0000256markblocks(unsigned char *code, Py_ssize_t len)
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000257{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000258 unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
259 int i,j, opcode, blockcnt = 0;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000260
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000261 if (blocks == NULL) {
262 PyErr_NoMemory();
263 return NULL;
264 }
265 memset(blocks, 0, len*sizeof(int));
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000266
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000267 /* Mark labels in the first pass */
268 for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
269 opcode = code[i];
270 switch (opcode) {
271 case FOR_ITER:
272 case JUMP_FORWARD:
273 case JUMP_IF_FALSE_OR_POP:
274 case JUMP_IF_TRUE_OR_POP:
275 case POP_JUMP_IF_FALSE:
276 case POP_JUMP_IF_TRUE:
277 case JUMP_ABSOLUTE:
278 case CONTINUE_LOOP:
279 case SETUP_LOOP:
280 case SETUP_EXCEPT:
281 case SETUP_FINALLY:
282 case SETUP_WITH:
283 j = GETJUMPTGT(code, i);
284 blocks[j] = 1;
285 break;
286 }
287 }
288 /* Build block numbers in the second pass */
289 for (i=0 ; i<len ; i++) {
290 blockcnt += blocks[i]; /* increment blockcnt over labels */
291 blocks[i] = blockcnt;
292 }
293 return blocks;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000294}
295
296/* Perform basic peephole optimizations to components of a code object.
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000297 The consts object should still be in list form to allow new constants
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000298 to be appended.
299
300 To keep the optimizer simple, it bails out (does nothing) for code
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000301 containing extended arguments or that has a length over 32,700. That
302 allows us to avoid overflow and sign issues. Likewise, it bails when
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000303 the lineno table has complex encoding for gaps >= 255.
304
305 Optimizations are restricted to simple transformations occuring within a
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000306 single basic block. All transformations keep the code size the same or
307 smaller. For those that reduce size, the gaps are initially filled with
308 NOPs. Later those NOPs are removed and the jump addresses retargeted in
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000309 a single pass. Line numbering is adjusted accordingly. */
310
311PyObject *
312PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
313 PyObject *lineno_obj)
314{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000315 Py_ssize_t i, j, codelen;
316 int nops, h, adj;
317 int tgt, tgttgt, opcode;
318 unsigned char *codestr = NULL;
319 unsigned char *lineno;
320 int *addrmap = NULL;
321 int new_line, cum_orig_line, last_line, tabsiz;
322 int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
323 unsigned int *blocks = NULL;
324 char *name;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000325
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000326 /* Bail out if an exception is set */
327 if (PyErr_Occurred())
328 goto exitError;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000329
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000330 /* Bypass optimization when the lineno table is too complex */
331 assert(PyString_Check(lineno_obj));
332 lineno = (unsigned char*)PyString_AS_STRING(lineno_obj);
333 tabsiz = PyString_GET_SIZE(lineno_obj);
334 if (memchr(lineno, 255, tabsiz) != NULL)
335 goto exitUnchanged;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000336
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000337 /* Avoid situations where jump retargeting could overflow */
338 assert(PyString_Check(code));
339 codelen = PyString_GET_SIZE(code);
340 if (codelen > 32700)
341 goto exitUnchanged;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000342
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000343 /* Make a modifiable copy of the code string */
344 codestr = (unsigned char *)PyMem_Malloc(codelen);
345 if (codestr == NULL)
346 goto exitError;
347 codestr = (unsigned char *)memcpy(codestr,
348 PyString_AS_STRING(code), codelen);
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000349
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700350 /* Verify that RETURN_VALUE terminates the codestring. This allows
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 the various transformation patterns to look ahead several
352 instructions without additional checks to make sure they are not
353 looking beyond the end of the code string.
354 */
355 if (codestr[codelen-1] != RETURN_VALUE)
356 goto exitUnchanged;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000357
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000358 /* Mapping to new jump targets after NOPs are removed */
359 addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
360 if (addrmap == NULL)
361 goto exitError;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000362
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000363 blocks = markblocks(codestr, codelen);
364 if (blocks == NULL)
365 goto exitError;
366 assert(PyList_Check(consts));
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000367
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000368 for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
369 reoptimize_current:
370 opcode = codestr[i];
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000371
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000372 lastlc = cumlc;
373 cumlc = 0;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000374
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000375 switch (opcode) {
376 /* Replace UNARY_NOT POP_JUMP_IF_FALSE
377 with POP_JUMP_IF_TRUE */
378 case UNARY_NOT:
379 if (codestr[i+1] != POP_JUMP_IF_FALSE
380 || !ISBASICBLOCK(blocks,i,4))
381 continue;
382 j = GETARG(codestr, i+1);
383 codestr[i] = POP_JUMP_IF_TRUE;
384 SETARG(codestr, i, j);
385 codestr[i+3] = NOP;
386 goto reoptimize_current;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000387
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000388 /* not a is b --> a is not b
389 not a in b --> a not in b
390 not a is not b --> a is b
391 not a not in b --> a in b
392 */
393 case COMPARE_OP:
394 j = GETARG(codestr, i);
395 if (j < 6 || j > 9 ||
396 codestr[i+3] != UNARY_NOT ||
397 !ISBASICBLOCK(blocks,i,4))
398 continue;
399 SETARG(codestr, i, (j^1));
400 codestr[i+3] = NOP;
401 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000402
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000403 /* Replace LOAD_GLOBAL/LOAD_NAME None
404 with LOAD_CONST None */
405 case LOAD_NAME:
406 case LOAD_GLOBAL:
407 j = GETARG(codestr, i);
408 name = PyString_AsString(PyTuple_GET_ITEM(names, j));
409 if (name == NULL || strcmp(name, "None") != 0)
410 continue;
411 for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
412 if (PyList_GET_ITEM(consts, j) == Py_None)
413 break;
414 }
415 if (j == PyList_GET_SIZE(consts)) {
416 if (PyList_Append(consts, Py_None) == -1)
417 goto exitError;
418 }
419 assert(PyList_GET_ITEM(consts, j) == Py_None);
420 codestr[i] = LOAD_CONST;
421 SETARG(codestr, i, j);
422 cumlc = lastlc + 1;
423 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000424
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000425 /* Skip over LOAD_CONST trueconst
426 POP_JUMP_IF_FALSE xx. This improves
427 "while 1" performance. */
428 case LOAD_CONST:
429 cumlc = lastlc + 1;
430 j = GETARG(codestr, i);
431 if (codestr[i+3] != POP_JUMP_IF_FALSE ||
432 !ISBASICBLOCK(blocks,i,6) ||
433 !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
434 continue;
435 memset(codestr+i, NOP, 6);
436 cumlc = 0;
437 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000438
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000439 /* Try to fold tuples of constants (includes a case for lists
440 which are only used for "in" and "not in" tests).
441 Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
442 Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
443 Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
444 case BUILD_TUPLE:
445 case BUILD_LIST:
446 j = GETARG(codestr, i);
447 h = i - 3 * j;
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700448 if (h >= 0 &&
449 j <= lastlc &&
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000450 ((opcode == BUILD_TUPLE &&
451 ISBASICBLOCK(blocks, h, 3*(j+1))) ||
452 (opcode == BUILD_LIST &&
453 codestr[i+3]==COMPARE_OP &&
454 ISBASICBLOCK(blocks, h, 3*(j+2)) &&
455 (GETARG(codestr,i+3)==6 ||
456 GETARG(codestr,i+3)==7))) &&
457 tuple_of_constants(&codestr[h], j, consts)) {
458 assert(codestr[i] == LOAD_CONST);
459 cumlc = 1;
460 break;
461 }
462 if (codestr[i+3] != UNPACK_SEQUENCE ||
463 !ISBASICBLOCK(blocks,i,6) ||
464 j != GETARG(codestr, i+3))
465 continue;
466 if (j == 1) {
467 memset(codestr+i, NOP, 6);
468 } else if (j == 2) {
469 codestr[i] = ROT_TWO;
470 memset(codestr+i+1, NOP, 5);
471 } else if (j == 3) {
472 codestr[i] = ROT_THREE;
473 codestr[i+1] = ROT_TWO;
474 memset(codestr+i+2, NOP, 4);
475 }
476 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000477
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000478 /* Fold binary ops on constants.
479 LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
480 case BINARY_POWER:
481 case BINARY_MULTIPLY:
482 case BINARY_TRUE_DIVIDE:
483 case BINARY_FLOOR_DIVIDE:
484 case BINARY_MODULO:
485 case BINARY_ADD:
486 case BINARY_SUBTRACT:
487 case BINARY_SUBSCR:
488 case BINARY_LSHIFT:
489 case BINARY_RSHIFT:
490 case BINARY_AND:
491 case BINARY_XOR:
492 case BINARY_OR:
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700493 if (lastlc >= 2 &&
494 ISBASICBLOCK(blocks, i-6, 7) &&
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000495 fold_binops_on_constants(&codestr[i-6], consts)) {
496 i -= 2;
497 assert(codestr[i] == LOAD_CONST);
498 cumlc = 1;
499 }
500 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000501
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000502 /* Fold unary ops on constants.
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700503 LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000504 case UNARY_NEGATIVE:
505 case UNARY_CONVERT:
506 case UNARY_INVERT:
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700507 if (lastlc >= 1 &&
508 ISBASICBLOCK(blocks, i-3, 4) &&
509 fold_unaryops_on_constants(&codestr[i-3], consts)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000510 i -= 2;
511 assert(codestr[i] == LOAD_CONST);
512 cumlc = 1;
513 }
514 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000515
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000516 /* Simplify conditional jump to conditional jump where the
517 result of the first test implies the success of a similar
518 test or the failure of the opposite test.
519 Arises in code like:
520 "if a and b:"
521 "if a or b:"
522 "a and b or c"
523 "(a and b) and c"
524 x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z
525 --> x:JUMP_IF_FALSE_OR_POP z
526 x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z
527 --> x:POP_JUMP_IF_FALSE y+3
528 where y+3 is the instruction following the second test.
529 */
530 case JUMP_IF_FALSE_OR_POP:
531 case JUMP_IF_TRUE_OR_POP:
532 tgt = GETJUMPTGT(codestr, i);
533 j = codestr[tgt];
534 if (CONDITIONAL_JUMP(j)) {
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700535 /* NOTE: all possible jumps here are absolute! */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000536 if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
537 /* The second jump will be
538 taken iff the first is. */
539 tgttgt = GETJUMPTGT(codestr, tgt);
540 /* The current opcode inherits
541 its target's stack behaviour */
542 codestr[i] = j;
543 SETARG(codestr, i, tgttgt);
544 goto reoptimize_current;
545 } else {
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700546 /* The second jump is not taken if the first is (so
547 jump past it), and all conditional jumps pop their
548 argument when they're not taken (so change the
549 first jump to pop its argument when it's taken). */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 if (JUMPS_ON_TRUE(opcode))
551 codestr[i] = POP_JUMP_IF_TRUE;
552 else
553 codestr[i] = POP_JUMP_IF_FALSE;
554 SETARG(codestr, i, (tgt + 3));
555 goto reoptimize_current;
556 }
557 }
558 /* Intentional fallthrough */
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000559
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000560 /* Replace jumps to unconditional jumps */
561 case POP_JUMP_IF_FALSE:
562 case POP_JUMP_IF_TRUE:
563 case FOR_ITER:
564 case JUMP_FORWARD:
565 case JUMP_ABSOLUTE:
566 case CONTINUE_LOOP:
567 case SETUP_LOOP:
568 case SETUP_EXCEPT:
569 case SETUP_FINALLY:
570 case SETUP_WITH:
571 tgt = GETJUMPTGT(codestr, i);
572 /* Replace JUMP_* to a RETURN into just a RETURN */
573 if (UNCONDITIONAL_JUMP(opcode) &&
574 codestr[tgt] == RETURN_VALUE) {
575 codestr[i] = RETURN_VALUE;
576 memset(codestr+i+1, NOP, 2);
577 continue;
578 }
579 if (!UNCONDITIONAL_JUMP(codestr[tgt]))
580 continue;
581 tgttgt = GETJUMPTGT(codestr, tgt);
582 if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
583 opcode = JUMP_ABSOLUTE;
584 if (!ABSOLUTE_JUMP(opcode))
Raymond Hettingerdee8af22012-07-20 17:47:59 -0700585 tgttgt -= i + 3; /* Calc relative jump addr */
586 if (tgttgt < 0) /* No backward relative jumps */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000587 continue;
588 codestr[i] = opcode;
589 SETARG(codestr, i, tgttgt);
590 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000591
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000592 case EXTENDED_ARG:
593 goto exitUnchanged;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000594
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000595 /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
596 /* Remove unreachable JUMPs after RETURN */
597 case RETURN_VALUE:
598 if (i+4 >= codelen)
599 continue;
600 if (codestr[i+4] == RETURN_VALUE &&
601 ISBASICBLOCK(blocks,i,5))
602 memset(codestr+i+1, NOP, 4);
603 else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
604 ISBASICBLOCK(blocks,i,4))
605 memset(codestr+i+1, NOP, 3);
606 break;
607 }
608 }
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000609
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000610 /* Fixup linenotab */
611 for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
612 addrmap[i] = i - nops;
613 if (codestr[i] == NOP)
614 nops++;
615 }
616 cum_orig_line = 0;
617 last_line = 0;
618 for (i=0 ; i < tabsiz ; i+=2) {
619 cum_orig_line += lineno[i];
620 new_line = addrmap[cum_orig_line];
621 assert (new_line - last_line < 255);
622 lineno[i] =((unsigned char)(new_line - last_line));
623 last_line = new_line;
624 }
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000625
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000626 /* Remove NOPs and fixup jump targets */
627 for (i=0, h=0 ; i<codelen ; ) {
628 opcode = codestr[i];
629 switch (opcode) {
630 case NOP:
631 i++;
632 continue;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000633
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000634 case JUMP_ABSOLUTE:
635 case CONTINUE_LOOP:
636 case POP_JUMP_IF_FALSE:
637 case POP_JUMP_IF_TRUE:
638 case JUMP_IF_FALSE_OR_POP:
639 case JUMP_IF_TRUE_OR_POP:
640 j = addrmap[GETARG(codestr, i)];
641 SETARG(codestr, i, j);
642 break;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000643
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000644 case FOR_ITER:
645 case JUMP_FORWARD:
646 case SETUP_LOOP:
647 case SETUP_EXCEPT:
648 case SETUP_FINALLY:
649 case SETUP_WITH:
650 j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
651 SETARG(codestr, i, j);
652 break;
653 }
654 adj = CODESIZE(opcode);
655 while (adj--)
656 codestr[h++] = codestr[i++];
657 }
658 assert(h + nops == codelen);
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000659
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 code = PyString_FromStringAndSize((char *)codestr, h);
661 PyMem_Free(addrmap);
662 PyMem_Free(codestr);
663 PyMem_Free(blocks);
664 return code;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000665
Georg Brandle323e0e2009-06-29 14:44:49 +0000666 exitError:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000667 code = NULL;
Georg Brandle323e0e2009-06-29 14:44:49 +0000668
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000669 exitUnchanged:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000670 if (blocks != NULL)
671 PyMem_Free(blocks);
672 if (addrmap != NULL)
673 PyMem_Free(addrmap);
674 if (codestr != NULL)
675 PyMem_Free(codestr);
676 Py_XINCREF(code);
677 return code;
Jeremy Hylton644dddc2006-08-21 16:19:37 +0000678}