annotate Python/peephole.c @ 58973:db86bf39ccaa legacy-trunk

Issue 7970: When email.Parser.Parser parses a MIME message of type message/rfc822 it turns it into an object whose body consists of a list containing a single Message object. HeaderParser, on the other hand, just copies the body as a string. Generator.flatten has a special handler for the message mime type that expected the body to be the one item list. This fails if the message was parsed by HeaderParser. So we now check to see if the body is a string first, and if so just we just emit it.
author R. David Murray <rdmurray@bitdance.com>
date Sun, 21 Feb 2010 04:23:00 +0000
parents e0d27b76a2e8
children fd25030223b0
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:
54353
ba305fe8e831 teach the peepholer about SETUP_WITH
Benjamin Peterson <benjamin@python.org>
parents: 51920
diff changeset
262 case SETUP_WITH:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
263 j = GETJUMPTGT(code, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
264 blocks[j] = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
265 break;
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 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
268 /* Build block numbers in the second pass */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
269 for (i=0 ; i<len ; i++) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
270 blockcnt += blocks[i]; /* increment blockcnt over labels */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
271 blocks[i] = blockcnt;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
272 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
273 return blocks;
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
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
276 /* 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
277 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
278 to be appended.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
279
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
280 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
281 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
282 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
283 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
284
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
285 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
286 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
287 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
288 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
289 a single pass. Line numbering is adjusted accordingly. */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
290
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
291 PyObject *
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
292 PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
293 PyObject *lineno_obj)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
294 {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
295 Py_ssize_t i, j, codelen;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
296 int nops, h, adj;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
297 int tgt, tgttgt, opcode;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
298 unsigned char *codestr = NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
299 unsigned char *lineno;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
300 int *addrmap = NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
301 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
302 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
303 unsigned int *blocks = NULL;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
304 char *name;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
305
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
306 /* Bail out if an exception is set */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
307 if (PyErr_Occurred())
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
308 goto exitError;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
309
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
310 /* 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
311 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
312 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
313 tabsiz = PyString_GET_SIZE(lineno_obj);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
314 if (memchr(lineno, 255, tabsiz) != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
315 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
316
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
317 /* 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
318 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
319 codelen = PyString_GET_SIZE(code);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
320 if (codelen > 32700)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
321 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
322
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
323 /* Make a modifiable copy of the code string */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
324 codestr = (unsigned char *)PyMem_Malloc(codelen);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
325 if (codestr == NULL)
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
326 goto exitError;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
327 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
328 PyString_AS_STRING(code), codelen);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
329
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
330 /* 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
331 the various transformation patterns to look ahead several
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
332 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
333 looking beyond the end of the code string.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
334 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
335 if (codestr[codelen-1] != RETURN_VALUE)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
336 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
337
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
338 /* 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
339 addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
340 if (addrmap == NULL)
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
341 goto exitError;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
342
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
343 blocks = markblocks(codestr, codelen);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
344 if (blocks == NULL)
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
345 goto exitError;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
346 assert(PyList_Check(consts));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
347
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
348 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
349 reoptimize_current:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
350 opcode = codestr[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
351
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
352 lastlc = cumlc;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
353 cumlc = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
354
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
355 switch (opcode) {
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
356 /* 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
357 with POP_JUMP_IF_TRUE */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
358 case UNARY_NOT:
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
359 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
360 || !ISBASICBLOCK(blocks,i,4))
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
361 continue;
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
362 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
363 codestr[i] = POP_JUMP_IF_TRUE;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
364 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
365 codestr[i+3] = NOP;
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
366 goto reoptimize_current;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
367
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
368 /* not a is b --> a is not b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
369 not a in b --> a not in b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
370 not a is not b --> a is b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
371 not a not in b --> a in b
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
372 */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
373 case COMPARE_OP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
374 j = GETARG(codestr, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
375 if (j < 6 || j > 9 ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
376 codestr[i+3] != UNARY_NOT ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
377 !ISBASICBLOCK(blocks,i,4))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
378 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
379 SETARG(codestr, i, (j^1));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
380 codestr[i+3] = NOP;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
381 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
382
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
383 /* Replace LOAD_GLOBAL/LOAD_NAME None
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
384 with LOAD_CONST None */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
385 case LOAD_NAME:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
386 case LOAD_GLOBAL:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
387 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
388 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
389 if (name == NULL || strcmp(name, "None") != 0)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
390 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
391 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
392 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
393 break;
40998
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
394 }
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
395 if (j == PyList_GET_SIZE(consts)) {
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
396 if (PyList_Append(consts, Py_None) == -1)
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
397 goto exitError;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
398 }
40998
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
399 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
400 codestr[i] = LOAD_CONST;
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
401 SETARG(codestr, i, j);
4e3481961fbb Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents: 40116
diff changeset
402 cumlc = lastlc + 1;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
403 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
404
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
405 /* 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
406 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
407 "while 1" performance. */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
408 case LOAD_CONST:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
409 cumlc = lastlc + 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
410 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
411 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
412 !ISBASICBLOCK(blocks,i,6) ||
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
413 !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
414 continue;
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
415 memset(codestr+i, NOP, 6);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
416 cumlc = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
417 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
418
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
419 /* 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
420 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
421 Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
422 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
423 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
424 case BUILD_TUPLE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
425 case BUILD_LIST:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
426 j = GETARG(codestr, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
427 h = i - 3 * j;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
428 if (h >= 0 &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
429 j <= lastlc &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
430 ((opcode == BUILD_TUPLE &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
431 ISBASICBLOCK(blocks, h, 3*(j+1))) ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
432 (opcode == BUILD_LIST &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
433 codestr[i+3]==COMPARE_OP &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
434 ISBASICBLOCK(blocks, h, 3*(j+2)) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
435 (GETARG(codestr,i+3)==6 ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
436 GETARG(codestr,i+3)==7))) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
437 tuple_of_constants(&codestr[h], j, consts)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
438 assert(codestr[i] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
439 cumlc = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
440 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
441 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
442 if (codestr[i+3] != UNPACK_SEQUENCE ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
443 !ISBASICBLOCK(blocks,i,6) ||
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
444 j != GETARG(codestr, i+3))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
445 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
446 if (j == 1) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
447 memset(codestr+i, NOP, 6);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
448 } else if (j == 2) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
449 codestr[i] = ROT_TWO;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
450 memset(codestr+i+1, NOP, 5);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
451 } else if (j == 3) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
452 codestr[i] = ROT_THREE;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
453 codestr[i+1] = ROT_TWO;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
454 memset(codestr+i+2, NOP, 4);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
455 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
456 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
457
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
458 /* Fold binary ops on constants.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
459 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
460 case BINARY_POWER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
461 case BINARY_MULTIPLY:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
462 case BINARY_TRUE_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
463 case BINARY_FLOOR_DIVIDE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
464 case BINARY_MODULO:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
465 case BINARY_ADD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
466 case BINARY_SUBTRACT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
467 case BINARY_SUBSCR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
468 case BINARY_LSHIFT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
469 case BINARY_RSHIFT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
470 case BINARY_AND:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
471 case BINARY_XOR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
472 case BINARY_OR:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
473 if (lastlc >= 2 &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
474 ISBASICBLOCK(blocks, i-6, 7) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
475 fold_binops_on_constants(&codestr[i-6], consts)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
476 i -= 2;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
477 assert(codestr[i] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
478 cumlc = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
479 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
480 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
481
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
482 /* Fold unary ops on constants.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
483 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
484 case UNARY_NEGATIVE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
485 case UNARY_CONVERT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
486 case UNARY_INVERT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
487 if (lastlc >= 1 &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
488 ISBASICBLOCK(blocks, i-3, 4) &&
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
489 fold_unaryops_on_constants(&codestr[i-3], consts)) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
490 i -= 2;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
491 assert(codestr[i] == LOAD_CONST);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
492 cumlc = 1;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
493 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
494 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
495
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
496 /* Simplify conditional jump to conditional jump where the
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
497 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
498 test or the failure of the opposite test.
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
499 Arises in code like:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
500 "if a and b:"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
501 "if a or b:"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
502 "a and b or c"
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
503 "(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
504 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
505 --> 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
506 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
507 --> x:POP_JUMP_IF_FALSE y+3
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
508 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
509 */
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
510 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
511 case JUMP_IF_TRUE_OR_POP:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
512 tgt = GETJUMPTGT(codestr, i);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
513 j = codestr[tgt];
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
514 if (CONDITIONAL_JUMP(j)) {
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
515 /* 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
516 absolute! */
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
517 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
518 /* 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
519 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
520 tgttgt = GETJUMPTGT(codestr, tgt);
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
521 /* The current opcode inherits
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
522 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
523 codestr[i] = j;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
524 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
525 goto reoptimize_current;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
526 } else {
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
527 /* 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
528 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
529 it), and all conditional
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
530 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
531 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
532 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
533 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
534 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
535 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
536 else
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
537 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
538 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
539 goto reoptimize_current;
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
540 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
541 }
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
542 /* Intentional fallthrough */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
543
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
544 /* 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
545 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
546 case POP_JUMP_IF_TRUE:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
547 case FOR_ITER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
548 case JUMP_FORWARD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
549 case JUMP_ABSOLUTE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
550 case CONTINUE_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
551 case SETUP_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
552 case SETUP_EXCEPT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
553 case SETUP_FINALLY:
54353
ba305fe8e831 teach the peepholer about SETUP_WITH
Benjamin Peterson <benjamin@python.org>
parents: 51920
diff changeset
554 case SETUP_WITH:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
555 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
556 /* 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
557 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
558 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
559 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
560 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
561 continue;
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
562 }
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
563 if (!UNCONDITIONAL_JUMP(codestr[tgt]))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
564 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
565 tgttgt = GETJUMPTGT(codestr, tgt);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
566 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
567 opcode = JUMP_ABSOLUTE;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
568 if (!ABSOLUTE_JUMP(opcode))
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
569 tgttgt -= i + 3; /* Calc relative jump addr */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
570 if (tgttgt < 0) /* No backward relative jumps */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
571 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
572 codestr[i] = opcode;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
573 SETARG(codestr, i, tgttgt);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
574 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
575
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
576 case EXTENDED_ARG:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
577 goto exitUnchanged;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
578
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
579 /* 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
580 /* Remove unreachable JUMPs after RETURN */
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
581 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
582 if (i+4 >= codelen)
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
583 continue;
40116
3985d7e2067d Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents: 39600
diff changeset
584 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
585 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
586 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
587 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
588 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
589 memset(codestr+i+1, NOP, 3);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
590 break;
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 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
593
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
594 /* Fixup linenotab */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
595 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
596 addrmap[i] = i - nops;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
597 if (codestr[i] == NOP)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
598 nops++;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
599 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
600 cum_orig_line = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
601 last_line = 0;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
602 for (i=0 ; i < tabsiz ; i+=2) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
603 cum_orig_line += lineno[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
604 new_line = addrmap[cum_orig_line];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
605 assert (new_line - last_line < 255);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
606 lineno[i] =((unsigned char)(new_line - last_line));
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
607 last_line = new_line;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
608 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
609
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
610 /* Remove NOPs and fixup jump targets */
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
611 for (i=0, h=0 ; i<codelen ; ) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
612 opcode = codestr[i];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
613 switch (opcode) {
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
614 case NOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
615 i++;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
616 continue;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
617
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
618 case JUMP_ABSOLUTE:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
619 case CONTINUE_LOOP:
51920
ef8fe9088696 Backport r69961 to trunk, replacing JUMP_IF_{TRUE,FALSE} with
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 47527
diff changeset
620 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
621 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
622 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
623 case JUMP_IF_TRUE_OR_POP:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
624 j = addrmap[GETARG(codestr, i)];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
625 SETARG(codestr, i, j);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
626 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
627
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
628 case FOR_ITER:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
629 case JUMP_FORWARD:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
630 case SETUP_LOOP:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
631 case SETUP_EXCEPT:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
632 case SETUP_FINALLY:
54353
ba305fe8e831 teach the peepholer about SETUP_WITH
Benjamin Peterson <benjamin@python.org>
parents: 51920
diff changeset
633 case SETUP_WITH:
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
634 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
635 SETARG(codestr, i, j);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
636 break;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
637 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
638 adj = CODESIZE(opcode);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
639 while (adj--)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
640 codestr[h++] = codestr[i++];
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
641 }
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
642 assert(h + nops == codelen);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
643
47527
52294af4b663 This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents: 47294
diff changeset
644 code = PyString_FromStringAndSize((char *)codestr, h);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
645 PyMem_Free(addrmap);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
646 PyMem_Free(codestr);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
647 PyMem_Free(blocks);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
648 return code;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
649
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
650 exitError:
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
651 code = NULL;
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
652
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
653 exitUnchanged:
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
654 if (blocks != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
655 PyMem_Free(blocks);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
656 if (addrmap != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
657 PyMem_Free(addrmap);
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
658 if (codestr != NULL)
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
659 PyMem_Free(codestr);
54972
e0d27b76a2e8 Fix error handling in PyCode_Optimize, by Alexander Schremmer at EuroPython sprint.
Georg Brandl <georg@python.org>
parents: 54353
diff changeset
660 Py_XINCREF(code);
39600
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
661 return code;
5e143944770b Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
662 }