annotate Python/peephole.c @ 58765:2ba7677bfa95 legacy-trunk

testCopysign was defined twice in test_math; combine the definitions
author Mark Dickinson <dickinsm@gmail.com>
date Sat, 06 Feb 2010 23:11:25 +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 }