blob: 9a2e5c0556df0e922387589be350e49924d6559e [file] [log] [blame]
Ben Cheng4238ec22009-08-24 16:32:22 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Dalvik.h"
18#include "Dataflow.h"
19#include "Loop.h"
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 */
29int 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 */
810int 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 */
820char *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 */
858static 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 */
868static 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 */
877void 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 */
929static 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 */
938static 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 */
956static 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 */
971static 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 */
986void 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 */
1089static void setConstant(CompilationUnit *cUnit, int ssaReg, int value)
1090{
1091 dvmSetBit(cUnit->isConstantV, ssaReg);
1092 cUnit->constantValues[ssaReg] = value;
1093}
1094
1095void 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
1169void 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 */
1334void 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
1380void 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 */
1391void dvmCompilerNonLoopAnalysis(CompilationUnit *cUnit)
1392{
1393 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion);
1394}