1 /*
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"
20 #include "libdex/DexOpcodes.h"
21
22 /*
23 * Main table containing data flow attributes for each bytecode. The
24 * first kNumPackedOpcodes entries are for Dalvik bytecode
25 * instructions, where extended opcode at the MIR level are appended
26 * afterwards.
27 *
28 * TODO - many optimization flags are incomplete - they will only limit the
29 * scope of optimizations but will not cause mis-optimizations.
30 */
31 int dvmCompilerDataFlowAttributes[kMirOpLast] = {
32 // 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
168 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C,
169
170 // 2E OP_CMPG_FLOAT vAA, vBB, vCC
171 DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C,
172
173 // 2F OP_CMPL_DOUBLE vAA, vBB, vCC
174 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C,
175
176 // 30 OP_CMPG_DOUBLE vAA, vBB, vCC
177 DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C,
178
179 // 31 OP_CMP_LONG vAA, vBB, vCC
180 DF_DA | DF_UB_WIDE | DF_UC_WIDE,
181
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
238 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
239
240 // 45 OP_AGET_WIDE vAA, vBB, vCC
241 DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
242
243 // 46 OP_AGET_OBJECT vAA, vBB, vCC
244 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
245
246 // 47 OP_AGET_BOOLEAN vAA, vBB, vCC
247 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
248
249 // 48 OP_AGET_BYTE vAA, vBB, vCC
250 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
251
252 // 49 OP_AGET_CHAR vAA, vBB, vCC
253 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
254
255 // 4A OP_AGET_SHORT vAA, vBB, vCC
256 DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
257
258 // 4B OP_APUT vAA, vBB, vCC
259 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
260
261 // 4C OP_APUT_WIDE vAA, vBB, vCC
262 DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_2 | DF_IS_SETTER,
263
264 // 4D OP_APUT_OBJECT vAA, vBB, vCC
265 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
266
267 // 4E OP_APUT_BOOLEAN vAA, vBB, vCC
268 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
269
270 // 4F OP_APUT_BYTE vAA, vBB, vCC
271 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
272
273 // 50 OP_APUT_CHAR vAA, vBB, vCC
274 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
275
276 // 51 OP_APUT_SHORT vAA, vBB, vCC
277 DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
278
279 // 52 OP_IGET vA, vB, field@CCCC
280 DF_DA | DF_UB | DF_IS_GETTER,
281
282 // 53 OP_IGET_WIDE vA, vB, field@CCCC
283 DF_DA_WIDE | DF_UB | DF_IS_GETTER,
284
285 // 54 OP_IGET_OBJECT vA, vB, field@CCCC
286 DF_DA | DF_UB | DF_IS_GETTER,
287
288 // 55 OP_IGET_BOOLEAN vA, vB, field@CCCC
289 DF_DA | DF_UB | DF_IS_GETTER,
290
291 // 56 OP_IGET_BYTE vA, vB, field@CCCC
292 DF_DA | DF_UB | DF_IS_GETTER,
293
294 // 57 OP_IGET_CHAR vA, vB, field@CCCC
295 DF_DA | DF_UB | DF_IS_GETTER,
296
297 // 58 OP_IGET_SHORT vA, vB, field@CCCC
298 DF_DA | DF_UB | DF_IS_GETTER,
299
300 // 59 OP_IPUT vA, vB, field@CCCC
301 DF_UA | DF_UB | DF_IS_SETTER,
302
303 // 5A OP_IPUT_WIDE vA, vB, field@CCCC
304 DF_UA_WIDE | DF_UB | DF_IS_SETTER,
305
306 // 5B OP_IPUT_OBJECT vA, vB, field@CCCC
307 DF_UA | DF_UB | DF_IS_SETTER,
308
309 // 5C OP_IPUT_BOOLEAN vA, vB, field@CCCC
310 DF_UA | DF_UB | DF_IS_SETTER,
311
312 // 5D OP_IPUT_BYTE vA, vB, field@CCCC
313 DF_UA | DF_UB | DF_IS_SETTER,
314
315 // 5E OP_IPUT_CHAR vA, vB, field@CCCC
316 DF_UA | DF_UB | DF_IS_SETTER,
317
318 // 5F OP_IPUT_SHORT vA, vB, field@CCCC
319 DF_UA | DF_UB | DF_IS_SETTER,
320
321 // 60 OP_SGET vAA, field@BBBB
322 DF_DA | DF_IS_GETTER,
323
324 // 61 OP_SGET_WIDE vAA, field@BBBB
325 DF_DA_WIDE | DF_IS_GETTER,
326
327 // 62 OP_SGET_OBJECT vAA, field@BBBB
328 DF_DA | DF_IS_GETTER,
329
330 // 63 OP_SGET_BOOLEAN vAA, field@BBBB
331 DF_DA | DF_IS_GETTER,
332
333 // 64 OP_SGET_BYTE vAA, field@BBBB
334 DF_DA | DF_IS_GETTER,
335
336 // 65 OP_SGET_CHAR vAA, field@BBBB
337 DF_DA | DF_IS_GETTER,
338
339 // 66 OP_SGET_SHORT vAA, field@BBBB
340 DF_DA | DF_IS_GETTER,
341
342 // 67 OP_SPUT vAA, field@BBBB
343 DF_UA | DF_IS_SETTER,
344
345 // 68 OP_SPUT_WIDE vAA, field@BBBB
346 DF_UA_WIDE | DF_IS_SETTER,
347
348 // 69 OP_SPUT_OBJECT vAA, field@BBBB
349 DF_UA | DF_IS_SETTER,
350
351 // 6A OP_SPUT_BOOLEAN vAA, field@BBBB
352 DF_UA | DF_IS_SETTER,
353
354 // 6B OP_SPUT_BYTE vAA, field@BBBB
355 DF_UA | DF_IS_SETTER,
356
357 // 6C OP_SPUT_CHAR vAA, field@BBBB
358 DF_UA | DF_IS_SETTER,
359
360 // 6D OP_SPUT_SHORT vAA, field@BBBB
361 DF_UA | DF_IS_SETTER,
362
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
415 DF_DA | DF_UB | DF_FP_A | DF_FP_B,
416
417 // 80 OP_NEG_DOUBLE vA, vB
418 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
419
420 // 81 OP_INT_TO_LONG vA, vB
421 DF_DA_WIDE | DF_UB,
422
423 // 82 OP_INT_TO_FLOAT vA, vB
424 DF_DA | DF_UB | DF_FP_A,
425
426 // 83 OP_INT_TO_DOUBLE vA, vB
427 DF_DA_WIDE | DF_UB | DF_FP_A,
428
429 // 84 OP_LONG_TO_INT vA, vB
430 DF_DA | DF_UB_WIDE,
431
432 // 85 OP_LONG_TO_FLOAT vA, vB
433 DF_DA | DF_UB_WIDE | DF_FP_A,
434
435 // 86 OP_LONG_TO_DOUBLE vA, vB
436 DF_DA_WIDE | DF_UB_WIDE | DF_FP_A,
437
438 // 87 OP_FLOAT_TO_INT vA, vB
439 DF_DA | DF_UB | DF_FP_B,
440
441 // 88 OP_FLOAT_TO_LONG vA, vB
442 DF_DA_WIDE | DF_UB | DF_FP_B,
443
444 // 89 OP_FLOAT_TO_DOUBLE vA, vB
445 DF_DA_WIDE | DF_UB | DF_FP_A | DF_FP_B,
446
447 // 8A OP_DOUBLE_TO_INT vA, vB
448 DF_DA | DF_UB_WIDE | DF_FP_B,
449
450 // 8B OP_DOUBLE_TO_LONG vA, vB
451 DF_DA_WIDE | DF_UB_WIDE | DF_FP_B,
452
453 // 8C OP_DOUBLE_TO_FLOAT vA, vB
454 DF_DA | DF_UB_WIDE | DF_FP_A | DF_FP_B,
455
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
523 DF_DA_WIDE | DF_UB_WIDE | DF_UC,
524
525 // A4 OP_SHR_LONG vAA, vBB, vCC
526 DF_DA_WIDE | DF_UB_WIDE | DF_UC,
527
528 // A5 OP_USHR_LONG vAA, vBB, vCC
529 DF_DA_WIDE | DF_UB_WIDE | DF_UC,
530
531 // A6 OP_ADD_FLOAT vAA, vBB, vCC
532 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
533
534 // A7 OP_SUB_FLOAT vAA, vBB, vCC
535 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
536
537 // A8 OP_MUL_FLOAT vAA, vBB, vCC
538 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
539
540 // A9 OP_DIV_FLOAT vAA, vBB, vCC
541 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
542
543 // AA OP_REM_FLOAT vAA, vBB, vCC
544 DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
545
546 // AB OP_ADD_DOUBLE vAA, vBB, vCC
547 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
548
549 // AC OP_SUB_DOUBLE vAA, vBB, vCC
550 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
551
552 // AD OP_MUL_DOUBLE vAA, vBB, vCC
553 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
554
555 // AE OP_DIV_DOUBLE vAA, vBB, vCC
556 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
557
558 // AF OP_REM_DOUBLE vAA, vBB, vCC
559 DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
560
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
619 DF_DA_WIDE | DF_UA_WIDE | DF_UB,
620
621 // C4 OP_SHR_LONG_2ADDR vA, vB
622 DF_DA_WIDE | DF_UA_WIDE | DF_UB,
623
624 // C5 OP_USHR_LONG_2ADDR vA, vB
625 DF_DA_WIDE | DF_UA_WIDE | DF_UB,
626
627 // C6 OP_ADD_FLOAT_2ADDR vA, vB
628 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
629
630 // C7 OP_SUB_FLOAT_2ADDR vA, vB
631 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
632
633 // C8 OP_MUL_FLOAT_2ADDR vA, vB
634 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
635
636 // C9 OP_DIV_FLOAT_2ADDR vA, vB
637 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
638
639 // CA OP_REM_FLOAT_2ADDR vA, vB
640 DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
641
642 // CB OP_ADD_DOUBLE_2ADDR vA, vB
643 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
644
645 // CC OP_SUB_DOUBLE_2ADDR vA, vB
646 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
647
648 // CD OP_MUL_DOUBLE_2ADDR vA, vB
649 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
650
651 // CE OP_DIV_DOUBLE_2ADDR vA, vB
652 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
653
654 // CF OP_REM_DOUBLE_2ADDR vA, vB
655 DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
656
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
714 // E3 OP_IGET_VOLATILE
715 DF_DA | DF_UB,
716
717 // E4 OP_IPUT_VOLATILE
718 DF_UA | DF_UB,
719
720 // E5 OP_SGET_VOLATILE
721 DF_DA,
722
723 // E6 OP_SPUT_VOLATILE
724 DF_UA,
725
726 // E7 OP_IGET_OBJECT_VOLATILE
727 DF_DA | DF_UB,
728
729 // E8 OP_IGET_WIDE_VOLATILE
730 DF_DA_WIDE | DF_UB,
731
732 // E9 OP_IPUT_WIDE_VOLATILE
733 DF_UA_WIDE | DF_UB,
734
735 // EA OP_SGET_WIDE_VOLATILE
736 DF_DA_WIDE,
737
738 // EB OP_SPUT_WIDE_VOLATILE
739 DF_UA_WIDE,
740
741 // EC OP_BREAKPOINT
742 DF_NOP,
743
744 // ED OP_THROW_VERIFICATION_ERROR
745 DF_NOP,
746
747 // EE OP_EXECUTE_INLINE
748 DF_FORMAT_35C,
749
750 // EF OP_EXECUTE_INLINE_RANGE
751 DF_FORMAT_3RC,
752
753 // F0 OP_INVOKE_OBJECT_INIT_RANGE
754 DF_NOP,
755
756 // F1 OP_RETURN_VOID_BARRIER
757 DF_NOP,
758
759 // F2 OP_IGET_QUICK
760 DF_DA | DF_UB | DF_IS_GETTER,
761
762 // F3 OP_IGET_WIDE_QUICK
763 DF_DA_WIDE | DF_UB | DF_IS_GETTER,
764
765 // F4 OP_IGET_OBJECT_QUICK
766 DF_DA | DF_UB | DF_IS_GETTER,
767
768 // F5 OP_IPUT_QUICK
769 DF_UA | DF_UB | DF_IS_SETTER,
770
771 // F6 OP_IPUT_WIDE_QUICK
772 DF_UA_WIDE | DF_UB | DF_IS_SETTER,
773
774 // F7 OP_IPUT_OBJECT_QUICK
775 DF_UA | DF_UB | DF_IS_SETTER,
776
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
789 // FC OP_IPUT_OBJECT_VOLATILE
790 DF_UA | DF_UB,
791
792 // FD OP_SGET_OBJECT_VOLATILE
793 DF_DA,
794
795 // FE OP_SPUT_OBJECT_VOLATILE
796 DF_UA,
797
798 // FF OP_DISPATCH_FF
799 DF_NOP,
800
801 // 100 OP_CONST_CLASS_JUMBO vAAAA, type@BBBBBBBB
802 DF_DA,
803
804 // 101 OP_CHECK_CAST_JUMBO vAAAA, type@BBBBBBBB
805 DF_UA,
806
807 // 102 OP_INSTANCE_OF_JUMBO vAAAA, vBBBB, type@CCCCCCCC
808 DF_DA | DF_UB,
809
810 // 103 OP_NEW_INSTANCE_JUMBO vAAAA, type@BBBBBBBB
811 DF_DA,
812
813 // 104 OP_NEW_ARRAY_JUMBO vAAAA, vBBBB, type@CCCCCCCC
814 DF_DA | DF_UB,
815
816 // 105 OP_FILLED_NEW_ARRAY_JUMBO {vCCCC .. vNNNN}, type@BBBBBBBB
817 DF_FORMAT_3RC,
818
819 // 106 OP_IGET_JUMBO vAAAA, vBBBB, field@CCCCCCCC
820 DF_DA | DF_UB | DF_IS_GETTER,
821
822 // 107 OP_IGET_WIDE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
823 DF_DA_WIDE | DF_UB | DF_IS_GETTER,
824
825 // 108 OP_IGET_OBJECT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
826 DF_DA | DF_UB | DF_IS_GETTER,
827
828 // 109 OP_IGET_BOOLEAN_JUMBO vAAAA, vBBBB, field@CCCCCCCC
829 DF_DA | DF_UB | DF_IS_GETTER,
830
831 // 10A OP_IGET_BYTE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
832 DF_DA | DF_UB | DF_IS_GETTER,
833
834 // 10B OP_IGET_CHAR_JUMBO vAAAA, vBBBB, field@CCCCCCCC
835 DF_DA | DF_UB | DF_IS_GETTER,
836
837 // 10C OP_IGET_SHORT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
838 DF_DA | DF_UB | DF_IS_GETTER,
839
840 // 10D OP_IPUT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
841 DF_UA | DF_UB | DF_IS_SETTER,
842
843 // 10E OP_IPUT_WIDE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
844 DF_UA_WIDE | DF_UB | DF_IS_SETTER,
845
846 // 10F OP_IPUT_OBJECT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
847 DF_UA | DF_UB | DF_IS_SETTER,
848
849 // 110 OP_IPUT_BOOLEAN_JUMBO vAAAA, vBBBB, field@CCCCCCCC
850 DF_UA | DF_UB | DF_IS_SETTER,
851
852 // 111 OP_IPUT_BYTE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
853 DF_UA | DF_UB | DF_IS_SETTER,
854
855 // 112 OP_IPUT_CHAR_JUMBO vAAAA, vBBBB, field@CCCCCCCC
856 DF_UA | DF_UB | DF_IS_SETTER,
857
858 // 113 OP_IPUT_SHORT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
859 DF_UA | DF_UB | DF_IS_SETTER,
860
861 // 114 OP_SGET_JUMBO vAAAA, vBBBB, field@CCCCCCCC
862 DF_DA | DF_IS_GETTER,
863
864 // 115 OP_SGET_WIDE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
865 DF_DA_WIDE | DF_IS_GETTER,
866
867 // 116 OP_SGET_OBJECT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
868 DF_DA | DF_IS_GETTER,
869
870 // 117 OP_SGET_BOOLEAN_JUMBO vAAAA, vBBBB, field@CCCCCCCC
871 DF_DA | DF_IS_GETTER,
872
873 // 118 OP_SGET_BYTE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
874 DF_DA | DF_IS_GETTER,
875
876 // 119 OP_SGET_CHAR_JUMBO vAAAA, vBBBB, field@CCCCCCCC
877 DF_DA | DF_IS_GETTER,
878
879 // 11A OP_SGET_SHORT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
880 DF_DA | DF_IS_GETTER,
881
882 // 11B OP_SPUT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
883 DF_UA | DF_IS_SETTER,
884
885 // 11C OP_SPUT_WIDE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
886 DF_UA_WIDE | DF_IS_SETTER,
887
888 // 11D OP_SPUT_OBJECT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
889 DF_UA | DF_IS_SETTER,
890
891 // 11E OP_SPUT_BOOLEAN_JUMBO vAAAA, vBBBB, field@CCCCCCCC
892 DF_UA | DF_IS_SETTER,
893
894 // 11F OP_SPUT_BYTE_JUMBO vAAAA, vBBBB, field@CCCCCCCC
895 DF_UA | DF_IS_SETTER,
896
897 // 120 OP_SPUT_CHAR_JUMBO vAAAA, vBBBB, field@CCCCCCCC
898 DF_UA | DF_IS_SETTER,
899
900 // 121 OP_SPUT_SHORT_JUMBO vAAAA, vBBBB, field@CCCCCCCC
901 DF_UA | DF_IS_SETTER,
902
903 // 122 OP_INVOKE_VIRTUAL_JUMBO {vCCCC .. vNNNN}, meth@BBBBBBBB
904 DF_FORMAT_3RC,
905
906 // 123 OP_INVOKE_SUPER_JUMBO {vCCCC .. vNNNN}, meth@BBBBBBBB
907 DF_FORMAT_3RC,
908
909 // 124 OP_INVOKE_DIRECT_JUMBO {vCCCC .. vNNNN}, meth@BBBBBBBB
910 DF_FORMAT_3RC,
911
912 // 125 OP_INVOKE_STATIC_JUMBO {vCCCC .. vNNNN}, meth@BBBBBBBB
913 DF_FORMAT_3RC,
914
915 // 126 OP_INVOKE_INTERFACE_JUMBO {vCCCC .. vNNNN}, meth@BBBBBBBB
916 DF_FORMAT_3RC,
917
918 // 127 OP_UNUSED_27FF
919 DF_NOP,
920
921 // 128 OP_UNUSED_28FF
922 DF_NOP,
923
924 // 129 OP_UNUSED_29FF
925 DF_NOP,
926
927 // 12A OP_UNUSED_2AFF
928 DF_NOP,
929
930 // 12B OP_UNUSED_2BFF
931 DF_NOP,
932
933 // 12C OP_UNUSED_2CFF
934 DF_NOP,
935
936 // 12D OP_UNUSED_2DFF
937 DF_NOP,
938
939 // 12E OP_UNUSED_2EFF
940 DF_NOP,
941
942 // 12F OP_UNUSED_2FFF
943 DF_NOP,
944
945 // 130 OP_UNUSED_30FF
946 DF_NOP,
947
948 // 131 OP_UNUSED_31FF
949 DF_NOP,
950
951 // 132 OP_UNUSED_32FF
952 DF_NOP,
953
954 // 133 OP_UNUSED_33FF
955 DF_NOP,
956
957 // 134 OP_UNUSED_34FF
958 DF_NOP,
959
960 // 135 OP_UNUSED_35FF
961 DF_NOP,
962
963 // 136 OP_UNUSED_36FF
964 DF_NOP,
965
966 // 137 OP_UNUSED_37FF
967 DF_NOP,
968
969 // 138 OP_UNUSED_38FF
970 DF_NOP,
971
972 // 139 OP_UNUSED_39FF
973 DF_NOP,
974
975 // 13A OP_UNUSED_3AFF
976 DF_NOP,
977
978 // 13B OP_UNUSED_3BFF
979 DF_NOP,
980
981 // 13C OP_UNUSED_3CFF
982 DF_NOP,
983
984 // 13D OP_UNUSED_3DFF
985 DF_NOP,
986
987 // 13E OP_UNUSED_3EFF
988 DF_NOP,
989
990 // 13F OP_UNUSED_3FFF
991 DF_NOP,
992
993 // 140 OP_UNUSED_40FF
994 DF_NOP,
995
996 // 141 OP_UNUSED_41FF
997 DF_NOP,
998
999 // 142 OP_UNUSED_42FF
1000 DF_NOP,
1001
1002 // 143 OP_UNUSED_43FF
1003 DF_NOP,
1004
1005 // 144 OP_UNUSED_44FF
1006 DF_NOP,
1007
1008 // 145 OP_UNUSED_45FF
1009 DF_NOP,
1010
1011 // 146 OP_UNUSED_46FF
1012 DF_NOP,
1013
1014 // 147 OP_UNUSED_47FF
1015 DF_NOP,
1016
1017 // 148 OP_UNUSED_48FF
1018 DF_NOP,
1019
1020 // 149 OP_UNUSED_49FF
1021 DF_NOP,
1022
1023 // 14A OP_UNUSED_4AFF
1024 DF_NOP,
1025
1026 // 14B OP_UNUSED_4BFF
1027 DF_NOP,
1028
1029 // 14C OP_UNUSED_4CFF
1030 DF_NOP,
1031
1032 // 14D OP_UNUSED_4DFF
1033 DF_NOP,
1034
1035 // 14E OP_UNUSED_4EFF
1036 DF_NOP,
1037
1038 // 14F OP_UNUSED_4FFF
1039 DF_NOP,
1040
1041 // 150 OP_UNUSED_50FF
1042 DF_NOP,
1043
1044 // 151 OP_UNUSED_51FF
1045 DF_NOP,
1046
1047 // 152 OP_UNUSED_52FF
1048 DF_NOP,
1049
1050 // 153 OP_UNUSED_53FF
1051 DF_NOP,
1052
1053 // 154 OP_UNUSED_54FF
1054 DF_NOP,
1055
1056 // 155 OP_UNUSED_55FF
1057 DF_NOP,
1058
1059 // 156 OP_UNUSED_56FF
1060 DF_NOP,
1061
1062 // 157 OP_UNUSED_57FF
1063 DF_NOP,
1064
1065 // 158 OP_UNUSED_58FF
1066 DF_NOP,
1067
1068 // 159 OP_UNUSED_59FF
1069 DF_NOP,
1070
1071 // 15A OP_UNUSED_5AFF
1072 DF_NOP,
1073
1074 // 15B OP_UNUSED_5BFF
1075 DF_NOP,
1076
1077 // 15C OP_UNUSED_5CFF
1078 DF_NOP,
1079
1080 // 15D OP_UNUSED_5DFF
1081 DF_NOP,
1082
1083 // 15E OP_UNUSED_5EFF
1084 DF_NOP,
1085
1086 // 15F OP_UNUSED_5FFF
1087 DF_NOP,
1088
1089 // 160 OP_UNUSED_60FF
1090 DF_NOP,
1091
1092 // 161 OP_UNUSED_61FF
1093 DF_NOP,
1094
1095 // 162 OP_UNUSED_62FF
1096 DF_NOP,
1097
1098 // 163 OP_UNUSED_63FF
1099 DF_NOP,
1100
1101 // 164 OP_UNUSED_64FF
1102 DF_NOP,
1103
1104 // 165 OP_UNUSED_65FF
1105 DF_NOP,
1106
1107 // 166 OP_UNUSED_66FF
1108 DF_NOP,
1109
1110 // 167 OP_UNUSED_67FF
1111 DF_NOP,
1112
1113 // 168 OP_UNUSED_68FF
1114 DF_NOP,
1115
1116 // 169 OP_UNUSED_69FF
1117 DF_NOP,
1118
1119 // 16A OP_UNUSED_6AFF
1120 DF_NOP,
1121
1122 // 16B OP_UNUSED_6BFF
1123 DF_NOP,
1124
1125 // 16C OP_UNUSED_6CFF
1126 DF_NOP,
1127
1128 // 16D OP_UNUSED_6DFF
1129 DF_NOP,
1130
1131 // 16E OP_UNUSED_6EFF
1132 DF_NOP,
1133
1134 // 16F OP_UNUSED_6FFF
1135 DF_NOP,
1136
1137 // 170 OP_UNUSED_70FF
1138 DF_NOP,
1139
1140 // 171 OP_UNUSED_71FF
1141 DF_NOP,
1142
1143 // 172 OP_UNUSED_72FF
1144 DF_NOP,
1145
1146 // 173 OP_UNUSED_73FF
1147 DF_NOP,
1148
1149 // 174 OP_UNUSED_74FF
1150 DF_NOP,
1151
1152 // 175 OP_UNUSED_75FF
1153 DF_NOP,
1154
1155 // 176 OP_UNUSED_76FF
1156 DF_NOP,
1157
1158 // 177 OP_UNUSED_77FF
1159 DF_NOP,
1160
1161 // 178 OP_UNUSED_78FF
1162 DF_NOP,
1163
1164 // 179 OP_UNUSED_79FF
1165 DF_NOP,
1166
1167 // 17A OP_UNUSED_7AFF
1168 DF_NOP,
1169
1170 // 17B OP_UNUSED_7BFF
1171 DF_NOP,
1172
1173 // 17C OP_UNUSED_7CFF
1174 DF_NOP,
1175
1176 // 17D OP_UNUSED_7DFF
1177 DF_NOP,
1178
1179 // 17E OP_UNUSED_7EFF
1180 DF_NOP,
1181
1182 // 17F OP_UNUSED_7FFF
1183 DF_NOP,
1184
1185 // 180 OP_UNUSED_80FF
1186 DF_NOP,
1187
1188 // 181 OP_UNUSED_81FF
1189 DF_NOP,
1190
1191 // 182 OP_UNUSED_82FF
1192 DF_NOP,
1193
1194 // 183 OP_UNUSED_83FF
1195 DF_NOP,
1196
1197 // 184 OP_UNUSED_84FF
1198 DF_NOP,
1199
1200 // 185 OP_UNUSED_85FF
1201 DF_NOP,
1202
1203 // 186 OP_UNUSED_86FF
1204 DF_NOP,
1205
1206 // 187 OP_UNUSED_87FF
1207 DF_NOP,
1208
1209 // 188 OP_UNUSED_88FF
1210 DF_NOP,
1211
1212 // 189 OP_UNUSED_89FF
1213 DF_NOP,
1214
1215 // 18A OP_UNUSED_8AFF
1216 DF_NOP,
1217
1218 // 18B OP_UNUSED_8BFF
1219 DF_NOP,
1220
1221 // 18C OP_UNUSED_8CFF
1222 DF_NOP,
1223
1224 // 18D OP_UNUSED_8DFF
1225 DF_NOP,
1226
1227 // 18E OP_UNUSED_8EFF
1228 DF_NOP,
1229
1230 // 18F OP_UNUSED_8FFF
1231 DF_NOP,
1232
1233 // 190 OP_UNUSED_90FF
1234 DF_NOP,
1235
1236 // 191 OP_UNUSED_91FF
1237 DF_NOP,
1238
1239 // 192 OP_UNUSED_92FF
1240 DF_NOP,
1241
1242 // 193 OP_UNUSED_93FF
1243 DF_NOP,
1244
1245 // 194 OP_UNUSED_94FF
1246 DF_NOP,
1247
1248 // 195 OP_UNUSED_95FF
1249 DF_NOP,
1250
1251 // 196 OP_UNUSED_96FF
1252 DF_NOP,
1253
1254 // 197 OP_UNUSED_97FF
1255 DF_NOP,
1256
1257 // 198 OP_UNUSED_98FF
1258 DF_NOP,
1259
1260 // 199 OP_UNUSED_99FF
1261 DF_NOP,
1262
1263 // 19A OP_UNUSED_9AFF
1264 DF_NOP,
1265
1266 // 19B OP_UNUSED_9BFF
1267 DF_NOP,
1268
1269 // 19C OP_UNUSED_9CFF
1270 DF_NOP,
1271
1272 // 19D OP_UNUSED_9DFF
1273 DF_NOP,
1274
1275 // 19E OP_UNUSED_9EFF
1276 DF_NOP,
1277
1278 // 19F OP_UNUSED_9FFF
1279 DF_NOP,
1280
1281 // 1A0 OP_UNUSED_A0FF
1282 DF_NOP,
1283
1284 // 1A1 OP_UNUSED_A1FF
1285 DF_NOP,
1286
1287 // 1A2 OP_UNUSED_A2FF
1288 DF_NOP,
1289
1290 // 1A3 OP_UNUSED_A3FF
1291 DF_NOP,
1292
1293 // 1A4 OP_UNUSED_A4FF
1294 DF_NOP,
1295
1296 // 1A5 OP_UNUSED_A5FF
1297 DF_NOP,
1298
1299 // 1A6 OP_UNUSED_A6FF
1300 DF_NOP,
1301
1302 // 1A7 OP_UNUSED_A7FF
1303 DF_NOP,
1304
1305 // 1A8 OP_UNUSED_A8FF
1306 DF_NOP,
1307
1308 // 1A9 OP_UNUSED_A9FF
1309 DF_NOP,
1310
1311 // 1AA OP_UNUSED_AAFF
1312 DF_NOP,
1313
1314 // 1AB OP_UNUSED_ABFF
1315 DF_NOP,
1316
1317 // 1AC OP_UNUSED_ACFF
1318 DF_NOP,
1319
1320 // 1AD OP_UNUSED_ADFF
1321 DF_NOP,
1322
1323 // 1AE OP_UNUSED_AEFF
1324 DF_NOP,
1325
1326 // 1AF OP_UNUSED_AFFF
1327 DF_NOP,
1328
1329 // 1B0 OP_UNUSED_B0FF
1330 DF_NOP,
1331
1332 // 1B1 OP_UNUSED_B1FF
1333 DF_NOP,
1334
1335 // 1B2 OP_UNUSED_B2FF
1336 DF_NOP,
1337
1338 // 1B3 OP_UNUSED_B3FF
1339 DF_NOP,
1340
1341 // 1B4 OP_UNUSED_B4FF
1342 DF_NOP,
1343
1344 // 1B5 OP_UNUSED_B5FF
1345 DF_NOP,
1346
1347 // 1B6 OP_UNUSED_B6FF
1348 DF_NOP,
1349
1350 // 1B7 OP_UNUSED_B7FF
1351 DF_NOP,
1352
1353 // 1B8 OP_UNUSED_B8FF
1354 DF_NOP,
1355
1356 // 1B9 OP_UNUSED_B9FF
1357 DF_NOP,
1358
1359 // 1BA OP_UNUSED_BAFF
1360 DF_NOP,
1361
1362 // 1BB OP_UNUSED_BBFF
1363 DF_NOP,
1364
1365 // 1BC OP_UNUSED_BCFF
1366 DF_NOP,
1367
1368 // 1BD OP_UNUSED_BDFF
1369 DF_NOP,
1370
1371 // 1BE OP_UNUSED_BEFF
1372 DF_NOP,
1373
1374 // 1BF OP_UNUSED_BFFF
1375 DF_NOP,
1376
1377 // 1C0 OP_UNUSED_C0FF
1378 DF_NOP,
1379
1380 // 1C1 OP_UNUSED_C1FF
1381 DF_NOP,
1382
1383 // 1C2 OP_UNUSED_C2FF
1384 DF_NOP,
1385
1386 // 1C3 OP_UNUSED_C3FF
1387 DF_NOP,
1388
1389 // 1C4 OP_UNUSED_C4FF
1390 DF_NOP,
1391
1392 // 1C5 OP_UNUSED_C5FF
1393 DF_NOP,
1394
1395 // 1C6 OP_UNUSED_C6FF
1396 DF_NOP,
1397
1398 // 1C7 OP_UNUSED_C7FF
1399 DF_NOP,
1400
1401 // 1C8 OP_UNUSED_C8FF
1402 DF_NOP,
1403
1404 // 1C9 OP_UNUSED_C9FF
1405 DF_NOP,
1406
1407 // 1CA OP_UNUSED_CAFF
1408 DF_NOP,
1409
1410 // 1CB OP_UNUSED_CBFF
1411 DF_NOP,
1412
1413 // 1CC OP_UNUSED_CCFF
1414 DF_NOP,
1415
1416 // 1CD OP_UNUSED_CDFF
1417 DF_NOP,
1418
1419 // 1CE OP_UNUSED_CEFF
1420 DF_NOP,
1421
1422 // 1CF OP_UNUSED_CFFF
1423 DF_NOP,
1424
1425 // 1D0 OP_UNUSED_D0FF
1426 DF_NOP,
1427
1428 // 1D1 OP_UNUSED_D1FF
1429 DF_NOP,
1430
1431 // 1D2 OP_UNUSED_D2FF
1432 DF_NOP,
1433
1434 // 1D3 OP_UNUSED_D3FF
1435 DF_NOP,
1436
1437 // 1D4 OP_UNUSED_D4FF
1438 DF_NOP,
1439
1440 // 1D5 OP_UNUSED_D5FF
1441 DF_NOP,
1442
1443 // 1D6 OP_UNUSED_D6FF
1444 DF_NOP,
1445
1446 // 1D7 OP_UNUSED_D7FF
1447 DF_NOP,
1448
1449 // 1D8 OP_UNUSED_D8FF
1450 DF_NOP,
1451
1452 // 1D9 OP_UNUSED_D9FF
1453 DF_NOP,
1454
1455 // 1DA OP_UNUSED_DAFF
1456 DF_NOP,
1457
1458 // 1DB OP_UNUSED_DBFF
1459 DF_NOP,
1460
1461 // 1DC OP_UNUSED_DCFF
1462 DF_NOP,
1463
1464 // 1DD OP_UNUSED_DDFF
1465 DF_NOP,
1466
1467 // 1DE OP_UNUSED_DEFF
1468 DF_NOP,
1469
1470 // 1DF OP_UNUSED_DFFF
1471 DF_NOP,
1472
1473 // 1E0 OP_UNUSED_E0FF
1474 DF_NOP,
1475
1476 // 1E1 OP_UNUSED_E1FF
1477 DF_NOP,
1478
1479 // 1E2 OP_UNUSED_E2FF
1480 DF_NOP,
1481
1482 // 1E3 OP_UNUSED_E3FF
1483 DF_NOP,
1484
1485 // 1E4 OP_UNUSED_E4FF
1486 DF_NOP,
1487
1488 // 1E5 OP_UNUSED_E5FF
1489 DF_NOP,
1490
1491 // 1E6 OP_UNUSED_E6FF
1492 DF_NOP,
1493
1494 // 1E7 OP_UNUSED_E7FF
1495 DF_NOP,
1496
1497 // 1E8 OP_UNUSED_E8FF
1498 DF_NOP,
1499
1500 // 1E9 OP_UNUSED_E9FF
1501 DF_NOP,
1502
1503 // 1EA OP_UNUSED_EAFF
1504 DF_NOP,
1505
1506 // 1EB OP_UNUSED_EBFF
1507 DF_NOP,
1508
1509 // 1EC OP_UNUSED_ECFF
1510 DF_NOP,
1511
1512 // 1ED OP_UNUSED_EDFF
1513 DF_NOP,
1514
1515 // 1EE OP_UNUSED_EEFF
1516 DF_NOP,
1517
1518 // 1EF OP_UNUSED_EFFF
1519 DF_NOP,
1520
1521 // 1F0 OP_UNUSED_F0FF
1522 DF_NOP,
1523
1524 // 1F1 OP_UNUSED_F1FF
1525 DF_NOP,
1526
1527 // 1F2 OP_INVOKE_OBJECT_INIT_JUMBO
1528 DF_NOP,
1529
1530 // 1F3 OP_IGET_VOLATILE_JUMBO
1531 DF_DA | DF_UB,
1532
1533 // 1F4 OP_IGET_WIDE_VOLATILE_JUMBO
1534 DF_DA_WIDE | DF_UB,
1535
1536 // 1F5 OP_IGET_OBJECT_VOLATILE_JUMBO
1537 DF_DA | DF_UB,
1538
1539 // 1F6 OP_IPUT_VOLATILE_JUMBO
1540 DF_UA | DF_UB,
1541
1542 // 1F7 OP_IPUT_WIDE_VOLATILE_JUMBO
1543 DF_UA_WIDE | DF_UB,
1544
1545 // 1F8 OP_IPUT_OBJECT_VOLATILE_JUMBO
1546 DF_UA | DF_UB,
1547
1548 // 1F9 OP_SGET_VOLATILE_JUMBO
1549 DF_DA,
1550
1551 // 1FA OP_SGET_WIDE_VOLATILE_JUMBO
1552 DF_DA_WIDE,
1553
1554 // 1FB OP_SGET_OBJECT_VOLATILE_JUMBO
1555 DF_DA,
1556
1557 // 1FC OP_SPUT_VOLATILE_JUMBO
1558 DF_UA,
1559
1560 // 1FD OP_SPUT_WIDE_VOLATILE_JUMBO
1561 DF_UA_WIDE,
1562
1563 // 1FE OP_SPUT_OBJECT_VOLATILE_JUMBO
1564 DF_UA,
1565
1566 // 1FF OP_THROW_VERIFICATION_ERROR_JUMBO
1567 DF_NOP,
1568
1569 // Beginning of extended MIR opcodes
1570 // 200 OP_MIR_PHI
1571 DF_PHI | DF_DA,
1572 /*
1573 * For extended MIR inserted at the MIR2LIR stage, it is okay to have
1574 * undefined values here.
1575 */
1576 };
1577
1578 /* Return the Dalvik register/subscript pair of a given SSA register */
dvmConvertSSARegToDalvik(const CompilationUnit * cUnit,int ssaReg)1579 int dvmConvertSSARegToDalvik(const CompilationUnit *cUnit, int ssaReg)
1580 {
1581 return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
1582 }
1583
1584 /*
1585 * Utility function to convert encoded SSA register value into Dalvik register
1586 * and subscript pair. Each SSA register can be used to index the
1587 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
1588 */
dvmCompilerGetDalvikDisassembly(const DecodedInstruction * insn,const char * note)1589 char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
1590 const char *note)
1591 {
1592 char buffer[256];
1593 Opcode opcode = insn->opcode;
1594 int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
1595 int flags;
1596 char *ret;
1597
1598 buffer[0] = 0;
1599 if ((int)opcode >= (int)kMirOpFirst) {
1600 if ((int)opcode == (int)kMirOpPhi) {
1601 strcpy(buffer, "PHI");
1602 }
1603 else {
1604 sprintf(buffer, "Opcode %#x", opcode);
1605 }
1606 flags = 0;
1607 } else {
1608 strcpy(buffer, dexGetOpcodeName(opcode));
1609 flags = dexGetFlagsFromOpcode(insn->opcode);
1610 }
1611
1612 if (note)
1613 strcat(buffer, note);
1614
1615 /* For branches, decode the instructions to print out the branch targets */
1616 if (flags & kInstrCanBranch) {
1617 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
1618 int offset = 0;
1619 switch (dalvikFormat) {
1620 case kFmt21t:
1621 snprintf(buffer + strlen(buffer), 256, " v%d,", insn->vA);
1622 offset = (int) insn->vB;
1623 break;
1624 case kFmt22t:
1625 snprintf(buffer + strlen(buffer), 256, " v%d, v%d,",
1626 insn->vA, insn->vB);
1627 offset = (int) insn->vC;
1628 break;
1629 case kFmt10t:
1630 case kFmt20t:
1631 case kFmt30t:
1632 offset = (int) insn->vA;
1633 break;
1634 default:
1635 LOGE("Unexpected branch format %d / opcode %#x", dalvikFormat,
1636 opcode);
1637 dvmAbort();
1638 break;
1639 }
1640 snprintf(buffer + strlen(buffer), 256, " (%c%x)",
1641 offset > 0 ? '+' : '-',
1642 offset > 0 ? offset : -offset);
1643 } else if (dfAttributes & DF_FORMAT_35C) {
1644 unsigned int i;
1645 for (i = 0; i < insn->vA; i++) {
1646 if (i != 0) strcat(buffer, ",");
1647 snprintf(buffer + strlen(buffer), 256, " v%d", insn->arg[i]);
1648 }
1649 }
1650 else if (dfAttributes & DF_FORMAT_3RC) {
1651 snprintf(buffer + strlen(buffer), 256,
1652 " v%d..v%d", insn->vC, insn->vC + insn->vA - 1);
1653 }
1654 else {
1655 if (dfAttributes & DF_A_IS_REG) {
1656 snprintf(buffer + strlen(buffer), 256, " v%d", insn->vA);
1657 }
1658 if (dfAttributes & DF_B_IS_REG) {
1659 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vB);
1660 }
1661 else if ((int)opcode < (int)kMirOpFirst) {
1662 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vB);
1663 }
1664 if (dfAttributes & DF_C_IS_REG) {
1665 snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vC);
1666 }
1667 else if ((int)opcode < (int)kMirOpFirst) {
1668 snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vC);
1669 }
1670 }
1671 int length = strlen(buffer) + 1;
1672 ret = (char *)dvmCompilerNew(length, false);
1673 memcpy(ret, buffer, length);
1674 return ret;
1675 }
1676
getSSAName(const CompilationUnit * cUnit,int ssaReg,char * name)1677 char *getSSAName(const CompilationUnit *cUnit, int ssaReg, char *name)
1678 {
1679 int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaReg);
1680
1681 sprintf(name, "v%d_%d",
1682 DECODE_REG(ssa2DalvikValue), DECODE_SUB(ssa2DalvikValue));
1683 return name;
1684 }
1685
1686 /*
1687 * Dalvik instruction disassembler with optional SSA printing.
1688 */
dvmCompilerFullDisassembler(const CompilationUnit * cUnit,const MIR * mir)1689 char *dvmCompilerFullDisassembler(const CompilationUnit *cUnit,
1690 const MIR *mir)
1691 {
1692 char buffer[256];
1693 char operand0[256], operand1[256];
1694 const DecodedInstruction *insn = &mir->dalvikInsn;
1695 int opcode = insn->opcode;
1696 int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
1697 char *ret;
1698 int length;
1699 OpcodeFlags flags;
1700
1701 buffer[0] = 0;
1702 if (opcode >= kMirOpFirst) {
1703 if (opcode == kMirOpPhi) {
1704 snprintf(buffer, 256, "PHI %s = (%s",
1705 getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
1706 getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
1707 int i;
1708 for (i = 1; i < mir->ssaRep->numUses; i++) {
1709 snprintf(buffer + strlen(buffer), 256, ", %s",
1710 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
1711 }
1712 snprintf(buffer + strlen(buffer), 256, ")");
1713 }
1714 else {
1715 sprintf(buffer, "Opcode %#x", opcode);
1716 }
1717 goto done;
1718 } else {
1719 strcpy(buffer, dexGetOpcodeName((Opcode)opcode));
1720 }
1721
1722 flags = dexGetFlagsFromOpcode((Opcode)opcode);
1723 /* For branches, decode the instructions to print out the branch targets */
1724 if (flags & kInstrCanBranch) {
1725 InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
1726 int delta = 0;
1727 switch (dalvikFormat) {
1728 case kFmt21t:
1729 snprintf(buffer + strlen(buffer), 256, " %s, ",
1730 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
1731 delta = (int) insn->vB;
1732 break;
1733 case kFmt22t:
1734 snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
1735 getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
1736 getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
1737 delta = (int) insn->vC;
1738 break;
1739 case kFmt10t:
1740 case kFmt20t:
1741 case kFmt30t:
1742 delta = (int) insn->vA;
1743 break;
1744 default:
1745 LOGE("Unexpected branch format: %d", dalvikFormat);
1746 dvmAbort();
1747 break;
1748 }
1749 snprintf(buffer + strlen(buffer), 256, " %04x",
1750 mir->offset + delta);
1751 } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
1752 unsigned int i;
1753 for (i = 0; i < insn->vA; i++) {
1754 if (i != 0) strcat(buffer, ",");
1755 snprintf(buffer + strlen(buffer), 256, " %s",
1756 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
1757 }
1758 } else {
1759 int udIdx;
1760 if (mir->ssaRep->numDefs) {
1761
1762 for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
1763 snprintf(buffer + strlen(buffer), 256, " %s",
1764 getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
1765 }
1766 strcat(buffer, ",");
1767 }
1768 if (mir->ssaRep->numUses) {
1769 /* No leading ',' for the first use */
1770 snprintf(buffer + strlen(buffer), 256, " %s",
1771 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
1772 for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
1773 snprintf(buffer + strlen(buffer), 256, ", %s",
1774 getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
1775 }
1776 }
1777 if (opcode < kMirOpFirst) {
1778 InstructionFormat dalvikFormat =
1779 dexGetFormatFromOpcode((Opcode)opcode);
1780 switch (dalvikFormat) {
1781 case kFmt11n: // op vA, #+B
1782 case kFmt21s: // op vAA, #+BBBB
1783 case kFmt21h: // op vAA, #+BBBB00000[00000000]
1784 case kFmt31i: // op vAA, #+BBBBBBBB
1785 case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
1786 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
1787 break;
1788 case kFmt21c: // op vAA, thing@BBBB
1789 case kFmt31c: // op vAA, thing@BBBBBBBB
1790 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
1791 break;
1792 case kFmt22b: // op vAA, vBB, #+CC
1793 case kFmt22s: // op vA, vB, #+CCCC
1794 snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
1795 break;
1796 case kFmt22c: // op vA, vB, thing@CCCC
1797 case kFmt22cs: // [opt] op vA, vB, field offset CCCC
1798 snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
1799 break;
1800 /* No need for special printing */
1801 default:
1802 break;
1803 }
1804 }
1805 }
1806
1807 done:
1808 length = strlen(buffer) + 1;
1809 ret = (char *) dvmCompilerNew(length, false);
1810 memcpy(ret, buffer, length);
1811 return ret;
1812 }
1813
1814 /*
1815 * Utility function to convert encoded SSA register value into Dalvik register
1816 * and subscript pair. Each SSA register can be used to index the
1817 * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
1818 */
dvmCompilerGetSSAString(CompilationUnit * cUnit,SSARepresentation * ssaRep)1819 char *dvmCompilerGetSSAString(CompilationUnit *cUnit, SSARepresentation *ssaRep)
1820 {
1821 char buffer[256];
1822 char *ret;
1823 int i;
1824
1825 buffer[0] = 0;
1826 for (i = 0; i < ssaRep->numDefs; i++) {
1827 int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaRep->defs[i]);
1828
1829 sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ",
1830 ssaRep->defs[i], DECODE_REG(ssa2DalvikValue),
1831 DECODE_SUB(ssa2DalvikValue));
1832 }
1833
1834 if (ssaRep->numDefs) {
1835 strcat(buffer, "<- ");
1836 }
1837
1838 for (i = 0; i < ssaRep->numUses; i++) {
1839 int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaRep->uses[i]);
1840 int len = strlen(buffer);
1841
1842 if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ",
1843 ssaRep->uses[i], DECODE_REG(ssa2DalvikValue),
1844 DECODE_SUB(ssa2DalvikValue)) >= (250 - len)) {
1845 strcat(buffer, "...");
1846 break;
1847 }
1848 }
1849
1850 int length = strlen(buffer) + 1;
1851 ret = (char *)dvmCompilerNew(length, false);
1852 memcpy(ret, buffer, length);
1853 return ret;
1854 }
1855
1856 /* Any register that is used before being defined is considered live-in */
handleLiveInUse(BitVector * useV,BitVector * defV,BitVector * liveInV,int dalvikRegId)1857 static inline void handleLiveInUse(BitVector *useV, BitVector *defV,
1858 BitVector *liveInV, int dalvikRegId)
1859 {
1860 dvmCompilerSetBit(useV, dalvikRegId);
1861 if (!dvmIsBitSet(defV, dalvikRegId)) {
1862 dvmCompilerSetBit(liveInV, dalvikRegId);
1863 }
1864 }
1865
1866 /* Mark a reg as being defined */
handleDef(BitVector * defV,int dalvikRegId)1867 static inline void handleDef(BitVector *defV, int dalvikRegId)
1868 {
1869 dvmCompilerSetBit(defV, dalvikRegId);
1870 }
1871
1872 /*
1873 * Find out live-in variables for natural loops. Variables that are live-in in
1874 * the main loop body are considered to be defined in the entry block.
1875 */
dvmCompilerFindLocalLiveIn(CompilationUnit * cUnit,BasicBlock * bb)1876 bool dvmCompilerFindLocalLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
1877 {
1878 MIR *mir;
1879 BitVector *useV, *defV, *liveInV;
1880
1881 if (bb->dataFlowInfo == NULL) return false;
1882
1883 useV = bb->dataFlowInfo->useV =
1884 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
1885 defV = bb->dataFlowInfo->defV =
1886 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
1887 liveInV = bb->dataFlowInfo->liveInV =
1888 dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
1889
1890 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1891 int dfAttributes =
1892 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
1893 DecodedInstruction *dInsn = &mir->dalvikInsn;
1894
1895 if (dfAttributes & DF_HAS_USES) {
1896 if (dfAttributes & DF_UA) {
1897 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
1898 } else if (dfAttributes & DF_UA_WIDE) {
1899 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
1900 handleLiveInUse(useV, defV, liveInV, dInsn->vA+1);
1901 }
1902 if (dfAttributes & DF_UB) {
1903 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
1904 } else if (dfAttributes & DF_UB_WIDE) {
1905 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
1906 handleLiveInUse(useV, defV, liveInV, dInsn->vB+1);
1907 }
1908 if (dfAttributes & DF_UC) {
1909 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
1910 } else if (dfAttributes & DF_UC_WIDE) {
1911 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
1912 handleLiveInUse(useV, defV, liveInV, dInsn->vC+1);
1913 }
1914 }
1915 if (dfAttributes & DF_HAS_DEFS) {
1916 handleDef(defV, dInsn->vA);
1917 if (dfAttributes & DF_DA_WIDE) {
1918 handleDef(defV, dInsn->vA+1);
1919 }
1920 }
1921 }
1922 return true;
1923 }
1924
1925 /* Find out the latest SSA register for a given Dalvik register */
handleSSAUse(CompilationUnit * cUnit,int * uses,int dalvikReg,int regIndex)1926 static void handleSSAUse(CompilationUnit *cUnit, int *uses, int dalvikReg,
1927 int regIndex)
1928 {
1929 int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
1930 int ssaReg = DECODE_REG(encodedValue);
1931 uses[regIndex] = ssaReg;
1932 }
1933
1934 /* Setup a new SSA register for a given Dalvik register */
handleSSADef(CompilationUnit * cUnit,int * defs,int dalvikReg,int regIndex)1935 static void handleSSADef(CompilationUnit *cUnit, int *defs, int dalvikReg,
1936 int regIndex)
1937 {
1938 int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
1939 int ssaReg = cUnit->numSSARegs++;
1940 /* Bump up the subscript */
1941 int dalvikSub = DECODE_SUB(encodedValue) + 1;
1942 int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);
1943
1944 cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
1945
1946 int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
1947 dvmInsertGrowableList(cUnit->ssaToDalvikMap, newS2DMapping);
1948
1949 defs[regIndex] = ssaReg;
1950 }
1951
1952 /* Loop up new SSA names for format_35c instructions */
dataFlowSSAFormat35C(CompilationUnit * cUnit,MIR * mir)1953 static void dataFlowSSAFormat35C(CompilationUnit *cUnit, MIR *mir)
1954 {
1955 DecodedInstruction *dInsn = &mir->dalvikInsn;
1956 int numUses = dInsn->vA;
1957 int i;
1958
1959 mir->ssaRep->numUses = numUses;
1960 mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
1961
1962 for (i = 0; i < numUses; i++) {
1963 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
1964 }
1965 }
1966
1967 /* Loop up new SSA names for format_3rc instructions */
dataFlowSSAFormat3RC(CompilationUnit * cUnit,MIR * mir)1968 static void dataFlowSSAFormat3RC(CompilationUnit *cUnit, MIR *mir)
1969 {
1970 DecodedInstruction *dInsn = &mir->dalvikInsn;
1971 int numUses = dInsn->vA;
1972 int i;
1973
1974 mir->ssaRep->numUses = numUses;
1975 mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
1976
1977 for (i = 0; i < numUses; i++) {
1978 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
1979 }
1980 }
1981
1982 /* Entry function to convert a block into SSA representation */
dvmCompilerDoSSAConversion(CompilationUnit * cUnit,BasicBlock * bb)1983 bool dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
1984 {
1985 MIR *mir;
1986
1987 if (bb->dataFlowInfo == NULL) return false;
1988
1989 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1990 mir->ssaRep = (struct SSARepresentation *)
1991 dvmCompilerNew(sizeof(SSARepresentation), true);
1992
1993 int dfAttributes =
1994 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
1995
1996 int numUses = 0;
1997
1998 if (dfAttributes & DF_FORMAT_35C) {
1999 dataFlowSSAFormat35C(cUnit, mir);
2000 continue;
2001 }
2002
2003 if (dfAttributes & DF_FORMAT_3RC) {
2004 dataFlowSSAFormat3RC(cUnit, mir);
2005 continue;
2006 }
2007
2008 if (dfAttributes & DF_HAS_USES) {
2009 if (dfAttributes & DF_UA) {
2010 numUses++;
2011 } else if (dfAttributes & DF_UA_WIDE) {
2012 numUses += 2;
2013 }
2014 if (dfAttributes & DF_UB) {
2015 numUses++;
2016 } else if (dfAttributes & DF_UB_WIDE) {
2017 numUses += 2;
2018 }
2019 if (dfAttributes & DF_UC) {
2020 numUses++;
2021 } else if (dfAttributes & DF_UC_WIDE) {
2022 numUses += 2;
2023 }
2024 }
2025
2026 if (numUses) {
2027 mir->ssaRep->numUses = numUses;
2028 mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses,
2029 false);
2030 mir->ssaRep->fpUse = (bool *)dvmCompilerNew(sizeof(bool) * numUses,
2031 false);
2032 }
2033
2034 int numDefs = 0;
2035
2036 if (dfAttributes & DF_HAS_DEFS) {
2037 numDefs++;
2038 if (dfAttributes & DF_DA_WIDE) {
2039 numDefs++;
2040 }
2041 }
2042
2043 if (numDefs) {
2044 mir->ssaRep->numDefs = numDefs;
2045 mir->ssaRep->defs = (int *)dvmCompilerNew(sizeof(int) * numDefs,
2046 false);
2047 mir->ssaRep->fpDef = (bool *)dvmCompilerNew(sizeof(bool) * numDefs,
2048 false);
2049 }
2050
2051 DecodedInstruction *dInsn = &mir->dalvikInsn;
2052
2053 if (dfAttributes & DF_HAS_USES) {
2054 numUses = 0;
2055 if (dfAttributes & DF_UA) {
2056 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
2057 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
2058 } else if (dfAttributes & DF_UA_WIDE) {
2059 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
2060 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
2061 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
2062 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
2063 }
2064 if (dfAttributes & DF_UB) {
2065 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
2066 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
2067 } else if (dfAttributes & DF_UB_WIDE) {
2068 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
2069 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
2070 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
2071 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
2072 }
2073 if (dfAttributes & DF_UC) {
2074 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
2075 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
2076 } else if (dfAttributes & DF_UC_WIDE) {
2077 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
2078 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
2079 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
2080 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
2081 }
2082 }
2083 if (dfAttributes & DF_HAS_DEFS) {
2084 mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
2085 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
2086 if (dfAttributes & DF_DA_WIDE) {
2087 mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
2088 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
2089 }
2090 }
2091 }
2092
2093 /*
2094 * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
2095 * input to PHI nodes can be derived from the snapshot of all predecessor
2096 * blocks.
2097 */
2098 bb->dataFlowInfo->dalvikToSSAMap =
2099 (int *)dvmCompilerNew(sizeof(int) * cUnit->method->registersSize,
2100 false);
2101
2102 memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
2103 sizeof(int) * cUnit->method->registersSize);
2104 return true;
2105 }
2106
2107 /* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
setConstant(CompilationUnit * cUnit,int ssaReg,int value)2108 static void setConstant(CompilationUnit *cUnit, int ssaReg, int value)
2109 {
2110 dvmSetBit(cUnit->isConstantV, ssaReg);
2111 cUnit->constantValues[ssaReg] = value;
2112 }
2113
dvmCompilerDoConstantPropagation(CompilationUnit * cUnit,BasicBlock * bb)2114 bool dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
2115 {
2116 MIR *mir;
2117 BitVector *isConstantV = cUnit->isConstantV;
2118
2119 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
2120 int dfAttributes =
2121 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
2122
2123 DecodedInstruction *dInsn = &mir->dalvikInsn;
2124
2125 if (!(dfAttributes & DF_HAS_DEFS)) continue;
2126
2127 /* Handle instructions that set up constants directly */
2128 if (dfAttributes & DF_SETS_CONST) {
2129 if (dfAttributes & DF_DA) {
2130 switch (dInsn->opcode) {
2131 case OP_CONST_4:
2132 case OP_CONST_16:
2133 case OP_CONST:
2134 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
2135 break;
2136 case OP_CONST_HIGH16:
2137 setConstant(cUnit, mir->ssaRep->defs[0],
2138 dInsn->vB << 16);
2139 break;
2140 default:
2141 break;
2142 }
2143 } else if (dfAttributes & DF_DA_WIDE) {
2144 switch (dInsn->opcode) {
2145 case OP_CONST_WIDE_16:
2146 case OP_CONST_WIDE_32:
2147 setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
2148 setConstant(cUnit, mir->ssaRep->defs[1], 0);
2149 break;
2150 case OP_CONST_WIDE:
2151 setConstant(cUnit, mir->ssaRep->defs[0],
2152 (int) dInsn->vB_wide);
2153 setConstant(cUnit, mir->ssaRep->defs[1],
2154 (int) (dInsn->vB_wide >> 32));
2155 break;
2156 case OP_CONST_WIDE_HIGH16:
2157 setConstant(cUnit, mir->ssaRep->defs[0], 0);
2158 setConstant(cUnit, mir->ssaRep->defs[1],
2159 dInsn->vB << 16);
2160 break;
2161 default:
2162 break;
2163 }
2164 }
2165 /* Handle instructions that set up constants directly */
2166 } else if (dfAttributes & DF_IS_MOVE) {
2167 int i;
2168
2169 for (i = 0; i < mir->ssaRep->numUses; i++) {
2170 if (!dvmIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
2171 }
2172 /* Move a register holding a constant to another register */
2173 if (i == mir->ssaRep->numUses) {
2174 setConstant(cUnit, mir->ssaRep->defs[0],
2175 cUnit->constantValues[mir->ssaRep->uses[0]]);
2176 if (dfAttributes & DF_DA_WIDE) {
2177 setConstant(cUnit, mir->ssaRep->defs[1],
2178 cUnit->constantValues[mir->ssaRep->uses[1]]);
2179 }
2180 }
2181 }
2182 }
2183 /* TODO: implement code to handle arithmetic operations */
2184 return true;
2185 }
2186
dvmCompilerFindInductionVariables(struct CompilationUnit * cUnit,struct BasicBlock * bb)2187 bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
2188 struct BasicBlock *bb)
2189 {
2190 BitVector *isIndVarV = cUnit->loopAnalysis->isIndVarV;
2191 BitVector *isConstantV = cUnit->isConstantV;
2192 GrowableList *ivList = cUnit->loopAnalysis->ivList;
2193 MIR *mir;
2194
2195 if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock) {
2196 return false;
2197 }
2198
2199 /* If the bb doesn't have a phi it cannot contain an induction variable */
2200 if (bb->firstMIRInsn == NULL ||
2201 (int)bb->firstMIRInsn->dalvikInsn.opcode != (int)kMirOpPhi) {
2202 return false;
2203 }
2204
2205 /* Find basic induction variable first */
2206 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
2207 int dfAttributes =
2208 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
2209
2210 if (!(dfAttributes & DF_IS_LINEAR)) continue;
2211
2212 /*
2213 * For a basic induction variable:
2214 * 1) use[0] should belong to the output of a phi node
2215 * 2) def[0] should belong to the input of the same phi node
2216 * 3) the value added/subtracted is a constant
2217 */
2218 MIR *phi;
2219 for (phi = bb->firstMIRInsn; phi; phi = phi->next) {
2220 if ((int)phi->dalvikInsn.opcode != (int)kMirOpPhi) break;
2221
2222 if (phi->ssaRep->defs[0] == mir->ssaRep->uses[0] &&
2223 phi->ssaRep->uses[1] == mir->ssaRep->defs[0]) {
2224 bool deltaIsConstant = false;
2225 int deltaValue;
2226
2227 switch (mir->dalvikInsn.opcode) {
2228 case OP_ADD_INT:
2229 if (dvmIsBitSet(isConstantV,
2230 mir->ssaRep->uses[1])) {
2231 deltaValue =
2232 cUnit->constantValues[mir->ssaRep->uses[1]];
2233 deltaIsConstant = true;
2234 }
2235 break;
2236 case OP_SUB_INT:
2237 if (dvmIsBitSet(isConstantV,
2238 mir->ssaRep->uses[1])) {
2239 deltaValue =
2240 -cUnit->constantValues[mir->ssaRep->uses[1]];
2241 deltaIsConstant = true;
2242 }
2243 break;
2244 case OP_ADD_INT_LIT8:
2245 deltaValue = mir->dalvikInsn.vC;
2246 deltaIsConstant = true;
2247 break;
2248 default:
2249 break;
2250 }
2251 if (deltaIsConstant) {
2252 dvmSetBit(isIndVarV, mir->ssaRep->uses[0]);
2253 InductionVariableInfo *ivInfo = (InductionVariableInfo *)
2254 dvmCompilerNew(sizeof(InductionVariableInfo),
2255 false);
2256
2257 ivInfo->ssaReg = mir->ssaRep->uses[0];
2258 ivInfo->basicSSAReg = mir->ssaRep->uses[0];
2259 ivInfo->m = 1; // always 1 to basic iv
2260 ivInfo->c = 0; // N/A to basic iv
2261 ivInfo->inc = deltaValue;
2262 dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
2263 cUnit->loopAnalysis->numBasicIV++;
2264 break;
2265 }
2266 }
2267 }
2268 }
2269
2270 /* Find dependent induction variable now */
2271 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
2272 int dfAttributes =
2273 dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
2274
2275 if (!(dfAttributes & DF_IS_LINEAR)) continue;
2276
2277 /* Skip already identified induction variables */
2278 if (dvmIsBitSet(isIndVarV, mir->ssaRep->defs[0])) continue;
2279
2280 /*
2281 * For a dependent induction variable:
2282 * 1) use[0] should be an induction variable (basic/dependent)
2283 * 2) operand2 should be a constant
2284 */
2285 if (dvmIsBitSet(isIndVarV, mir->ssaRep->uses[0])) {
2286 int srcDalvikReg = dvmConvertSSARegToDalvik(cUnit,
2287 mir->ssaRep->uses[0]);
2288 int dstDalvikReg = dvmConvertSSARegToDalvik(cUnit,
2289 mir->ssaRep->defs[0]);
2290
2291 bool cIsConstant = false;
2292 int c = 0;
2293
2294 switch (mir->dalvikInsn.opcode) {
2295 case OP_ADD_INT:
2296 if (dvmIsBitSet(isConstantV,
2297 mir->ssaRep->uses[1])) {
2298 c = cUnit->constantValues[mir->ssaRep->uses[1]];
2299 cIsConstant = true;
2300 }
2301 break;
2302 case OP_SUB_INT:
2303 if (dvmIsBitSet(isConstantV,
2304 mir->ssaRep->uses[1])) {
2305 c = -cUnit->constantValues[mir->ssaRep->uses[1]];
2306 cIsConstant = true;
2307 }
2308 break;
2309 case OP_ADD_INT_LIT8:
2310 c = mir->dalvikInsn.vC;
2311 cIsConstant = true;
2312 break;
2313 default:
2314 break;
2315 }
2316
2317 /* Ignore the update to the basic induction variable itself */
2318 if (DECODE_REG(srcDalvikReg) == DECODE_REG(dstDalvikReg)) {
2319 cUnit->loopAnalysis->ssaBIV = mir->ssaRep->defs[0];
2320 cIsConstant = false;
2321 }
2322
2323 if (cIsConstant) {
2324 unsigned int i;
2325 dvmSetBit(isIndVarV, mir->ssaRep->defs[0]);
2326 InductionVariableInfo *ivInfo = (InductionVariableInfo *)
2327 dvmCompilerNew(sizeof(InductionVariableInfo),
2328 false);
2329 InductionVariableInfo *ivInfoOld = NULL ;
2330
2331 for (i = 0; i < ivList->numUsed; i++) {
2332 ivInfoOld = (InductionVariableInfo *) ivList->elemList[i];
2333 if (ivInfoOld->ssaReg == mir->ssaRep->uses[0]) break;
2334 }
2335
2336 /* Guaranteed to find an element */
2337 assert(i < ivList->numUsed);
2338
2339 ivInfo->ssaReg = mir->ssaRep->defs[0];
2340 ivInfo->basicSSAReg = ivInfoOld->basicSSAReg;
2341 ivInfo->m = ivInfoOld->m;
2342 ivInfo->c = c + ivInfoOld->c;
2343 ivInfo->inc = ivInfoOld->inc;
2344 dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
2345 }
2346 }
2347 }
2348 return true;
2349 }
2350
2351 /* Setup the basic data structures for SSA conversion */
dvmInitializeSSAConversion(CompilationUnit * cUnit)2352 void dvmInitializeSSAConversion(CompilationUnit *cUnit)
2353 {
2354 int i;
2355 int numDalvikReg = cUnit->method->registersSize;
2356
2357 cUnit->ssaToDalvikMap = (GrowableList *)dvmCompilerNew(sizeof(GrowableList),
2358 false);
2359 dvmInitGrowableList(cUnit->ssaToDalvikMap, numDalvikReg);
2360
2361 /*
2362 * Initial number of SSA registers is equal to the number of Dalvik
2363 * registers.
2364 */
2365 cUnit->numSSARegs = numDalvikReg;
2366
2367 /*
2368 * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
2369 * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
2370 * into "(0 << 16) | i"
2371 */
2372 for (i = 0; i < numDalvikReg; i++) {
2373 dvmInsertGrowableList(cUnit->ssaToDalvikMap, ENCODE_REG_SUB(i, 0));
2374 }
2375
2376 /*
2377 * Initialize the DalvikToSSAMap map. The low 16 bit is the SSA register id,
2378 * while the high 16 bit is the current subscript. The original Dalvik
2379 * register N is mapped to SSA register N with subscript 0.
2380 */
2381 cUnit->dalvikToSSAMap = (int *)dvmCompilerNew(sizeof(int) * numDalvikReg,
2382 false);
2383 for (i = 0; i < numDalvikReg; i++) {
2384 cUnit->dalvikToSSAMap[i] = i;
2385 }
2386
2387 /*
2388 * Allocate the BasicBlockDataFlow structure for the entry and code blocks
2389 */
2390 GrowableListIterator iterator;
2391
2392 dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
2393
2394 while (true) {
2395 BasicBlock *bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
2396 if (bb == NULL) break;
2397 if (bb->hidden == true) continue;
2398 if (bb->blockType == kDalvikByteCode ||
2399 bb->blockType == kEntryBlock ||
2400 bb->blockType == kExitBlock) {
2401 bb->dataFlowInfo = (BasicBlockDataFlow *)
2402 dvmCompilerNew(sizeof(BasicBlockDataFlow),
2403 true);
2404 }
2405 }
2406 }
2407
2408 /* Clear the visited flag for each BB */
dvmCompilerClearVisitedFlag(struct CompilationUnit * cUnit,struct BasicBlock * bb)2409 bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
2410 struct BasicBlock *bb)
2411 {
2412 bb->visited = false;
2413 return true;
2414 }
2415
dvmCompilerDataFlowAnalysisDispatcher(CompilationUnit * cUnit,bool (* func)(CompilationUnit *,BasicBlock *),DataFlowAnalysisMode dfaMode,bool isIterative)2416 void dvmCompilerDataFlowAnalysisDispatcher(CompilationUnit *cUnit,
2417 bool (*func)(CompilationUnit *, BasicBlock *),
2418 DataFlowAnalysisMode dfaMode,
2419 bool isIterative)
2420 {
2421 bool change = true;
2422
2423 while (change) {
2424 change = false;
2425
2426 /* Scan all blocks and perform the operations specified in func */
2427 if (dfaMode == kAllNodes) {
2428 GrowableListIterator iterator;
2429 dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
2430 while (true) {
2431 BasicBlock *bb =
2432 (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
2433 if (bb == NULL) break;
2434 if (bb->hidden == true) continue;
2435 change |= (*func)(cUnit, bb);
2436 }
2437 }
2438 /*
2439 * Scan all reachable blocks and perform the operations specified in
2440 * func.
2441 */
2442 else if (dfaMode == kReachableNodes) {
2443 int numReachableBlocks = cUnit->numReachableBlocks;
2444 int idx;
2445 const GrowableList *blockList = &cUnit->blockList;
2446
2447 for (idx = 0; idx < numReachableBlocks; idx++) {
2448 int blockIdx = cUnit->dfsOrder.elemList[idx];
2449 BasicBlock *bb =
2450 (BasicBlock *) dvmGrowableListGetElement(blockList,
2451 blockIdx);
2452 change |= (*func)(cUnit, bb);
2453 }
2454 }
2455 /*
2456 * Scan all reachable blocks by the pre-order in the depth-first-search
2457 * CFG and perform the operations specified in func.
2458 */
2459 else if (dfaMode == kPreOrderDFSTraversal) {
2460 int numReachableBlocks = cUnit->numReachableBlocks;
2461 int idx;
2462 const GrowableList *blockList = &cUnit->blockList;
2463
2464 for (idx = 0; idx < numReachableBlocks; idx++) {
2465 int dfsIdx = cUnit->dfsOrder.elemList[idx];
2466 BasicBlock *bb =
2467 (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
2468 change |= (*func)(cUnit, bb);
2469 }
2470 }
2471 /*
2472 * Scan all reachable blocks by the post-order in the depth-first-search
2473 * CFG and perform the operations specified in func.
2474 */
2475 else if (dfaMode == kPostOrderDFSTraversal) {
2476 int numReachableBlocks = cUnit->numReachableBlocks;
2477 int idx;
2478 const GrowableList *blockList = &cUnit->blockList;
2479
2480 for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
2481 int dfsIdx = cUnit->dfsOrder.elemList[idx];
2482 BasicBlock *bb =
2483 (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
2484 change |= (*func)(cUnit, bb);
2485 }
2486 }
2487 /*
2488 * Scan all reachable blocks by the post-order in the dominator tree
2489 * and perform the operations specified in func.
2490 */
2491 else if (dfaMode == kPostOrderDOMTraversal) {
2492 int numReachableBlocks = cUnit->numReachableBlocks;
2493 int idx;
2494 const GrowableList *blockList = &cUnit->blockList;
2495
2496 for (idx = 0; idx < numReachableBlocks; idx++) {
2497 int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
2498 BasicBlock *bb =
2499 (BasicBlock *) dvmGrowableListGetElement(blockList, domIdx);
2500 change |= (*func)(cUnit, bb);
2501 }
2502 }
2503 /* If isIterative is false, exit the loop after the first iteration */
2504 change &= isIterative;
2505 }
2506 }
2507
2508 /* Main entry point to do SSA conversion for non-loop traces */
dvmCompilerNonLoopAnalysis(CompilationUnit * cUnit)2509 void dvmCompilerNonLoopAnalysis(CompilationUnit *cUnit)
2510 {
2511 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion,
2512 kAllNodes,
2513 false /* isIterative */);
2514 }
2515