blob: 411f456e724f4710d9e0603f55d9a7cd6c13a6bf [file] [log] [blame]
Ben Cheng4238ec22009-08-24 16:32:22 -07001/*
2 * Copyright (C) 2009 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 "Loop.h"
Dan Bornsteindf4daaf2010-12-01 14:23:44 -080020#include "libdex/DexOpcodes.h"
Ben Cheng4238ec22009-08-24 16:32:22 -070021
22/*
Dan Bornstein675b6422010-11-19 16:01:25 -080023 * Main table containing data flow attributes for each bytecode. The
Dan Bornsteinccaab182010-12-03 15:32:40 -080024 * first kNumPackedOpcodes entries are for Dalvik bytecode
Dan Bornstein675b6422010-11-19 16:01:25 -080025 * instructions, where extended opcode at the MIR level are appended
26 * afterwards.
Ben Cheng4238ec22009-08-24 16:32:22 -070027 *
28 * TODO - many optimization flags are incomplete - they will only limit the
29 * scope of optimizations but will not cause mis-optimizations.
30 */
Bill Buzbee1465db52009-09-23 17:17:35 -070031int dvmCompilerDataFlowAttributes[kMirOpLast] = {
Ben Cheng4238ec22009-08-24 16:32:22 -070032 // 00 OP_NOP
33 DF_NOP,
34
35 // 01 OP_MOVE vA, vB
36 DF_DA | DF_UB | DF_IS_MOVE,
37
38 // 02 OP_MOVE_FROM16 vAA, vBBBB
39 DF_DA | DF_UB | DF_IS_MOVE,
40
41 // 03 OP_MOVE_16 vAAAA, vBBBB
42 DF_DA | DF_UB | DF_IS_MOVE,
43
44 // 04 OP_MOVE_WIDE vA, vB
45 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
46
47 // 05 OP_MOVE_WIDE_FROM16 vAA, vBBBB
48 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
49
50 // 06 OP_MOVE_WIDE_16 vAAAA, vBBBB
51 DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
52
53 // 07 OP_MOVE_OBJECT vA, vB
54 DF_DA | DF_UB | DF_IS_MOVE,
55
56 // 08 OP_MOVE_OBJECT_FROM16 vAA, vBBBB
57 DF_DA | DF_UB | DF_IS_MOVE,
58
59 // 09 OP_MOVE_OBJECT_16 vAAAA, vBBBB
60 DF_DA | DF_UB | DF_IS_MOVE,
61
62 // 0A OP_MOVE_RESULT vAA
63 DF_DA,
64
65 // 0B OP_MOVE_RESULT_WIDE vAA
66 DF_DA_WIDE,
67
68 // 0C OP_MOVE_RESULT_OBJECT vAA
69 DF_DA,
70
71 // 0D OP_MOVE_EXCEPTION vAA
72 DF_DA,
73
74 // 0E OP_RETURN_VOID
75 DF_NOP,
76
77 // 0F OP_RETURN vAA
78 DF_UA,
79
80 // 10 OP_RETURN_WIDE vAA
81 DF_UA_WIDE,
82
83 // 11 OP_RETURN_OBJECT vAA
84 DF_UA,
85
86 // 12 OP_CONST_4 vA, #+B
87 DF_DA | DF_SETS_CONST,
88
89 // 13 OP_CONST_16 vAA, #+BBBB
90 DF_DA | DF_SETS_CONST,
91
92 // 14 OP_CONST vAA, #+BBBBBBBB
93 DF_DA | DF_SETS_CONST,
94
95 // 15 OP_CONST_HIGH16 VAA, #+BBBB0000
96 DF_DA | DF_SETS_CONST,
97
98 // 16 OP_CONST_WIDE_16 vAA, #+BBBB
99 DF_DA_WIDE | DF_SETS_CONST,
100
101 // 17 OP_CONST_WIDE_32 vAA, #+BBBBBBBB
102 DF_DA_WIDE | DF_SETS_CONST,
103
104 // 18 OP_CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
105 DF_DA_WIDE | DF_SETS_CONST,
106
107 // 19 OP_CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
108 DF_DA_WIDE | DF_SETS_CONST,
109
110 // 1A OP_CONST_STRING vAA, string@BBBB
111 DF_DA,
112
113 // 1B OP_CONST_STRING_JUMBO vAA, string@BBBBBBBB
114 DF_DA,
115
116 // 1C OP_CONST_CLASS vAA, type@BBBB
117 DF_DA,
118
119 // 1D OP_MONITOR_ENTER vAA
120 DF_UA,
121
122 // 1E OP_MONITOR_EXIT vAA
123 DF_UA,
124
125 // 1F OP_CHECK_CAST vAA, type@BBBB
126 DF_UA,
127
128 // 20 OP_INSTANCE_OF vA, vB, type@CCCC
129 DF_DA | DF_UB,
130
131 // 21 OP_ARRAY_LENGTH vA, vB
132 DF_DA | DF_UB,
133
134 // 22 OP_NEW_INSTANCE vAA, type@BBBB
135 DF_DA,
136
137 // 23 OP_NEW_ARRAY vA, vB, type@CCCC
138 DF_DA | DF_UB,
139
140 // 24 OP_FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
141 DF_FORMAT_35C,
142
143 // 25 OP_FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
144 DF_FORMAT_3RC,
145
146 // 26 OP_FILL_ARRAY_DATA vAA, +BBBBBBBB
147 DF_UA,
148
149 // 27 OP_THROW vAA
150 DF_UA,
151
152 // 28 OP_GOTO
153 DF_NOP,
154
155 // 29 OP_GOTO_16
156 DF_NOP,
157
158 // 2A OP_GOTO_32
159 DF_NOP,
160
161 // 2B OP_PACKED_SWITCH vAA, +BBBBBBBB
162 DF_UA,
163
164 // 2C OP_SPARSE_SWITCH vAA, +BBBBBBBB
165 DF_UA,
166
167 // 2D OP_CMPL_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700168 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700169
170 // 2E OP_CMPG_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700171 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700172
173 // 2F OP_CMPL_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700174 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700175
176 // 30 OP_CMPG_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700177 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700178
179 // 31 OP_CMP_LONG vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700180 DF_DA | DF_UB_WIDE | DF_UC_WIDE,
Ben Cheng4238ec22009-08-24 16:32:22 -0700181
182 // 32 OP_IF_EQ vA, vB, +CCCC
183 DF_UA | DF_UB,
184
185 // 33 OP_IF_NE vA, vB, +CCCC
186 DF_UA | DF_UB,
187
188 // 34 OP_IF_LT vA, vB, +CCCC
189 DF_UA | DF_UB,
190
191 // 35 OP_IF_GE vA, vB, +CCCC
192 DF_UA | DF_UB,
193
194 // 36 OP_IF_GT vA, vB, +CCCC
195 DF_UA | DF_UB,
196
197 // 37 OP_IF_LE vA, vB, +CCCC
198 DF_UA | DF_UB,
199
200
201 // 38 OP_IF_EQZ vAA, +BBBB
202 DF_UA,
203
204 // 39 OP_IF_NEZ vAA, +BBBB
205 DF_UA,
206
207 // 3A OP_IF_LTZ vAA, +BBBB
208 DF_UA,
209
210 // 3B OP_IF_GEZ vAA, +BBBB
211 DF_UA,
212
213 // 3C OP_IF_GTZ vAA, +BBBB
214 DF_UA,
215
216 // 3D OP_IF_LEZ vAA, +BBBB
217 DF_UA,
218
219 // 3E OP_UNUSED_3E
220 DF_NOP,
221
222 // 3F OP_UNUSED_3F
223 DF_NOP,
224
225 // 40 OP_UNUSED_40
226 DF_NOP,
227
228 // 41 OP_UNUSED_41
229 DF_NOP,
230
231 // 42 OP_UNUSED_42
232 DF_NOP,
233
234 // 43 OP_UNUSED_43
235 DF_NOP,
236
237 // 44 OP_AGET vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700238 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700239
240 // 45 OP_AGET_WIDE vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700241 DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700242
243 // 46 OP_AGET_OBJECT vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700244 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700245
246 // 47 OP_AGET_BOOLEAN vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700247 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700248
249 // 48 OP_AGET_BYTE vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700250 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700251
252 // 49 OP_AGET_CHAR vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700253 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700254
255 // 4A OP_AGET_SHORT vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700256 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700257
258 // 4B OP_APUT vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700259 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700260
261 // 4C OP_APUT_WIDE vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700262 DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_2 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700263
264 // 4D OP_APUT_OBJECT vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700265 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700266
267 // 4E OP_APUT_BOOLEAN vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700268 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700269
270 // 4F OP_APUT_BYTE vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700271 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700272
273 // 50 OP_APUT_CHAR vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700274 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700275
276 // 51 OP_APUT_SHORT vAA, vBB, vCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700277 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700278
279 // 52 OP_IGET vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700280 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700281
282 // 53 OP_IGET_WIDE vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700283 DF_DA_WIDE | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700284
285 // 54 OP_IGET_OBJECT vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700286 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700287
288 // 55 OP_IGET_BOOLEAN vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700289 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700290
291 // 56 OP_IGET_BYTE vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700292 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700293
294 // 57 OP_IGET_CHAR vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700295 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700296
297 // 58 OP_IGET_SHORT vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700298 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700299
300 // 59 OP_IPUT vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700301 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700302
303 // 5A OP_IPUT_WIDE vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700304 DF_UA_WIDE | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700305
306 // 5B OP_IPUT_OBJECT vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700307 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700308
309 // 5C OP_IPUT_BOOLEAN vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700310 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700311
312 // 5D OP_IPUT_BYTE vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700313 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700314
315 // 5E OP_IPUT_CHAR vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700316 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700317
318 // 5F OP_IPUT_SHORT vA, vB, field@CCCC
Ben Cheng7a2697d2010-06-07 13:44:23 -0700319 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700320
321 // 60 OP_SGET vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700322 DF_DA | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700323
324 // 61 OP_SGET_WIDE vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700325 DF_DA_WIDE | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700326
327 // 62 OP_SGET_OBJECT vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700328 DF_DA | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700329
330 // 63 OP_SGET_BOOLEAN vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700331 DF_DA | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700332
333 // 64 OP_SGET_BYTE vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700334 DF_DA | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700335
336 // 65 OP_SGET_CHAR vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700337 DF_DA | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700338
339 // 66 OP_SGET_SHORT vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700340 DF_DA | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700341
342 // 67 OP_SPUT vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700343 DF_UA | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700344
345 // 68 OP_SPUT_WIDE vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700346 DF_UA_WIDE | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700347
348 // 69 OP_SPUT_OBJECT vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700349 DF_UA | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700350
351 // 6A OP_SPUT_BOOLEAN vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700352 DF_UA | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700353
354 // 6B OP_SPUT_BYTE vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700355 DF_UA | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700356
357 // 6C OP_SPUT_CHAR vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700358 DF_UA | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700359
360 // 6D OP_SPUT_SHORT vAA, field@BBBB
Ben Cheng7a2697d2010-06-07 13:44:23 -0700361 DF_UA | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700362
363 // 6E OP_INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
364 DF_FORMAT_35C,
365
366 // 6F OP_INVOKE_SUPER {vD, vE, vF, vG, vA}
367 DF_FORMAT_35C,
368
369 // 70 OP_INVOKE_DIRECT {vD, vE, vF, vG, vA}
370 DF_FORMAT_35C,
371
372 // 71 OP_INVOKE_STATIC {vD, vE, vF, vG, vA}
373 DF_FORMAT_35C,
374
375 // 72 OP_INVOKE_INTERFACE {vD, vE, vF, vG, vA}
376 DF_FORMAT_35C,
377
378 // 73 OP_UNUSED_73
379 DF_NOP,
380
381 // 74 OP_INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
382 DF_FORMAT_3RC,
383
384 // 75 OP_INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
385 DF_FORMAT_3RC,
386
387 // 76 OP_INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
388 DF_FORMAT_3RC,
389
390 // 77 OP_INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
391 DF_FORMAT_3RC,
392
393 // 78 OP_INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
394 DF_FORMAT_3RC,
395
396 // 79 OP_UNUSED_79
397 DF_NOP,
398
399 // 7A OP_UNUSED_7A
400 DF_NOP,
401
402 // 7B OP_NEG_INT vA, vB
403 DF_DA | DF_UB,
404
405 // 7C OP_NOT_INT vA, vB
406 DF_DA | DF_UB,
407
408 // 7D OP_NEG_LONG vA, vB
409 DF_DA_WIDE | DF_UB_WIDE,
410
411 // 7E OP_NOT_LONG vA, vB
412 DF_DA_WIDE | DF_UB_WIDE,
413
414 // 7F OP_NEG_FLOAT vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700415 DF_DA | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700416
417 // 80 OP_NEG_DOUBLE vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700418 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700419
420 // 81 OP_INT_TO_LONG vA, vB
421 DF_DA_WIDE | DF_UB,
422
423 // 82 OP_INT_TO_FLOAT vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700424 DF_DA | DF_UB | DF_FP_A,
Ben Cheng4238ec22009-08-24 16:32:22 -0700425
426 // 83 OP_INT_TO_DOUBLE vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700427 DF_DA_WIDE | DF_UB | DF_FP_A,
Ben Cheng4238ec22009-08-24 16:32:22 -0700428
429 // 84 OP_LONG_TO_INT vA, vB
430 DF_DA | DF_UB_WIDE,
431
432 // 85 OP_LONG_TO_FLOAT vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700433 DF_DA | DF_UB_WIDE | DF_FP_A,
Ben Cheng4238ec22009-08-24 16:32:22 -0700434
435 // 86 OP_LONG_TO_DOUBLE vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700436 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A,
Ben Cheng4238ec22009-08-24 16:32:22 -0700437
438 // 87 OP_FLOAT_TO_INT vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700439 DF_DA | DF_UB | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700440
441 // 88 OP_FLOAT_TO_LONG vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700442 DF_DA_WIDE | DF_UB | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700443
444 // 89 OP_FLOAT_TO_DOUBLE vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700445 DF_DA_WIDE | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700446
447 // 8A OP_DOUBLE_TO_INT vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700448 DF_DA | DF_UB_WIDE | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700449
450 // 8B OP_DOUBLE_TO_LONG vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700451 DF_DA_WIDE | DF_UB_WIDE | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700452
453 // 8C OP_DOUBLE_TO_FLOAT vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700454 DF_DA | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700455
456 // 8D OP_INT_TO_BYTE vA, vB
457 DF_DA | DF_UB,
458
459 // 8E OP_INT_TO_CHAR vA, vB
460 DF_DA | DF_UB,
461
462 // 8F OP_INT_TO_SHORT vA, vB
463 DF_DA | DF_UB,
464
465 // 90 OP_ADD_INT vAA, vBB, vCC
466 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR,
467
468 // 91 OP_SUB_INT vAA, vBB, vCC
469 DF_DA | DF_UB | DF_UC | DF_IS_LINEAR,
470
471 // 92 OP_MUL_INT vAA, vBB, vCC
472 DF_DA | DF_UB | DF_UC,
473
474 // 93 OP_DIV_INT vAA, vBB, vCC
475 DF_DA | DF_UB | DF_UC,
476
477 // 94 OP_REM_INT vAA, vBB, vCC
478 DF_DA | DF_UB | DF_UC,
479
480 // 95 OP_AND_INT vAA, vBB, vCC
481 DF_DA | DF_UB | DF_UC,
482
483 // 96 OP_OR_INT vAA, vBB, vCC
484 DF_DA | DF_UB | DF_UC,
485
486 // 97 OP_XOR_INT vAA, vBB, vCC
487 DF_DA | DF_UB | DF_UC,
488
489 // 98 OP_SHL_INT vAA, vBB, vCC
490 DF_DA | DF_UB | DF_UC,
491
492 // 99 OP_SHR_INT vAA, vBB, vCC
493 DF_DA | DF_UB | DF_UC,
494
495 // 9A OP_USHR_INT vAA, vBB, vCC
496 DF_DA | DF_UB | DF_UC,
497
498 // 9B OP_ADD_LONG vAA, vBB, vCC
499 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
500
501 // 9C OP_SUB_LONG vAA, vBB, vCC
502 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
503
504 // 9D OP_MUL_LONG vAA, vBB, vCC
505 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
506
507 // 9E OP_DIV_LONG vAA, vBB, vCC
508 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
509
510 // 9F OP_REM_LONG vAA, vBB, vCC
511 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
512
513 // A0 OP_AND_LONG vAA, vBB, vCC
514 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
515
516 // A1 OP_OR_LONG vAA, vBB, vCC
517 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
518
519 // A2 OP_XOR_LONG vAA, vBB, vCC
520 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
521
522 // A3 OP_SHL_LONG vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700523 DF_DA_WIDE | DF_UB_WIDE | DF_UC,
Ben Cheng4238ec22009-08-24 16:32:22 -0700524
525 // A4 OP_SHR_LONG vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700526 DF_DA_WIDE | DF_UB_WIDE | DF_UC,
Ben Cheng4238ec22009-08-24 16:32:22 -0700527
528 // A5 OP_USHR_LONG vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700529 DF_DA_WIDE | DF_UB_WIDE | DF_UC,
Ben Cheng4238ec22009-08-24 16:32:22 -0700530
531 // A6 OP_ADD_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700532 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700533
534 // A7 OP_SUB_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700535 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700536
537 // A8 OP_MUL_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700538 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700539
540 // A9 OP_DIV_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700541 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700542
543 // AA OP_REM_FLOAT vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700544 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700545
546 // AB OP_ADD_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700547 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700548
549 // AC OP_SUB_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700550 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700551
552 // AD OP_MUL_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700553 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700554
555 // AE OP_DIV_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700556 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700557
558 // AF OP_REM_DOUBLE vAA, vBB, vCC
Bill Buzbee1465db52009-09-23 17:17:35 -0700559 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
Ben Cheng4238ec22009-08-24 16:32:22 -0700560
561 // B0 OP_ADD_INT_2ADDR vA, vB
562 DF_DA | DF_UA | DF_UB,
563
564 // B1 OP_SUB_INT_2ADDR vA, vB
565 DF_DA | DF_UA | DF_UB,
566
567 // B2 OP_MUL_INT_2ADDR vA, vB
568 DF_DA | DF_UA | DF_UB,
569
570 // B3 OP_DIV_INT_2ADDR vA, vB
571 DF_DA | DF_UA | DF_UB,
572
573 // B4 OP_REM_INT_2ADDR vA, vB
574 DF_DA | DF_UA | DF_UB,
575
576 // B5 OP_AND_INT_2ADDR vA, vB
577 DF_DA | DF_UA | DF_UB,
578
579 // B6 OP_OR_INT_2ADDR vA, vB
580 DF_DA | DF_UA | DF_UB,
581
582 // B7 OP_XOR_INT_2ADDR vA, vB
583 DF_DA | DF_UA | DF_UB,
584
585 // B8 OP_SHL_INT_2ADDR vA, vB
586 DF_DA | DF_UA | DF_UB,
587
588 // B9 OP_SHR_INT_2ADDR vA, vB
589 DF_DA | DF_UA | DF_UB,
590
591 // BA OP_USHR_INT_2ADDR vA, vB
592 DF_DA | DF_UA | DF_UB,
593
594 // BB OP_ADD_LONG_2ADDR vA, vB
595 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
596
597 // BC OP_SUB_LONG_2ADDR vA, vB
598 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
599
600 // BD OP_MUL_LONG_2ADDR vA, vB
601 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
602
603 // BE OP_DIV_LONG_2ADDR vA, vB
604 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
605
606 // BF OP_REM_LONG_2ADDR vA, vB
607 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
608
609 // C0 OP_AND_LONG_2ADDR vA, vB
610 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
611
612 // C1 OP_OR_LONG_2ADDR vA, vB
613 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
614
615 // C2 OP_XOR_LONG_2ADDR vA, vB
616 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
617
618 // C3 OP_SHL_LONG_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700619 DF_DA_WIDE | DF_UA_WIDE | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700620
621 // C4 OP_SHR_LONG_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700622 DF_DA_WIDE | DF_UA_WIDE | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700623
624 // C5 OP_USHR_LONG_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700625 DF_DA_WIDE | DF_UA_WIDE | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700626
627 // C6 OP_ADD_FLOAT_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700628 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700629
630 // C7 OP_SUB_FLOAT_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700631 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700632
633 // C8 OP_MUL_FLOAT_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700634 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700635
636 // C9 OP_DIV_FLOAT_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700637 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700638
639 // CA OP_REM_FLOAT_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700640 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700641
642 // CB OP_ADD_DOUBLE_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700643 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700644
645 // CC OP_SUB_DOUBLE_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700646 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700647
648 // CD OP_MUL_DOUBLE_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700649 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700650
651 // CE OP_DIV_DOUBLE_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700652 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700653
654 // CF OP_REM_DOUBLE_2ADDR vA, vB
Bill Buzbee1465db52009-09-23 17:17:35 -0700655 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
Ben Cheng4238ec22009-08-24 16:32:22 -0700656
657 // D0 OP_ADD_INT_LIT16 vA, vB, #+CCCC
658 DF_DA | DF_UB,
659
660 // D1 OP_RSUB_INT vA, vB, #+CCCC
661 DF_DA | DF_UB,
662
663 // D2 OP_MUL_INT_LIT16 vA, vB, #+CCCC
664 DF_DA | DF_UB,
665
666 // D3 OP_DIV_INT_LIT16 vA, vB, #+CCCC
667 DF_DA | DF_UB,
668
669 // D4 OP_REM_INT_LIT16 vA, vB, #+CCCC
670 DF_DA | DF_UB,
671
672 // D5 OP_AND_INT_LIT16 vA, vB, #+CCCC
673 DF_DA | DF_UB,
674
675 // D6 OP_OR_INT_LIT16 vA, vB, #+CCCC
676 DF_DA | DF_UB,
677
678 // D7 OP_XOR_INT_LIT16 vA, vB, #+CCCC
679 DF_DA | DF_UB,
680
681 // D8 OP_ADD_INT_LIT8 vAA, vBB, #+CC
682 DF_DA | DF_UB | DF_IS_LINEAR,
683
684 // D9 OP_RSUB_INT_LIT8 vAA, vBB, #+CC
685 DF_DA | DF_UB,
686
687 // DA OP_MUL_INT_LIT8 vAA, vBB, #+CC
688 DF_DA | DF_UB,
689
690 // DB OP_DIV_INT_LIT8 vAA, vBB, #+CC
691 DF_DA | DF_UB,
692
693 // DC OP_REM_INT_LIT8 vAA, vBB, #+CC
694 DF_DA | DF_UB,
695
696 // DD OP_AND_INT_LIT8 vAA, vBB, #+CC
697 DF_DA | DF_UB,
698
699 // DE OP_OR_INT_LIT8 vAA, vBB, #+CC
700 DF_DA | DF_UB,
701
702 // DF OP_XOR_INT_LIT8 vAA, vBB, #+CC
703 DF_DA | DF_UB,
704
705 // E0 OP_SHL_INT_LIT8 vAA, vBB, #+CC
706 DF_DA | DF_UB,
707
708 // E1 OP_SHR_INT_LIT8 vAA, vBB, #+CC
709 DF_DA | DF_UB,
710
711 // E2 OP_USHR_INT_LIT8 vAA, vBB, #+CC
712 DF_DA | DF_UB,
713
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700714 // E3 OP_IGET_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700715 DF_DA | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700716
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700717 // E4 OP_IPUT_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700718 DF_UA | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700719
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700720 // E5 OP_SGET_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700721 DF_DA,
Ben Cheng4238ec22009-08-24 16:32:22 -0700722
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700723 // E6 OP_SPUT_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700724 DF_UA,
Ben Cheng4238ec22009-08-24 16:32:22 -0700725
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700726 // E7 OP_IGET_OBJECT_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700727 DF_DA | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700728
Andy McFadden53878242010-03-05 07:24:27 -0800729 // E8 OP_IGET_WIDE_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700730 DF_DA_WIDE | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700731
Andy McFadden53878242010-03-05 07:24:27 -0800732 // E9 OP_IPUT_WIDE_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700733 DF_UA_WIDE | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700734
Andy McFadden53878242010-03-05 07:24:27 -0800735 // EA OP_SGET_WIDE_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700736 DF_DA_WIDE,
Ben Cheng4238ec22009-08-24 16:32:22 -0700737
Andy McFadden53878242010-03-05 07:24:27 -0800738 // EB OP_SPUT_WIDE_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700739 DF_UA_WIDE,
Ben Cheng4238ec22009-08-24 16:32:22 -0700740
Andy McFadden96516932009-10-28 17:39:02 -0700741 // EC OP_BREAKPOINT
Ben Cheng4238ec22009-08-24 16:32:22 -0700742 DF_NOP,
743
744 // ED OP_THROW_VERIFICATION_ERROR
745 DF_NOP,
746
747 // EE OP_EXECUTE_INLINE
748 DF_FORMAT_35C,
749
Andy McFaddenb0a05412009-11-19 10:23:41 -0800750 // EF OP_EXECUTE_INLINE_RANGE
Bill Buzbeece46c942009-11-20 15:41:34 -0800751 DF_FORMAT_3RC,
Ben Cheng4238ec22009-08-24 16:32:22 -0700752
753 // F0 OP_INVOKE_DIRECT_EMPTY
754 DF_NOP,
755
Andy McFadden291758c2010-09-10 08:04:52 -0700756 // F1 OP_RETURN_VOID_BARRIER
Ben Cheng4238ec22009-08-24 16:32:22 -0700757 DF_NOP,
758
759 // F2 OP_IGET_QUICK
Ben Cheng7a2697d2010-06-07 13:44:23 -0700760 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700761
762 // F3 OP_IGET_WIDE_QUICK
Ben Cheng7a2697d2010-06-07 13:44:23 -0700763 DF_DA_WIDE | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700764
765 // F4 OP_IGET_OBJECT_QUICK
Ben Cheng7a2697d2010-06-07 13:44:23 -0700766 DF_DA | DF_UB | DF_IS_GETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700767
768 // F5 OP_IPUT_QUICK
Ben Cheng7a2697d2010-06-07 13:44:23 -0700769 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700770
771 // F6 OP_IPUT_WIDE_QUICK
Ben Cheng7a2697d2010-06-07 13:44:23 -0700772 DF_UA_WIDE | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700773
774 // F7 OP_IPUT_OBJECT_QUICK
Ben Cheng7a2697d2010-06-07 13:44:23 -0700775 DF_UA | DF_UB | DF_IS_SETTER,
Ben Cheng4238ec22009-08-24 16:32:22 -0700776
777 // F8 OP_INVOKE_VIRTUAL_QUICK
778 DF_FORMAT_35C,
779
780 // F9 OP_INVOKE_VIRTUAL_QUICK_RANGE
781 DF_FORMAT_3RC,
782
783 // FA OP_INVOKE_SUPER_QUICK
784 DF_FORMAT_35C,
785
786 // FB OP_INVOKE_SUPER_QUICK_RANGE
787 DF_FORMAT_3RC,
788
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700789 // FC OP_IPUT_OBJECT_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700790 DF_UA | DF_UB,
Ben Cheng4238ec22009-08-24 16:32:22 -0700791
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700792 // FD OP_SGET_OBJECT_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700793 DF_DA,
Ben Cheng4238ec22009-08-24 16:32:22 -0700794
Andy McFaddenc35a2ef2010-06-17 12:36:00 -0700795 // FE OP_SPUT_OBJECT_VOLATILE
buzbee35ff69b2010-07-29 13:17:35 -0700796 DF_UA,
Ben Cheng4238ec22009-08-24 16:32:22 -0700797
Dan Bornstein90f15432010-12-02 16:46:25 -0800798 // FF OP_DISPATCH_FF
Ben Cheng4238ec22009-08-24 16:32:22 -0700799 DF_NOP,
800
801 // Beginning of extended MIR opcodes
802 // 100 OP_MIR_PHI
803 DF_PHI | DF_DA,
804
805 /*
806 * For extended MIR inserted at the MIR2LIR stage, it is okay to have
807 * undefined values here.
808 */
809};
810
811/* Return the Dalvik register/subscript pair of a given SSA register */
Ben Cheng00603072010-10-28 11:13:58 -0700812int dvmConvertSSARegToDalvik(const CompilationUnit *cUnit, int ssaReg)
Ben Cheng4238ec22009-08-24 16:32:22 -0700813{
814 return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
815}
816
817/*
818 * Utility function to convert encoded SSA register value into Dalvik register
819 * and subscript pair. Each SSA register can be used to index the
820 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
821 */
Ben Cheng00603072010-10-28 11:13:58 -0700822char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
Ben Cheng7a2697d2010-06-07 13:44:23 -0700823 char *note)
Ben Chengccd6c012009-10-15 14:52:45 -0700824{
825 char buffer[256];
Dan Bornstein9a1f8162010-12-01 17:02:26 -0800826 int opcode = insn->opcode;
Ben Chengccd6c012009-10-15 14:52:45 -0700827 int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
Ben Cheng00603072010-10-28 11:13:58 -0700828 int flags = dexGetFlagsFromOpcode(insn->opcode);
Ben Chengccd6c012009-10-15 14:52:45 -0700829 char *ret;
830
831 buffer[0] = 0;
Ben Cheng00603072010-10-28 11:13:58 -0700832 if (opcode >= kMirOpFirst) {
833 if (opcode == kMirOpPhi) {
834 strcpy(buffer, "PHI");
835 }
836 else {
837 sprintf(buffer, "Opcode 0x%x", opcode);
838 }
839 } else {
840 strcpy(buffer, dexGetOpcodeName(opcode));
841 }
Ben Chengccd6c012009-10-15 14:52:45 -0700842
Ben Cheng7a2697d2010-06-07 13:44:23 -0700843 if (note)
844 strcat(buffer, note);
845
Ben Cheng00603072010-10-28 11:13:58 -0700846 /* 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 LOGE("Unexpected branch format: %d", dalvikFormat);
867 dvmAbort();
868 break;
869 }
870 snprintf(buffer + strlen(buffer), 256, " (%c%x)",
871 offset > 0 ? '+' : '-',
872 offset > 0 ? offset : -offset);
873 } else if (dfAttributes & DF_FORMAT_35C) {
Ben Chengccd6c012009-10-15 14:52:45 -0700874 unsigned int i;
875 for (i = 0; i < insn->vA; i++) {
876 if (i != 0) strcat(buffer, ",");
Ben Cheng7a2697d2010-06-07 13:44:23 -0700877 snprintf(buffer + strlen(buffer), 256, " v%d", insn->arg[i]);
Ben Chengccd6c012009-10-15 14:52:45 -0700878 }
879 }
880 else if (dfAttributes & DF_FORMAT_3RC) {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700881 snprintf(buffer + strlen(buffer), 256,
882 " v%d..v%d", insn->vC, insn->vC + insn->vA - 1);
Ben Chengccd6c012009-10-15 14:52:45 -0700883 }
884 else {
885 if (dfAttributes & DF_A_IS_REG) {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700886 snprintf(buffer + strlen(buffer), 256, " v%d", insn->vA);
Ben Chengccd6c012009-10-15 14:52:45 -0700887 }
888 if (dfAttributes & DF_B_IS_REG) {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700889 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vB);
Ben Chengccd6c012009-10-15 14:52:45 -0700890 }
Ben Cheng00603072010-10-28 11:13:58 -0700891 else if (opcode < kMirOpFirst) {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700892 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vB);
Ben Chengccd6c012009-10-15 14:52:45 -0700893 }
894 if (dfAttributes & DF_C_IS_REG) {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700895 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vC);
Ben Chengccd6c012009-10-15 14:52:45 -0700896 }
Ben Cheng00603072010-10-28 11:13:58 -0700897 else if (opcode < kMirOpFirst) {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700898 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vC);
Ben Chengccd6c012009-10-15 14:52:45 -0700899 }
900 }
901 int length = strlen(buffer) + 1;
Carl Shapirofc75f3e2010-12-07 11:43:38 -0800902 ret = (char *)dvmCompilerNew(length, false);
Ben Chengccd6c012009-10-15 14:52:45 -0700903 memcpy(ret, buffer, length);
904 return ret;
905}
906
Ben Cheng00603072010-10-28 11:13:58 -0700907char *getSSAName(const CompilationUnit *cUnit, int ssaReg, char *name)
908{
909 int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaReg);
910
911 sprintf(name, "v%d_%d",
912 DECODE_REG(ssa2DalvikValue), DECODE_SUB(ssa2DalvikValue));
913 return name;
914}
915
916/*
917 * Dalvik instruction disassembler with optional SSA printing.
918 */
919char *dvmCompilerFullDisassembler(const CompilationUnit *cUnit,
920 const MIR *mir)
921{
922 char buffer[256];
923 char operand0[256], operand1[256];
924 const DecodedInstruction *insn = &mir->dalvikInsn;
925 int opcode = insn->opcode;
926 int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
927 int flags = dexGetFlagsFromOpcode(insn->opcode);
928 char *ret;
929 int length;
930
931 buffer[0] = 0;
932 if (opcode >= kMirOpFirst) {
933 if (opcode == kMirOpPhi) {
934 snprintf(buffer, 256, "PHI %s = (%s",
935 getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
936 getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
937 int i;
938 for (i = 1; i < mir->ssaRep->numUses; i++) {
939 snprintf(buffer + strlen(buffer), 256, ", %s",
940 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
941 }
942 snprintf(buffer + strlen(buffer), 256, ")");
943 }
944 else {
945 sprintf(buffer, "Opcode 0x%x", opcode);
946 }
947 goto done;
948 } else {
949 strcpy(buffer, dexGetOpcodeName(opcode));
950 }
951
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 LOGE("Unexpected branch format: %d", dalvikFormat);
975 dvmAbort();
976 break;
977 }
978 snprintf(buffer + strlen(buffer), 256, " %04x",
979 mir->offset + delta);
980 } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
981 unsigned int i;
982 for (i = 0; i < insn->vA; i++) {
983 if (i != 0) strcat(buffer, ",");
984 snprintf(buffer + strlen(buffer), 256, " %s",
985 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
986 }
987 } else {
988 int udIdx;
989 if (mir->ssaRep->numDefs) {
990
991 for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
992 snprintf(buffer + strlen(buffer), 256, " %s",
993 getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
994 }
995 strcat(buffer, ",");
996 }
997 if (mir->ssaRep->numUses) {
998 /* No leading ',' for the first use */
999 snprintf(buffer + strlen(buffer), 256, " %s",
1000 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
1001 for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
1002 snprintf(buffer + strlen(buffer), 256, ", %s",
1003 getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
1004 }
1005 }
1006 if (opcode < kMirOpFirst) {
1007 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(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;
1037 ret = (char *) dvmCompilerNew(length, false);
1038 memcpy(ret, buffer, length);
1039 return ret;
1040}
1041
Ben Chengccd6c012009-10-15 14:52:45 -07001042/*
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 */
Ben Cheng4238ec22009-08-24 16:32:22 -07001047char *dvmCompilerGetSSAString(CompilationUnit *cUnit, SSARepresentation *ssaRep)
1048{
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 = dvmConvertSSARegToDalvik(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 = dvmConvertSSARegToDalvik(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;
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001079 ret = (char *)dvmCompilerNew(length, false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001080 memcpy(ret, buffer, length);
1081 return ret;
1082}
1083
1084/* Any register that is used before being defined is considered live-in */
1085static inline void handleLiveInUse(BitVector *useV, BitVector *defV,
1086 BitVector *liveInV, int dalvikRegId)
1087{
1088 dvmCompilerSetBit(useV, dalvikRegId);
1089 if (!dvmIsBitSet(defV, dalvikRegId)) {
1090 dvmCompilerSetBit(liveInV, dalvikRegId);
1091 }
1092}
1093
1094/* Mark a reg as being defined */
Ben Cheng00603072010-10-28 11:13:58 -07001095static inline void handleDef(BitVector *defV, int dalvikRegId)
Ben Cheng4238ec22009-08-24 16:32:22 -07001096{
1097 dvmCompilerSetBit(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 */
Ben Cheng00603072010-10-28 11:13:58 -07001104bool dvmCompilerFindLocalLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
Ben Cheng4238ec22009-08-24 16:32:22 -07001105{
1106 MIR *mir;
1107 BitVector *useV, *defV, *liveInV;
1108
Ben Cheng00603072010-10-28 11:13:58 -07001109 if (bb->dataFlowInfo == NULL) return false;
Ben Cheng4238ec22009-08-24 16:32:22 -07001110
1111 useV = bb->dataFlowInfo->useV =
Ben Cheng00603072010-10-28 11:13:58 -07001112 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001113 defV = bb->dataFlowInfo->defV =
Ben Cheng00603072010-10-28 11:13:58 -07001114 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001115 liveInV = bb->dataFlowInfo->liveInV =
Ben Cheng00603072010-10-28 11:13:58 -07001116 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001117
1118 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1119 int dfAttributes =
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001120 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
Ben Cheng4238ec22009-08-24 16:32:22 -07001121 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) {
Ben Cheng00603072010-10-28 11:13:58 -07001144 handleDef(defV, dInsn->vA);
Ben Cheng4238ec22009-08-24 16:32:22 -07001145 if (dfAttributes & DF_DA_WIDE) {
Ben Cheng00603072010-10-28 11:13:58 -07001146 handleDef(defV, dInsn->vA+1);
Ben Cheng4238ec22009-08-24 16:32:22 -07001147 }
1148 }
1149 }
Ben Cheng00603072010-10-28 11:13:58 -07001150 return true;
Ben Cheng4238ec22009-08-24 16:32:22 -07001151}
1152
1153/* Find out the latest SSA register for a given Dalvik register */
1154static void handleSSAUse(CompilationUnit *cUnit, int *uses, int dalvikReg,
1155 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 */
1163static void handleSSADef(CompilationUnit *cUnit, int *defs, int dalvikReg,
1164 int regIndex)
1165{
1166 int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
1167 int ssaReg = cUnit->numSSARegs++;
1168 /* Bump up the subscript */
1169 int dalvikSub = DECODE_SUB(encodedValue) + 1;
1170 int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);
1171
1172 cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
1173
1174 int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
Ben Cheng00603072010-10-28 11:13:58 -07001175 dvmInsertGrowableList(cUnit->ssaToDalvikMap, newS2DMapping);
Ben Cheng4238ec22009-08-24 16:32:22 -07001176
1177 defs[regIndex] = ssaReg;
1178}
1179
1180/* Loop up new SSA names for format_35c instructions */
1181static void dataFlowSSAFormat35C(CompilationUnit *cUnit, MIR *mir)
1182{
1183 DecodedInstruction *dInsn = &mir->dalvikInsn;
1184 int numUses = dInsn->vA;
1185 int i;
1186
1187 mir->ssaRep->numUses = numUses;
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001188 mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001189
1190 for (i = 0; i < numUses; i++) {
1191 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
1192 }
1193}
1194
1195/* Loop up new SSA names for format_3rc instructions */
1196static void dataFlowSSAFormat3RC(CompilationUnit *cUnit, MIR *mir)
1197{
1198 DecodedInstruction *dInsn = &mir->dalvikInsn;
1199 int numUses = dInsn->vA;
1200 int i;
1201
1202 mir->ssaRep->numUses = numUses;
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001203 mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001204
1205 for (i = 0; i < numUses; i++) {
1206 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
1207 }
1208}
1209
1210/* Entry function to convert a block into SSA representation */
Ben Cheng00603072010-10-28 11:13:58 -07001211bool dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
Ben Cheng4238ec22009-08-24 16:32:22 -07001212{
1213 MIR *mir;
1214
Ben Cheng00603072010-10-28 11:13:58 -07001215 if (bb->dataFlowInfo == NULL) return false;
Ben Cheng4238ec22009-08-24 16:32:22 -07001216
1217 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001218 mir->ssaRep = (struct SSARepresentation *)
1219 dvmCompilerNew(sizeof(SSARepresentation), true);
Ben Cheng4238ec22009-08-24 16:32:22 -07001220
1221 int dfAttributes =
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001222 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
Ben Cheng4238ec22009-08-24 16:32:22 -07001223
1224 int numUses = 0;
1225
1226 if (dfAttributes & DF_FORMAT_35C) {
1227 dataFlowSSAFormat35C(cUnit, mir);
1228 continue;
1229 }
1230
1231 if (dfAttributes & DF_FORMAT_3RC) {
1232 dataFlowSSAFormat3RC(cUnit, mir);
1233 continue;
1234 }
1235
1236 if (dfAttributes & DF_HAS_USES) {
1237 if (dfAttributes & DF_UA) {
1238 numUses++;
1239 } else if (dfAttributes & DF_UA_WIDE) {
1240 numUses += 2;
1241 }
1242 if (dfAttributes & DF_UB) {
1243 numUses++;
1244 } else if (dfAttributes & DF_UB_WIDE) {
1245 numUses += 2;
1246 }
1247 if (dfAttributes & DF_UC) {
1248 numUses++;
1249 } else if (dfAttributes & DF_UC_WIDE) {
1250 numUses += 2;
1251 }
1252 }
1253
1254 if (numUses) {
1255 mir->ssaRep->numUses = numUses;
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001256 mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses,
1257 false);
1258 mir->ssaRep->fpUse = (bool *)dvmCompilerNew(sizeof(bool) * numUses,
1259 false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001260 }
1261
1262 int numDefs = 0;
1263
1264 if (dfAttributes & DF_HAS_DEFS) {
1265 numDefs++;
1266 if (dfAttributes & DF_DA_WIDE) {
1267 numDefs++;
1268 }
1269 }
1270
1271 if (numDefs) {
1272 mir->ssaRep->numDefs = numDefs;
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001273 mir->ssaRep->defs = (int *)dvmCompilerNew(sizeof(int) * numDefs,
1274 false);
1275 mir->ssaRep->fpDef = (bool *)dvmCompilerNew(sizeof(bool) * numDefs,
1276 false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001277 }
1278
1279 DecodedInstruction *dInsn = &mir->dalvikInsn;
1280
1281 if (dfAttributes & DF_HAS_USES) {
1282 numUses = 0;
1283 if (dfAttributes & DF_UA) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001284 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
Ben Cheng4238ec22009-08-24 16:32:22 -07001285 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1286 } else if (dfAttributes & DF_UA_WIDE) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001287 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
Ben Cheng4238ec22009-08-24 16:32:22 -07001288 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
Bill Buzbee1465db52009-09-23 17:17:35 -07001289 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
Ben Cheng4238ec22009-08-24 16:32:22 -07001290 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
1291 }
1292 if (dfAttributes & DF_UB) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001293 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
Ben Cheng4238ec22009-08-24 16:32:22 -07001294 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1295 } else if (dfAttributes & DF_UB_WIDE) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001296 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
Ben Cheng4238ec22009-08-24 16:32:22 -07001297 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
Bill Buzbee1465db52009-09-23 17:17:35 -07001298 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
Ben Cheng4238ec22009-08-24 16:32:22 -07001299 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
1300 }
1301 if (dfAttributes & DF_UC) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001302 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
Ben Cheng4238ec22009-08-24 16:32:22 -07001303 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1304 } else if (dfAttributes & DF_UC_WIDE) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001305 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
Ben Cheng4238ec22009-08-24 16:32:22 -07001306 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
Bill Buzbee1465db52009-09-23 17:17:35 -07001307 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
Ben Cheng4238ec22009-08-24 16:32:22 -07001308 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
1309 }
1310 }
1311 if (dfAttributes & DF_HAS_DEFS) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001312 mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
Ben Cheng4238ec22009-08-24 16:32:22 -07001313 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
1314 if (dfAttributes & DF_DA_WIDE) {
Bill Buzbee1465db52009-09-23 17:17:35 -07001315 mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
Ben Cheng4238ec22009-08-24 16:32:22 -07001316 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
1317 }
1318 }
1319 }
1320
Ben Cheng00603072010-10-28 11:13:58 -07001321 /*
1322 * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
1323 * input to PHI nodes can be derived from the snapshot of all predecessor
1324 * blocks.
1325 */
Ben Cheng4238ec22009-08-24 16:32:22 -07001326 bb->dataFlowInfo->dalvikToSSAMap =
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001327 (int *)dvmCompilerNew(sizeof(int) * cUnit->method->registersSize,
1328 false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001329
Ben Cheng4238ec22009-08-24 16:32:22 -07001330 memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
1331 sizeof(int) * cUnit->method->registersSize);
Ben Cheng00603072010-10-28 11:13:58 -07001332 return true;
Ben Cheng4238ec22009-08-24 16:32:22 -07001333}
1334
1335/* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
1336static void setConstant(CompilationUnit *cUnit, int ssaReg, int value)
1337{
1338 dvmSetBit(cUnit->isConstantV, ssaReg);
1339 cUnit->constantValues[ssaReg] = value;
1340}
1341
Ben Cheng00603072010-10-28 11:13:58 -07001342bool dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
Ben Cheng4238ec22009-08-24 16:32:22 -07001343{
1344 MIR *mir;
1345 BitVector *isConstantV = cUnit->isConstantV;
1346
1347 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1348 int dfAttributes =
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001349 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
Ben Cheng4238ec22009-08-24 16:32:22 -07001350
Ben Cheng4238ec22009-08-24 16:32:22 -07001351 DecodedInstruction *dInsn = &mir->dalvikInsn;
1352
1353 if (!(dfAttributes & DF_HAS_DEFS)) continue;
1354
1355 /* Handle instructions that set up constants directly */
1356 if (dfAttributes & DF_SETS_CONST) {
1357 if (dfAttributes & DF_DA) {
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001358 switch (dInsn->opcode) {
Ben Cheng4238ec22009-08-24 16:32:22 -07001359 case OP_CONST_4:
1360 case OP_CONST_16:
1361 case OP_CONST:
1362 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1363 break;
1364 case OP_CONST_HIGH16:
1365 setConstant(cUnit, mir->ssaRep->defs[0],
1366 dInsn->vB << 16);
1367 break;
1368 default:
1369 break;
1370 }
1371 } else if (dfAttributes & DF_DA_WIDE) {
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001372 switch (dInsn->opcode) {
Ben Cheng4238ec22009-08-24 16:32:22 -07001373 case OP_CONST_WIDE_16:
1374 case OP_CONST_WIDE_32:
1375 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1376 setConstant(cUnit, mir->ssaRep->defs[1], 0);
1377 break;
1378 case OP_CONST_WIDE:
1379 setConstant(cUnit, mir->ssaRep->defs[0],
1380 (int) dInsn->vB_wide);
1381 setConstant(cUnit, mir->ssaRep->defs[1],
1382 (int) (dInsn->vB_wide >> 32));
1383 break;
1384 case OP_CONST_WIDE_HIGH16:
1385 setConstant(cUnit, mir->ssaRep->defs[0], 0);
1386 setConstant(cUnit, mir->ssaRep->defs[1],
1387 dInsn->vB << 16);
1388 break;
1389 default:
1390 break;
1391 }
1392 }
1393 /* Handle instructions that set up constants directly */
1394 } else if (dfAttributes & DF_IS_MOVE) {
1395 int i;
1396
1397 for (i = 0; i < mir->ssaRep->numUses; i++) {
1398 if (!dvmIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
1399 }
1400 /* Move a register holding a constant to another register */
1401 if (i == mir->ssaRep->numUses) {
1402 setConstant(cUnit, mir->ssaRep->defs[0],
1403 cUnit->constantValues[mir->ssaRep->uses[0]]);
1404 if (dfAttributes & DF_DA_WIDE) {
1405 setConstant(cUnit, mir->ssaRep->defs[1],
1406 cUnit->constantValues[mir->ssaRep->uses[1]]);
1407 }
1408 }
1409 }
1410 }
1411 /* TODO: implement code to handle arithmetic operations */
Ben Cheng00603072010-10-28 11:13:58 -07001412 return true;
Ben Cheng4238ec22009-08-24 16:32:22 -07001413}
1414
Ben Cheng00603072010-10-28 11:13:58 -07001415bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -07001416 struct BasicBlock *bb)
1417{
1418 BitVector *isIndVarV = cUnit->loopAnalysis->isIndVarV;
1419 BitVector *isConstantV = cUnit->isConstantV;
1420 GrowableList *ivList = cUnit->loopAnalysis->ivList;
1421 MIR *mir;
1422
Bill Buzbee1465db52009-09-23 17:17:35 -07001423 if (bb->blockType != kDalvikByteCode &&
Ben Cheng7a2697d2010-06-07 13:44:23 -07001424 bb->blockType != kTraceEntryBlock) {
Ben Cheng00603072010-10-28 11:13:58 -07001425 return false;
Ben Cheng4238ec22009-08-24 16:32:22 -07001426 }
1427
1428 /* If the bb doesn't have a phi it cannot contain an induction variable */
1429 if (bb->firstMIRInsn == NULL ||
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001430 bb->firstMIRInsn->dalvikInsn.opcode != kMirOpPhi) {
Ben Cheng00603072010-10-28 11:13:58 -07001431 return false;
Ben Cheng4238ec22009-08-24 16:32:22 -07001432 }
1433
1434 /* Find basic induction variable first */
1435 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1436 int dfAttributes =
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001437 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
Ben Cheng4238ec22009-08-24 16:32:22 -07001438
1439 if (!(dfAttributes & DF_IS_LINEAR)) continue;
1440
1441 /*
1442 * For a basic induction variable:
1443 * 1) use[0] should belong to the output of a phi node
1444 * 2) def[0] should belong to the input of the same phi node
1445 * 3) the value added/subtracted is a constant
1446 */
1447 MIR *phi;
1448 for (phi = bb->firstMIRInsn; phi; phi = phi->next) {
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001449 if (phi->dalvikInsn.opcode != kMirOpPhi) break;
Ben Cheng4238ec22009-08-24 16:32:22 -07001450
1451 if (phi->ssaRep->defs[0] == mir->ssaRep->uses[0] &&
1452 phi->ssaRep->uses[1] == mir->ssaRep->defs[0]) {
1453 bool deltaIsConstant = false;
1454 int deltaValue;
1455
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001456 switch (mir->dalvikInsn.opcode) {
Ben Cheng4238ec22009-08-24 16:32:22 -07001457 case OP_ADD_INT:
1458 if (dvmIsBitSet(isConstantV,
1459 mir->ssaRep->uses[1])) {
1460 deltaValue =
1461 cUnit->constantValues[mir->ssaRep->uses[1]];
1462 deltaIsConstant = true;
1463 }
1464 break;
1465 case OP_SUB_INT:
1466 if (dvmIsBitSet(isConstantV,
1467 mir->ssaRep->uses[1])) {
1468 deltaValue =
1469 -cUnit->constantValues[mir->ssaRep->uses[1]];
1470 deltaIsConstant = true;
1471 }
1472 break;
1473 case OP_ADD_INT_LIT8:
1474 deltaValue = mir->dalvikInsn.vC;
1475 deltaIsConstant = true;
1476 break;
1477 default:
1478 break;
1479 }
1480 if (deltaIsConstant) {
1481 dvmSetBit(isIndVarV, mir->ssaRep->uses[0]);
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001482 InductionVariableInfo *ivInfo = (InductionVariableInfo *)
Ben Cheng4238ec22009-08-24 16:32:22 -07001483 dvmCompilerNew(sizeof(InductionVariableInfo),
1484 false);
1485
1486 ivInfo->ssaReg = mir->ssaRep->uses[0];
1487 ivInfo->basicSSAReg = mir->ssaRep->uses[0];
1488 ivInfo->m = 1; // always 1 to basic iv
1489 ivInfo->c = 0; // N/A to basic iv
1490 ivInfo->inc = deltaValue;
Ben Cheng00603072010-10-28 11:13:58 -07001491 dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
Ben Cheng4238ec22009-08-24 16:32:22 -07001492 cUnit->loopAnalysis->numBasicIV++;
1493 break;
1494 }
1495 }
1496 }
1497 }
1498
1499 /* Find dependent induction variable now */
1500 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1501 int dfAttributes =
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001502 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
Ben Cheng4238ec22009-08-24 16:32:22 -07001503
1504 if (!(dfAttributes & DF_IS_LINEAR)) continue;
1505
1506 /* Skip already identified induction variables */
1507 if (dvmIsBitSet(isIndVarV, mir->ssaRep->defs[0])) continue;
1508
1509 /*
1510 * For a dependent induction variable:
1511 * 1) use[0] should be an induction variable (basic/dependent)
1512 * 2) operand2 should be a constant
1513 */
1514 if (dvmIsBitSet(isIndVarV, mir->ssaRep->uses[0])) {
1515 int srcDalvikReg = dvmConvertSSARegToDalvik(cUnit,
1516 mir->ssaRep->uses[0]);
1517 int dstDalvikReg = dvmConvertSSARegToDalvik(cUnit,
1518 mir->ssaRep->defs[0]);
1519
1520 bool cIsConstant = false;
1521 int c = 0;
1522
Dan Bornstein9a1f8162010-12-01 17:02:26 -08001523 switch (mir->dalvikInsn.opcode) {
Ben Cheng4238ec22009-08-24 16:32:22 -07001524 case OP_ADD_INT:
1525 if (dvmIsBitSet(isConstantV,
1526 mir->ssaRep->uses[1])) {
1527 c = cUnit->constantValues[mir->ssaRep->uses[1]];
1528 cIsConstant = true;
1529 }
1530 break;
1531 case OP_SUB_INT:
1532 if (dvmIsBitSet(isConstantV,
1533 mir->ssaRep->uses[1])) {
1534 c = -cUnit->constantValues[mir->ssaRep->uses[1]];
1535 cIsConstant = true;
1536 }
1537 break;
1538 case OP_ADD_INT_LIT8:
1539 c = mir->dalvikInsn.vC;
1540 cIsConstant = true;
1541 break;
1542 default:
1543 break;
1544 }
1545
1546 /* Ignore the update to the basic induction variable itself */
1547 if (DECODE_REG(srcDalvikReg) == DECODE_REG(dstDalvikReg)) {
1548 cUnit->loopAnalysis->ssaBIV = mir->ssaRep->defs[0];
1549 cIsConstant = false;
1550 }
1551
1552 if (cIsConstant) {
1553 unsigned int i;
1554 dvmSetBit(isIndVarV, mir->ssaRep->defs[0]);
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001555 InductionVariableInfo *ivInfo = (InductionVariableInfo *)
Ben Cheng4238ec22009-08-24 16:32:22 -07001556 dvmCompilerNew(sizeof(InductionVariableInfo),
1557 false);
1558 InductionVariableInfo *ivInfoOld = NULL ;
1559
1560 for (i = 0; i < ivList->numUsed; i++) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001561 ivInfoOld = (InductionVariableInfo *) ivList->elemList[i];
Ben Cheng4238ec22009-08-24 16:32:22 -07001562 if (ivInfoOld->ssaReg == mir->ssaRep->uses[0]) break;
1563 }
1564
1565 /* Guaranteed to find an element */
1566 assert(i < ivList->numUsed);
1567
1568 ivInfo->ssaReg = mir->ssaRep->defs[0];
1569 ivInfo->basicSSAReg = ivInfoOld->basicSSAReg;
1570 ivInfo->m = ivInfoOld->m;
1571 ivInfo->c = c + ivInfoOld->c;
1572 ivInfo->inc = ivInfoOld->inc;
Ben Cheng00603072010-10-28 11:13:58 -07001573 dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
Ben Cheng4238ec22009-08-24 16:32:22 -07001574 }
1575 }
1576 }
Ben Cheng00603072010-10-28 11:13:58 -07001577 return true;
Ben Cheng4238ec22009-08-24 16:32:22 -07001578}
1579
1580/* Setup the basic data structures for SSA conversion */
1581void dvmInitializeSSAConversion(CompilationUnit *cUnit)
1582{
1583 int i;
1584 int numDalvikReg = cUnit->method->registersSize;
1585
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001586 cUnit->ssaToDalvikMap = (GrowableList *)dvmCompilerNew(sizeof(GrowableList),
1587 false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001588 dvmInitGrowableList(cUnit->ssaToDalvikMap, numDalvikReg);
1589
1590 /*
1591 * Initial number of SSA registers is equal to the number of Dalvik
1592 * registers.
1593 */
1594 cUnit->numSSARegs = numDalvikReg;
1595
1596 /*
1597 * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
1598 * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
1599 * into "(0 << 16) | i"
1600 */
1601 for (i = 0; i < numDalvikReg; i++) {
Ben Cheng00603072010-10-28 11:13:58 -07001602 dvmInsertGrowableList(cUnit->ssaToDalvikMap, ENCODE_REG_SUB(i, 0));
Ben Cheng4238ec22009-08-24 16:32:22 -07001603 }
1604
1605 /*
1606 * Initialize the DalvikToSSAMap map. The low 16 bit is the SSA register id,
1607 * while the high 16 bit is the current subscript. The original Dalvik
1608 * register N is mapped to SSA register N with subscript 0.
1609 */
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001610 cUnit->dalvikToSSAMap = (int *)dvmCompilerNew(sizeof(int) * numDalvikReg,
1611 false);
Ben Cheng4238ec22009-08-24 16:32:22 -07001612 for (i = 0; i < numDalvikReg; i++) {
1613 cUnit->dalvikToSSAMap[i] = i;
1614 }
1615
1616 /*
1617 * Allocate the BasicBlockDataFlow structure for the entry and code blocks
1618 */
Ben Cheng00603072010-10-28 11:13:58 -07001619 GrowableListIterator iterator;
1620
1621 dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
1622
1623 while (true) {
1624 BasicBlock *bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
1625 if (bb == NULL) break;
Bill Buzbee1465db52009-09-23 17:17:35 -07001626 if (bb->blockType == kDalvikByteCode ||
Ben Cheng00603072010-10-28 11:13:58 -07001627 bb->blockType == kTraceEntryBlock ||
1628 bb->blockType == kMethodEntryBlock ||
1629 bb->blockType == kMethodExitBlock) {
Carl Shapirofc75f3e2010-12-07 11:43:38 -08001630 bb->dataFlowInfo = (BasicBlockDataFlow *)
1631 dvmCompilerNew(sizeof(BasicBlockDataFlow),
1632 true);
Ben Cheng4238ec22009-08-24 16:32:22 -07001633 }
1634 }
1635}
1636
Ben Cheng00603072010-10-28 11:13:58 -07001637/* Clear the visited flag for each BB */
1638bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
1639 struct BasicBlock *bb)
Ben Cheng4238ec22009-08-24 16:32:22 -07001640{
Ben Cheng00603072010-10-28 11:13:58 -07001641 bb->visited = false;
1642 return true;
1643}
1644
1645void dvmCompilerDataFlowAnalysisDispatcher(CompilationUnit *cUnit,
1646 bool (*func)(CompilationUnit *, BasicBlock *),
1647 DataFlowAnalysisMode dfaMode,
1648 bool isIterative)
1649{
1650 bool change = true;
1651
1652 while (change) {
1653 change = false;
1654
1655 /* Scan all blocks and perform the operations specified in func */
1656 if (dfaMode == kAllNodes) {
1657 GrowableListIterator iterator;
1658 dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
1659 while (true) {
1660 BasicBlock *bb =
1661 (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
1662 if (bb == NULL) break;
1663 change |= (*func)(cUnit, bb);
1664 }
1665 }
1666 /*
1667 * Scan all reachable blocks and perform the operations specified in
1668 * func.
1669 */
1670 else if (dfaMode == kReachableNodes) {
1671 int numReachableBlocks = cUnit->numReachableBlocks;
1672 int idx;
1673 const GrowableList *blockList = &cUnit->blockList;
1674
1675 for (idx = 0; idx < numReachableBlocks; idx++) {
1676 int blockIdx = cUnit->dfsOrder.elemList[idx];
1677 BasicBlock *bb =
1678 (BasicBlock *) dvmGrowableListGetElement(blockList,
1679 blockIdx);
1680 change |= (*func)(cUnit, bb);
1681 }
1682 }
1683 /*
1684 * Scan all reachable blocks by the pre-order in the depth-first-search
1685 * CFG and perform the operations specified in func.
1686 */
1687 else if (dfaMode == kPreOrderDFSTraversal) {
1688 int numReachableBlocks = cUnit->numReachableBlocks;
1689 int idx;
1690 const GrowableList *blockList = &cUnit->blockList;
1691
1692 for (idx = 0; idx < numReachableBlocks; idx++) {
1693 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1694 BasicBlock *bb =
1695 (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
1696 change |= (*func)(cUnit, bb);
1697 }
1698 }
1699 /*
1700 * Scan all reachable blocks by the post-order in the depth-first-search
1701 * CFG and perform the operations specified in func.
1702 */
1703 else if (dfaMode == kPostOrderDFSTraversal) {
1704 int numReachableBlocks = cUnit->numReachableBlocks;
1705 int idx;
1706 const GrowableList *blockList = &cUnit->blockList;
1707
1708 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
1709 int dfsIdx = cUnit->dfsOrder.elemList[idx];
1710 BasicBlock *bb =
1711 (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
1712 change |= (*func)(cUnit, bb);
1713 }
1714 }
1715 /*
1716 * Scan all reachable blocks by the post-order in the dominator tree
1717 * and perform the operations specified in func.
1718 */
1719 else if (dfaMode == kPostOrderDOMTraversal) {
1720 int numReachableBlocks = cUnit->numReachableBlocks;
1721 int idx;
1722 const GrowableList *blockList = &cUnit->blockList;
1723
1724 for (idx = 0; idx < numReachableBlocks; idx++) {
1725 int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
1726 BasicBlock *bb =
1727 (BasicBlock *) dvmGrowableListGetElement(blockList, domIdx);
1728 change |= (*func)(cUnit, bb);
1729 }
1730 }
1731 /* If isIterative is false, exit the loop after the first iteration */
1732 change &= isIterative;
Ben Cheng4238ec22009-08-24 16:32:22 -07001733 }
1734}
1735
1736/* Main entry point to do SSA conversion for non-loop traces */
1737void dvmCompilerNonLoopAnalysis(CompilationUnit *cUnit)
1738{
Ben Cheng00603072010-10-28 11:13:58 -07001739 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion,
1740 kAllNodes,
1741 false /* isIterative */);
Ben Cheng4238ec22009-08-24 16:32:22 -07001742}