OSDN Git Service

9a2e5c0556df0e922387589be350e49924d6559e
[android-x86/dalvik.git] / vm / compiler / Dataflow.c
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
21 /*
22  * Main table containing data flow attributes for each bytecode. The first
23  * 256 entries are for Dalvik bytecode instructions, where extended opcode at
24  * the MIR level are appended afterwards.
25  *
26  * TODO - many optimization flags are incomplete - they will only limit the
27  * scope of optimizations but will not cause mis-optimizations.
28  */
29 int dvmCompilerDataFlowAttributes[MIR_OP_LAST] = {
30     // 00 OP_NOP
31     DF_NOP,
32
33     // 01 OP_MOVE vA, vB
34     DF_DA | DF_UB | DF_IS_MOVE,
35
36     // 02 OP_MOVE_FROM16 vAA, vBBBB
37     DF_DA | DF_UB | DF_IS_MOVE,
38
39     // 03 OP_MOVE_16 vAAAA, vBBBB
40     DF_DA | DF_UB | DF_IS_MOVE,
41
42     // 04 OP_MOVE_WIDE vA, vB
43     DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
44
45     // 05 OP_MOVE_WIDE_FROM16 vAA, vBBBB
46     DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
47
48     // 06 OP_MOVE_WIDE_16 vAAAA, vBBBB
49     DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
50
51     // 07 OP_MOVE_OBJECT vA, vB
52     DF_DA | DF_UB | DF_IS_MOVE,
53
54     // 08 OP_MOVE_OBJECT_FROM16 vAA, vBBBB
55     DF_DA | DF_UB | DF_IS_MOVE,
56
57     // 09 OP_MOVE_OBJECT_16 vAAAA, vBBBB
58     DF_DA | DF_UB | DF_IS_MOVE,
59
60     // 0A OP_MOVE_RESULT vAA
61     DF_DA,
62
63     // 0B OP_MOVE_RESULT_WIDE vAA
64     DF_DA_WIDE,
65
66     // 0C OP_MOVE_RESULT_OBJECT vAA
67     DF_DA,
68
69     // 0D OP_MOVE_EXCEPTION vAA
70     DF_DA,
71
72     // 0E OP_RETURN_VOID
73     DF_NOP,
74
75     // 0F OP_RETURN vAA
76     DF_UA,
77
78     // 10 OP_RETURN_WIDE vAA
79     DF_UA_WIDE,
80
81     // 11 OP_RETURN_OBJECT vAA
82     DF_UA,
83
84     // 12 OP_CONST_4 vA, #+B
85     DF_DA | DF_SETS_CONST,
86
87     // 13 OP_CONST_16 vAA, #+BBBB
88     DF_DA | DF_SETS_CONST,
89
90     // 14 OP_CONST vAA, #+BBBBBBBB
91     DF_DA | DF_SETS_CONST,
92
93     // 15 OP_CONST_HIGH16 VAA, #+BBBB0000
94     DF_DA | DF_SETS_CONST,
95
96     // 16 OP_CONST_WIDE_16 vAA, #+BBBB
97     DF_DA_WIDE | DF_SETS_CONST,
98
99     // 17 OP_CONST_WIDE_32 vAA, #+BBBBBBBB
100     DF_DA_WIDE | DF_SETS_CONST,
101
102     // 18 OP_CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
103     DF_DA_WIDE | DF_SETS_CONST,
104
105     // 19 OP_CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
106     DF_DA_WIDE | DF_SETS_CONST,
107
108     // 1A OP_CONST_STRING vAA, string@BBBB
109     DF_DA,
110
111     // 1B OP_CONST_STRING_JUMBO vAA, string@BBBBBBBB
112     DF_DA,
113
114     // 1C OP_CONST_CLASS vAA, type@BBBB
115     DF_DA,
116
117     // 1D OP_MONITOR_ENTER vAA
118     DF_UA,
119
120     // 1E OP_MONITOR_EXIT vAA
121     DF_UA,
122
123     // 1F OP_CHECK_CAST vAA, type@BBBB
124     DF_UA,
125
126     // 20 OP_INSTANCE_OF vA, vB, type@CCCC
127     DF_DA | DF_UB,
128
129     // 21 OP_ARRAY_LENGTH vA, vB
130     DF_DA | DF_UB,
131
132     // 22 OP_NEW_INSTANCE vAA, type@BBBB
133     DF_DA,
134
135     // 23 OP_NEW_ARRAY vA, vB, type@CCCC
136     DF_DA | DF_UB,
137
138     // 24 OP_FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
139     DF_FORMAT_35C,
140
141     // 25 OP_FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
142     DF_FORMAT_3RC,
143
144     // 26 OP_FILL_ARRAY_DATA vAA, +BBBBBBBB
145     DF_UA,
146
147     // 27 OP_THROW vAA
148     DF_UA,
149
150     // 28 OP_GOTO
151     DF_NOP,
152
153     // 29 OP_GOTO_16
154     DF_NOP,
155
156     // 2A OP_GOTO_32
157     DF_NOP,
158
159     // 2B OP_PACKED_SWITCH vAA, +BBBBBBBB
160     DF_UA,
161
162     // 2C OP_SPARSE_SWITCH vAA, +BBBBBBBB
163     DF_UA,
164
165     // 2D OP_CMPL_FLOAT vAA, vBB, vCC
166     DF_DA | DF_UB | DF_UC,
167
168     // 2E OP_CMPG_FLOAT vAA, vBB, vCC
169     DF_DA | DF_UB | DF_UC,
170
171     // 2F OP_CMPL_DOUBLE vAA, vBB, vCC
172     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
173
174     // 30 OP_CMPG_DOUBLE vAA, vBB, vCC
175     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
176
177     // 31 OP_CMP_LONG vAA, vBB, vCC
178     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
179
180     // 32 OP_IF_EQ vA, vB, +CCCC
181     DF_UA | DF_UB,
182
183     // 33 OP_IF_NE vA, vB, +CCCC
184     DF_UA | DF_UB,
185
186     // 34 OP_IF_LT vA, vB, +CCCC
187     DF_UA | DF_UB,
188
189     // 35 OP_IF_GE vA, vB, +CCCC
190     DF_UA | DF_UB,
191
192     // 36 OP_IF_GT vA, vB, +CCCC
193     DF_UA | DF_UB,
194
195     // 37 OP_IF_LE vA, vB, +CCCC
196     DF_UA | DF_UB,
197
198
199     // 38 OP_IF_EQZ vAA, +BBBB
200     DF_UA,
201
202     // 39 OP_IF_NEZ vAA, +BBBB
203     DF_UA,
204
205     // 3A OP_IF_LTZ vAA, +BBBB
206     DF_UA,
207
208     // 3B OP_IF_GEZ vAA, +BBBB
209     DF_UA,
210
211     // 3C OP_IF_GTZ vAA, +BBBB
212     DF_UA,
213
214     // 3D OP_IF_LEZ vAA, +BBBB
215     DF_UA,
216
217     // 3E OP_UNUSED_3E
218     DF_NOP,
219
220     // 3F OP_UNUSED_3F
221     DF_NOP,
222
223     // 40 OP_UNUSED_40
224     DF_NOP,
225
226     // 41 OP_UNUSED_41
227     DF_NOP,
228
229     // 42 OP_UNUSED_42
230     DF_NOP,
231
232     // 43 OP_UNUSED_43
233     DF_NOP,
234
235     // 44 OP_AGET vAA, vBB, vCC
236     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
237
238     // 45 OP_AGET_WIDE vAA, vBB, vCC
239     DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
240
241     // 46 OP_AGET_OBJECT vAA, vBB, vCC
242     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
243
244     // 47 OP_AGET_BOOLEAN vAA, vBB, vCC
245     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
246
247     // 48 OP_AGET_BYTE vAA, vBB, vCC
248     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
249
250     // 49 OP_AGET_CHAR vAA, vBB, vCC
251     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
252
253     // 4A OP_AGET_SHORT vAA, vBB, vCC
254     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0,
255
256     // 4B OP_APUT vAA, vBB, vCC
257     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1,
258
259     // 4C OP_APUT_WIDE vAA, vBB, vCC
260     DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_2,
261
262     // 4D OP_APUT_OBJECT vAA, vBB, vCC
263     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1,
264
265     // 4E OP_APUT_BOOLEAN vAA, vBB, vCC
266     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1,
267
268     // 4F OP_APUT_BYTE vAA, vBB, vCC
269     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1,
270
271     // 50 OP_APUT_CHAR vAA, vBB, vCC
272     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1,
273
274     // 51 OP_APUT_SHORT vAA, vBB, vCC
275     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1,
276
277     // 52 OP_IGET vA, vB, field@CCCC
278     DF_DA | DF_UB,
279
280     // 53 OP_IGET_WIDE vA, vB, field@CCCC
281     DF_DA_WIDE | DF_UB,
282
283     // 54 OP_IGET_OBJECT vA, vB, field@CCCC
284     DF_DA | DF_UB,
285
286     // 55 OP_IGET_BOOLEAN vA, vB, field@CCCC
287     DF_DA | DF_UB,
288
289     // 56 OP_IGET_BYTE vA, vB, field@CCCC
290     DF_DA | DF_UB,
291
292     // 57 OP_IGET_CHAR vA, vB, field@CCCC
293     DF_DA | DF_UB,
294
295     // 58 OP_IGET_SHORT vA, vB, field@CCCC
296     DF_DA | DF_UB,
297
298     // 59 OP_IPUT vA, vB, field@CCCC
299     DF_UA | DF_UB,
300
301     // 5A OP_IPUT_WIDE vA, vB, field@CCCC
302     DF_UA_WIDE | DF_UB,
303
304     // 5B OP_IPUT_OBJECT vA, vB, field@CCCC
305     DF_UA | DF_UB,
306
307     // 5C OP_IPUT_BOOLEAN vA, vB, field@CCCC
308     DF_UA | DF_UB,
309
310     // 5D OP_IPUT_BYTE vA, vB, field@CCCC
311     DF_UA | DF_UB,
312
313     // 5E OP_IPUT_CHAR vA, vB, field@CCCC
314     DF_UA | DF_UB,
315
316     // 5F OP_IPUT_SHORT vA, vB, field@CCCC
317     DF_UA | DF_UB,
318
319     // 60 OP_SGET vAA, field@BBBB
320     DF_DA,
321
322     // 61 OP_SGET_WIDE vAA, field@BBBB
323     DF_DA_WIDE,
324
325     // 62 OP_SGET_OBJECT vAA, field@BBBB
326     DF_DA,
327
328     // 63 OP_SGET_BOOLEAN vAA, field@BBBB
329     DF_DA,
330
331     // 64 OP_SGET_BYTE vAA, field@BBBB
332     DF_DA,
333
334     // 65 OP_SGET_CHAR vAA, field@BBBB
335     DF_DA,
336
337     // 66 OP_SGET_SHORT vAA, field@BBBB
338     DF_DA,
339
340     // 67 OP_SPUT vAA, field@BBBB
341     DF_UA,
342
343     // 68 OP_SPUT_WIDE vAA, field@BBBB
344     DF_UA_WIDE,
345
346     // 69 OP_SPUT_OBJECT vAA, field@BBBB
347     DF_UA,
348
349     // 6A OP_SPUT_BOOLEAN vAA, field@BBBB
350     DF_UA,
351
352     // 6B OP_SPUT_BYTE vAA, field@BBBB
353     DF_UA,
354
355     // 6C OP_SPUT_CHAR vAA, field@BBBB
356     DF_UA,
357
358     // 6D OP_SPUT_SHORT vAA, field@BBBB
359     DF_UA,
360
361     // 6E OP_INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
362     DF_FORMAT_35C,
363
364     // 6F OP_INVOKE_SUPER {vD, vE, vF, vG, vA}
365     DF_FORMAT_35C,
366
367     // 70 OP_INVOKE_DIRECT {vD, vE, vF, vG, vA}
368     DF_FORMAT_35C,
369
370     // 71 OP_INVOKE_STATIC {vD, vE, vF, vG, vA}
371     DF_FORMAT_35C,
372
373     // 72 OP_INVOKE_INTERFACE {vD, vE, vF, vG, vA}
374     DF_FORMAT_35C,
375
376     // 73 OP_UNUSED_73
377     DF_NOP,
378
379     // 74 OP_INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
380     DF_FORMAT_3RC,
381
382     // 75 OP_INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
383     DF_FORMAT_3RC,
384
385     // 76 OP_INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
386     DF_FORMAT_3RC,
387
388     // 77 OP_INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
389     DF_FORMAT_3RC,
390
391     // 78 OP_INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
392     DF_FORMAT_3RC,
393
394     // 79 OP_UNUSED_79
395     DF_NOP,
396
397     // 7A OP_UNUSED_7A
398     DF_NOP,
399
400     // 7B OP_NEG_INT vA, vB
401     DF_DA | DF_UB,
402
403     // 7C OP_NOT_INT vA, vB
404     DF_DA | DF_UB,
405
406     // 7D OP_NEG_LONG vA, vB
407     DF_DA_WIDE | DF_UB_WIDE,
408
409     // 7E OP_NOT_LONG vA, vB
410     DF_DA_WIDE | DF_UB_WIDE,
411
412     // 7F OP_NEG_FLOAT vA, vB
413     DF_DA | DF_UB,
414
415     // 80 OP_NEG_DOUBLE vA, vB
416     DF_DA_WIDE | DF_UB_WIDE,
417
418     // 81 OP_INT_TO_LONG vA, vB
419     DF_DA_WIDE | DF_UB,
420
421     // 82 OP_INT_TO_FLOAT vA, vB
422     DF_DA | DF_UB,
423
424     // 83 OP_INT_TO_DOUBLE vA, vB
425     DF_DA_WIDE | DF_UB,
426
427     // 84 OP_LONG_TO_INT vA, vB
428     DF_DA | DF_UB_WIDE,
429
430     // 85 OP_LONG_TO_FLOAT vA, vB
431     DF_DA | DF_UB_WIDE,
432
433     // 86 OP_LONG_TO_DOUBLE vA, vB
434     DF_DA_WIDE | DF_UB_WIDE,
435
436     // 87 OP_FLOAT_TO_INT vA, vB
437     DF_DA | DF_UB,
438
439     // 88 OP_FLOAT_TO_LONG vA, vB
440     DF_DA_WIDE | DF_UB,
441
442     // 89 OP_FLOAT_TO_DOUBLE vA, vB
443     DF_DA_WIDE | DF_UB,
444
445     // 8A OP_DOUBLE_TO_INT vA, vB
446     DF_DA | DF_UB_WIDE,
447
448     // 8B OP_DOUBLE_TO_LONG vA, vB
449     DF_DA_WIDE | DF_UB_WIDE,
450
451     // 8C OP_DOUBLE_TO_FLOAT vA, vB
452     DF_DA | DF_UB_WIDE,
453
454     // 8D OP_INT_TO_BYTE vA, vB
455     DF_DA | DF_UB,
456
457     // 8E OP_INT_TO_CHAR vA, vB
458     DF_DA | DF_UB,
459
460     // 8F OP_INT_TO_SHORT vA, vB
461     DF_DA | DF_UB,
462
463     // 90 OP_ADD_INT vAA, vBB, vCC
464     DF_DA | DF_UB | DF_UC | DF_IS_LINEAR,
465
466     // 91 OP_SUB_INT vAA, vBB, vCC
467     DF_DA | DF_UB | DF_UC | DF_IS_LINEAR,
468
469     // 92 OP_MUL_INT vAA, vBB, vCC
470     DF_DA | DF_UB | DF_UC,
471
472     // 93 OP_DIV_INT vAA, vBB, vCC
473     DF_DA | DF_UB | DF_UC,
474
475     // 94 OP_REM_INT vAA, vBB, vCC
476     DF_DA | DF_UB | DF_UC,
477
478     // 95 OP_AND_INT vAA, vBB, vCC
479     DF_DA | DF_UB | DF_UC,
480
481     // 96 OP_OR_INT vAA, vBB, vCC
482     DF_DA | DF_UB | DF_UC,
483
484     // 97 OP_XOR_INT vAA, vBB, vCC
485     DF_DA | DF_UB | DF_UC,
486
487     // 98 OP_SHL_INT vAA, vBB, vCC
488     DF_DA | DF_UB | DF_UC,
489
490     // 99 OP_SHR_INT vAA, vBB, vCC
491     DF_DA | DF_UB | DF_UC,
492
493     // 9A OP_USHR_INT vAA, vBB, vCC
494     DF_DA | DF_UB | DF_UC,
495
496     // 9B OP_ADD_LONG vAA, vBB, vCC
497     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
498
499     // 9C OP_SUB_LONG vAA, vBB, vCC
500     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
501
502     // 9D OP_MUL_LONG vAA, vBB, vCC
503     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
504
505     // 9E OP_DIV_LONG vAA, vBB, vCC
506     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
507
508     // 9F OP_REM_LONG vAA, vBB, vCC
509     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
510
511     // A0 OP_AND_LONG vAA, vBB, vCC
512     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
513
514     // A1 OP_OR_LONG vAA, vBB, vCC
515     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
516
517     // A2 OP_XOR_LONG vAA, vBB, vCC
518     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
519
520     // A3 OP_SHL_LONG vAA, vBB, vCC
521     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
522
523     // A4 OP_SHR_LONG vAA, vBB, vCC
524     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
525
526     // A5 OP_USHR_LONG vAA, vBB, vCC
527     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
528
529     // A6 OP_ADD_FLOAT vAA, vBB, vCC
530     DF_DA | DF_UB | DF_UC,
531
532     // A7 OP_SUB_FLOAT vAA, vBB, vCC
533     DF_DA | DF_UB | DF_UC,
534
535     // A8 OP_MUL_FLOAT vAA, vBB, vCC
536     DF_DA | DF_UB | DF_UC,
537
538     // A9 OP_DIV_FLOAT vAA, vBB, vCC
539     DF_DA | DF_UB | DF_UC,
540
541     // AA OP_REM_FLOAT vAA, vBB, vCC
542     DF_DA | DF_UB | DF_UC,
543
544     // AB OP_ADD_DOUBLE vAA, vBB, vCC
545     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
546
547     // AC OP_SUB_DOUBLE vAA, vBB, vCC
548     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
549
550     // AD OP_MUL_DOUBLE vAA, vBB, vCC
551     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
552
553     // AE OP_DIV_DOUBLE vAA, vBB, vCC
554     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
555
556     // AF OP_REM_DOUBLE vAA, vBB, vCC
557     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
558
559     // B0 OP_ADD_INT_2ADDR vA, vB
560     DF_DA | DF_UA | DF_UB,
561
562     // B1 OP_SUB_INT_2ADDR vA, vB
563     DF_DA | DF_UA | DF_UB,
564
565     // B2 OP_MUL_INT_2ADDR vA, vB
566     DF_DA | DF_UA | DF_UB,
567
568     // B3 OP_DIV_INT_2ADDR vA, vB
569     DF_DA | DF_UA | DF_UB,
570
571     // B4 OP_REM_INT_2ADDR vA, vB
572     DF_DA | DF_UA | DF_UB,
573
574     // B5 OP_AND_INT_2ADDR vA, vB
575     DF_DA | DF_UA | DF_UB,
576
577     // B6 OP_OR_INT_2ADDR vA, vB
578     DF_DA | DF_UA | DF_UB,
579
580     // B7 OP_XOR_INT_2ADDR vA, vB
581     DF_DA | DF_UA | DF_UB,
582
583     // B8 OP_SHL_INT_2ADDR vA, vB
584     DF_DA | DF_UA | DF_UB,
585
586     // B9 OP_SHR_INT_2ADDR vA, vB
587     DF_DA | DF_UA | DF_UB,
588
589     // BA OP_USHR_INT_2ADDR vA, vB
590     DF_DA | DF_UA | DF_UB,
591
592     // BB OP_ADD_LONG_2ADDR vA, vB
593     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
594
595     // BC OP_SUB_LONG_2ADDR vA, vB
596     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
597
598     // BD OP_MUL_LONG_2ADDR vA, vB
599     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
600
601     // BE OP_DIV_LONG_2ADDR vA, vB
602     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
603
604     // BF OP_REM_LONG_2ADDR vA, vB
605     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
606
607     // C0 OP_AND_LONG_2ADDR vA, vB
608     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
609
610     // C1 OP_OR_LONG_2ADDR vA, vB
611     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
612
613     // C2 OP_XOR_LONG_2ADDR vA, vB
614     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
615
616     // C3 OP_SHL_LONG_2ADDR vA, vB
617     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
618
619     // C4 OP_SHR_LONG_2ADDR vA, vB
620     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
621
622     // C5 OP_USHR_LONG_2ADDR vA, vB
623     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
624
625     // C6 OP_ADD_FLOAT_2ADDR vA, vB
626     DF_DA | DF_UA | DF_UB,
627
628     // C7 OP_SUB_FLOAT_2ADDR vA, vB
629     DF_DA | DF_UA | DF_UB,
630
631     // C8 OP_MUL_FLOAT_2ADDR vA, vB
632     DF_DA | DF_UA | DF_UB,
633
634     // C9 OP_DIV_FLOAT_2ADDR vA, vB
635     DF_DA | DF_UA | DF_UB,
636
637     // CA OP_REM_FLOAT_2ADDR vA, vB
638     DF_DA | DF_UA | DF_UB,
639
640     // CB OP_ADD_DOUBLE_2ADDR vA, vB
641     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
642
643     // CC OP_SUB_DOUBLE_2ADDR vA, vB
644     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
645
646     // CD OP_MUL_DOUBLE_2ADDR vA, vB
647     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
648
649     // CE OP_DIV_DOUBLE_2ADDR vA, vB
650     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
651
652     // CF OP_REM_DOUBLE_2ADDR vA, vB
653     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
654
655     // D0 OP_ADD_INT_LIT16 vA, vB, #+CCCC
656     DF_DA | DF_UB,
657
658     // D1 OP_RSUB_INT vA, vB, #+CCCC
659     DF_DA | DF_UB,
660
661     // D2 OP_MUL_INT_LIT16 vA, vB, #+CCCC
662     DF_DA | DF_UB,
663
664     // D3 OP_DIV_INT_LIT16 vA, vB, #+CCCC
665     DF_DA | DF_UB,
666
667     // D4 OP_REM_INT_LIT16 vA, vB, #+CCCC
668     DF_DA | DF_UB,
669
670     // D5 OP_AND_INT_LIT16 vA, vB, #+CCCC
671     DF_DA | DF_UB,
672
673     // D6 OP_OR_INT_LIT16 vA, vB, #+CCCC
674     DF_DA | DF_UB,
675
676     // D7 OP_XOR_INT_LIT16 vA, vB, #+CCCC
677     DF_DA | DF_UB,
678
679     // D8 OP_ADD_INT_LIT8 vAA, vBB, #+CC
680     DF_DA | DF_UB | DF_IS_LINEAR,
681
682     // D9 OP_RSUB_INT_LIT8 vAA, vBB, #+CC
683     DF_DA | DF_UB,
684
685     // DA OP_MUL_INT_LIT8 vAA, vBB, #+CC
686     DF_DA | DF_UB,
687
688     // DB OP_DIV_INT_LIT8 vAA, vBB, #+CC
689     DF_DA | DF_UB,
690
691     // DC OP_REM_INT_LIT8 vAA, vBB, #+CC
692     DF_DA | DF_UB,
693
694     // DD OP_AND_INT_LIT8 vAA, vBB, #+CC
695     DF_DA | DF_UB,
696
697     // DE OP_OR_INT_LIT8 vAA, vBB, #+CC
698     DF_DA | DF_UB,
699
700     // DF OP_XOR_INT_LIT8 vAA, vBB, #+CC
701     DF_DA | DF_UB,
702
703     // E0 OP_SHL_INT_LIT8 vAA, vBB, #+CC
704     DF_DA | DF_UB,
705
706     // E1 OP_SHR_INT_LIT8 vAA, vBB, #+CC
707     DF_DA | DF_UB,
708
709     // E2 OP_USHR_INT_LIT8 vAA, vBB, #+CC
710     DF_DA | DF_UB,
711
712     // E3 OP_UNUSED_E3
713     DF_NOP,
714
715     // E4 OP_UNUSED_E4
716     DF_NOP,
717
718     // E5 OP_UNUSED_E5
719     DF_NOP,
720
721     // E6 OP_UNUSED_E6
722     DF_NOP,
723
724     // E7 OP_UNUSED_E7
725     DF_NOP,
726
727     // E8 OP_UNUSED_E8
728     DF_NOP,
729
730     // E9 OP_UNUSED_E9
731     DF_NOP,
732
733     // EA OP_UNUSED_EA
734     DF_NOP,
735
736     // EB OP_UNUSED_EB
737     DF_NOP,
738
739     // EC OP_UNUSED_EC
740     DF_NOP,
741
742     // ED OP_THROW_VERIFICATION_ERROR
743     DF_NOP,
744
745     // EE OP_EXECUTE_INLINE
746     DF_FORMAT_35C,
747
748     // EF OP_UNUSED_EF
749     DF_NOP,
750
751     // F0 OP_INVOKE_DIRECT_EMPTY
752     DF_NOP,
753
754     // F1 OP_UNUSED_F1
755     DF_NOP,
756
757     // F2 OP_IGET_QUICK
758     DF_DA | DF_UB,
759
760     // F3 OP_IGET_WIDE_QUICK
761     DF_DA_WIDE | DF_UB,
762
763     // F4 OP_IGET_OBJECT_QUICK
764     DF_DA | DF_UB,
765
766     // F5 OP_IPUT_QUICK
767     DF_UA | DF_UB,
768
769     // F6 OP_IPUT_WIDE_QUICK
770     DF_UA_WIDE | DF_UB,
771
772     // F7 OP_IPUT_OBJECT_QUICK
773     DF_UA | DF_UB,
774
775     // F8 OP_INVOKE_VIRTUAL_QUICK
776     DF_FORMAT_35C,
777
778     // F9 OP_INVOKE_VIRTUAL_QUICK_RANGE
779     DF_FORMAT_3RC,
780
781     // FA OP_INVOKE_SUPER_QUICK
782     DF_FORMAT_35C,
783
784     // FB OP_INVOKE_SUPER_QUICK_RANGE
785     DF_FORMAT_3RC,
786
787     // FC OP_UNUSED_FC
788     DF_NOP,
789
790     // FD OP_UNUSED_FD
791     DF_NOP,
792
793     // FE OP_UNUSED_FE
794     DF_NOP,
795
796     // FF OP_UNUSED_FF
797     DF_NOP,
798
799     // Beginning of extended MIR opcodes
800     // 100 OP_MIR_PHI
801     DF_PHI | DF_DA,
802
803     /*
804      * For extended MIR inserted at the MIR2LIR stage, it is okay to have
805      * undefined values here.
806      */
807 };
808
809 /* Return the Dalvik register/subscript pair of a given SSA register */
810 int dvmConvertSSARegToDalvik(CompilationUnit *cUnit, int ssaReg)
811 {
812       return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
813 }
814
815 /*
816  * Utility function to convert encoded SSA register value into Dalvik register
817  * and subscript pair. Each SSA register can be used to index the
818  * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
819  */
820 char *dvmCompilerGetSSAString(CompilationUnit *cUnit, SSARepresentation *ssaRep)
821 {
822     char buffer[256];
823     char *ret;
824     int i;
825
826     buffer[0] = 0;
827     for (i = 0; i < ssaRep->numDefs; i++) {
828         int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaRep->defs[i]);
829
830         sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ",
831                 ssaRep->defs[i], DECODE_REG(ssa2DalvikValue),
832                 DECODE_SUB(ssa2DalvikValue));
833     }
834
835     if (ssaRep->numDefs) {
836         strcat(buffer, "<- ");
837     }
838
839     for (i = 0; i < ssaRep->numUses; i++) {
840         int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaRep->uses[i]);
841         int len = strlen(buffer);
842
843         if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ",
844                      ssaRep->uses[i], DECODE_REG(ssa2DalvikValue),
845                      DECODE_SUB(ssa2DalvikValue)) >= (250 - len)) {
846             strcat(buffer, "...");
847             break;
848         }
849     }
850
851     int length = strlen(buffer) + 1;
852     ret = dvmCompilerNew(length, false);
853     memcpy(ret, buffer, length);
854     return ret;
855 }
856
857 /* Any register that is used before being defined is considered live-in */
858 static inline void handleLiveInUse(BitVector *useV, BitVector *defV,
859                                    BitVector *liveInV, int dalvikRegId)
860 {
861     dvmCompilerSetBit(useV, dalvikRegId);
862     if (!dvmIsBitSet(defV, dalvikRegId)) {
863         dvmCompilerSetBit(liveInV, dalvikRegId);
864     }
865 }
866
867 /* Mark a reg as being defined */
868 static inline void handleLiveInDef(BitVector *defV, int dalvikRegId)
869 {
870     dvmCompilerSetBit(defV, dalvikRegId);
871 }
872
873 /*
874  * Find out live-in variables for natural loops. Variables that are live-in in
875  * the main loop body are considered to be defined in the entry block.
876  */
877 void dvmCompilerFindLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
878 {
879     MIR *mir;
880     BitVector *useV, *defV, *liveInV;
881
882     if (bb->blockType != DALVIK_BYTECODE &&
883         bb->blockType != ENTRY_BLOCK) {
884         return;
885     }
886
887     useV = bb->dataFlowInfo->useV =
888         dvmCompilerAllocBitVector(cUnit->method->registersSize, false);
889     defV = bb->dataFlowInfo->defV =
890         dvmCompilerAllocBitVector(cUnit->method->registersSize, false);
891     liveInV = bb->dataFlowInfo->liveInV =
892         dvmCompilerAllocBitVector(cUnit->method->registersSize, false);
893
894     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
895         int dfAttributes =
896             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opCode];
897         DecodedInstruction *dInsn = &mir->dalvikInsn;
898
899         if (dfAttributes & DF_HAS_USES) {
900             if (dfAttributes & DF_UA) {
901                 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
902             } else if (dfAttributes & DF_UA_WIDE) {
903                 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
904                 handleLiveInUse(useV, defV, liveInV, dInsn->vA+1);
905             }
906             if (dfAttributes & DF_UB) {
907                 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
908             } else if (dfAttributes & DF_UB_WIDE) {
909                 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
910                 handleLiveInUse(useV, defV, liveInV, dInsn->vB+1);
911             }
912             if (dfAttributes & DF_UC) {
913                 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
914             } else if (dfAttributes & DF_UC_WIDE) {
915                 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
916                 handleLiveInUse(useV, defV, liveInV, dInsn->vC+1);
917             }
918         }
919         if (dfAttributes & DF_HAS_DEFS) {
920             handleLiveInDef(defV, dInsn->vA);
921             if (dfAttributes & DF_DA_WIDE) {
922                 handleLiveInDef(defV, dInsn->vA+1);
923             }
924         }
925     }
926 }
927
928 /* Find out the latest SSA register for a given Dalvik register */
929 static void handleSSAUse(CompilationUnit *cUnit, int *uses, int dalvikReg,
930                          int regIndex)
931 {
932     int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
933     int ssaReg = DECODE_REG(encodedValue);
934     uses[regIndex] = ssaReg;
935 }
936
937 /* Setup a new SSA register for a given Dalvik register */
938 static void handleSSADef(CompilationUnit *cUnit, int *defs, int dalvikReg,
939                          int regIndex)
940 {
941     int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
942     int ssaReg = cUnit->numSSARegs++;
943     /* Bump up the subscript */
944     int dalvikSub = DECODE_SUB(encodedValue) + 1;
945     int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);
946
947     cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
948
949     int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
950     dvmInsertGrowableList(cUnit->ssaToDalvikMap, (void *) newS2DMapping);
951
952     defs[regIndex] = ssaReg;
953 }
954
955 /* Loop up new SSA names for format_35c instructions */
956 static void dataFlowSSAFormat35C(CompilationUnit *cUnit, MIR *mir)
957 {
958     DecodedInstruction *dInsn = &mir->dalvikInsn;
959     int numUses = dInsn->vA;
960     int i;
961
962     mir->ssaRep->numUses = numUses;
963     mir->ssaRep->uses = dvmCompilerNew(sizeof(int) * numUses, false);
964
965     for (i = 0; i < numUses; i++) {
966         handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
967     }
968 }
969
970 /* Loop up new SSA names for format_3rc instructions */
971 static void dataFlowSSAFormat3RC(CompilationUnit *cUnit, MIR *mir)
972 {
973     DecodedInstruction *dInsn = &mir->dalvikInsn;
974     int numUses = dInsn->vA;
975     int i;
976
977     mir->ssaRep->numUses = numUses;
978     mir->ssaRep->uses = dvmCompilerNew(sizeof(int) * numUses, false);
979
980     for (i = 0; i < numUses; i++) {
981         handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
982     }
983 }
984
985 /* Entry function to convert a block into SSA representation */
986 void dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
987 {
988     MIR *mir;
989
990     if (bb->blockType != DALVIK_BYTECODE && bb->blockType != ENTRY_BLOCK) {
991         return;
992     }
993
994     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
995         mir->ssaRep = dvmCompilerNew(sizeof(SSARepresentation), true);
996
997         int dfAttributes =
998             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opCode];
999
1000         int numUses = 0;
1001
1002         if (dfAttributes & DF_FORMAT_35C) {
1003             dataFlowSSAFormat35C(cUnit, mir);
1004             continue;
1005         }
1006
1007         if (dfAttributes & DF_FORMAT_3RC) {
1008             dataFlowSSAFormat3RC(cUnit, mir);
1009             continue;
1010         }
1011
1012         if (dfAttributes & DF_HAS_USES) {
1013             if (dfAttributes & DF_UA) {
1014                 numUses++;
1015             } else if (dfAttributes & DF_UA_WIDE) {
1016                 numUses += 2;
1017             }
1018             if (dfAttributes & DF_UB) {
1019                 numUses++;
1020             } else if (dfAttributes & DF_UB_WIDE) {
1021                 numUses += 2;
1022             }
1023             if (dfAttributes & DF_UC) {
1024                 numUses++;
1025             } else if (dfAttributes & DF_UC_WIDE) {
1026                 numUses += 2;
1027             }
1028         }
1029
1030         if (numUses) {
1031             mir->ssaRep->numUses = numUses;
1032             mir->ssaRep->uses = dvmCompilerNew(sizeof(int) * numUses, false);
1033         }
1034
1035         int numDefs = 0;
1036
1037         if (dfAttributes & DF_HAS_DEFS) {
1038             numDefs++;
1039             if (dfAttributes & DF_DA_WIDE) {
1040                 numDefs++;
1041             }
1042         }
1043
1044         if (numDefs) {
1045             mir->ssaRep->numDefs = numDefs;
1046             mir->ssaRep->defs = dvmCompilerNew(sizeof(int) * numDefs, false);
1047         }
1048
1049         DecodedInstruction *dInsn = &mir->dalvikInsn;
1050
1051         if (dfAttributes & DF_HAS_USES) {
1052             numUses = 0;
1053             if (dfAttributes & DF_UA) {
1054                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1055             } else if (dfAttributes & DF_UA_WIDE) {
1056                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
1057                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
1058             }
1059             if (dfAttributes & DF_UB) {
1060                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1061             } else if (dfAttributes & DF_UB_WIDE) {
1062                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
1063                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
1064             }
1065             if (dfAttributes & DF_UC) {
1066                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1067             } else if (dfAttributes & DF_UC_WIDE) {
1068                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
1069                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
1070             }
1071         }
1072         if (dfAttributes & DF_HAS_DEFS) {
1073             handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
1074             if (dfAttributes & DF_DA_WIDE) {
1075                 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
1076             }
1077         }
1078     }
1079
1080     bb->dataFlowInfo->dalvikToSSAMap =
1081         dvmCompilerNew(sizeof(int) * cUnit->method->registersSize, false);
1082
1083     /* Take a snapshot of Dalvik->SSA mapping at the end of each block */
1084     memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
1085            sizeof(int) * cUnit->method->registersSize);
1086 }
1087
1088 /* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
1089 static void setConstant(CompilationUnit *cUnit, int ssaReg, int value)
1090 {
1091     dvmSetBit(cUnit->isConstantV, ssaReg);
1092     cUnit->constantValues[ssaReg] = value;
1093 }
1094
1095 void dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
1096 {
1097     MIR *mir;
1098     BitVector *isConstantV = cUnit->isConstantV;
1099
1100     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1101         int dfAttributes =
1102             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opCode];
1103
1104         int numUses = 0;
1105
1106         DecodedInstruction *dInsn = &mir->dalvikInsn;
1107
1108         if (!(dfAttributes & DF_HAS_DEFS)) continue;
1109
1110         /* Handle instructions that set up constants directly */
1111         if (dfAttributes & DF_SETS_CONST) {
1112             if (dfAttributes & DF_DA) {
1113                 switch (dInsn->opCode) {
1114                     case OP_CONST_4:
1115                     case OP_CONST_16:
1116                     case OP_CONST:
1117                         setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1118                         break;
1119                     case OP_CONST_HIGH16:
1120                         setConstant(cUnit, mir->ssaRep->defs[0],
1121                                     dInsn->vB << 16);
1122                         break;
1123                     default:
1124                         break;
1125                 }
1126             } else if (dfAttributes & DF_DA_WIDE) {
1127                 switch (dInsn->opCode) {
1128                     case OP_CONST_WIDE_16:
1129                     case OP_CONST_WIDE_32:
1130                         setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
1131                         setConstant(cUnit, mir->ssaRep->defs[1], 0);
1132                         break;
1133                     case OP_CONST_WIDE:
1134                         setConstant(cUnit, mir->ssaRep->defs[0],
1135                                     (int) dInsn->vB_wide);
1136                         setConstant(cUnit, mir->ssaRep->defs[1],
1137                                     (int) (dInsn->vB_wide >> 32));
1138                         break;
1139                     case OP_CONST_WIDE_HIGH16:
1140                         setConstant(cUnit, mir->ssaRep->defs[0], 0);
1141                         setConstant(cUnit, mir->ssaRep->defs[1],
1142                                     dInsn->vB << 16);
1143                         break;
1144                     default:
1145                         break;
1146                 }
1147             }
1148         /* Handle instructions that set up constants directly */
1149         } else if (dfAttributes & DF_IS_MOVE) {
1150             int i;
1151
1152             for (i = 0; i < mir->ssaRep->numUses; i++) {
1153                 if (!dvmIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
1154             }
1155             /* Move a register holding a constant to another register */
1156             if (i == mir->ssaRep->numUses) {
1157                 setConstant(cUnit, mir->ssaRep->defs[0],
1158                             cUnit->constantValues[mir->ssaRep->uses[0]]);
1159                 if (dfAttributes & DF_DA_WIDE) {
1160                     setConstant(cUnit, mir->ssaRep->defs[1],
1161                                 cUnit->constantValues[mir->ssaRep->uses[1]]);
1162                 }
1163             }
1164         }
1165     }
1166     /* TODO: implement code to handle arithmetic operations */
1167 }
1168
1169 void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
1170                                        struct BasicBlock *bb)
1171 {
1172     BitVector *isIndVarV = cUnit->loopAnalysis->isIndVarV;
1173     BitVector *isConstantV = cUnit->isConstantV;
1174     GrowableList *ivList = cUnit->loopAnalysis->ivList;
1175     MIR *mir;
1176
1177     if (bb->blockType != DALVIK_BYTECODE &&
1178         bb->blockType != ENTRY_BLOCK) {
1179         return;
1180     }
1181
1182     /* If the bb doesn't have a phi it cannot contain an induction variable */
1183     if (bb->firstMIRInsn == NULL ||
1184         bb->firstMIRInsn->dalvikInsn.opCode != MIR_OP_PHI) {
1185         return;
1186     }
1187
1188     /* Find basic induction variable first */
1189     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1190         int dfAttributes =
1191             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opCode];
1192
1193         if (!(dfAttributes & DF_IS_LINEAR)) continue;
1194
1195         /*
1196          * For a basic induction variable:
1197          *   1) use[0] should belong to the output of a phi node
1198          *   2) def[0] should belong to the input of the same phi node
1199          *   3) the value added/subtracted is a constant
1200          */
1201         MIR *phi;
1202         for (phi = bb->firstMIRInsn; phi; phi = phi->next) {
1203             if (phi->dalvikInsn.opCode != MIR_OP_PHI) break;
1204
1205             if (phi->ssaRep->defs[0] == mir->ssaRep->uses[0] &&
1206                 phi->ssaRep->uses[1] == mir->ssaRep->defs[0]) {
1207                 bool deltaIsConstant = false;
1208                 int deltaValue;
1209
1210                 switch (mir->dalvikInsn.opCode) {
1211                     case OP_ADD_INT:
1212                         if (dvmIsBitSet(isConstantV,
1213                                         mir->ssaRep->uses[1])) {
1214                             deltaValue =
1215                                 cUnit->constantValues[mir->ssaRep->uses[1]];
1216                             deltaIsConstant = true;
1217                         }
1218                         break;
1219                     case OP_SUB_INT:
1220                         if (dvmIsBitSet(isConstantV,
1221                                         mir->ssaRep->uses[1])) {
1222                             deltaValue =
1223                                 -cUnit->constantValues[mir->ssaRep->uses[1]];
1224                             deltaIsConstant = true;
1225                         }
1226                         break;
1227                     case OP_ADD_INT_LIT8:
1228                         deltaValue = mir->dalvikInsn.vC;
1229                         deltaIsConstant = true;
1230                         break;
1231                     default:
1232                         break;
1233                 }
1234                 if (deltaIsConstant) {
1235                     dvmSetBit(isIndVarV, mir->ssaRep->uses[0]);
1236                     InductionVariableInfo *ivInfo =
1237                         dvmCompilerNew(sizeof(InductionVariableInfo),
1238                                        false);
1239
1240                     ivInfo->ssaReg = mir->ssaRep->uses[0];
1241                     ivInfo->basicSSAReg = mir->ssaRep->uses[0];
1242                     ivInfo->m = 1;         // always 1 to basic iv
1243                     ivInfo->c = 0;         // N/A to basic iv
1244                     ivInfo->inc = deltaValue;
1245                     dvmInsertGrowableList(ivList, (void *) ivInfo);
1246                     cUnit->loopAnalysis->numBasicIV++;
1247                     break;
1248                 }
1249             }
1250         }
1251     }
1252
1253     /* Find dependent induction variable now */
1254     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
1255         int dfAttributes =
1256             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opCode];
1257
1258         if (!(dfAttributes & DF_IS_LINEAR)) continue;
1259
1260         /* Skip already identified induction variables */
1261         if (dvmIsBitSet(isIndVarV, mir->ssaRep->defs[0])) continue;
1262
1263         /*
1264          * For a dependent induction variable:
1265          *  1) use[0] should be an induction variable (basic/dependent)
1266          *  2) operand2 should be a constant
1267          */
1268         if (dvmIsBitSet(isIndVarV, mir->ssaRep->uses[0])) {
1269             int srcDalvikReg = dvmConvertSSARegToDalvik(cUnit,
1270                                                         mir->ssaRep->uses[0]);
1271             int dstDalvikReg = dvmConvertSSARegToDalvik(cUnit,
1272                                                         mir->ssaRep->defs[0]);
1273
1274             bool cIsConstant = false;
1275             int c = 0;
1276
1277             switch (mir->dalvikInsn.opCode) {
1278                 case OP_ADD_INT:
1279                     if (dvmIsBitSet(isConstantV,
1280                                     mir->ssaRep->uses[1])) {
1281                         c = cUnit->constantValues[mir->ssaRep->uses[1]];
1282                         cIsConstant = true;
1283                     }
1284                     break;
1285                 case OP_SUB_INT:
1286                     if (dvmIsBitSet(isConstantV,
1287                                     mir->ssaRep->uses[1])) {
1288                         c = -cUnit->constantValues[mir->ssaRep->uses[1]];
1289                         cIsConstant = true;
1290                     }
1291                     break;
1292                 case OP_ADD_INT_LIT8:
1293                     c = mir->dalvikInsn.vC;
1294                     cIsConstant = true;
1295                     break;
1296                 default:
1297                     break;
1298             }
1299
1300             /* Ignore the update to the basic induction variable itself */
1301             if (DECODE_REG(srcDalvikReg) == DECODE_REG(dstDalvikReg))  {
1302                 cUnit->loopAnalysis->ssaBIV = mir->ssaRep->defs[0];
1303                 cIsConstant = false;
1304             }
1305
1306             if (cIsConstant) {
1307                 unsigned int i;
1308                 dvmSetBit(isIndVarV, mir->ssaRep->defs[0]);
1309                 InductionVariableInfo *ivInfo =
1310                     dvmCompilerNew(sizeof(InductionVariableInfo),
1311                                    false);
1312                 InductionVariableInfo *ivInfoOld = NULL ;
1313
1314                 for (i = 0; i < ivList->numUsed; i++) {
1315                     ivInfoOld = ivList->elemList[i];
1316                     if (ivInfoOld->ssaReg == mir->ssaRep->uses[0]) break;
1317                 }
1318
1319                 /* Guaranteed to find an element */
1320                 assert(i < ivList->numUsed);
1321
1322                 ivInfo->ssaReg = mir->ssaRep->defs[0];
1323                 ivInfo->basicSSAReg = ivInfoOld->basicSSAReg;
1324                 ivInfo->m = ivInfoOld->m;
1325                 ivInfo->c = c + ivInfoOld->c;
1326                 ivInfo->inc = ivInfoOld->inc;
1327                 dvmInsertGrowableList(ivList, (void *) ivInfo);
1328             }
1329         }
1330     }
1331 }
1332
1333 /* Setup the basic data structures for SSA conversion */
1334 void dvmInitializeSSAConversion(CompilationUnit *cUnit)
1335 {
1336     int i;
1337     int numDalvikReg = cUnit->method->registersSize;
1338
1339     cUnit->ssaToDalvikMap = dvmCompilerNew(sizeof(GrowableList), false);
1340     dvmInitGrowableList(cUnit->ssaToDalvikMap, numDalvikReg);
1341
1342     /*
1343      * Initial number of SSA registers is equal to the number of Dalvik
1344      * registers.
1345      */
1346     cUnit->numSSARegs = numDalvikReg;
1347
1348     /*
1349      * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
1350      * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
1351      * into "(0 << 16) | i"
1352      */
1353     for (i = 0; i < numDalvikReg; i++) {
1354         dvmInsertGrowableList(cUnit->ssaToDalvikMap,
1355                               (void *) ENCODE_REG_SUB(i, 0));
1356     }
1357
1358     /*
1359      * Initialize the DalvikToSSAMap map. The low 16 bit is the SSA register id,
1360      * while the high 16 bit is the current subscript. The original Dalvik
1361      * register N is mapped to SSA register N with subscript 0.
1362      */
1363     cUnit->dalvikToSSAMap = dvmCompilerNew(sizeof(int) * numDalvikReg, false);
1364     for (i = 0; i < numDalvikReg; i++) {
1365         cUnit->dalvikToSSAMap[i] = i;
1366     }
1367
1368     /*
1369      * Allocate the BasicBlockDataFlow structure for the entry and code blocks
1370      */
1371     for (i = 0; i < cUnit->numBlocks; i++) {
1372         BasicBlock *bb = cUnit->blockList[i];
1373         if (bb->blockType == DALVIK_BYTECODE ||
1374             bb->blockType == ENTRY_BLOCK) {
1375             bb->dataFlowInfo = dvmCompilerNew(sizeof(BasicBlockDataFlow), true);
1376         }
1377     }
1378 }
1379
1380 void dvmCompilerDataFlowAnalysisDispatcher(CompilationUnit *cUnit,
1381                 void (*func)(CompilationUnit *, BasicBlock *))
1382 {
1383     int i;
1384     for (i = 0; i < cUnit->numBlocks; i++) {
1385         BasicBlock *bb = cUnit->blockList[i];
1386         (*func)(cUnit, bb);
1387     }
1388 }
1389
1390 /* Main entry point to do SSA conversion for non-loop traces */
1391 void dvmCompilerNonLoopAnalysis(CompilationUnit *cUnit)
1392 {
1393     dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion);
1394 }