blob: 54a1e15cc4d889f681e8ec2d11aa5297164211c3 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Dalvik.h"
18#include "Dataflow.h"
19//#include "libdex/DexOpcodes.h"
20
21/*
22 * Main table containing data flow attributes for each bytecode. The
23 * first kNumPackedOpcodes entries are for Dalvik bytecode
24 * instructions, where extended opcode at the MIR level are appended
25 * afterwards.
26 *
27 * TODO - many optimization flags are incomplete - they will only limit the
28 * scope of optimizations but will not cause mis-optimizations.
29 */
30int oatDataFlowAttributes[kMirOpLast] = {
31 // 00 OP_NOP
32 DF_NOP,
33
34 // 01 OP_MOVE vA, vB
35 DF_DA | DF_UB | DF_IS_MOVE,
36
37 // 02 OP_MOVE_FROM16 vAA, vBBBB
38 DF_DA | DF_UB | DF_IS_MOVE,
39
40 // 03 OP_MOVE_16 vAAAA, vBBBB
41 DF_DA | DF_UB | DF_IS_MOVE,
42
43 // 04 OP_MOVE_WIDE vA, vB
44 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
45
46 // 05 OP_MOVE_WIDE_FROM16 vAA, vBBBB
47 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
48
49 // 06 OP_MOVE_WIDE_16 vAAAA, vBBBB
50 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
51
52 // 07 OP_MOVE_OBJECT vA, vB
buzbee67bc2362011-10-11 18:08:40 -070053 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070054
55 // 08 OP_MOVE_OBJECT_FROM16 vAA, vBBBB
buzbee67bc2362011-10-11 18:08:40 -070056 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070057
58 // 09 OP_MOVE_OBJECT_16 vAAAA, vBBBB
buzbee67bc2362011-10-11 18:08:40 -070059 DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -070060
61 // 0A OP_MOVE_RESULT vAA
62 DF_DA,
63
64 // 0B OP_MOVE_RESULT_WIDE vAA
65 DF_DA_WIDE,
66
67 // 0C OP_MOVE_RESULT_OBJECT vAA
buzbee67bc2362011-10-11 18:08:40 -070068 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070069
70 // 0D OP_MOVE_EXCEPTION vAA
buzbee67bc2362011-10-11 18:08:40 -070071 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070072
73 // 0E OP_RETURN_VOID
74 DF_NOP,
75
76 // 0F OP_RETURN vAA
77 DF_UA,
78
79 // 10 OP_RETURN_WIDE vAA
80 DF_UA_WIDE,
81
82 // 11 OP_RETURN_OBJECT vAA
buzbee67bc2362011-10-11 18:08:40 -070083 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -070084
85 // 12 OP_CONST_4 vA, #+B
86 DF_DA | DF_SETS_CONST,
87
88 // 13 OP_CONST_16 vAA, #+BBBB
89 DF_DA | DF_SETS_CONST,
90
91 // 14 OP_CONST vAA, #+BBBBBBBB
92 DF_DA | DF_SETS_CONST,
93
94 // 15 OP_CONST_HIGH16 VAA, #+BBBB0000
95 DF_DA | DF_SETS_CONST,
96
97 // 16 OP_CONST_WIDE_16 vAA, #+BBBB
98 DF_DA_WIDE | DF_SETS_CONST,
99
100 // 17 OP_CONST_WIDE_32 vAA, #+BBBBBBBB
101 DF_DA_WIDE | DF_SETS_CONST,
102
103 // 18 OP_CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
104 DF_DA_WIDE | DF_SETS_CONST,
105
106 // 19 OP_CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
107 DF_DA_WIDE | DF_SETS_CONST,
108
109 // 1A OP_CONST_STRING vAA, string@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700110 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700111
112 // 1B OP_CONST_STRING_JUMBO vAA, string@BBBBBBBB
buzbee67bc2362011-10-11 18:08:40 -0700113 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700114
115 // 1C OP_CONST_CLASS vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700116 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700117
118 // 1D OP_MONITOR_ENTER vAA
buzbee67bc2362011-10-11 18:08:40 -0700119 DF_UA | DF_NULL_CHK_0 | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700120
121 // 1E OP_MONITOR_EXIT vAA
buzbee67bc2362011-10-11 18:08:40 -0700122 DF_UA | DF_NULL_CHK_0 | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700123
buzbee43a36422011-09-14 14:00:13 -0700124 // 1F OP_CHK_CAST vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700125 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700126
127 // 20 OP_INSTANCE_OF vA, vB, type@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700128 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700129
130 // 21 OP_ARRAY_LENGTH vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700131 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700132
133 // 22 OP_NEW_INSTANCE vAA, type@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700134 DF_DA | DF_NON_NULL_DST | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700135
136 // 23 OP_NEW_ARRAY vA, vB, type@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700137 DF_DA | DF_UB | DF_NON_NULL_DST | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700138
139 // 24 OP_FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700140 DF_FORMAT_35C | DF_NON_NULL_RET,
buzbee67bf8852011-08-17 17:51:35 -0700141
142 // 25 OP_FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
buzbee43a36422011-09-14 14:00:13 -0700143 DF_FORMAT_3RC | DF_NON_NULL_RET,
buzbee67bf8852011-08-17 17:51:35 -0700144
145 // 26 OP_FILL_ARRAY_DATA vAA, +BBBBBBBB
buzbee67bc2362011-10-11 18:08:40 -0700146 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700147
148 // 27 OP_THROW vAA
buzbee67bc2362011-10-11 18:08:40 -0700149 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700150
151 // 28 OP_GOTO
152 DF_NOP,
153
154 // 29 OP_GOTO_16
155 DF_NOP,
156
157 // 2A OP_GOTO_32
158 DF_NOP,
159
160 // 2B OP_PACKED_SWITCH vAA, +BBBBBBBB
161 DF_UA,
162
163 // 2C OP_SPARSE_SWITCH vAA, +BBBBBBBB
164 DF_UA,
165
166 // 2D OP_CMPL_FLOAT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700167 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700168
169 // 2E OP_CMPG_FLOAT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700170 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700171
172 // 2F OP_CMPL_DOUBLE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700173 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700174
175 // 30 OP_CMPG_DOUBLE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700176 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700177
178 // 31 OP_CMP_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700179 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700180
181 // 32 OP_IF_EQ vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700182 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700183
184 // 33 OP_IF_NE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700185 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700186
187 // 34 OP_IF_LT vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700188 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700189
190 // 35 OP_IF_GE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700191 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700192
193 // 36 OP_IF_GT vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700194 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700195
196 // 37 OP_IF_LE vA, vB, +CCCC
buzbee67bc2362011-10-11 18:08:40 -0700197 DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700198
199
200 // 38 OP_IF_EQZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700201 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700202
203 // 39 OP_IF_NEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700204 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700205
206 // 3A OP_IF_LTZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700207 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700208
209 // 3B OP_IF_GEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700210 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700211
212 // 3C OP_IF_GTZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700213 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700214
215 // 3D OP_IF_LEZ vAA, +BBBB
buzbee67bc2362011-10-11 18:08:40 -0700216 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700217
218 // 3E OP_UNUSED_3E
219 DF_NOP,
220
221 // 3F OP_UNUSED_3F
222 DF_NOP,
223
224 // 40 OP_UNUSED_40
225 DF_NOP,
226
227 // 41 OP_UNUSED_41
228 DF_NOP,
229
230 // 42 OP_UNUSED_42
231 DF_NOP,
232
233 // 43 OP_UNUSED_43
234 DF_NOP,
235
236 // 44 OP_AGET vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700237 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700238
239 // 45 OP_AGET_WIDE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700240 DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700241
242 // 46 OP_AGET_OBJECT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700243 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700244
245 // 47 OP_AGET_BOOLEAN vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700246 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700247
248 // 48 OP_AGET_BYTE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700249 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700250
251 // 49 OP_AGET_CHAR vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700252 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700253
254 // 4A OP_AGET_SHORT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700255 DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_IS_GETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700256
257 // 4B OP_APUT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700258 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700259
260 // 4C OP_APUT_WIDE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700261 DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700262
263 // 4D OP_APUT_OBJECT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700264 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700265
266 // 4E OP_APUT_BOOLEAN vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700267 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700268
269 // 4F OP_APUT_BYTE vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700270 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700271
272 // 50 OP_APUT_CHAR vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700273 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700274
275 // 51 OP_APUT_SHORT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700276 DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_IS_SETTER | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700277
278 // 52 OP_IGET vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700279 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700280
281 // 53 OP_IGET_WIDE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700282 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700283
284 // 54 OP_IGET_OBJECT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700285 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700286
287 // 55 OP_IGET_BOOLEAN vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700288 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700289
290 // 56 OP_IGET_BYTE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700291 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700292
293 // 57 OP_IGET_CHAR vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700294 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700295
296 // 58 OP_IGET_SHORT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700297 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700298
299 // 59 OP_IPUT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700300 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700301
302 // 5A OP_IPUT_WIDE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700303 DF_UA_WIDE | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700304
305 // 5B OP_IPUT_OBJECT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700306 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700307
308 // 5C OP_IPUT_BOOLEAN vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700309 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700310
311 // 5D OP_IPUT_BYTE vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700312 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700313
314 // 5E OP_IPUT_CHAR vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700315 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700316
317 // 5F OP_IPUT_SHORT vA, vB, field@CCCC
buzbee67bc2362011-10-11 18:08:40 -0700318 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700319
320 // 60 OP_SGET vAA, field@BBBB
321 DF_DA | DF_IS_GETTER,
322
323 // 61 OP_SGET_WIDE vAA, field@BBBB
324 DF_DA_WIDE | DF_IS_GETTER,
325
326 // 62 OP_SGET_OBJECT vAA, field@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700327 DF_DA | DF_IS_GETTER | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700328
329 // 63 OP_SGET_BOOLEAN vAA, field@BBBB
330 DF_DA | DF_IS_GETTER,
331
332 // 64 OP_SGET_BYTE vAA, field@BBBB
333 DF_DA | DF_IS_GETTER,
334
335 // 65 OP_SGET_CHAR vAA, field@BBBB
336 DF_DA | DF_IS_GETTER,
337
338 // 66 OP_SGET_SHORT vAA, field@BBBB
339 DF_DA | DF_IS_GETTER,
340
341 // 67 OP_SPUT vAA, field@BBBB
342 DF_UA | DF_IS_SETTER,
343
344 // 68 OP_SPUT_WIDE vAA, field@BBBB
345 DF_UA_WIDE | DF_IS_SETTER,
346
347 // 69 OP_SPUT_OBJECT vAA, field@BBBB
buzbee67bc2362011-10-11 18:08:40 -0700348 DF_UA | DF_IS_SETTER | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700349
350 // 6A OP_SPUT_BOOLEAN vAA, field@BBBB
351 DF_UA | DF_IS_SETTER,
352
353 // 6B OP_SPUT_BYTE vAA, field@BBBB
354 DF_UA | DF_IS_SETTER,
355
356 // 6C OP_SPUT_CHAR vAA, field@BBBB
357 DF_UA | DF_IS_SETTER,
358
359 // 6D OP_SPUT_SHORT vAA, field@BBBB
360 DF_UA | DF_IS_SETTER,
361
362 // 6E OP_INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700363 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700364
365 // 6F OP_INVOKE_SUPER {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700366 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700367
368 // 70 OP_INVOKE_DIRECT {vD, vE, vF, vG, vA}
buzbee43a36422011-09-14 14:00:13 -0700369 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700370
371 // 71 OP_INVOKE_STATIC {vD, vE, vF, vG, vA}
372 DF_FORMAT_35C,
373
374 // 72 OP_INVOKE_INTERFACE {vD, vE, vF, vG, vA}
375 DF_FORMAT_35C,
376
377 // 73 OP_UNUSED_73
378 DF_NOP,
379
380 // 74 OP_INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
buzbee43a36422011-09-14 14:00:13 -0700381 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700382
383 // 75 OP_INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
buzbee43a36422011-09-14 14:00:13 -0700384 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700385
386 // 76 OP_INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
buzbee43a36422011-09-14 14:00:13 -0700387 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700388
389 // 77 OP_INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
390 DF_FORMAT_3RC,
391
392 // 78 OP_INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
393 DF_FORMAT_3RC,
394
395 // 79 OP_UNUSED_79
396 DF_NOP,
397
398 // 7A OP_UNUSED_7A
399 DF_NOP,
400
401 // 7B OP_NEG_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700402 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700403
404 // 7C OP_NOT_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700405 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700406
407 // 7D OP_NEG_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700408 DF_DA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700409
410 // 7E OP_NOT_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700411 DF_DA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700412
413 // 7F OP_NEG_FLOAT vA, vB
414 DF_DA | DF_UB | DF_FP_A | DF_FP_B,
415
416 // 80 OP_NEG_DOUBLE vA, vB
417 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
418
419 // 81 OP_INT_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700420 DF_DA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700421
422 // 82 OP_INT_TO_FLOAT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700423 DF_DA | DF_UB | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700424
425 // 83 OP_INT_TO_DOUBLE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700426 DF_DA_WIDE | DF_UB | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700427
428 // 84 OP_LONG_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700429 DF_DA | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700430
431 // 85 OP_LONG_TO_FLOAT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700432 DF_DA | DF_UB_WIDE | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700433
434 // 86 OP_LONG_TO_DOUBLE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700435 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700436
437 // 87 OP_FLOAT_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700438 DF_DA | DF_UB | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700439
440 // 88 OP_FLOAT_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700441 DF_DA_WIDE | DF_UB | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700442
443 // 89 OP_FLOAT_TO_DOUBLE vA, vB
444 DF_DA_WIDE | DF_UB | DF_FP_A | DF_FP_B,
445
446 // 8A OP_DOUBLE_TO_INT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700447 DF_DA | DF_UB_WIDE | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700448
449 // 8B OP_DOUBLE_TO_LONG vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700450 DF_DA_WIDE | DF_UB_WIDE | DF_FP_B | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700451
452 // 8C OP_DOUBLE_TO_FLOAT vA, vB
453 DF_DA | DF_UB_WIDE | DF_FP_A | DF_FP_B,
454
455 // 8D OP_INT_TO_BYTE vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700456 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700457
458 // 8E OP_INT_TO_CHAR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700459 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700460
461 // 8F OP_INT_TO_SHORT vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700462 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700463
464 // 90 OP_ADD_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700465 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700466
467 // 91 OP_SUB_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700468 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700469
470 // 92 OP_MUL_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700471 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700472
473 // 93 OP_DIV_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700474 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700475
476 // 94 OP_REM_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700477 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700478
479 // 95 OP_AND_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700480 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700481
482 // 96 OP_OR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700483 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700484
485 // 97 OP_XOR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700486 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700487
488 // 98 OP_SHL_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700489 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700490
491 // 99 OP_SHR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700492 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700493
494 // 9A OP_USHR_INT vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700495 DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700496
497 // 9B OP_ADD_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700498 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700499
500 // 9C OP_SUB_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700501 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700502
503 // 9D OP_MUL_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700504 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700505
506 // 9E OP_DIV_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700507 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700508
509 // 9F OP_REM_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700510 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700511
512 // A0 OP_AND_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700513 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700514
515 // A1 OP_OR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700516 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700517
518 // A2 OP_XOR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700519 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700520
521 // A3 OP_SHL_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700522 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700523
524 // A4 OP_SHR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700525 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700526
527 // A5 OP_USHR_LONG vAA, vBB, vCC
buzbee67bc2362011-10-11 18:08:40 -0700528 DF_DA_WIDE | DF_UB_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
buzbee67bf8852011-08-17 17:51:35 -0700529
530 // A6 OP_ADD_FLOAT vAA, vBB, vCC
531 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
532
533 // A7 OP_SUB_FLOAT vAA, vBB, vCC
534 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
535
536 // A8 OP_MUL_FLOAT vAA, vBB, vCC
537 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
538
539 // A9 OP_DIV_FLOAT vAA, vBB, vCC
540 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
541
542 // AA OP_REM_FLOAT vAA, vBB, vCC
543 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
544
545 // AB OP_ADD_DOUBLE vAA, vBB, vCC
546 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
547
548 // AC OP_SUB_DOUBLE vAA, vBB, vCC
549 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
550
551 // AD OP_MUL_DOUBLE vAA, vBB, vCC
552 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
553
554 // AE OP_DIV_DOUBLE vAA, vBB, vCC
555 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
556
557 // AF OP_REM_DOUBLE vAA, vBB, vCC
558 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
559
560 // B0 OP_ADD_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700561 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700562
563 // B1 OP_SUB_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700564 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700565
566 // B2 OP_MUL_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700567 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700568
569 // B3 OP_DIV_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700570 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700571
572 // B4 OP_REM_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700573 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700574
575 // B5 OP_AND_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700576 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700577
578 // B6 OP_OR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700579 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700580
581 // B7 OP_XOR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700582 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700583
584 // B8 OP_SHL_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700585 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700586
587 // B9 OP_SHR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700588 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700589
590 // BA OP_USHR_INT_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700591 DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700592
593 // BB OP_ADD_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700594 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700595
596 // BC OP_SUB_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700597 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700598
599 // BD OP_MUL_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700600 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700601
602 // BE OP_DIV_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700603 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700604
605 // BF OP_REM_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700606 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700607
608 // C0 OP_AND_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700609 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700610
611 // C1 OP_OR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700612 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700613
614 // C2 OP_XOR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700615 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700616
617 // C3 OP_SHL_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700618 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700619
620 // C4 OP_SHR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700621 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700622
623 // C5 OP_USHR_LONG_2ADDR vA, vB
buzbee67bc2362011-10-11 18:08:40 -0700624 DF_DA_WIDE | DF_UA_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700625
626 // C6 OP_ADD_FLOAT_2ADDR vA, vB
627 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
628
629 // C7 OP_SUB_FLOAT_2ADDR vA, vB
630 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
631
632 // C8 OP_MUL_FLOAT_2ADDR vA, vB
633 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
634
635 // C9 OP_DIV_FLOAT_2ADDR vA, vB
636 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
637
638 // CA OP_REM_FLOAT_2ADDR vA, vB
639 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
640
641 // CB OP_ADD_DOUBLE_2ADDR vA, vB
642 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
643
644 // CC OP_SUB_DOUBLE_2ADDR vA, vB
645 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
646
647 // CD OP_MUL_DOUBLE_2ADDR vA, vB
648 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
649
650 // CE OP_DIV_DOUBLE_2ADDR vA, vB
651 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
652
653 // CF OP_REM_DOUBLE_2ADDR vA, vB
654 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
655
656 // D0 OP_ADD_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700657 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700658
659 // D1 OP_RSUB_INT vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700660 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700661
662 // D2 OP_MUL_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700663 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700664
665 // D3 OP_DIV_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700666 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700667
668 // D4 OP_REM_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700669 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700670
671 // D5 OP_AND_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700672 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700673
674 // D6 OP_OR_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700675 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700676
677 // D7 OP_XOR_INT_LIT16 vA, vB, #+CCCC
buzbee67bc2362011-10-11 18:08:40 -0700678 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700679
680 // D8 OP_ADD_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700681 DF_DA | DF_UB | DF_IS_LINEAR | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700682
683 // D9 OP_RSUB_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700684 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700685
686 // DA OP_MUL_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700687 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700688
689 // DB OP_DIV_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700690 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700691
692 // DC OP_REM_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700693 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700694
695 // DD OP_AND_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700696 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700697
698 // DE OP_OR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700699 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700700
701 // DF OP_XOR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700702 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700703
704 // E0 OP_SHL_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700705 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700706
707 // E1 OP_SHR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700708 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700709
710 // E2 OP_USHR_INT_LIT8 vAA, vBB, #+CC
buzbee67bc2362011-10-11 18:08:40 -0700711 DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700712
713 // E3 OP_IGET_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700714 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700715
716 // E4 OP_IPUT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700717 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700718
719 // E5 OP_SGET_VOLATILE
720 DF_DA,
721
722 // E6 OP_SPUT_VOLATILE
723 DF_UA,
724
725 // E7 OP_IGET_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700726 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700727
728 // E8 OP_IGET_WIDE_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700729 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700730
731 // E9 OP_IPUT_WIDE_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700732 DF_UA_WIDE | DF_UB | DF_NULL_CHK_1 | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700733
734 // EA OP_SGET_WIDE_VOLATILE
735 DF_DA_WIDE,
736
737 // EB OP_SPUT_WIDE_VOLATILE
738 DF_UA_WIDE,
739
740 // EC OP_BREAKPOINT
741 DF_NOP,
742
743 // ED OP_THROW_VERIFICATION_ERROR
744 DF_NOP,
745
746 // EE OP_EXECUTE_INLINE
747 DF_FORMAT_35C,
748
749 // EF OP_EXECUTE_INLINE_RANGE
750 DF_FORMAT_3RC,
751
752 // F0 OP_INVOKE_OBJECT_INIT_RANGE
buzbee43a36422011-09-14 14:00:13 -0700753 DF_NOP | DF_NULL_CHK_0,
buzbee67bf8852011-08-17 17:51:35 -0700754
755 // F1 OP_RETURN_VOID_BARRIER
756 DF_NOP,
757
758 // F2 OP_IGET_QUICK
buzbee43a36422011-09-14 14:00:13 -0700759 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER,
buzbee67bf8852011-08-17 17:51:35 -0700760
761 // F3 OP_IGET_WIDE_QUICK
buzbee43a36422011-09-14 14:00:13 -0700762 DF_DA_WIDE | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER,
buzbee67bf8852011-08-17 17:51:35 -0700763
764 // F4 OP_IGET_OBJECT_QUICK
buzbee43a36422011-09-14 14:00:13 -0700765 DF_DA | DF_UB | DF_NULL_CHK_0 | DF_IS_GETTER,
buzbee67bf8852011-08-17 17:51:35 -0700766
767 // F5 OP_IPUT_QUICK
buzbee43a36422011-09-14 14:00:13 -0700768 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER,
buzbee67bf8852011-08-17 17:51:35 -0700769
770 // F6 OP_IPUT_WIDE_QUICK
buzbee43a36422011-09-14 14:00:13 -0700771 DF_UA_WIDE | DF_UB | DF_NULL_CHK_1 |DF_IS_SETTER,
buzbee67bf8852011-08-17 17:51:35 -0700772
773 // F7 OP_IPUT_OBJECT_QUICK
buzbee43a36422011-09-14 14:00:13 -0700774 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_IS_SETTER,
buzbee67bf8852011-08-17 17:51:35 -0700775
776 // F8 OP_INVOKE_VIRTUAL_QUICK
buzbee43a36422011-09-14 14:00:13 -0700777 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700778
779 // F9 OP_INVOKE_VIRTUAL_QUICK_RANGE
buzbee43a36422011-09-14 14:00:13 -0700780 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700781
782 // FA OP_INVOKE_SUPER_QUICK
buzbee43a36422011-09-14 14:00:13 -0700783 DF_FORMAT_35C | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700784
785 // FB OP_INVOKE_SUPER_QUICK_RANGE
buzbee43a36422011-09-14 14:00:13 -0700786 DF_FORMAT_3RC | DF_NULL_CHK_OUT0,
buzbee67bf8852011-08-17 17:51:35 -0700787
788 // FC OP_IPUT_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700789 DF_UA | DF_UB | DF_NULL_CHK_1 | DF_CORE_A | DF_CORE_B,
buzbee67bf8852011-08-17 17:51:35 -0700790
791 // FD OP_SGET_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700792 DF_DA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700793
794 // FE OP_SPUT_OBJECT_VOLATILE
buzbee67bc2362011-10-11 18:08:40 -0700795 DF_UA | DF_CORE_A,
buzbee67bf8852011-08-17 17:51:35 -0700796
Elliott Hughes8e5944b2012-01-05 13:44:44 -0800797 // FF OP_UNUSED_FF
buzbee67bf8852011-08-17 17:51:35 -0700798 DF_NOP,
799
800 // Beginning of extended MIR opcodes
Elliott Hughes8e5944b2012-01-05 13:44:44 -0800801 // 100 OP_MIR_PHI
buzbee43a36422011-09-14 14:00:13 -0700802 DF_PHI | DF_DA | DF_NULL_TRANSFER_N,
buzbee67bf8852011-08-17 17:51:35 -0700803 /*
804 * For extended MIR inserted at the MIR2LIR stage, it is okay to have
805 * undefined values here.
806 */
807};
808
809/* Return the Dalvik register/subscript pair of a given SSA register */
810int oatConvertSSARegToDalvik(const CompilationUnit* cUnit, int ssaReg)
811{
812 return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
813}
814
815/*
816 * Utility function to convert encoded SSA register value into Dalvik register
817 * and subscript pair. Each SSA register can be used to index the
818 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
819 */
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800820char* oatGetDalvikDisassembly(const DecodedInstruction* insn,
buzbee67bf8852011-08-17 17:51:35 -0700821 const char* note)
822{
823 char buffer[256];
824 Opcode opcode = insn->opcode;
825 int dfAttributes = oatDataFlowAttributes[opcode];
826 int flags;
827 char* ret;
828
829 buffer[0] = 0;
830 if ((int)opcode >= (int)kMirOpFirst) {
831 if ((int)opcode == (int)kMirOpPhi) {
832 strcpy(buffer, "PHI");
833 }
834 else {
835 sprintf(buffer, "Opcode %#x", opcode);
836 }
837 flags = 0;
838 } else {
839 strcpy(buffer, dexGetOpcodeName(opcode));
840 flags = dexGetFlagsFromOpcode(insn->opcode);
841 }
842
843 if (note)
844 strcat(buffer, note);
845
846 /* For branches, decode the instructions to print out the branch targets */
847 if (flags & kInstrCanBranch) {
848 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
849 int offset = 0;
850 switch (dalvikFormat) {
851 case kFmt21t:
852 snprintf(buffer + strlen(buffer), 256, " v%d,", insn->vA);
853 offset = (int) insn->vB;
854 break;
855 case kFmt22t:
856 snprintf(buffer + strlen(buffer), 256, " v%d, v%d,",
857 insn->vA, insn->vB);
858 offset = (int) insn->vC;
859 break;
860 case kFmt10t:
861 case kFmt20t:
862 case kFmt30t:
863 offset = (int) insn->vA;
864 break;
865 default:
866 LOG(FATAL) << "Unexpected branch format " << (int)dalvikFormat
867 << " / opcode " << (int)opcode;
868 }
869 snprintf(buffer + strlen(buffer), 256, " (%c%x)",
870 offset > 0 ? '+' : '-',
871 offset > 0 ? offset : -offset);
872 } else if (dfAttributes & DF_FORMAT_35C) {
873 unsigned int i;
874 for (i = 0; i < insn->vA; i++) {
875 if (i != 0) strcat(buffer, ",");
876 snprintf(buffer + strlen(buffer), 256, " v%d", insn->arg[i]);
877 }
878 }
879 else if (dfAttributes & DF_FORMAT_3RC) {
880 snprintf(buffer + strlen(buffer), 256,
881 " v%d..v%d", insn->vC, insn->vC + insn->vA - 1);
882 }
883 else {
884 if (dfAttributes & DF_A_IS_REG) {
885 snprintf(buffer + strlen(buffer), 256, " v%d", insn->vA);
886 }
887 if (dfAttributes & DF_B_IS_REG) {
888 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vB);
889 }
890 else if ((int)opcode < (int)kMirOpFirst) {
891 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vB);
892 }
893 if (dfAttributes & DF_C_IS_REG) {
894 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vC);
895 }
896 else if ((int)opcode < (int)kMirOpFirst) {
897 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vC);
898 }
899 }
900 int length = strlen(buffer) + 1;
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800901 ret = (char*)oatNew(length, false);
buzbee67bf8852011-08-17 17:51:35 -0700902 memcpy(ret, buffer, length);
903 return ret;
904}
905
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800906char* getSSAName(const CompilationUnit* cUnit, int ssaReg, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700907{
908 int ssa2DalvikValue = oatConvertSSARegToDalvik(cUnit, ssaReg);
909
910 sprintf(name, "v%d_%d",
911 DECODE_REG(ssa2DalvikValue), DECODE_SUB(ssa2DalvikValue));
912 return name;
913}
914
915/*
916 * Dalvik instruction disassembler with optional SSA printing.
917 */
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800918char* oatFullDisassembler(const CompilationUnit* cUnit,
buzbee67bf8852011-08-17 17:51:35 -0700919 const MIR* mir)
920{
921 char buffer[256];
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700922 char operand0[32], operand1[32];
buzbee67bf8852011-08-17 17:51:35 -0700923 const DecodedInstruction *insn = &mir->dalvikInsn;
924 int opcode = insn->opcode;
925 int dfAttributes = oatDataFlowAttributes[opcode];
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800926 char* ret;
buzbee67bf8852011-08-17 17:51:35 -0700927 int length;
928 OpcodeFlags flags;
929
930 buffer[0] = 0;
931 if (opcode >= kMirOpFirst) {
932 if (opcode == kMirOpPhi) {
933 snprintf(buffer, 256, "PHI %s = (%s",
934 getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
935 getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
936 int i;
937 for (i = 1; i < mir->ssaRep->numUses; i++) {
938 snprintf(buffer + strlen(buffer), 256, ", %s",
939 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
940 }
941 snprintf(buffer + strlen(buffer), 256, ")");
942 }
943 else {
944 sprintf(buffer, "Opcode %#x", opcode);
945 }
946 goto done;
947 } else {
948 strcpy(buffer, dexGetOpcodeName((Opcode)opcode));
949 }
950
951 flags = dexGetFlagsFromOpcode((Opcode)opcode);
952 /* For branches, decode the instructions to print out the branch targets */
953 if (flags & kInstrCanBranch) {
954 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
955 int delta = 0;
956 switch (dalvikFormat) {
957 case kFmt21t:
958 snprintf(buffer + strlen(buffer), 256, " %s, ",
959 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
960 delta = (int) insn->vB;
961 break;
962 case kFmt22t:
963 snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
964 getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
965 getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
966 delta = (int) insn->vC;
967 break;
968 case kFmt10t:
969 case kFmt20t:
970 case kFmt30t:
971 delta = (int) insn->vA;
972 break;
973 default:
974 LOG(FATAL) << "Unexpected branch format: " <<
975 (int)dalvikFormat;
976 }
977 snprintf(buffer + strlen(buffer), 256, " %04x",
978 mir->offset + delta);
979 } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
980 unsigned int i;
981 for (i = 0; i < insn->vA; i++) {
982 if (i != 0) strcat(buffer, ",");
983 snprintf(buffer + strlen(buffer), 256, " %s",
984 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
985 }
986 } else {
987 int udIdx;
988 if (mir->ssaRep->numDefs) {
989
990 for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
991 snprintf(buffer + strlen(buffer), 256, " %s",
992 getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
993 }
994 strcat(buffer, ",");
995 }
996 if (mir->ssaRep->numUses) {
997 /* No leading ',' for the first use */
998 snprintf(buffer + strlen(buffer), 256, " %s",
999 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
1000 for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
1001 snprintf(buffer + strlen(buffer), 256, ", %s",
1002 getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
1003 }
1004 }
1005 if (opcode < kMirOpFirst) {
1006 InstructionFormat dalvikFormat =
1007 dexGetFormatFromOpcode((Opcode)opcode);
1008 switch (dalvikFormat) {
1009 case kFmt11n: // op vA, #+B
1010 case kFmt21s: // op vAA, #+BBBB
1011 case kFmt21h: // op vAA, #+BBBB00000[00000000]
1012 case kFmt31i: // op vAA, #+BBBBBBBB
1013 case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
1014 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
1015 break;
1016 case kFmt21c: // op vAA, thing@BBBB
1017 case kFmt31c: // op vAA, thing@BBBBBBBB
1018 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
1019 break;
1020 case kFmt22b: // op vAA, vBB, #+CC
1021 case kFmt22s: // op vA, vB, #+CCCC
1022 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
1023 break;
1024 case kFmt22c: // op vA, vB, thing@CCCC
1025 case kFmt22cs: // [opt] op vA, vB, field offset CCCC
1026 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
1027 break;
1028 /* No need for special printing */
1029 default:
1030 break;
1031 }
1032 }
1033 }
1034
1035done:
1036 length = strlen(buffer) + 1;
Elliott Hughesc1f143d2011-12-01 17:31:10 -08001037 ret = (char*) oatNew(length, false);
buzbee67bf8852011-08-17 17:51:35 -07001038 memcpy(ret, buffer, length);
1039 return ret;
1040}
1041
1042/*
1043 * Utility function to convert encoded SSA register value into Dalvik register
1044 * and subscript pair. Each SSA register can be used to index the
1045 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
1046 */
Elliott Hughesc1f143d2011-12-01 17:31:10 -08001047char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep)
buzbee67bf8852011-08-17 17:51:35 -07001048{
1049 char buffer[256];
1050 char* ret;
1051 int i;
1052
1053 buffer[0] = 0;
1054 for (i = 0; i < ssaRep->numDefs; i++) {
1055 int ssa2DalvikValue = oatConvertSSARegToDalvik(cUnit, ssaRep->defs[i]);
1056
1057 sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ",
1058 ssaRep->defs[i], DECODE_REG(ssa2DalvikValue),
1059 DECODE_SUB(ssa2DalvikValue));
1060 }
1061
1062 if (ssaRep->numDefs) {
1063 strcat(buffer, "<- ");
1064 }
1065
1066 for (i = 0; i < ssaRep->numUses; i++) {
1067 int ssa2DalvikValue = oatConvertSSARegToDalvik(cUnit, ssaRep->uses[i]);
1068 int len = strlen(buffer);
1069
1070 if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ",
1071 ssaRep->uses[i], DECODE_REG(ssa2DalvikValue),
1072 DECODE_SUB(ssa2DalvikValue)) >= (250 - len)) {
1073 strcat(buffer, "...");
1074 break;
1075 }
1076 }
1077
1078 int length = strlen(buffer) + 1;
Elliott Hughesc1f143d2011-12-01 17:31:10 -08001079 ret = (char*)oatNew(length, false);
buzbee67bf8852011-08-17 17:51:35 -07001080 memcpy(ret, buffer, length);
1081 return ret;
1082}
1083
1084/* Any register that is used before being defined is considered live-in */
buzbeeed3e9302011-09-23 17:34:19 -07001085STATIC inline void handleLiveInUse(ArenaBitVector* useV, ArenaBitVector* defV,
buzbee67bf8852011-08-17 17:51:35 -07001086 ArenaBitVector* liveInV, int dalvikRegId)
1087{
1088 oatSetBit(useV, dalvikRegId);
1089 if (!oatIsBitSet(defV, dalvikRegId)) {
1090 oatSetBit(liveInV, dalvikRegId);
1091 }
1092}
1093
1094/* Mark a reg as being defined */
buzbeeed3e9302011-09-23 17:34:19 -07001095STATIC inline void handleDef(ArenaBitVector* defV, int dalvikRegId)
buzbee67bf8852011-08-17 17:51:35 -07001096{
1097 oatSetBit(defV, dalvikRegId);
1098}
1099
1100/*
1101 * Find out live-in variables for natural loops. Variables that are live-in in
1102 * the main loop body are considered to be defined in the entry block.
1103 */
1104bool oatFindLocalLiveIn(CompilationUnit* cUnit, BasicBlock* bb)
1105{
1106 MIR* mir;
1107 ArenaBitVector *useV, *defV, *liveInV;
1108
1109 if (bb->dataFlowInfo == NULL) return false;
1110
1111 useV = bb->dataFlowInfo->useV =
1112 oatAllocBitVector(cUnit->numDalvikRegisters, false);
1113 defV = bb->dataFlowInfo->defV =
1114 oatAllocBitVector(cUnit->numDalvikRegisters, false);
1115 liveInV = bb->dataFlowInfo->liveInV =
1116 oatAllocBitVector(cUnit->numDalvikRegisters, false);
1117
1118 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1119 int dfAttributes =
1120 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1121 DecodedInstruction *dInsn = &mir->dalvikInsn;
1122
1123 if (dfAttributes & DF_HAS_USES) {
1124 if (dfAttributes & DF_UA) {
1125 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
1126 } else if (dfAttributes & DF_UA_WIDE) {
1127 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
1128 handleLiveInUse(useV, defV, liveInV, dInsn->vA+1);
1129 }
1130 if (dfAttributes & DF_UB) {
1131 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
1132 } else if (dfAttributes & DF_UB_WIDE) {
1133 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
1134 handleLiveInUse(useV, defV, liveInV, dInsn->vB+1);
1135 }
1136 if (dfAttributes & DF_UC) {
1137 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
1138 } else if (dfAttributes & DF_UC_WIDE) {
1139 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
1140 handleLiveInUse(useV, defV, liveInV, dInsn->vC+1);
1141 }
1142 }
1143 if (dfAttributes & DF_HAS_DEFS) {
1144 handleDef(defV, dInsn->vA);
1145 if (dfAttributes & DF_DA_WIDE) {
1146 handleDef(defV, dInsn->vA+1);
1147 }
1148 }
1149 }
1150 return true;
1151}
1152
1153/* Find out the latest SSA register for a given Dalvik register */
buzbeeed3e9302011-09-23 17:34:19 -07001154STATIC void handleSSAUse(CompilationUnit* cUnit, int* uses, int dalvikReg,
buzbee67bf8852011-08-17 17:51:35 -07001155 int regIndex)
1156{
1157 int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
1158 int ssaReg = DECODE_REG(encodedValue);
1159 uses[regIndex] = ssaReg;
1160}
1161
1162/* Setup a new SSA register for a given Dalvik register */
buzbeeed3e9302011-09-23 17:34:19 -07001163STATIC void handleSSADef(CompilationUnit* cUnit, int* defs, int dalvikReg,
buzbee67bf8852011-08-17 17:51:35 -07001164 int regIndex)
1165{
buzbee67bf8852011-08-17 17:51:35 -07001166 int ssaReg = cUnit->numSSARegs++;
1167 /* Bump up the subscript */
buzbeef0cde542011-09-13 14:55:02 -07001168 int dalvikSub = ++cUnit->SSALastDefs[dalvikReg];
buzbee67bf8852011-08-17 17:51:35 -07001169 int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);
1170
1171 cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
1172
1173 int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
1174 oatInsertGrowableList(cUnit->ssaToDalvikMap, newS2DMapping);
1175
1176 defs[regIndex] = ssaReg;
1177}
1178
buzbeeec5adf32011-09-11 15:25:43 -07001179/* Look up new SSA names for format_35c instructions */
buzbeeed3e9302011-09-23 17:34:19 -07001180STATIC void dataFlowSSAFormat35C(CompilationUnit* cUnit, MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -07001181{
1182 DecodedInstruction *dInsn = &mir->dalvikInsn;
1183 int numUses = dInsn->vA;
1184 int i;
1185
1186 mir->ssaRep->numUses = numUses;
buzbeec0ecd652011-09-25 18:11:54 -07001187 mir->ssaRep->uses = (int *)oatNew(sizeof(int) * numUses, true);
buzbeeed3e9302011-09-23 17:34:19 -07001188 // NOTE: will be filled in during type & size inference pass
buzbeec0ecd652011-09-25 18:11:54 -07001189 mir->ssaRep->fpUse = (bool *)oatNew(sizeof(bool) * numUses, true);
buzbee67bf8852011-08-17 17:51:35 -07001190
1191 for (i = 0; i < numUses; i++) {
1192 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
1193 }
1194}
1195
buzbeeec5adf32011-09-11 15:25:43 -07001196/* Look up new SSA names for format_3rc instructions */
buzbeeed3e9302011-09-23 17:34:19 -07001197STATIC void dataFlowSSAFormat3RC(CompilationUnit* cUnit, MIR* mir)
buzbee67bf8852011-08-17 17:51:35 -07001198{
1199 DecodedInstruction *dInsn = &mir->dalvikInsn;
1200 int numUses = dInsn->vA;
1201 int i;
1202
1203 mir->ssaRep->numUses = numUses;
buzbeec0ecd652011-09-25 18:11:54 -07001204 mir->ssaRep->uses = (int *)oatNew(sizeof(int) * numUses, true);
buzbeeed3e9302011-09-23 17:34:19 -07001205 // NOTE: will be filled in during type & size inference pass
buzbeec0ecd652011-09-25 18:11:54 -07001206 mir->ssaRep->fpUse = (bool *)oatNew(sizeof(bool) * numUses, true);
buzbee67bf8852011-08-17 17:51:35 -07001207
1208 for (i = 0; i < numUses; i++) {
1209 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
1210 }
1211}
1212
1213/* Entry function to convert a block into SSA representation */
1214bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb)
1215{
1216 MIR* mir;
1217
1218 if (bb->dataFlowInfo == NULL) return false;
1219
1220 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1221 mir->ssaRep = (struct SSARepresentation *)
1222 oatNew(sizeof(SSARepresentation), true);
1223
1224 int dfAttributes =
1225 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1226
buzbeef0cde542011-09-13 14:55:02 -07001227 // If not a pseudo-op, note non-leaf or can throw
1228 if (mir->dalvikInsn.opcode < kNumPackedOpcodes) {
1229 int flags = dexGetFlagsFromOpcode(mir->dalvikInsn.opcode);
buzbeecefd1872011-09-09 09:59:52 -07001230
buzbeef0cde542011-09-13 14:55:02 -07001231 if (flags & kInstrCanThrow) {
1232 cUnit->attrs &= ~METHOD_IS_THROW_FREE;
1233 }
buzbeecefd1872011-09-09 09:59:52 -07001234
buzbeef0cde542011-09-13 14:55:02 -07001235 if (flags & kInstrInvoke) {
1236 cUnit->attrs &= ~METHOD_IS_LEAF;
1237 }
buzbeecefd1872011-09-09 09:59:52 -07001238 }
1239
buzbee67bf8852011-08-17 17:51:35 -07001240 int numUses = 0;
1241
1242 if (dfAttributes & DF_FORMAT_35C) {
1243 dataFlowSSAFormat35C(cUnit, mir);
1244 continue;
1245 }
1246
1247 if (dfAttributes & DF_FORMAT_3RC) {
1248 dataFlowSSAFormat3RC(cUnit, mir);
1249 continue;
1250 }
1251
1252 if (dfAttributes & DF_HAS_USES) {
1253 if (dfAttributes & DF_UA) {
1254 numUses++;
1255 } else if (dfAttributes & DF_UA_WIDE) {
1256 numUses += 2;
1257 }
1258 if (dfAttributes & DF_UB) {
1259 numUses++;
1260 } else if (dfAttributes & DF_UB_WIDE) {
1261 numUses += 2;
1262 }
1263 if (dfAttributes & DF_UC) {
1264 numUses++;
1265 } else if (dfAttributes & DF_UC_WIDE) {
1266 numUses += 2;
1267 }
1268 }
1269
1270 if (numUses) {
1271 mir->ssaRep->numUses = numUses;
1272 mir->ssaRep->uses = (int *)oatNew(sizeof(int) * numUses,
1273 false);
1274 mir->ssaRep->fpUse = (bool *)oatNew(sizeof(bool) * numUses,
1275 false);
1276 }
1277
1278 int numDefs = 0;
1279
1280 if (dfAttributes & DF_HAS_DEFS) {
1281 numDefs++;
1282 if (dfAttributes & DF_DA_WIDE) {
1283 numDefs++;
1284 }
1285 }
1286
1287 if (numDefs) {
1288 mir->ssaRep->numDefs = numDefs;
1289 mir->ssaRep->defs = (int *)oatNew(sizeof(int) * numDefs,
1290 false);
1291 mir->ssaRep->fpDef = (bool *)oatNew(sizeof(bool) * numDefs,
1292 false);
1293 }
1294
1295 DecodedInstruction *dInsn = &mir->dalvikInsn;
1296
1297 if (dfAttributes & DF_HAS_USES) {
1298 numUses = 0;
1299 if (dfAttributes & DF_UA) {
1300 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1301 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1302 } else if (dfAttributes & DF_UA_WIDE) {
1303 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1304 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1305 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
1306 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
1307 }
1308 if (dfAttributes & DF_UB) {
1309 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1310 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1311 } else if (dfAttributes & DF_UB_WIDE) {
1312 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1313 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1314 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
1315 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
1316 }
1317 if (dfAttributes & DF_UC) {
1318 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1319 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1320 } else if (dfAttributes & DF_UC_WIDE) {
1321 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1322 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1323 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
1324 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
1325 }
1326 }
1327 if (dfAttributes & DF_HAS_DEFS) {
1328 mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
1329 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
1330 if (dfAttributes & DF_DA_WIDE) {
1331 mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
1332 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
1333 }
1334 }
1335 }
1336
1337 /*
1338 * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
1339 * input to PHI nodes can be derived from the snapshot of all predecessor
1340 * blocks.
1341 */
1342 bb->dataFlowInfo->dalvikToSSAMap =
Ian Rogersa3760aa2011-11-14 14:32:37 -08001343 (int *)oatNew(sizeof(int) * cUnit->numDalvikRegisters, false);
buzbee67bf8852011-08-17 17:51:35 -07001344
1345 memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
Ian Rogersa3760aa2011-11-14 14:32:37 -08001346 sizeof(int) * cUnit->numDalvikRegisters);
buzbee67bf8852011-08-17 17:51:35 -07001347 return true;
1348}
1349
1350/* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
buzbeeed3e9302011-09-23 17:34:19 -07001351STATIC void setConstant(CompilationUnit* cUnit, int ssaReg, int value)
buzbee67bf8852011-08-17 17:51:35 -07001352{
1353 oatSetBit(cUnit->isConstantV, ssaReg);
1354 cUnit->constantValues[ssaReg] = value;
1355}
1356
1357bool oatDoConstantPropagation(CompilationUnit* cUnit, BasicBlock* bb)
1358{
1359 MIR* mir;
1360 ArenaBitVector *isConstantV = cUnit->isConstantV;
1361
1362 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1363 int dfAttributes =
1364 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1365
1366 DecodedInstruction *dInsn = &mir->dalvikInsn;
1367
1368 if (!(dfAttributes & DF_HAS_DEFS)) continue;
1369
1370 /* Handle instructions that set up constants directly */
1371 if (dfAttributes & DF_SETS_CONST) {
1372 if (dfAttributes & DF_DA) {
1373 switch (dInsn->opcode) {
1374 case OP_CONST_4:
1375 case OP_CONST_16:
1376 case OP_CONST:
1377 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1378 break;
1379 case OP_CONST_HIGH16:
1380 setConstant(cUnit, mir->ssaRep->defs[0],
1381 dInsn->vB << 16);
1382 break;
1383 default:
1384 break;
1385 }
1386 } else if (dfAttributes & DF_DA_WIDE) {
1387 switch (dInsn->opcode) {
1388 case OP_CONST_WIDE_16:
1389 case OP_CONST_WIDE_32:
1390 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1391 setConstant(cUnit, mir->ssaRep->defs[1], 0);
1392 break;
1393 case OP_CONST_WIDE:
1394 setConstant(cUnit, mir->ssaRep->defs[0],
1395 (int) dInsn->vB_wide);
1396 setConstant(cUnit, mir->ssaRep->defs[1],
1397 (int) (dInsn->vB_wide >> 32));
1398 break;
1399 case OP_CONST_WIDE_HIGH16:
1400 setConstant(cUnit, mir->ssaRep->defs[0], 0);
1401 setConstant(cUnit, mir->ssaRep->defs[1],
1402 dInsn->vB << 16);
1403 break;
1404 default:
1405 break;
1406 }
1407 }
1408 /* Handle instructions that set up constants directly */
1409 } else if (dfAttributes & DF_IS_MOVE) {
1410 int i;
1411
1412 for (i = 0; i < mir->ssaRep->numUses; i++) {
1413 if (!oatIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
1414 }
1415 /* Move a register holding a constant to another register */
1416 if (i == mir->ssaRep->numUses) {
1417 setConstant(cUnit, mir->ssaRep->defs[0],
1418 cUnit->constantValues[mir->ssaRep->uses[0]]);
1419 if (dfAttributes & DF_DA_WIDE) {
1420 setConstant(cUnit, mir->ssaRep->defs[1],
1421 cUnit->constantValues[mir->ssaRep->uses[1]]);
1422 }
1423 }
1424 }
1425 }
1426 /* TODO: implement code to handle arithmetic operations */
1427 return true;
1428}
1429
1430/* Setup the basic data structures for SSA conversion */
1431void oatInitializeSSAConversion(CompilationUnit* cUnit)
1432{
1433 int i;
Ian Rogersa3760aa2011-11-14 14:32:37 -08001434 int numDalvikReg = cUnit->numDalvikRegisters;
buzbee67bf8852011-08-17 17:51:35 -07001435
1436 cUnit->ssaToDalvikMap = (GrowableList *)oatNew(sizeof(GrowableList),
1437 false);
1438 oatInitGrowableList(cUnit->ssaToDalvikMap, numDalvikReg);
1439
1440 /*
1441 * Initial number of SSA registers is equal to the number of Dalvik
1442 * registers.
1443 */
1444 cUnit->numSSARegs = numDalvikReg;
1445
1446 /*
1447 * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
1448 * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
1449 * into "(0 << 16) | i"
1450 */
1451 for (i = 0; i < numDalvikReg; i++) {
1452 oatInsertGrowableList(cUnit->ssaToDalvikMap, ENCODE_REG_SUB(i, 0));
1453 }
1454
1455 /*
1456 * Initialize the DalvikToSSAMap map. The low 16 bit is the SSA register id,
1457 * while the high 16 bit is the current subscript. The original Dalvik
1458 * register N is mapped to SSA register N with subscript 0.
1459 */
1460 cUnit->dalvikToSSAMap = (int *)oatNew(sizeof(int) * numDalvikReg,
1461 false);
buzbeef0cde542011-09-13 14:55:02 -07001462 /* Keep track of the higest def for each dalvik reg */
1463 cUnit->SSALastDefs = (int *)oatNew(sizeof(int) * numDalvikReg,
1464 false);
1465
buzbee67bf8852011-08-17 17:51:35 -07001466 for (i = 0; i < numDalvikReg; i++) {
1467 cUnit->dalvikToSSAMap[i] = i;
buzbeef0cde542011-09-13 14:55:02 -07001468 cUnit->SSALastDefs[i] = 0;
buzbee67bf8852011-08-17 17:51:35 -07001469 }
1470
1471 /*
1472 * Allocate the BasicBlockDataFlow structure for the entry and code blocks
1473 */
1474 GrowableListIterator iterator;
1475
1476 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
1477
1478 while (true) {
1479 BasicBlock* bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
1480 if (bb == NULL) break;
1481 if (bb->hidden == true) continue;
1482 if (bb->blockType == kDalvikByteCode ||
1483 bb->blockType == kEntryBlock ||
1484 bb->blockType == kExitBlock) {
1485 bb->dataFlowInfo = (BasicBlockDataFlow *)
1486 oatNew(sizeof(BasicBlockDataFlow),
1487 true);
1488 }
1489 }
1490}
1491
1492/* Clear the visited flag for each BB */
1493bool oatClearVisitedFlag(struct CompilationUnit* cUnit,
1494 struct BasicBlock* bb)
1495{
1496 bb->visited = false;
1497 return true;
1498}
1499
1500void oatDataFlowAnalysisDispatcher(CompilationUnit* cUnit,
1501 bool (*func)(CompilationUnit*, BasicBlock*),
1502 DataFlowAnalysisMode dfaMode,
1503 bool isIterative)
1504{
1505 bool change = true;
1506
1507 while (change) {
1508 change = false;
1509
1510 /* Scan all blocks and perform the operations specified in func */
1511 if (dfaMode == kAllNodes) {
1512 GrowableListIterator iterator;
1513 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
1514 while (true) {
1515 BasicBlock* bb =
1516 (BasicBlock *) oatGrowableListIteratorNext(&iterator);
1517 if (bb == NULL) break;
1518 if (bb->hidden == true) continue;
1519 change |= (*func)(cUnit, bb);
1520 }
1521 }
1522 /*
1523 * Scan all reachable blocks and perform the operations specified in
1524 * func.
1525 */
1526 else if (dfaMode == kReachableNodes) {
1527 int numReachableBlocks = cUnit->numReachableBlocks;
1528 int idx;
1529 const GrowableList *blockList = &cUnit->blockList;
1530
1531 for (idx = 0; idx < numReachableBlocks; idx++) {
1532 int blockIdx = cUnit->dfsOrder.elemList[idx];
1533 BasicBlock* bb =
1534 (BasicBlock *) oatGrowableListGetElement(blockList,
1535 blockIdx);
1536 change |= (*func)(cUnit, bb);
1537 }
1538 }
1539 /*
1540 * Scan all reachable blocks by the pre-order in the depth-first-search
1541 * CFG and perform the operations specified in func.
1542 */
1543 else if (dfaMode == kPreOrderDFSTraversal) {
1544 int numReachableBlocks = cUnit->numReachableBlocks;
1545 int idx;
1546 const GrowableList *blockList = &cUnit->blockList;
1547
1548 for (idx = 0; idx < numReachableBlocks; idx++) {
1549 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1550 BasicBlock* bb =
1551 (BasicBlock *) oatGrowableListGetElement(blockList, dfsIdx);
1552 change |= (*func)(cUnit, bb);
1553 }
1554 }
1555 /*
1556 * Scan all reachable blocks by the post-order in the depth-first-search
1557 * CFG and perform the operations specified in func.
1558 */
1559 else if (dfaMode == kPostOrderDFSTraversal) {
1560 int numReachableBlocks = cUnit->numReachableBlocks;
1561 int idx;
1562 const GrowableList *blockList = &cUnit->blockList;
1563
1564 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
1565 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1566 BasicBlock* bb =
1567 (BasicBlock *) oatGrowableListGetElement(blockList, dfsIdx);
1568 change |= (*func)(cUnit, bb);
1569 }
1570 }
1571 /*
1572 * Scan all reachable blocks by the post-order in the dominator tree
1573 * and perform the operations specified in func.
1574 */
1575 else if (dfaMode == kPostOrderDOMTraversal) {
1576 int numReachableBlocks = cUnit->numReachableBlocks;
1577 int idx;
1578 const GrowableList *blockList = &cUnit->blockList;
1579
1580 for (idx = 0; idx < numReachableBlocks; idx++) {
1581 int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
1582 BasicBlock* bb =
1583 (BasicBlock *) oatGrowableListGetElement(blockList, domIdx);
1584 change |= (*func)(cUnit, bb);
1585 }
1586 }
1587 /* If isIterative is false, exit the loop after the first iteration */
1588 change &= isIterative;
1589 }
1590}
buzbee43a36422011-09-14 14:00:13 -07001591
buzbeeed3e9302011-09-23 17:34:19 -07001592STATIC bool nullCheckEliminationInit(struct CompilationUnit* cUnit,
buzbee43a36422011-09-14 14:00:13 -07001593 struct BasicBlock* bb)
1594{
1595 if (bb->dataFlowInfo == NULL) return false;
1596 bb->dataFlowInfo->endingNullCheckV =
1597 oatAllocBitVector(cUnit->numSSARegs, false);
1598 oatClearAllBits(bb->dataFlowInfo->endingNullCheckV);
1599 return true;
1600}
1601
1602/* Eliminate unnecessary null checks for a basic block. */
buzbeeed3e9302011-09-23 17:34:19 -07001603STATIC bool eliminateNullChecks( struct CompilationUnit* cUnit,
buzbee43a36422011-09-14 14:00:13 -07001604 struct BasicBlock* bb)
1605{
1606 if (bb->dataFlowInfo == NULL) return false;
1607 /*
1608 * Set initial state. Be conservative with catch
1609 * blocks and start with no assumptions about null check
1610 * status (except for "this").
1611 */
1612
1613 if ((bb->blockType == kEntryBlock) | bb->catchEntry) {
1614 oatClearAllBits(cUnit->tempSSARegisterV);
Ian Rogersa3760aa2011-11-14 14:32:37 -08001615 if ((cUnit->access_flags & art::kAccStatic) == 0) {
buzbee43a36422011-09-14 14:00:13 -07001616 // If non-static method, mark "this" as non-null
Ian Rogersa3760aa2011-11-14 14:32:37 -08001617 int thisReg = cUnit->numDalvikRegisters - cUnit->numIns;
buzbee43a36422011-09-14 14:00:13 -07001618 oatSetBit(cUnit->tempSSARegisterV, thisReg);
1619 }
1620 } else {
1621 // Starting state is intesection of all incoming arcs
1622 GrowableList* blockList = &cUnit->blockList;
1623 ArenaBitVectorIterator bvIterator;
1624 oatBitVectorIteratorInit(bb->predecessors, &bvIterator);
1625 int predBBIdx = oatBitVectorIteratorNext(&bvIterator);
buzbeeed3e9302011-09-23 17:34:19 -07001626 DCHECK_NE(predBBIdx, -1);
buzbee43a36422011-09-14 14:00:13 -07001627 BasicBlock* predBB = (BasicBlock*)oatGrowableListGetElement(
1628 blockList, predBBIdx);
1629 oatCopyBitVector(cUnit->tempSSARegisterV,
1630 predBB->dataFlowInfo->endingNullCheckV);
1631 while (true) {
1632 predBBIdx = oatBitVectorIteratorNext(&bvIterator);
1633 if (predBBIdx == -1) break;
1634 predBB = (BasicBlock*)oatGrowableListGetElement(
1635 blockList, predBBIdx);
buzbeeaad72012011-09-21 21:52:09 -07001636 if ((predBB->dataFlowInfo == NULL) ||
1637 (predBB->dataFlowInfo->endingNullCheckV == NULL)) {
1638 continue;
1639 }
buzbee43a36422011-09-14 14:00:13 -07001640 oatIntersectBitVectors(cUnit->tempSSARegisterV,
1641 cUnit->tempSSARegisterV,
1642 predBB->dataFlowInfo->endingNullCheckV);
1643 }
1644 }
1645
1646 // Walk through the instruction in the block, updating as necessary
1647 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1648 if (mir->ssaRep == NULL) {
1649 continue;
1650 }
1651 int dfAttributes =
1652 oatDataFlowAttributes[mir->dalvikInsn.opcode];
1653
1654 // Mark target of NEW* as non-null
1655 if (dfAttributes & DF_NON_NULL_DST) {
1656 oatSetBit(cUnit->tempSSARegisterV, mir->ssaRep->defs[0]);
1657 }
1658
1659 // Mark non-null returns from invoke-style NEW*
1660 if (dfAttributes & DF_NON_NULL_RET) {
1661 MIR* nextMir = mir->next;
1662 // Next should be an OP_MOVE_RESULT_OBJECT
1663 if (nextMir && nextMir->dalvikInsn.opcode == OP_MOVE_RESULT_OBJECT) {
1664 // Mark as null checked
buzbee949f56e2011-10-06 11:05:45 -07001665 oatSetBit(cUnit->tempSSARegisterV, nextMir->ssaRep->defs[0]);
buzbee43a36422011-09-14 14:00:13 -07001666 } else {
1667 if (nextMir) {
1668 LOG(WARNING) << "Unexpected opcode following new: " <<
1669 (int)nextMir->dalvikInsn.opcode;
buzbee949f56e2011-10-06 11:05:45 -07001670 } else if (bb->fallThrough) {
1671 // Look in next basic block
1672 struct BasicBlock* nextBB = bb->fallThrough;
1673 for (MIR* tmir = nextBB->firstMIRInsn; tmir;
1674 tmir =tmir->next){
1675 if ((int)tmir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1676 continue;
1677 }
1678 // First non-pseudo should be OP_MOVE_RESULT_OBJECT
1679 if (tmir->dalvikInsn.opcode == OP_MOVE_RESULT_OBJECT) {
1680 // Mark as null checked
1681 oatSetBit(cUnit->tempSSARegisterV,
1682 tmir->ssaRep->defs[0]);
1683 } else {
1684 LOG(WARNING) << "Unexpected op after new: " <<
1685 (int)tmir->dalvikInsn.opcode;
1686 }
1687 break;
1688 }
buzbee43a36422011-09-14 14:00:13 -07001689 }
1690 }
1691 }
1692
1693 /*
1694 * Propagate nullcheck state on register copies (including
1695 * Phi pseudo copies. For the latter, nullcheck state is
1696 * the "and" of all the Phi's operands.
1697 */
1698 if (dfAttributes & (DF_NULL_TRANSFER_0 | DF_NULL_TRANSFER_N)) {
1699 int tgtSreg = mir->ssaRep->defs[0];
1700 int operands = (dfAttributes & DF_NULL_TRANSFER_0) ? 1 :
1701 mir->ssaRep->numUses;
1702 bool nullChecked = true;
1703 for (int i = 0; i < operands; i++) {
1704 nullChecked &= oatIsBitSet(cUnit->tempSSARegisterV,
1705 mir->ssaRep->uses[i]);
1706 }
1707 if (nullChecked) {
1708 oatSetBit(cUnit->tempSSARegisterV, tgtSreg);
1709 }
1710 }
1711
1712 // Already nullchecked?
1713 if (dfAttributes & DF_HAS_NULL_CHKS) {
1714 int srcSreg = (dfAttributes & DF_NULL_CHK_1) ?
1715 mir->ssaRep->uses[1] : mir->ssaRep->uses[0];
1716 if (oatIsBitSet(cUnit->tempSSARegisterV, srcSreg)) {
1717 // Eliminate the null check
1718 mir->optimizationFlags |= MIR_IGNORE_NULL_CHECK;
1719 } else {
1720 // Mark sReg as null-checked
1721 oatSetBit(cUnit->tempSSARegisterV, srcSreg);
1722 }
1723 }
1724 }
1725
1726 // Did anything change?
1727 bool res = oatCompareBitVectors(bb->dataFlowInfo->endingNullCheckV,
1728 cUnit->tempSSARegisterV);
1729 if (res) {
1730 oatCopyBitVector(bb->dataFlowInfo->endingNullCheckV,
1731 cUnit->tempSSARegisterV);
1732 }
1733 return res;
1734}
1735
1736void oatMethodNullCheckElimination(CompilationUnit *cUnit)
1737{
1738 if (!(cUnit->disableOpt & (1 << kNullCheckElimination))) {
1739 DCHECK(cUnit->tempSSARegisterV != NULL);
1740 oatDataFlowAnalysisDispatcher(cUnit, nullCheckEliminationInit,
1741 kAllNodes,
1742 false /* isIterative */);
1743 oatDataFlowAnalysisDispatcher(cUnit, eliminateNullChecks,
1744 kPreOrderDFSTraversal,
1745 true /* isIterative */);
1746 }
1747}