Mercurial > cpython-lru_cache-weakref
annotate Python/peephole.c @ 49955:878d40468c4e legacy-trunk
Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
| author | Vinay Sajip <vinay_sajip@yahoo.co.uk> |
|---|---|
| date | Wed, 03 Dec 2008 23:22:58 +0000 |
| parents | 52294af4b663 |
| children | 97d7cd365dd5 ef8fe9088696 |
| 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) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
16 #define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
17 #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
|
18 #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
|
19 #define CODESIZE(op) (HAS_ARG(op) ? 3 : 1) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
20 #define ISBASICBLOCK(blocks, start, bytes) \ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
21 (blocks[start]==blocks[start+bytes-1]) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
22 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
23 /* 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
|
24 with LOAD_CONST (c1, c2, ... cn). |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
25 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
|
26 new constant (c1, c2, ... cn) can be appended. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
27 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
|
28 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
|
29 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
|
30 */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
31 static int |
|
46062
09adff3d6691
Try to fix a bunch of compiler warnings on Win64.
Neal Norwitz <nnorwitz@gmail.com>
parents:
45511
diff
changeset
|
32 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
|
33 { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
34 PyObject *newconst, *constant; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
35 Py_ssize_t i, arg, len_consts; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
36 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
37 /* Pre-conditions */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
38 assert(PyList_CheckExact(consts)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
39 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
|
40 assert(GETARG(codestr, (n*3)) == n); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
41 for (i=0 ; i<n ; i++) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
42 assert(codestr[i*3] == LOAD_CONST); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
43 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
44 /* Buildup new tuple of constants */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
45 newconst = PyTuple_New(n); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
46 if (newconst == NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
47 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
48 len_consts = PyList_GET_SIZE(consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
49 for (i=0 ; i<n ; i++) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
50 arg = GETARG(codestr, (i*3)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
51 assert(arg < len_consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
52 constant = PyList_GET_ITEM(consts, arg); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
53 Py_INCREF(constant); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
54 PyTuple_SET_ITEM(newconst, i, constant); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
55 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
56 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
57 /* Append folded constant onto consts */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
58 if (PyList_Append(consts, newconst)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
59 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
60 return 0; |
|
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 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
63 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
64 /* Write NOPs over old LOAD_CONSTS and |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
65 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
|
66 memset(codestr, NOP, n*3); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
67 codestr[n*3] = LOAD_CONST; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
68 SETARG(codestr, (n*3), len_consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
69 return 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
70 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
71 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
72 /* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
73 with LOAD_CONST binop(c1,c2) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
74 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
|
75 new constant can be appended. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
76 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
|
77 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
|
78 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
|
79 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
|
80 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
|
81 */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
82 static int |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
83 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
|
84 { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
85 PyObject *newconst, *v, *w; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
86 Py_ssize_t len_consts, size; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
87 int opcode; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
88 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
89 /* Pre-conditions */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
90 assert(PyList_CheckExact(consts)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
91 assert(codestr[0] == LOAD_CONST); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
92 assert(codestr[3] == LOAD_CONST); |
|
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 /* Create new constant */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
95 v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
96 w = PyList_GET_ITEM(consts, GETARG(codestr, 3)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
97 opcode = codestr[6]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
98 switch (opcode) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
99 case BINARY_POWER: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
100 newconst = PyNumber_Power(v, w, Py_None); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
101 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
102 case BINARY_MULTIPLY: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
103 newconst = PyNumber_Multiply(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
104 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
105 case BINARY_DIVIDE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
106 /* Cannot fold this operation statically since |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
107 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
|
108 of the -Qnew flag */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
109 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
110 case BINARY_TRUE_DIVIDE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
111 newconst = PyNumber_TrueDivide(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
112 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
113 case BINARY_FLOOR_DIVIDE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
114 newconst = PyNumber_FloorDivide(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
115 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
116 case BINARY_MODULO: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
117 newconst = PyNumber_Remainder(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
118 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
119 case BINARY_ADD: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
120 newconst = PyNumber_Add(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
121 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
122 case BINARY_SUBTRACT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
123 newconst = PyNumber_Subtract(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
124 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
125 case BINARY_SUBSCR: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
126 newconst = PyObject_GetItem(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
127 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
128 case BINARY_LSHIFT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
129 newconst = PyNumber_Lshift(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
130 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
131 case BINARY_RSHIFT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
132 newconst = PyNumber_Rshift(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
133 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
134 case BINARY_AND: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
135 newconst = PyNumber_And(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
136 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
137 case BINARY_XOR: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
138 newconst = PyNumber_Xor(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
139 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
140 case BINARY_OR: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
141 newconst = PyNumber_Or(v, w); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
142 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
143 default: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
144 /* Called with an unknown opcode */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
145 PyErr_Format(PyExc_SystemError, |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
146 "unexpected binary operation %d on a constant", |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
147 opcode); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
148 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
149 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
150 if (newconst == NULL) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
151 PyErr_Clear(); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
152 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
153 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
154 size = PyObject_Size(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
155 if (size == -1) |
|
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 else if (size > 20) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
158 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
159 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
160 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
161 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
162 /* Append folded constant into consts table */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
163 len_consts = PyList_GET_SIZE(consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
164 if (PyList_Append(consts, newconst)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
165 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
166 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
167 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
168 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
169 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
170 /* Write NOP NOP NOP NOP LOAD_CONST newconst */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
171 memset(codestr, NOP, 4); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
172 codestr[4] = LOAD_CONST; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
173 SETARG(codestr, 4, len_consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
174 return 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
175 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
176 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
177 static int |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
178 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
|
179 { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
180 PyObject *newconst=NULL, *v; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
181 Py_ssize_t len_consts; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
182 int opcode; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
183 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
184 /* Pre-conditions */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
185 assert(PyList_CheckExact(consts)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
186 assert(codestr[0] == LOAD_CONST); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
187 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
188 /* Create new constant */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
189 v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
190 opcode = codestr[3]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
191 switch (opcode) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
192 case UNARY_NEGATIVE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
193 /* Preserve the sign of -0.0 */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
194 if (PyObject_IsTrue(v) == 1) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
195 newconst = PyNumber_Negative(v); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
196 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
197 case UNARY_CONVERT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
198 newconst = PyObject_Repr(v); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
199 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
200 case UNARY_INVERT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
201 newconst = PyNumber_Invert(v); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
202 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
203 default: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
204 /* Called with an unknown opcode */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
205 PyErr_Format(PyExc_SystemError, |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
206 "unexpected unary operation %d on a constant", |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
207 opcode); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
208 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
209 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
210 if (newconst == NULL) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
211 PyErr_Clear(); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
212 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
213 } |
|
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 /* Append folded constant into consts table */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
216 len_consts = PyList_GET_SIZE(consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
217 if (PyList_Append(consts, newconst)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
218 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
219 return 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
220 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
221 Py_DECREF(newconst); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
222 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
223 /* Write NOP LOAD_CONST newconst */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
224 codestr[0] = NOP; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
225 codestr[1] = LOAD_CONST; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
226 SETARG(codestr, 1, len_consts); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
227 return 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
228 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
229 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
230 static unsigned int * |
|
46062
09adff3d6691
Try to fix a bunch of compiler warnings on Win64.
Neal Norwitz <nnorwitz@gmail.com>
parents:
45511
diff
changeset
|
231 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
|
232 { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
233 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
|
234 int i,j, opcode, blockcnt = 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
235 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
236 if (blocks == NULL) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
237 PyErr_NoMemory(); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
238 return NULL; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
239 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
240 memset(blocks, 0, len*sizeof(int)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
241 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
242 /* Mark labels in the first pass */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
243 for (i=0 ; i<len ; i+=CODESIZE(opcode)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
244 opcode = code[i]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
245 switch (opcode) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
246 case FOR_ITER: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
247 case JUMP_FORWARD: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
248 case JUMP_IF_FALSE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
249 case JUMP_IF_TRUE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
250 case JUMP_ABSOLUTE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
251 case CONTINUE_LOOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
252 case SETUP_LOOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
253 case SETUP_EXCEPT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
254 case SETUP_FINALLY: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
255 j = GETJUMPTGT(code, i); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
256 blocks[j] = 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
257 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
258 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
259 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
260 /* Build block numbers in the second pass */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
261 for (i=0 ; i<len ; i++) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
262 blockcnt += blocks[i]; /* increment blockcnt over labels */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
263 blocks[i] = blockcnt; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
264 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
265 return blocks; |
|
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 /* 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
|
269 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
|
270 to be appended. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
271 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
272 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
|
273 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
|
274 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
|
275 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
|
276 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
277 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
|
278 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
|
279 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
|
280 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
|
281 a single pass. Line numbering is adjusted accordingly. */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
282 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
283 PyObject * |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
284 PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
285 PyObject *lineno_obj) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
286 { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
287 Py_ssize_t i, j, codelen; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
288 int nops, h, adj; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
289 int tgt, tgttgt, opcode; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
290 unsigned char *codestr = NULL; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
291 unsigned char *lineno; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
292 int *addrmap = NULL; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
293 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
|
294 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
|
295 unsigned int *blocks = NULL; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
296 char *name; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
297 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
298 /* Bail out if an exception is set */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
299 if (PyErr_Occurred()) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
300 goto exitUnchanged; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
301 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
302 /* 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
|
303 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
|
304 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
|
305 tabsiz = PyString_GET_SIZE(lineno_obj); |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
306 if (memchr(lineno, 255, tabsiz) != NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
307 goto exitUnchanged; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
308 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
309 /* 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
|
310 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
|
311 codelen = PyString_GET_SIZE(code); |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
312 if (codelen > 32700) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
313 goto exitUnchanged; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
314 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
315 /* Make a modifiable copy of the code string */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
316 codestr = (unsigned char *)PyMem_Malloc(codelen); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
317 if (codestr == NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
318 goto exitUnchanged; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
319 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
|
320 PyString_AS_STRING(code), codelen); |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
321 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
322 /* 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
|
323 the various transformation patterns to look ahead several |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
324 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
|
325 looking beyond the end of the code string. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
326 */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
327 if (codestr[codelen-1] != RETURN_VALUE) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
328 goto exitUnchanged; |
|
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 /* 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
|
331 addrmap = (int *)PyMem_Malloc(codelen * sizeof(int)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
332 if (addrmap == NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
333 goto exitUnchanged; |
|
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 blocks = markblocks(codestr, codelen); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
336 if (blocks == NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
337 goto exitUnchanged; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
338 assert(PyList_Check(consts)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
339 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
340 for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
341 opcode = codestr[i]; |
|
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 lastlc = cumlc; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
344 cumlc = 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
345 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
346 switch (opcode) { |
|
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 /* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
349 with JUMP_IF_TRUE POP_TOP */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
350 case UNARY_NOT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
351 if (codestr[i+1] != JUMP_IF_FALSE || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
352 codestr[i+4] != POP_TOP || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
353 !ISBASICBLOCK(blocks,i,5)) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
354 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
355 tgt = GETJUMPTGT(codestr, (i+1)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
356 if (codestr[tgt] != POP_TOP) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
357 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
358 j = GETARG(codestr, i+1) + 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
359 codestr[i] = JUMP_IF_TRUE; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
360 SETARG(codestr, i, j); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
361 codestr[i+3] = POP_TOP; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
362 codestr[i+4] = NOP; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
363 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
364 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
365 /* not a is b --> a is not b |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
366 not a in b --> a not in b |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
367 not a is not b --> a is b |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
368 not a not in b --> a in b |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
369 */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
370 case COMPARE_OP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
371 j = GETARG(codestr, i); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
372 if (j < 6 || j > 9 || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
373 codestr[i+3] != UNARY_NOT || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
374 !ISBASICBLOCK(blocks,i,4)) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
375 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
376 SETARG(codestr, i, (j^1)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
377 codestr[i+3] = NOP; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
378 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
379 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
380 /* Replace LOAD_GLOBAL/LOAD_NAME None |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
381 with LOAD_CONST None */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
382 case LOAD_NAME: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
383 case LOAD_GLOBAL: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
384 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
|
385 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
|
386 if (name == NULL || strcmp(name, "None") != 0) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
387 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
388 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
|
389 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
|
390 break; |
|
40998
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
391 } |
|
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
392 if (j == PyList_GET_SIZE(consts)) { |
|
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
393 if (PyList_Append(consts, Py_None) == -1) |
|
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
394 goto exitUnchanged; |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
395 } |
|
40998
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
396 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
|
397 codestr[i] = LOAD_CONST; |
|
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
398 SETARG(codestr, i, j); |
|
4e3481961fbb
Fix embarrassing typo and fix constantification of None
Raymond Hettinger <python@rcn.com>
parents:
40116
diff
changeset
|
399 cumlc = lastlc + 1; |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
400 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
401 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
402 /* Skip over LOAD_CONST trueconst |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
403 JUMP_IF_FALSE xx POP_TOP */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
404 case LOAD_CONST: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
405 cumlc = lastlc + 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
406 j = GETARG(codestr, i); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
407 if (codestr[i+3] != JUMP_IF_FALSE || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
408 codestr[i+6] != POP_TOP || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
409 !ISBASICBLOCK(blocks,i,7) || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
410 !PyObject_IsTrue(PyList_GET_ITEM(consts, j))) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
411 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
412 memset(codestr+i, NOP, 7); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
413 cumlc = 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
414 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
415 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
416 /* 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
|
417 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
|
418 Skip over BUILD_SEQN 1 UNPACK_SEQN 1. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
419 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
|
420 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
|
421 case BUILD_TUPLE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
422 case BUILD_LIST: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
423 j = GETARG(codestr, i); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
424 h = i - 3 * j; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
425 if (h >= 0 && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
426 j <= lastlc && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
427 ((opcode == BUILD_TUPLE && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
428 ISBASICBLOCK(blocks, h, 3*(j+1))) || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
429 (opcode == BUILD_LIST && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
430 codestr[i+3]==COMPARE_OP && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
431 ISBASICBLOCK(blocks, h, 3*(j+2)) && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
432 (GETARG(codestr,i+3)==6 || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
433 GETARG(codestr,i+3)==7))) && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
434 tuple_of_constants(&codestr[h], j, consts)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
435 assert(codestr[i] == LOAD_CONST); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
436 cumlc = 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
437 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
438 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
439 if (codestr[i+3] != UNPACK_SEQUENCE || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
440 !ISBASICBLOCK(blocks,i,6) || |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
441 j != GETARG(codestr, i+3)) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
442 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
443 if (j == 1) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
444 memset(codestr+i, NOP, 6); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
445 } else if (j == 2) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
446 codestr[i] = ROT_TWO; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
447 memset(codestr+i+1, NOP, 5); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
448 } else if (j == 3) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
449 codestr[i] = ROT_THREE; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
450 codestr[i+1] = ROT_TWO; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
451 memset(codestr+i+2, NOP, 4); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
452 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
453 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
454 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
455 /* Fold binary ops on constants. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
456 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
|
457 case BINARY_POWER: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
458 case BINARY_MULTIPLY: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
459 case BINARY_TRUE_DIVIDE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
460 case BINARY_FLOOR_DIVIDE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
461 case BINARY_MODULO: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
462 case BINARY_ADD: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
463 case BINARY_SUBTRACT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
464 case BINARY_SUBSCR: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
465 case BINARY_LSHIFT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
466 case BINARY_RSHIFT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
467 case BINARY_AND: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
468 case BINARY_XOR: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
469 case BINARY_OR: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
470 if (lastlc >= 2 && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
471 ISBASICBLOCK(blocks, i-6, 7) && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
472 fold_binops_on_constants(&codestr[i-6], consts)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
473 i -= 2; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
474 assert(codestr[i] == LOAD_CONST); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
475 cumlc = 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
476 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
477 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
478 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
479 /* Fold unary ops on constants. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
480 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
|
481 case UNARY_NEGATIVE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
482 case UNARY_CONVERT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
483 case UNARY_INVERT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
484 if (lastlc >= 1 && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
485 ISBASICBLOCK(blocks, i-3, 4) && |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
486 fold_unaryops_on_constants(&codestr[i-3], consts)) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
487 i -= 2; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
488 assert(codestr[i] == LOAD_CONST); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
489 cumlc = 1; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
490 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
491 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
492 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
493 /* Simplify conditional jump to conditional jump where the |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
494 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
|
495 test or the failure of the opposite test. |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
496 Arises in code like: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
497 "if a and b:" |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
498 "if a or b:" |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
499 "a and b or c" |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
500 "(a and b) and c" |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
501 x:JUMP_IF_FALSE y y:JUMP_IF_FALSE z --> x:JUMP_IF_FALSE z |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
502 x:JUMP_IF_FALSE y y:JUMP_IF_TRUE z --> x:JUMP_IF_FALSE y+3 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
503 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
|
504 */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
505 case JUMP_IF_FALSE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
506 case JUMP_IF_TRUE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
507 tgt = GETJUMPTGT(codestr, i); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
508 j = codestr[tgt]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
509 if (j == JUMP_IF_FALSE || j == JUMP_IF_TRUE) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
510 if (j == opcode) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
511 tgttgt = GETJUMPTGT(codestr, tgt) - i - 3; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
512 SETARG(codestr, i, tgttgt); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
513 } else { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
514 tgt -= i; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
515 SETARG(codestr, i, tgt); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
516 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
517 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
518 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
519 /* Intentional fallthrough */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
520 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
521 /* Replace jumps to unconditional jumps */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
522 case FOR_ITER: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
523 case JUMP_FORWARD: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
524 case JUMP_ABSOLUTE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
525 case CONTINUE_LOOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
526 case SETUP_LOOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
527 case SETUP_EXCEPT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
528 case SETUP_FINALLY: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
529 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
|
530 /* 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
|
531 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
|
532 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
|
533 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
|
534 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
|
535 continue; |
|
3985d7e2067d
Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents:
39600
diff
changeset
|
536 } |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
537 if (!UNCONDITIONAL_JUMP(codestr[tgt])) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
538 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
539 tgttgt = GETJUMPTGT(codestr, tgt); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
540 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
|
541 opcode = JUMP_ABSOLUTE; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
542 if (!ABSOLUTE_JUMP(opcode)) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
543 tgttgt -= i + 3; /* Calc relative jump addr */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
544 if (tgttgt < 0) /* No backward relative jumps */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
545 continue; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
546 codestr[i] = opcode; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
547 SETARG(codestr, i, tgttgt); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
548 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
549 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
550 case EXTENDED_ARG: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
551 goto exitUnchanged; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
552 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
553 /* 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
|
554 /* Remove unreachable JUMPs after RETURN */ |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
555 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
|
556 if (i+4 >= codelen) |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
557 continue; |
|
40116
3985d7e2067d
Update the peephole optimizer to remove more dead code (jumps after returns)
Neal Norwitz <nnorwitz@gmail.com>
parents:
39600
diff
changeset
|
558 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
|
559 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
|
560 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
|
561 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
|
562 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
|
563 memset(codestr+i+1, NOP, 3); |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
564 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
565 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
566 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
567 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
568 /* Fixup linenotab */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
569 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
|
570 addrmap[i] = i - nops; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
571 if (codestr[i] == NOP) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
572 nops++; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
573 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
574 cum_orig_line = 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
575 last_line = 0; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
576 for (i=0 ; i < tabsiz ; i+=2) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
577 cum_orig_line += lineno[i]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
578 new_line = addrmap[cum_orig_line]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
579 assert (new_line - last_line < 255); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
580 lineno[i] =((unsigned char)(new_line - last_line)); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
581 last_line = new_line; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
582 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
583 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
584 /* Remove NOPs and fixup jump targets */ |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
585 for (i=0, h=0 ; i<codelen ; ) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
586 opcode = codestr[i]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
587 switch (opcode) { |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
588 case NOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
589 i++; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
590 continue; |
|
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 case JUMP_ABSOLUTE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
593 case CONTINUE_LOOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
594 j = addrmap[GETARG(codestr, i)]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
595 SETARG(codestr, i, j); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
596 break; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
597 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
598 case FOR_ITER: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
599 case JUMP_FORWARD: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
600 case JUMP_IF_FALSE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
601 case JUMP_IF_TRUE: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
602 case SETUP_LOOP: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
603 case SETUP_EXCEPT: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
604 case SETUP_FINALLY: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
605 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
|
606 SETARG(codestr, i, j); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
607 break; |
|
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 adj = CODESIZE(opcode); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
610 while (adj--) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
611 codestr[h++] = codestr[i++]; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
612 } |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
613 assert(h + nops == codelen); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
614 |
|
47527
52294af4b663
This reverts r63675 based on the discussion in this thread:
Gregory P. Smith <greg@mad-scientist.com>
parents:
47294
diff
changeset
|
615 code = PyString_FromStringAndSize((char *)codestr, h); |
|
39600
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
616 PyMem_Free(addrmap); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
617 PyMem_Free(codestr); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
618 PyMem_Free(blocks); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
619 return code; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
620 |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
621 exitUnchanged: |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
622 if (blocks != NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
623 PyMem_Free(blocks); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
624 if (addrmap != NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
625 PyMem_Free(addrmap); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
626 if (codestr != NULL) |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
627 PyMem_Free(codestr); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
628 Py_INCREF(code); |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
629 return code; |
|
5e143944770b
Move peephole optimizer to separate file.
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff
changeset
|
630 } |
