blob: 18ce563fc2b0f6aac5bdc65af07e9c7fc52645b6 [file] [log] [blame]
buzbeeee17e0a2013-07-31 10:47:37 -07001/*
2 * Copyright (C) 2013 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
Vladimir Markobe0e5462014-02-26 11:24:15 +000017#include <algorithm>
Ian Rogers700a4022014-05-19 16:49:03 -070018#include <memory>
19
Andreas Gampe0b9203e2015-01-22 20:39:27 -080020#include "base/logging.h"
Mathieu Chartierb666f482015-02-18 14:33:14 -080021#include "base/scoped_arena_containers.h"
buzbeeee17e0a2013-07-31 10:47:37 -070022#include "dataflow_iterator-inl.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080023#include "compiler_ir.h"
24#include "dex_flags.h"
Vladimir Markobe0e5462014-02-26 11:24:15 +000025#include "dex_instruction-inl.h"
Vladimir Markoaf6925b2014-10-31 16:37:32 +000026#include "dex/mir_field_info.h"
Vladimir Markof096aad2014-01-23 15:51:58 +000027#include "dex/verified_method.h"
Vladimir Marko5816ed42013-11-27 17:04:20 +000028#include "dex/quick/dex_file_method_inliner.h"
29#include "dex/quick/dex_file_to_method_inliner_map.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080030#include "driver/compiler_driver.h"
Brian Carlstrom6449c622014-02-10 23:48:36 -080031#include "driver/compiler_options.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080032#include "driver/dex_compilation_unit.h"
Mathieu Chartier736b5602015-09-02 14:54:11 -070033#include "scoped_thread_state_change.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010034#include "utils.h"
buzbeeee17e0a2013-07-31 10:47:37 -070035
36namespace art {
37
Ian Rogers584cc792014-09-29 10:49:11 -070038enum InstructionAnalysisAttributeOps : uint8_t {
39 kUninterestingOp = 0,
40 kArithmeticOp,
41 kFpOp,
42 kSingleOp,
43 kDoubleOp,
44 kIntOp,
45 kLongOp,
46 kBranchOp,
47 kInvokeOp,
48 kArrayOp,
49 kHeavyweightOp,
50 kSimpleConstOp,
51 kMoveOp,
52 kSwitch
53};
54
55enum InstructionAnalysisAttributeMasks : uint16_t {
56 kAnNone = 1 << kUninterestingOp,
57 kAnMath = 1 << kArithmeticOp,
58 kAnFp = 1 << kFpOp,
59 kAnLong = 1 << kLongOp,
60 kAnInt = 1 << kIntOp,
61 kAnSingle = 1 << kSingleOp,
62 kAnDouble = 1 << kDoubleOp,
63 kAnFloatMath = 1 << kFpOp,
64 kAnBranch = 1 << kBranchOp,
65 kAnInvoke = 1 << kInvokeOp,
66 kAnArrayOp = 1 << kArrayOp,
67 kAnHeavyWeight = 1 << kHeavyweightOp,
68 kAnSimpleConst = 1 << kSimpleConstOp,
69 kAnMove = 1 << kMoveOp,
70 kAnSwitch = 1 << kSwitch,
71 kAnComputational = kAnMath | kAnArrayOp | kAnMove | kAnSimpleConst,
72};
73
74// Instruction characteristics used to statically identify computation-intensive methods.
75static const uint16_t kAnalysisAttributes[kMirOpLast] = {
buzbeeee17e0a2013-07-31 10:47:37 -070076 // 00 NOP
Ian Rogers584cc792014-09-29 10:49:11 -070077 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -070078
79 // 01 MOVE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -070080 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070081
82 // 02 MOVE_FROM16 vAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070083 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070084
85 // 03 MOVE_16 vAAAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070086 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070087
88 // 04 MOVE_WIDE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -070089 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070090
91 // 05 MOVE_WIDE_FROM16 vAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070092 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070093
94 // 06 MOVE_WIDE_16 vAAAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070095 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070096
97 // 07 MOVE_OBJECT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -070098 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070099
100 // 08 MOVE_OBJECT_FROM16 vAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700101 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700102
103 // 09 MOVE_OBJECT_16 vAAAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700104 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700105
106 // 0A MOVE_RESULT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700107 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700108
109 // 0B MOVE_RESULT_WIDE vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700110 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700111
112 // 0C MOVE_RESULT_OBJECT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700113 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700114
115 // 0D MOVE_EXCEPTION vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700116 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700117
118 // 0E RETURN_VOID
Ian Rogers584cc792014-09-29 10:49:11 -0700119 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700120
121 // 0F RETURN vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700122 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700123
124 // 10 RETURN_WIDE vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700125 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700126
127 // 11 RETURN_OBJECT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700128 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700129
130 // 12 CONST_4 vA, #+B
Ian Rogers584cc792014-09-29 10:49:11 -0700131 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700132
133 // 13 CONST_16 vAA, #+BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700134 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700135
136 // 14 CONST vAA, #+BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700137 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700138
139 // 15 CONST_HIGH16 VAA, #+BBBB0000
Ian Rogers584cc792014-09-29 10:49:11 -0700140 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700141
142 // 16 CONST_WIDE_16 vAA, #+BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700143 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700144
145 // 17 CONST_WIDE_32 vAA, #+BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700146 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700147
148 // 18 CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700149 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700150
151 // 19 CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
Ian Rogers584cc792014-09-29 10:49:11 -0700152 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700153
154 // 1A CONST_STRING vAA, string@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700155 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700156
157 // 1B CONST_STRING_JUMBO vAA, string@BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700158 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700159
160 // 1C CONST_CLASS vAA, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700161 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700162
163 // 1D MONITOR_ENTER vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700164 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700165
166 // 1E MONITOR_EXIT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700167 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700168
169 // 1F CHK_CAST vAA, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700170 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700171
172 // 20 INSTANCE_OF vA, vB, type@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700173 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700174
175 // 21 ARRAY_LENGTH vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700176 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700177
178 // 22 NEW_INSTANCE vAA, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700179 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700180
181 // 23 NEW_ARRAY vA, vB, type@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700182 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700183
184 // 24 FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700185 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700186
187 // 25 FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700188 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700189
190 // 26 FILL_ARRAY_DATA vAA, +BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700191 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700192
193 // 27 THROW vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700194 kAnHeavyWeight | kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700195
196 // 28 GOTO
Ian Rogers584cc792014-09-29 10:49:11 -0700197 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700198
199 // 29 GOTO_16
Ian Rogers584cc792014-09-29 10:49:11 -0700200 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700201
202 // 2A GOTO_32
Ian Rogers584cc792014-09-29 10:49:11 -0700203 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700204
205 // 2B PACKED_SWITCH vAA, +BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700206 kAnSwitch,
buzbeeee17e0a2013-07-31 10:47:37 -0700207
208 // 2C SPARSE_SWITCH vAA, +BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700209 kAnSwitch,
buzbeeee17e0a2013-07-31 10:47:37 -0700210
211 // 2D CMPL_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700212 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700213
214 // 2E CMPG_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700215 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700216
217 // 2F CMPL_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700218 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700219
220 // 30 CMPG_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700221 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700222
223 // 31 CMP_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700224 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700225
226 // 32 IF_EQ vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700227 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700228
229 // 33 IF_NE vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700230 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700231
232 // 34 IF_LT vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700233 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700234
235 // 35 IF_GE vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700236 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700237
238 // 36 IF_GT vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700239 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700240
241 // 37 IF_LE vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700242 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700243
244 // 38 IF_EQZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700245 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700246
247 // 39 IF_NEZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700248 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700249
250 // 3A IF_LTZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700251 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700252
253 // 3B IF_GEZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700254 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700255
256 // 3C IF_GTZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700257 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700258
259 // 3D IF_LEZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700260 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700261
262 // 3E UNUSED_3E
Ian Rogers584cc792014-09-29 10:49:11 -0700263 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700264
265 // 3F UNUSED_3F
Ian Rogers584cc792014-09-29 10:49:11 -0700266 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700267
268 // 40 UNUSED_40
Ian Rogers584cc792014-09-29 10:49:11 -0700269 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700270
271 // 41 UNUSED_41
Ian Rogers584cc792014-09-29 10:49:11 -0700272 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700273
274 // 42 UNUSED_42
Ian Rogers584cc792014-09-29 10:49:11 -0700275 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700276
277 // 43 UNUSED_43
Ian Rogers584cc792014-09-29 10:49:11 -0700278 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700279
280 // 44 AGET vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700281 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700282
283 // 45 AGET_WIDE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700284 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700285
286 // 46 AGET_OBJECT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700287 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700288
289 // 47 AGET_BOOLEAN vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700290 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700291
292 // 48 AGET_BYTE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700293 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700294
295 // 49 AGET_CHAR vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700296 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700297
298 // 4A AGET_SHORT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700299 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700300
301 // 4B APUT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700302 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700303
304 // 4C APUT_WIDE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700305 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700306
307 // 4D APUT_OBJECT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700308 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700309
310 // 4E APUT_BOOLEAN vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700311 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700312
313 // 4F APUT_BYTE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700314 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700315
316 // 50 APUT_CHAR vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700317 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700318
319 // 51 APUT_SHORT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700320 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700321
322 // 52 IGET vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700323 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700324
325 // 53 IGET_WIDE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700326 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700327
328 // 54 IGET_OBJECT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700329 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700330
331 // 55 IGET_BOOLEAN vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700332 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700333
334 // 56 IGET_BYTE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700335 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700336
337 // 57 IGET_CHAR vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700338 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700339
340 // 58 IGET_SHORT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700341 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700342
343 // 59 IPUT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700344 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700345
346 // 5A IPUT_WIDE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700347 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700348
349 // 5B IPUT_OBJECT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700350 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700351
352 // 5C IPUT_BOOLEAN vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700353 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700354
355 // 5D IPUT_BYTE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700356 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700357
358 // 5E IPUT_CHAR vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700359 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700360
361 // 5F IPUT_SHORT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700362 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700363
364 // 60 SGET vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700365 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700366
367 // 61 SGET_WIDE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700368 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700369
370 // 62 SGET_OBJECT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700371 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700372
373 // 63 SGET_BOOLEAN vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700374 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700375
376 // 64 SGET_BYTE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700377 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700378
379 // 65 SGET_CHAR vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700380 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700381
382 // 66 SGET_SHORT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700383 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700384
385 // 67 SPUT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700386 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700387
388 // 68 SPUT_WIDE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700389 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700390
391 // 69 SPUT_OBJECT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700392 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700393
394 // 6A SPUT_BOOLEAN vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700395 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700396
397 // 6B SPUT_BYTE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700398 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700399
400 // 6C SPUT_CHAR vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700401 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700402
403 // 6D SPUT_SHORT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700404 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700405
406 // 6E INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700407 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700408
409 // 6F INVOKE_SUPER {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700410 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700411
412 // 70 INVOKE_DIRECT {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700413 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700414
415 // 71 INVOKE_STATIC {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700416 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700417
418 // 72 INVOKE_INTERFACE {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700419 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700420
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700421 // 73 RETURN_VOID_NO_BARRIER
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800422 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700423
424 // 74 INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700425 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700426
427 // 75 INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700428 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700429
430 // 76 INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700431 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700432
433 // 77 INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700434 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700435
436 // 78 INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700437 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700438
439 // 79 UNUSED_79
Ian Rogers584cc792014-09-29 10:49:11 -0700440 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700441
442 // 7A UNUSED_7A
Ian Rogers584cc792014-09-29 10:49:11 -0700443 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700444
445 // 7B NEG_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700446 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700447
448 // 7C NOT_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700449 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700450
451 // 7D NEG_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700452 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700453
454 // 7E NOT_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700455 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700456
457 // 7F NEG_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700458 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700459
460 // 80 NEG_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700461 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700462
463 // 81 INT_TO_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700464 kAnMath | kAnInt | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700465
466 // 82 INT_TO_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700467 kAnMath | kAnFp | kAnInt | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700468
469 // 83 INT_TO_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700470 kAnMath | kAnFp | kAnInt | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700471
472 // 84 LONG_TO_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700473 kAnMath | kAnInt | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700474
475 // 85 LONG_TO_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700476 kAnMath | kAnFp | kAnLong | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700477
478 // 86 LONG_TO_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700479 kAnMath | kAnFp | kAnLong | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700480
481 // 87 FLOAT_TO_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700482 kAnMath | kAnFp | kAnInt | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700483
484 // 88 FLOAT_TO_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700485 kAnMath | kAnFp | kAnLong | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700486
487 // 89 FLOAT_TO_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700488 kAnMath | kAnFp | kAnSingle | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700489
490 // 8A DOUBLE_TO_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700491 kAnMath | kAnFp | kAnInt | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700492
493 // 8B DOUBLE_TO_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700494 kAnMath | kAnFp | kAnLong | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700495
496 // 8C DOUBLE_TO_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700497 kAnMath | kAnFp | kAnSingle | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700498
499 // 8D INT_TO_BYTE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700500 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700501
502 // 8E INT_TO_CHAR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700503 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700504
505 // 8F INT_TO_SHORT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700506 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700507
508 // 90 ADD_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700509 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700510
511 // 91 SUB_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700512 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700513
514 // 92 MUL_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700515 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700516
517 // 93 DIV_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700518 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700519
520 // 94 REM_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700521 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700522
523 // 95 AND_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700524 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700525
526 // 96 OR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700527 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700528
529 // 97 XOR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700530 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700531
532 // 98 SHL_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700533 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700534
535 // 99 SHR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700536 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700537
538 // 9A USHR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700539 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700540
541 // 9B ADD_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700542 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700543
544 // 9C SUB_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700545 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700546
547 // 9D MUL_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700548 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700549
550 // 9E DIV_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700551 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700552
553 // 9F REM_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700554 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700555
556 // A0 AND_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700557 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700558
559 // A1 OR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700560 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700561
562 // A2 XOR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700563 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700564
565 // A3 SHL_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700566 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700567
568 // A4 SHR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700569 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700570
571 // A5 USHR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700572 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700573
574 // A6 ADD_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700575 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700576
577 // A7 SUB_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700578 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700579
580 // A8 MUL_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700581 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700582
583 // A9 DIV_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700584 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700585
586 // AA REM_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700587 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700588
589 // AB ADD_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700590 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700591
592 // AC SUB_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700593 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700594
595 // AD MUL_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700596 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700597
598 // AE DIV_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700599 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700600
601 // AF REM_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700602 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700603
604 // B0 ADD_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700605 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700606
607 // B1 SUB_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700608 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700609
610 // B2 MUL_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700611 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700612
613 // B3 DIV_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700614 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700615
616 // B4 REM_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700617 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700618
619 // B5 AND_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700620 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700621
622 // B6 OR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700623 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700624
625 // B7 XOR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700626 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700627
628 // B8 SHL_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700629 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700630
631 // B9 SHR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700632 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700633
634 // BA USHR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700635 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700636
637 // BB ADD_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700638 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700639
640 // BC SUB_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700641 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700642
643 // BD MUL_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700644 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700645
646 // BE DIV_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700647 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700648
649 // BF REM_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700650 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700651
652 // C0 AND_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700653 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700654
655 // C1 OR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700656 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700657
658 // C2 XOR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700659 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700660
661 // C3 SHL_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700662 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700663
664 // C4 SHR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700665 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700666
667 // C5 USHR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700668 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700669
670 // C6 ADD_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700671 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700672
673 // C7 SUB_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700674 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700675
676 // C8 MUL_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700677 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700678
679 // C9 DIV_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700680 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700681
682 // CA REM_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700683 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700684
685 // CB ADD_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700686 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700687
688 // CC SUB_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700689 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700690
691 // CD MUL_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700692 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700693
694 // CE DIV_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700695 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700696
697 // CF REM_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700698 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700699
700 // D0 ADD_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700701 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700702
703 // D1 RSUB_INT vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700704 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700705
706 // D2 MUL_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700707 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700708
709 // D3 DIV_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700710 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700711
712 // D4 REM_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700713 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700714
715 // D5 AND_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700716 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700717
718 // D6 OR_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700719 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700720
721 // D7 XOR_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700722 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700723
724 // D8 ADD_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700725 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700726
727 // D9 RSUB_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700728 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700729
730 // DA MUL_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700731 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700732
733 // DB DIV_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700734 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700735
736 // DC REM_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700737 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700738
739 // DD AND_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700740 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700741
742 // DE OR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700743 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700744
745 // DF XOR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700746 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700747
748 // E0 SHL_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700749 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700750
751 // E1 SHR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700752 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700753
754 // E2 USHR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700755 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700756
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800757 // E3 IGET_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700758 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700759
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800760 // E4 IGET_WIDE_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700761 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700762
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800763 // E5 IGET_OBJECT_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700764 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700765
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800766 // E6 IPUT_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700767 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700768
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800769 // E7 IPUT_WIDE_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700770 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700771
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800772 // E8 IPUT_OBJECT_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700773 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700774
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800775 // E9 INVOKE_VIRTUAL_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700776 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700777
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800778 // EA INVOKE_VIRTUAL_RANGE_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700779 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700780
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800781 // EB IPUT_BOOLEAN_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700782 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700783
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800784 // EC IPUT_BYTE_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700785 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700786
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800787 // ED IPUT_CHAR_QUICK
788 kAnNone,
789
790 // EE IPUT_SHORT_QUICK
791 kAnNone,
792
793 // EF IGET_BOOLEAN_QUICK
794 kAnNone,
795
796 // F0 IGET_BYTE_QUICK
797 kAnNone,
798
799 // F1 IGET_CHAR_QUICK
800 kAnNone,
801
802 // F2 IGET_SHORT_QUICK
803 kAnNone,
804
805 // F3 UNUSED_F3
806 kAnNone,
807
808 // F4 UNUSED_F4
809 kAnNone,
810
811 // F5 UNUSED_F5
812 kAnNone,
813
814 // F6 UNUSED_F6
815 kAnNone,
816
817 // F7 UNUSED_F7
818 kAnNone,
819
820 // F8 UNUSED_F8
821 kAnNone,
822
823 // F9 UNUSED_F9
824 kAnNone,
825
826 // FA UNUSED_FA
827 kAnNone,
828
829 // FB UNUSED_FB
830 kAnNone,
831
832 // FC UNUSED_FC
833 kAnNone,
834
835 // FD UNUSED_FD
836 kAnNone,
837
838 // FE UNUSED_FE
Ian Rogers584cc792014-09-29 10:49:11 -0700839 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700840
841 // FF UNUSED_FF
Ian Rogers584cc792014-09-29 10:49:11 -0700842 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700843
844 // Beginning of extended MIR opcodes
845 // 100 MIR_PHI
Ian Rogers584cc792014-09-29 10:49:11 -0700846 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700847
848 // 101 MIR_COPY
Ian Rogers584cc792014-09-29 10:49:11 -0700849 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700850
851 // 102 MIR_FUSED_CMPL_FLOAT
Ian Rogers584cc792014-09-29 10:49:11 -0700852 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700853
854 // 103 MIR_FUSED_CMPG_FLOAT
Ian Rogers584cc792014-09-29 10:49:11 -0700855 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700856
857 // 104 MIR_FUSED_CMPL_DOUBLE
Ian Rogers584cc792014-09-29 10:49:11 -0700858 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700859
860 // 105 MIR_FUSED_CMPG_DOUBLE
Ian Rogers584cc792014-09-29 10:49:11 -0700861 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700862
863 // 106 MIR_FUSED_CMP_LONG
Ian Rogers584cc792014-09-29 10:49:11 -0700864 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700865
866 // 107 MIR_NOP
Ian Rogers584cc792014-09-29 10:49:11 -0700867 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700868
869 // 108 MIR_NULL_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700870 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700871
872 // 109 MIR_RANGE_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700873 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700874
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700875 // 10A MIR_DIV_ZERO_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700876 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700877
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700878 // 10B MIR_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700879 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700880
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700881 // 10C MIR_CHECKPART2
Ian Rogers584cc792014-09-29 10:49:11 -0700882 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700883
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700884 // 10D MIR_SELECT
Ian Rogers584cc792014-09-29 10:49:11 -0700885 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900886
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700887 // 10E MirOpConstVector
Ian Rogers584cc792014-09-29 10:49:11 -0700888 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900889
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700890 // 10F MirOpMoveVector
Ian Rogers584cc792014-09-29 10:49:11 -0700891 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900892
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700893 // 110 MirOpPackedMultiply
Ian Rogers584cc792014-09-29 10:49:11 -0700894 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900895
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700896 // 111 MirOpPackedAddition
Ian Rogers584cc792014-09-29 10:49:11 -0700897 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900898
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700899 // 112 MirOpPackedSubtract
Ian Rogers584cc792014-09-29 10:49:11 -0700900 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900901
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700902 // 113 MirOpPackedShiftLeft
Ian Rogers584cc792014-09-29 10:49:11 -0700903 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900904
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700905 // 114 MirOpPackedSignedShiftRight
Ian Rogers584cc792014-09-29 10:49:11 -0700906 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900907
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700908 // 115 MirOpPackedUnsignedShiftRight
Ian Rogers584cc792014-09-29 10:49:11 -0700909 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900910
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700911 // 116 MirOpPackedAnd
Ian Rogers584cc792014-09-29 10:49:11 -0700912 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900913
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700914 // 117 MirOpPackedOr
Ian Rogers584cc792014-09-29 10:49:11 -0700915 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900916
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700917 // 118 MirOpPackedXor
Ian Rogers584cc792014-09-29 10:49:11 -0700918 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900919
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700920 // 119 MirOpPackedAddReduce
Ian Rogers584cc792014-09-29 10:49:11 -0700921 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900922
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700923 // 11A MirOpPackedReduce
Ian Rogers584cc792014-09-29 10:49:11 -0700924 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900925
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700926 // 11B MirOpPackedSet
Ian Rogers584cc792014-09-29 10:49:11 -0700927 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900928
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700929 // 11C MirOpReserveVectorRegisters
Ian Rogers584cc792014-09-29 10:49:11 -0700930 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900931
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700932 // 11D MirOpReturnVectorRegisters
Ian Rogers584cc792014-09-29 10:49:11 -0700933 kAnNone,
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700934
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700935 // 11E MirOpMemBarrier
Ian Rogers584cc792014-09-29 10:49:11 -0700936 kAnNone,
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700937
938 // 11F MirOpPackedArrayGet
Ian Rogers584cc792014-09-29 10:49:11 -0700939 kAnArrayOp,
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700940
941 // 120 MirOpPackedArrayPut
Ian Rogers584cc792014-09-29 10:49:11 -0700942 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700943};
944
945struct MethodStats {
946 int dex_instructions;
947 int math_ops;
948 int fp_ops;
949 int array_ops;
950 int branch_ops;
951 int heavyweight_ops;
952 bool has_computational_loop;
buzbeefe9ca402013-08-21 09:48:11 -0700953 bool has_switch;
buzbeeee17e0a2013-07-31 10:47:37 -0700954 float math_ratio;
955 float fp_ratio;
956 float array_ratio;
957 float branch_ratio;
958 float heavyweight_ratio;
959};
960
961void MIRGraph::AnalyzeBlock(BasicBlock* bb, MethodStats* stats) {
962 if (bb->visited || (bb->block_type != kDalvikByteCode)) {
963 return;
964 }
965 bool computational_block = true;
966 bool has_math = false;
967 /*
968 * For the purposes of this scan, we want to treat the set of basic blocks broken
969 * by an exception edge as a single basic block. We'll scan forward along the fallthrough
970 * edges until we reach an explicit branch or return.
971 */
972 BasicBlock* ending_bb = bb;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700973 if (ending_bb->last_mir_insn != nullptr) {
Ian Rogers584cc792014-09-29 10:49:11 -0700974 uint32_t ending_flags = kAnalysisAttributes[ending_bb->last_mir_insn->dalvikInsn.opcode];
975 while ((ending_flags & kAnBranch) == 0) {
buzbee0d829482013-10-11 15:24:55 -0700976 ending_bb = GetBasicBlock(ending_bb->fall_through);
Ian Rogers584cc792014-09-29 10:49:11 -0700977 ending_flags = kAnalysisAttributes[ending_bb->last_mir_insn->dalvikInsn.opcode];
buzbeeee17e0a2013-07-31 10:47:37 -0700978 }
979 }
980 /*
981 * Ideally, we'd weight the operations by loop nesting level, but to do so we'd
982 * first need to do some expensive loop detection - and the point of this is to make
983 * an informed guess before investing in computation. However, we can cheaply detect
984 * many simple loop forms without having to do full dataflow analysis.
985 */
986 int loop_scale_factor = 1;
987 // Simple for and while loops
buzbee0d829482013-10-11 15:24:55 -0700988 if ((ending_bb->taken != NullBasicBlockId) && (ending_bb->fall_through == NullBasicBlockId)) {
989 if ((GetBasicBlock(ending_bb->taken)->taken == bb->id) ||
990 (GetBasicBlock(ending_bb->taken)->fall_through == bb->id)) {
buzbeeee17e0a2013-07-31 10:47:37 -0700991 loop_scale_factor = 25;
992 }
993 }
994 // Simple do-while loop
buzbee0d829482013-10-11 15:24:55 -0700995 if ((ending_bb->taken != NullBasicBlockId) && (ending_bb->taken == bb->id)) {
buzbeeee17e0a2013-07-31 10:47:37 -0700996 loop_scale_factor = 25;
997 }
998
999 BasicBlock* tbb = bb;
1000 bool done = false;
1001 while (!done) {
1002 tbb->visited = true;
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001003 for (MIR* mir = tbb->first_mir_insn; mir != nullptr; mir = mir->next) {
Jean Christophe Beyler2ab40eb2014-06-02 09:03:14 -07001004 if (MIR::DecodedInstruction::IsPseudoMirOp(mir->dalvikInsn.opcode)) {
buzbeeee17e0a2013-07-31 10:47:37 -07001005 // Skip any MIR pseudo-op.
1006 continue;
1007 }
Ian Rogers584cc792014-09-29 10:49:11 -07001008 uint16_t flags = kAnalysisAttributes[mir->dalvikInsn.opcode];
buzbeeee17e0a2013-07-31 10:47:37 -07001009 stats->dex_instructions += loop_scale_factor;
Ian Rogers584cc792014-09-29 10:49:11 -07001010 if ((flags & kAnBranch) == 0) {
1011 computational_block &= ((flags & kAnComputational) != 0);
buzbeeee17e0a2013-07-31 10:47:37 -07001012 } else {
1013 stats->branch_ops += loop_scale_factor;
1014 }
Ian Rogers584cc792014-09-29 10:49:11 -07001015 if ((flags & kAnMath) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001016 stats->math_ops += loop_scale_factor;
1017 has_math = true;
1018 }
Ian Rogers584cc792014-09-29 10:49:11 -07001019 if ((flags & kAnFp) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001020 stats->fp_ops += loop_scale_factor;
1021 }
Ian Rogers584cc792014-09-29 10:49:11 -07001022 if ((flags & kAnArrayOp) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001023 stats->array_ops += loop_scale_factor;
1024 }
Ian Rogers584cc792014-09-29 10:49:11 -07001025 if ((flags & kAnHeavyWeight) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001026 stats->heavyweight_ops += loop_scale_factor;
1027 }
Ian Rogers584cc792014-09-29 10:49:11 -07001028 if ((flags & kAnSwitch) != 0) {
buzbeefe9ca402013-08-21 09:48:11 -07001029 stats->has_switch = true;
1030 }
buzbeeee17e0a2013-07-31 10:47:37 -07001031 }
1032 if (tbb == ending_bb) {
1033 done = true;
1034 } else {
buzbee0d829482013-10-11 15:24:55 -07001035 tbb = GetBasicBlock(tbb->fall_through);
buzbeeee17e0a2013-07-31 10:47:37 -07001036 }
1037 }
1038 if (has_math && computational_block && (loop_scale_factor > 1)) {
1039 stats->has_computational_loop = true;
1040 }
1041}
1042
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001043bool MIRGraph::ComputeSkipCompilation(MethodStats* stats, bool skip_default,
1044 std::string* skip_message) {
buzbeeee17e0a2013-07-31 10:47:37 -07001045 float count = stats->dex_instructions;
1046 stats->math_ratio = stats->math_ops / count;
1047 stats->fp_ratio = stats->fp_ops / count;
1048 stats->branch_ratio = stats->branch_ops / count;
1049 stats->array_ratio = stats->array_ops / count;
1050 stats->heavyweight_ratio = stats->heavyweight_ops / count;
1051
1052 if (cu_->enable_debug & (1 << kDebugShowFilterStats)) {
1053 LOG(INFO) << "STATS " << stats->dex_instructions << ", math:"
1054 << stats->math_ratio << ", fp:"
1055 << stats->fp_ratio << ", br:"
1056 << stats->branch_ratio << ", hw:"
buzbeefe9ca402013-08-21 09:48:11 -07001057 << stats->heavyweight_ratio << ", arr:"
buzbeeee17e0a2013-07-31 10:47:37 -07001058 << stats->array_ratio << ", hot:"
1059 << stats->has_computational_loop << ", "
1060 << PrettyMethod(cu_->method_idx, *cu_->dex_file);
1061 }
1062
1063 // Computation intensive?
1064 if (stats->has_computational_loop && (stats->heavyweight_ratio < 0.04)) {
1065 return false;
1066 }
1067
1068 // Complex, logic-intensive?
Brian Carlstrom6449c622014-02-10 23:48:36 -08001069 if (cu_->compiler_driver->GetCompilerOptions().IsSmallMethod(GetNumDalvikInsns()) &&
buzbeeee17e0a2013-07-31 10:47:37 -07001070 stats->branch_ratio > 0.3) {
1071 return false;
1072 }
1073
1074 // Significant floating point?
1075 if (stats->fp_ratio > 0.05) {
1076 return false;
1077 }
1078
1079 // Significant generic math?
1080 if (stats->math_ratio > 0.3) {
1081 return false;
1082 }
1083
1084 // If array-intensive, compiling is probably worthwhile.
1085 if (stats->array_ratio > 0.1) {
1086 return false;
1087 }
1088
buzbeefe9ca402013-08-21 09:48:11 -07001089 // Switch operations benefit greatly from compilation, so go ahead and spend the cycles.
1090 if (stats->has_switch) {
1091 return false;
1092 }
1093
1094 // If significant in size and high proportion of expensive operations, skip.
Brian Carlstrom6449c622014-02-10 23:48:36 -08001095 if (cu_->compiler_driver->GetCompilerOptions().IsSmallMethod(GetNumDalvikInsns()) &&
buzbeefe9ca402013-08-21 09:48:11 -07001096 (stats->heavyweight_ratio > 0.3)) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001097 *skip_message = "Is a small method with heavyweight ratio " +
1098 std::to_string(stats->heavyweight_ratio);
buzbeeee17e0a2013-07-31 10:47:37 -07001099 return true;
1100 }
1101
1102 return skip_default;
1103}
1104
1105 /*
1106 * Will eventually want this to be a bit more sophisticated and happen at verification time.
buzbeeee17e0a2013-07-31 10:47:37 -07001107 */
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001108bool MIRGraph::SkipCompilation(std::string* skip_message) {
Brian Carlstrom6449c622014-02-10 23:48:36 -08001109 const CompilerOptions& compiler_options = cu_->compiler_driver->GetCompilerOptions();
1110 CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
1111 if (compiler_filter == CompilerOptions::kEverything) {
buzbeeee17e0a2013-07-31 10:47:37 -07001112 return false;
1113 }
1114
buzbeeb1f1d642014-02-27 12:55:32 -08001115 // Contains a pattern we don't want to compile?
buzbee8c7a02a2014-06-14 12:33:09 -07001116 if (PuntToInterpreter()) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001117 *skip_message = "Punt to interpreter set";
buzbeeb1f1d642014-02-27 12:55:32 -08001118 return true;
1119 }
1120
Ian Rogersaaf29b32014-11-07 17:05:19 -08001121 DCHECK(compiler_options.IsCompilationEnabled());
buzbeeee17e0a2013-07-31 10:47:37 -07001122
buzbeefe9ca402013-08-21 09:48:11 -07001123 // Set up compilation cutoffs based on current filter mode.
Ian Rogersaaf29b32014-11-07 17:05:19 -08001124 size_t small_cutoff;
1125 size_t default_cutoff;
buzbeefe9ca402013-08-21 09:48:11 -07001126 switch (compiler_filter) {
Brian Carlstrom6449c622014-02-10 23:48:36 -08001127 case CompilerOptions::kBalanced:
1128 small_cutoff = compiler_options.GetSmallMethodThreshold();
1129 default_cutoff = compiler_options.GetLargeMethodThreshold();
buzbeefe9ca402013-08-21 09:48:11 -07001130 break;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001131 case CompilerOptions::kSpace:
1132 small_cutoff = compiler_options.GetTinyMethodThreshold();
1133 default_cutoff = compiler_options.GetSmallMethodThreshold();
buzbeefe9ca402013-08-21 09:48:11 -07001134 break;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001135 case CompilerOptions::kSpeed:
Nicolas Geoffray88157ef2014-09-12 10:29:53 +01001136 case CompilerOptions::kTime:
Brian Carlstrom6449c622014-02-10 23:48:36 -08001137 small_cutoff = compiler_options.GetHugeMethodThreshold();
1138 default_cutoff = compiler_options.GetHugeMethodThreshold();
buzbeefe9ca402013-08-21 09:48:11 -07001139 break;
1140 default:
1141 LOG(FATAL) << "Unexpected compiler_filter_: " << compiler_filter;
Ian Rogersaaf29b32014-11-07 17:05:19 -08001142 UNREACHABLE();
buzbeefe9ca402013-08-21 09:48:11 -07001143 }
1144
1145 // If size < cutoff, assume we'll compile - but allow removal.
1146 bool skip_compilation = (GetNumDalvikInsns() >= default_cutoff);
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001147 if (skip_compilation) {
1148 *skip_message = "#Insns >= default_cutoff: " + std::to_string(GetNumDalvikInsns());
1149 }
buzbeefe9ca402013-08-21 09:48:11 -07001150
1151 /*
1152 * Filter 1: Huge methods are likely to be machine generated, but some aren't.
1153 * If huge, assume we won't compile, but allow futher analysis to turn it back on.
1154 */
Brian Carlstrom6449c622014-02-10 23:48:36 -08001155 if (compiler_options.IsHugeMethod(GetNumDalvikInsns())) {
buzbeefe9ca402013-08-21 09:48:11 -07001156 skip_compilation = true;
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001157 *skip_message = "Huge method: " + std::to_string(GetNumDalvikInsns());
buzbeeb48819d2013-09-14 16:15:25 -07001158 // If we're got a huge number of basic blocks, don't bother with further analysis.
Vladimir Markoffda4992014-12-18 17:05:58 +00001159 if (static_cast<size_t>(GetNumBlocks()) > (compiler_options.GetHugeMethodThreshold() / 2)) {
buzbeeb48819d2013-09-14 16:15:25 -07001160 return true;
1161 }
Brian Carlstrom6449c622014-02-10 23:48:36 -08001162 } else if (compiler_options.IsLargeMethod(GetNumDalvikInsns()) &&
buzbeeb48819d2013-09-14 16:15:25 -07001163 /* If it's large and contains no branches, it's likely to be machine generated initialization */
1164 (GetBranchCount() == 0)) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001165 *skip_message = "Large method with no branches";
buzbeeb48819d2013-09-14 16:15:25 -07001166 return true;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001167 } else if (compiler_filter == CompilerOptions::kSpeed) {
buzbeefe9ca402013-08-21 09:48:11 -07001168 // If not huge, compile.
1169 return false;
buzbeeee17e0a2013-07-31 10:47:37 -07001170 }
1171
1172 // Filter 2: Skip class initializers.
1173 if (((cu_->access_flags & kAccConstructor) != 0) && ((cu_->access_flags & kAccStatic) != 0)) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001174 *skip_message = "Class initializer";
buzbeeee17e0a2013-07-31 10:47:37 -07001175 return true;
1176 }
1177
1178 // Filter 3: if this method is a special pattern, go ahead and emit the canned pattern.
Vladimir Marko5816ed42013-11-27 17:04:20 +00001179 if (cu_->compiler_driver->GetMethodInlinerMap() != nullptr &&
1180 cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file)
1181 ->IsSpecial(cu_->method_idx)) {
buzbeeee17e0a2013-07-31 10:47:37 -07001182 return false;
1183 }
1184
buzbeefe9ca402013-08-21 09:48:11 -07001185 // Filter 4: if small, just compile.
buzbeeee17e0a2013-07-31 10:47:37 -07001186 if (GetNumDalvikInsns() < small_cutoff) {
1187 return false;
1188 }
1189
1190 // Analyze graph for:
1191 // o floating point computation
1192 // o basic blocks contained in loop with heavy arithmetic.
1193 // o proportion of conditional branches.
1194
1195 MethodStats stats;
1196 memset(&stats, 0, sizeof(stats));
1197
1198 ClearAllVisitedFlags();
buzbee56c71782013-09-05 17:13:19 -07001199 AllNodesIterator iter(this);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001200 for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
buzbeeee17e0a2013-07-31 10:47:37 -07001201 AnalyzeBlock(bb, &stats);
1202 }
1203
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001204 return ComputeSkipCompilation(&stats, skip_compilation, skip_message);
buzbeeee17e0a2013-07-31 10:47:37 -07001205}
1206
Vladimir Markobe0e5462014-02-26 11:24:15 +00001207void MIRGraph::DoCacheFieldLoweringInfo() {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001208 static constexpr uint32_t kFieldIndexFlagQuickened = 0x80000000;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001209 // All IGET/IPUT/SGET/SPUT instructions take 2 code units and there must also be a RETURN.
Razvan A Lupusoru75035972014-09-11 15:24:59 -07001210 const uint32_t max_refs = (GetNumDalvikInsns() - 1u) / 2u;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001211 ScopedArenaAllocator allocator(&cu_->arena_stack);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001212 auto* field_idxs = allocator.AllocArray<uint32_t>(max_refs, kArenaAllocMisc);
1213 DexMemAccessType* field_types = allocator.AllocArray<DexMemAccessType>(
1214 max_refs, kArenaAllocMisc);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001215 // Find IGET/IPUT/SGET/SPUT insns, store IGET/IPUT fields at the beginning, SGET/SPUT at the end.
1216 size_t ifield_pos = 0u;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001217 size_t sfield_pos = max_refs;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001218 AllNodesIterator iter(this);
1219 for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
1220 if (bb->block_type != kDalvikByteCode) {
1221 continue;
1222 }
1223 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001224 // Get field index and try to find it among existing indexes. If found, it's usually among
1225 // the last few added, so we'll start the search from ifield_pos/sfield_pos. Though this
1226 // is a linear search, it actually performs much better than map based approach.
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001227 const bool is_iget_or_iput = IsInstructionIGetOrIPut(mir->dalvikInsn.opcode);
1228 const bool is_iget_or_iput_quick = IsInstructionIGetQuickOrIPutQuick(mir->dalvikInsn.opcode);
1229 if (is_iget_or_iput || is_iget_or_iput_quick) {
1230 uint32_t field_idx;
1231 DexMemAccessType access_type;
1232 if (is_iget_or_iput) {
1233 field_idx = mir->dalvikInsn.vC;
1234 access_type = IGetOrIPutMemAccessType(mir->dalvikInsn.opcode);
1235 } else {
1236 DCHECK(is_iget_or_iput_quick);
1237 // Set kFieldIndexFlagQuickened so that we don't deduplicate against non quickened field
1238 // indexes.
1239 field_idx = mir->offset | kFieldIndexFlagQuickened;
1240 access_type = IGetQuickOrIPutQuickMemAccessType(mir->dalvikInsn.opcode);
1241 }
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001242 size_t i = ifield_pos;
1243 while (i != 0u && field_idxs[i - 1] != field_idx) {
1244 --i;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001245 }
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001246 if (i != 0u) {
1247 mir->meta.ifield_lowering_info = i - 1;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001248 DCHECK_EQ(field_types[i - 1], access_type);
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001249 } else {
1250 mir->meta.ifield_lowering_info = ifield_pos;
1251 field_idxs[ifield_pos] = field_idx;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001252 field_types[ifield_pos] = access_type;
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001253 ++ifield_pos;
1254 }
1255 } else if (IsInstructionSGetOrSPut(mir->dalvikInsn.opcode)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001256 auto field_idx = mir->dalvikInsn.vB;
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001257 size_t i = sfield_pos;
1258 while (i != max_refs && field_idxs[i] != field_idx) {
1259 ++i;
1260 }
1261 if (i != max_refs) {
1262 mir->meta.sfield_lowering_info = max_refs - i - 1u;
1263 DCHECK_EQ(field_types[i], SGetOrSPutMemAccessType(mir->dalvikInsn.opcode));
1264 } else {
1265 mir->meta.sfield_lowering_info = max_refs - sfield_pos;
1266 --sfield_pos;
1267 field_idxs[sfield_pos] = field_idx;
1268 field_types[sfield_pos] = SGetOrSPutMemAccessType(mir->dalvikInsn.opcode);
1269 }
Vladimir Markobe0e5462014-02-26 11:24:15 +00001270 }
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001271 DCHECK_LE(ifield_pos, sfield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001272 }
1273 }
1274
1275 if (ifield_pos != 0u) {
1276 // Resolve instance field infos.
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001277 DCHECK_EQ(ifield_lowering_infos_.size(), 0u);
1278 ifield_lowering_infos_.reserve(ifield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001279 for (size_t pos = 0u; pos != ifield_pos; ++pos) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001280 const uint32_t field_idx = field_idxs[pos];
1281 const bool is_quickened = (field_idx & kFieldIndexFlagQuickened) != 0;
1282 const uint32_t masked_field_idx = field_idx & ~kFieldIndexFlagQuickened;
1283 CHECK_LT(masked_field_idx, 1u << 16);
1284 ifield_lowering_infos_.push_back(
1285 MirIFieldLoweringInfo(masked_field_idx, field_types[pos], is_quickened));
Vladimir Markobe0e5462014-02-26 11:24:15 +00001286 }
Mathieu Chartier736b5602015-09-02 14:54:11 -07001287 ScopedObjectAccess soa(Thread::Current());
1288 MirIFieldLoweringInfo::Resolve(soa,
1289 cu_->compiler_driver,
1290 GetCurrentDexCompilationUnit(),
1291 ifield_lowering_infos_.data(),
1292 ifield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001293 }
1294
Vladimir Markoa24122d2014-03-07 10:18:14 +00001295 if (sfield_pos != max_refs) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001296 // Resolve static field infos.
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001297 DCHECK_EQ(sfield_lowering_infos_.size(), 0u);
1298 sfield_lowering_infos_.reserve(max_refs - sfield_pos);
Vladimir Markoa24122d2014-03-07 10:18:14 +00001299 for (size_t pos = max_refs; pos != sfield_pos;) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001300 --pos;
Vladimir Markoaf6925b2014-10-31 16:37:32 +00001301 sfield_lowering_infos_.push_back(MirSFieldLoweringInfo(field_idxs[pos], field_types[pos]));
Vladimir Markobe0e5462014-02-26 11:24:15 +00001302 }
1303 MirSFieldLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(),
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001304 sfield_lowering_infos_.data(), max_refs - sfield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001305 }
1306}
1307
Vladimir Markof096aad2014-01-23 15:51:58 +00001308void MIRGraph::DoCacheMethodLoweringInfo() {
1309 static constexpr uint16_t invoke_types[] = { kVirtual, kSuper, kDirect, kStatic, kInterface };
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001310 static constexpr uint32_t kMethodIdxFlagQuickened = 0x80000000;
Vladimir Markof096aad2014-01-23 15:51:58 +00001311
1312 // Embed the map value in the entry to avoid extra padding in 64-bit builds.
1313 struct MapEntry {
1314 // Map key: target_method_idx, invoke_type, devirt_target. Ordered to avoid padding.
1315 const MethodReference* devirt_target;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001316 uint32_t target_method_idx;
1317 uint32_t vtable_idx;
Vladimir Markof096aad2014-01-23 15:51:58 +00001318 uint16_t invoke_type;
1319 // Map value.
1320 uint32_t lowering_info_index;
1321 };
1322
Vladimir Markof096aad2014-01-23 15:51:58 +00001323 struct MapEntryComparator {
1324 bool operator()(const MapEntry& lhs, const MapEntry& rhs) const {
1325 if (lhs.target_method_idx != rhs.target_method_idx) {
1326 return lhs.target_method_idx < rhs.target_method_idx;
1327 }
1328 if (lhs.invoke_type != rhs.invoke_type) {
1329 return lhs.invoke_type < rhs.invoke_type;
1330 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001331 if (lhs.vtable_idx != rhs.vtable_idx) {
1332 return lhs.vtable_idx < rhs.vtable_idx;
1333 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001334 if (lhs.devirt_target != rhs.devirt_target) {
1335 if (lhs.devirt_target == nullptr) {
1336 return true;
1337 }
1338 if (rhs.devirt_target == nullptr) {
1339 return false;
1340 }
1341 return devirt_cmp(*lhs.devirt_target, *rhs.devirt_target);
1342 }
1343 return false;
1344 }
1345 MethodReferenceComparator devirt_cmp;
1346 };
1347
Vladimir Markof096aad2014-01-23 15:51:58 +00001348 ScopedArenaAllocator allocator(&cu_->arena_stack);
1349
1350 // All INVOKE instructions take 3 code units and there must also be a RETURN.
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001351 const uint32_t max_refs = (GetNumDalvikInsns() - 1u) / 3u;
Vladimir Markof096aad2014-01-23 15:51:58 +00001352
Vladimir Marko69f08ba2014-04-11 12:28:11 +01001353 // Map invoke key (see MapEntry) to lowering info index and vice versa.
Vladimir Markof096aad2014-01-23 15:51:58 +00001354 // The invoke_map and sequential entries are essentially equivalent to Boost.MultiIndex's
1355 // multi_index_container with one ordered index and one sequential index.
Vladimir Marko69f08ba2014-04-11 12:28:11 +01001356 ScopedArenaSet<MapEntry, MapEntryComparator> invoke_map(MapEntryComparator(),
1357 allocator.Adapter());
Vladimir Markoe4fcc5b2015-02-13 10:28:29 +00001358 const MapEntry** sequential_entries =
1359 allocator.AllocArray<const MapEntry*>(max_refs, kArenaAllocMisc);
Vladimir Markof096aad2014-01-23 15:51:58 +00001360
1361 // Find INVOKE insns and their devirtualization targets.
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001362 const VerifiedMethod* verified_method = GetCurrentDexCompilationUnit()->GetVerifiedMethod();
Vladimir Markof096aad2014-01-23 15:51:58 +00001363 AllNodesIterator iter(this);
1364 for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
1365 if (bb->block_type != kDalvikByteCode) {
1366 continue;
1367 }
1368 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001369 const bool is_quick_invoke = IsInstructionQuickInvoke(mir->dalvikInsn.opcode);
1370 const bool is_invoke = IsInstructionInvoke(mir->dalvikInsn.opcode);
1371 if (is_quick_invoke || is_invoke) {
1372 uint32_t vtable_index = 0;
1373 uint32_t target_method_idx = 0;
1374 uint32_t invoke_type_idx = 0; // Default to virtual (in case of quickened).
1375 DCHECK_EQ(invoke_types[invoke_type_idx], kVirtual);
1376 if (is_quick_invoke) {
1377 // We need to store the vtable index since we can't necessarily recreate it at resolve
1378 // phase if the dequickening resolved to an interface method.
1379 vtable_index = mir->dalvikInsn.vB;
1380 // Fake up the method index by storing the mir offset so that we can read the dequicken
1381 // info in resolve.
1382 target_method_idx = mir->offset | kMethodIdxFlagQuickened;
1383 } else {
1384 DCHECK(is_invoke);
1385 // Decode target method index and invoke type.
1386 invoke_type_idx = InvokeInstructionType(mir->dalvikInsn.opcode);
1387 target_method_idx = mir->dalvikInsn.vB;
1388 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001389 // Find devirtualization target.
1390 // TODO: The devirt map is ordered by the dex pc here. Is there a way to get INVOKEs
1391 // ordered by dex pc as well? That would allow us to keep an iterator to devirt targets
1392 // and increment it as needed instead of making O(log n) lookups.
Vladimir Markof096aad2014-01-23 15:51:58 +00001393 const MethodReference* devirt_target = verified_method->GetDevirtTarget(mir->offset);
Vladimir Markof096aad2014-01-23 15:51:58 +00001394 // Try to insert a new entry. If the insertion fails, we will have found an old one.
1395 MapEntry entry = {
1396 devirt_target,
1397 target_method_idx,
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001398 vtable_index,
Vladimir Markof096aad2014-01-23 15:51:58 +00001399 invoke_types[invoke_type_idx],
1400 static_cast<uint32_t>(invoke_map.size())
1401 };
1402 auto it = invoke_map.insert(entry).first; // Iterator to either the old or the new entry.
1403 mir->meta.method_lowering_info = it->lowering_info_index;
1404 // If we didn't actually insert, this will just overwrite an existing value with the same.
1405 sequential_entries[it->lowering_info_index] = &*it;
1406 }
1407 }
1408 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001409 if (invoke_map.empty()) {
1410 return;
1411 }
Vladimir Markof096aad2014-01-23 15:51:58 +00001412 // Prepare unique method infos, set method info indexes for their MIRs.
Vladimir Markof096aad2014-01-23 15:51:58 +00001413 const size_t count = invoke_map.size();
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001414 method_lowering_infos_.reserve(count);
Vladimir Markof096aad2014-01-23 15:51:58 +00001415 for (size_t pos = 0u; pos != count; ++pos) {
1416 const MapEntry* entry = sequential_entries[pos];
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001417 const bool is_quick = (entry->target_method_idx & kMethodIdxFlagQuickened) != 0;
1418 const uint32_t masked_method_idx = entry->target_method_idx & ~kMethodIdxFlagQuickened;
1419 MirMethodLoweringInfo method_info(masked_method_idx,
1420 static_cast<InvokeType>(entry->invoke_type), is_quick);
Vladimir Markof096aad2014-01-23 15:51:58 +00001421 if (entry->devirt_target != nullptr) {
1422 method_info.SetDevirtualizationTarget(*entry->devirt_target);
1423 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001424 if (is_quick) {
1425 method_info.SetVTableIndex(entry->vtable_idx);
1426 }
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001427 method_lowering_infos_.push_back(method_info);
Vladimir Markof096aad2014-01-23 15:51:58 +00001428 }
1429 MirMethodLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(),
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001430 method_lowering_infos_.data(), count);
Vladimir Markof096aad2014-01-23 15:51:58 +00001431}
1432
buzbeeee17e0a2013-07-31 10:47:37 -07001433} // namespace art