• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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