blob: 44f69ba674cc7665d27cd9ce0d94ad6614bd6019 [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
buzbeeee17e0a2013-07-31 10:47:37 -070020#include "compiler_internals.h"
21#include "dataflow_iterator-inl.h"
Vladimir Markobe0e5462014-02-26 11:24:15 +000022#include "dex_instruction.h"
23#include "dex_instruction-inl.h"
Vladimir Markof096aad2014-01-23 15:51:58 +000024#include "dex/verified_method.h"
Vladimir Marko5816ed42013-11-27 17:04:20 +000025#include "dex/quick/dex_file_method_inliner.h"
26#include "dex/quick/dex_file_to_method_inliner_map.h"
Brian Carlstrom6449c622014-02-10 23:48:36 -080027#include "driver/compiler_options.h"
Vladimir Marko69f08ba2014-04-11 12:28:11 +010028#include "utils/scoped_arena_containers.h"
buzbeeee17e0a2013-07-31 10:47:37 -070029
30namespace art {
31
Ian Rogers584cc792014-09-29 10:49:11 -070032enum InstructionAnalysisAttributeOps : uint8_t {
33 kUninterestingOp = 0,
34 kArithmeticOp,
35 kFpOp,
36 kSingleOp,
37 kDoubleOp,
38 kIntOp,
39 kLongOp,
40 kBranchOp,
41 kInvokeOp,
42 kArrayOp,
43 kHeavyweightOp,
44 kSimpleConstOp,
45 kMoveOp,
46 kSwitch
47};
48
49enum InstructionAnalysisAttributeMasks : uint16_t {
50 kAnNone = 1 << kUninterestingOp,
51 kAnMath = 1 << kArithmeticOp,
52 kAnFp = 1 << kFpOp,
53 kAnLong = 1 << kLongOp,
54 kAnInt = 1 << kIntOp,
55 kAnSingle = 1 << kSingleOp,
56 kAnDouble = 1 << kDoubleOp,
57 kAnFloatMath = 1 << kFpOp,
58 kAnBranch = 1 << kBranchOp,
59 kAnInvoke = 1 << kInvokeOp,
60 kAnArrayOp = 1 << kArrayOp,
61 kAnHeavyWeight = 1 << kHeavyweightOp,
62 kAnSimpleConst = 1 << kSimpleConstOp,
63 kAnMove = 1 << kMoveOp,
64 kAnSwitch = 1 << kSwitch,
65 kAnComputational = kAnMath | kAnArrayOp | kAnMove | kAnSimpleConst,
66};
67
68// Instruction characteristics used to statically identify computation-intensive methods.
69static const uint16_t kAnalysisAttributes[kMirOpLast] = {
buzbeeee17e0a2013-07-31 10:47:37 -070070 // 00 NOP
Ian Rogers584cc792014-09-29 10:49:11 -070071 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -070072
73 // 01 MOVE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -070074 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070075
76 // 02 MOVE_FROM16 vAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070077 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070078
79 // 03 MOVE_16 vAAAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070080 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070081
82 // 04 MOVE_WIDE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -070083 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070084
85 // 05 MOVE_WIDE_FROM16 vAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070086 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070087
88 // 06 MOVE_WIDE_16 vAAAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070089 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070090
91 // 07 MOVE_OBJECT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -070092 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070093
94 // 08 MOVE_OBJECT_FROM16 vAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070095 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070096
97 // 09 MOVE_OBJECT_16 vAAAA, vBBBB
Ian Rogers584cc792014-09-29 10:49:11 -070098 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -070099
100 // 0A MOVE_RESULT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700101 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700102
103 // 0B MOVE_RESULT_WIDE vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700104 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700105
106 // 0C MOVE_RESULT_OBJECT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700107 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700108
109 // 0D MOVE_EXCEPTION vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700110 kAnMove,
buzbeeee17e0a2013-07-31 10:47:37 -0700111
112 // 0E RETURN_VOID
Ian Rogers584cc792014-09-29 10:49:11 -0700113 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700114
115 // 0F RETURN vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700116 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700117
118 // 10 RETURN_WIDE vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700119 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700120
121 // 11 RETURN_OBJECT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700122 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700123
124 // 12 CONST_4 vA, #+B
Ian Rogers584cc792014-09-29 10:49:11 -0700125 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700126
127 // 13 CONST_16 vAA, #+BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700128 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700129
130 // 14 CONST vAA, #+BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700131 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700132
133 // 15 CONST_HIGH16 VAA, #+BBBB0000
Ian Rogers584cc792014-09-29 10:49:11 -0700134 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700135
136 // 16 CONST_WIDE_16 vAA, #+BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700137 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700138
139 // 17 CONST_WIDE_32 vAA, #+BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700140 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700141
142 // 18 CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700143 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700144
145 // 19 CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
Ian Rogers584cc792014-09-29 10:49:11 -0700146 kAnSimpleConst,
buzbeeee17e0a2013-07-31 10:47:37 -0700147
148 // 1A CONST_STRING vAA, string@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700149 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700150
151 // 1B CONST_STRING_JUMBO vAA, string@BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700152 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700153
154 // 1C CONST_CLASS vAA, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700155 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700156
157 // 1D MONITOR_ENTER vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700158 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700159
160 // 1E MONITOR_EXIT vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700161 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700162
163 // 1F CHK_CAST vAA, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700164 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700165
166 // 20 INSTANCE_OF vA, vB, type@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700167 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700168
169 // 21 ARRAY_LENGTH vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700170 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700171
172 // 22 NEW_INSTANCE vAA, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700173 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700174
175 // 23 NEW_ARRAY vA, vB, type@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700176 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700177
178 // 24 FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700179 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700180
181 // 25 FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700182 kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700183
184 // 26 FILL_ARRAY_DATA vAA, +BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700185 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700186
187 // 27 THROW vAA
Ian Rogers584cc792014-09-29 10:49:11 -0700188 kAnHeavyWeight | kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700189
190 // 28 GOTO
Ian Rogers584cc792014-09-29 10:49:11 -0700191 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700192
193 // 29 GOTO_16
Ian Rogers584cc792014-09-29 10:49:11 -0700194 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700195
196 // 2A GOTO_32
Ian Rogers584cc792014-09-29 10:49:11 -0700197 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700198
199 // 2B PACKED_SWITCH vAA, +BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700200 kAnSwitch,
buzbeeee17e0a2013-07-31 10:47:37 -0700201
202 // 2C SPARSE_SWITCH vAA, +BBBBBBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700203 kAnSwitch,
buzbeeee17e0a2013-07-31 10:47:37 -0700204
205 // 2D CMPL_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700206 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700207
208 // 2E CMPG_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700209 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700210
211 // 2F CMPL_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700212 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700213
214 // 30 CMPG_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700215 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700216
217 // 31 CMP_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700218 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700219
220 // 32 IF_EQ vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700221 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700222
223 // 33 IF_NE vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700224 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700225
226 // 34 IF_LT vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700227 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700228
229 // 35 IF_GE vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700230 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700231
232 // 36 IF_GT vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700233 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700234
235 // 37 IF_LE vA, vB, +CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700236 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700237
238 // 38 IF_EQZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700239 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700240
241 // 39 IF_NEZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700242 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700243
244 // 3A IF_LTZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700245 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700246
247 // 3B IF_GEZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700248 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700249
250 // 3C IF_GTZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700251 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700252
253 // 3D IF_LEZ vAA, +BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700254 kAnMath | kAnBranch | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700255
256 // 3E UNUSED_3E
Ian Rogers584cc792014-09-29 10:49:11 -0700257 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700258
259 // 3F UNUSED_3F
Ian Rogers584cc792014-09-29 10:49:11 -0700260 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700261
262 // 40 UNUSED_40
Ian Rogers584cc792014-09-29 10:49:11 -0700263 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700264
265 // 41 UNUSED_41
Ian Rogers584cc792014-09-29 10:49:11 -0700266 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700267
268 // 42 UNUSED_42
Ian Rogers584cc792014-09-29 10:49:11 -0700269 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700270
271 // 43 UNUSED_43
Ian Rogers584cc792014-09-29 10:49:11 -0700272 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700273
274 // 44 AGET vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700275 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700276
277 // 45 AGET_WIDE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700278 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700279
280 // 46 AGET_OBJECT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700281 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700282
283 // 47 AGET_BOOLEAN vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700284 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700285
286 // 48 AGET_BYTE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700287 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700288
289 // 49 AGET_CHAR vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700290 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700291
292 // 4A AGET_SHORT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700293 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700294
295 // 4B APUT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700296 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700297
298 // 4C APUT_WIDE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700299 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700300
301 // 4D APUT_OBJECT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700302 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700303
304 // 4E APUT_BOOLEAN vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700305 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700306
307 // 4F APUT_BYTE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700308 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700309
310 // 50 APUT_CHAR vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700311 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700312
313 // 51 APUT_SHORT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700314 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700315
316 // 52 IGET vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700317 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700318
319 // 53 IGET_WIDE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700320 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700321
322 // 54 IGET_OBJECT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700323 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700324
325 // 55 IGET_BOOLEAN vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700326 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700327
328 // 56 IGET_BYTE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700329 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700330
331 // 57 IGET_CHAR vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700332 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700333
334 // 58 IGET_SHORT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700335 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700336
337 // 59 IPUT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700338 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700339
340 // 5A IPUT_WIDE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700341 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700342
343 // 5B IPUT_OBJECT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700344 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700345
346 // 5C IPUT_BOOLEAN vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700347 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700348
349 // 5D IPUT_BYTE vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700350 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700351
352 // 5E IPUT_CHAR vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700353 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700354
355 // 5F IPUT_SHORT vA, vB, field@CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700356 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700357
358 // 60 SGET vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700359 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700360
361 // 61 SGET_WIDE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700362 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700363
364 // 62 SGET_OBJECT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700365 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700366
367 // 63 SGET_BOOLEAN vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700368 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700369
370 // 64 SGET_BYTE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700371 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700372
373 // 65 SGET_CHAR vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700374 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700375
376 // 66 SGET_SHORT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700377 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700378
379 // 67 SPUT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700380 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700381
382 // 68 SPUT_WIDE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700383 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700384
385 // 69 SPUT_OBJECT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700386 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700387
388 // 6A SPUT_BOOLEAN vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700389 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700390
391 // 6B SPUT_BYTE vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700392 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700393
394 // 6C SPUT_CHAR vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700395 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700396
397 // 6D SPUT_SHORT vAA, field@BBBB
Ian Rogers584cc792014-09-29 10:49:11 -0700398 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700399
400 // 6E INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700401 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700402
403 // 6F INVOKE_SUPER {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700404 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700405
406 // 70 INVOKE_DIRECT {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700407 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700408
409 // 71 INVOKE_STATIC {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700410 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700411
412 // 72 INVOKE_INTERFACE {vD, vE, vF, vG, vA}
Ian Rogers584cc792014-09-29 10:49:11 -0700413 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700414
415 // 73 UNUSED_73
Ian Rogers584cc792014-09-29 10:49:11 -0700416 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700417
418 // 74 INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700419 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700420
421 // 75 INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700422 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700423
424 // 76 INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700425 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700426
427 // 77 INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700428 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700429
430 // 78 INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
Ian Rogers584cc792014-09-29 10:49:11 -0700431 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700432
433 // 79 UNUSED_79
Ian Rogers584cc792014-09-29 10:49:11 -0700434 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700435
436 // 7A UNUSED_7A
Ian Rogers584cc792014-09-29 10:49:11 -0700437 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700438
439 // 7B NEG_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700440 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700441
442 // 7C NOT_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700443 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700444
445 // 7D NEG_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700446 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700447
448 // 7E NOT_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700449 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700450
451 // 7F NEG_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700452 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700453
454 // 80 NEG_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700455 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700456
457 // 81 INT_TO_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700458 kAnMath | kAnInt | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700459
460 // 82 INT_TO_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700461 kAnMath | kAnFp | kAnInt | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700462
463 // 83 INT_TO_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700464 kAnMath | kAnFp | kAnInt | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700465
466 // 84 LONG_TO_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700467 kAnMath | kAnInt | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700468
469 // 85 LONG_TO_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700470 kAnMath | kAnFp | kAnLong | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700471
472 // 86 LONG_TO_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700473 kAnMath | kAnFp | kAnLong | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700474
475 // 87 FLOAT_TO_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700476 kAnMath | kAnFp | kAnInt | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700477
478 // 88 FLOAT_TO_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700479 kAnMath | kAnFp | kAnLong | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700480
481 // 89 FLOAT_TO_DOUBLE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700482 kAnMath | kAnFp | kAnSingle | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700483
484 // 8A DOUBLE_TO_INT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700485 kAnMath | kAnFp | kAnInt | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700486
487 // 8B DOUBLE_TO_LONG vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700488 kAnMath | kAnFp | kAnLong | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700489
490 // 8C DOUBLE_TO_FLOAT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700491 kAnMath | kAnFp | kAnSingle | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700492
493 // 8D INT_TO_BYTE vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700494 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700495
496 // 8E INT_TO_CHAR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700497 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700498
499 // 8F INT_TO_SHORT vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700500 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700501
502 // 90 ADD_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700503 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700504
505 // 91 SUB_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700506 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700507
508 // 92 MUL_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700509 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700510
511 // 93 DIV_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700512 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700513
514 // 94 REM_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700515 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700516
517 // 95 AND_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700518 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700519
520 // 96 OR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700521 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700522
523 // 97 XOR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700524 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700525
526 // 98 SHL_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700527 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700528
529 // 99 SHR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700530 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700531
532 // 9A USHR_INT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700533 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700534
535 // 9B ADD_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700536 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700537
538 // 9C SUB_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700539 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700540
541 // 9D MUL_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700542 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700543
544 // 9E DIV_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700545 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700546
547 // 9F REM_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700548 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700549
550 // A0 AND_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700551 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700552
553 // A1 OR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700554 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700555
556 // A2 XOR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700557 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700558
559 // A3 SHL_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700560 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700561
562 // A4 SHR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700563 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700564
565 // A5 USHR_LONG vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700566 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700567
568 // A6 ADD_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700569 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700570
571 // A7 SUB_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700572 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700573
574 // A8 MUL_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700575 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700576
577 // A9 DIV_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700578 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700579
580 // AA REM_FLOAT vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700581 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700582
583 // AB ADD_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700584 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700585
586 // AC SUB_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700587 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700588
589 // AD MUL_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700590 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700591
592 // AE DIV_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700593 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700594
595 // AF REM_DOUBLE vAA, vBB, vCC
Ian Rogers584cc792014-09-29 10:49:11 -0700596 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700597
598 // B0 ADD_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700599 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700600
601 // B1 SUB_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700602 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700603
604 // B2 MUL_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700605 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700606
607 // B3 DIV_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700608 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700609
610 // B4 REM_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700611 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700612
613 // B5 AND_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700614 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700615
616 // B6 OR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700617 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700618
619 // B7 XOR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700620 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700621
622 // B8 SHL_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700623 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700624
625 // B9 SHR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700626 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700627
628 // BA USHR_INT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700629 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700630
631 // BB ADD_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700632 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700633
634 // BC SUB_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700635 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700636
637 // BD MUL_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700638 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700639
640 // BE DIV_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700641 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700642
643 // BF REM_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700644 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700645
646 // C0 AND_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700647 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700648
649 // C1 OR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700650 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700651
652 // C2 XOR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700653 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700654
655 // C3 SHL_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700656 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700657
658 // C4 SHR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700659 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700660
661 // C5 USHR_LONG_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700662 kAnMath | kAnLong,
buzbeeee17e0a2013-07-31 10:47:37 -0700663
664 // C6 ADD_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700665 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700666
667 // C7 SUB_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700668 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700669
670 // C8 MUL_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700671 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700672
673 // C9 DIV_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700674 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700675
676 // CA REM_FLOAT_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700677 kAnMath | kAnFp | kAnSingle,
buzbeeee17e0a2013-07-31 10:47:37 -0700678
679 // CB ADD_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700680 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700681
682 // CC SUB_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700683 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700684
685 // CD MUL_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700686 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700687
688 // CE DIV_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700689 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700690
691 // CF REM_DOUBLE_2ADDR vA, vB
Ian Rogers584cc792014-09-29 10:49:11 -0700692 kAnMath | kAnFp | kAnDouble,
buzbeeee17e0a2013-07-31 10:47:37 -0700693
694 // D0 ADD_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700695 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700696
697 // D1 RSUB_INT vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700698 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700699
700 // D2 MUL_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700701 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700702
703 // D3 DIV_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700704 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700705
706 // D4 REM_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700707 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700708
709 // D5 AND_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700710 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700711
712 // D6 OR_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700713 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700714
715 // D7 XOR_INT_LIT16 vA, vB, #+CCCC
Ian Rogers584cc792014-09-29 10:49:11 -0700716 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700717
718 // D8 ADD_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700719 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700720
721 // D9 RSUB_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700722 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700723
724 // DA MUL_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700725 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700726
727 // DB DIV_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700728 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700729
730 // DC REM_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700731 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700732
733 // DD AND_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700734 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700735
736 // DE OR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700737 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700738
739 // DF XOR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700740 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700741
742 // E0 SHL_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700743 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700744
745 // E1 SHR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700746 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700747
748 // E2 USHR_INT_LIT8 vAA, vBB, #+CC
Ian Rogers584cc792014-09-29 10:49:11 -0700749 kAnMath | kAnInt,
buzbeeee17e0a2013-07-31 10:47:37 -0700750
751 // E3 IGET_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700752 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700753
754 // E4 IPUT_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700755 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700756
757 // E5 SGET_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700758 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700759
760 // E6 SPUT_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700761 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700762
763 // E7 IGET_OBJECT_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700764 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700765
766 // E8 IGET_WIDE_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700767 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700768
769 // E9 IPUT_WIDE_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700770 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700771
772 // EA SGET_WIDE_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700773 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700774
775 // EB SPUT_WIDE_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700776 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700777
778 // EC BREAKPOINT
Ian Rogers584cc792014-09-29 10:49:11 -0700779 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700780
781 // ED THROW_VERIFICATION_ERROR
Ian Rogers584cc792014-09-29 10:49:11 -0700782 kAnHeavyWeight | kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700783
784 // EE EXECUTE_INLINE
Ian Rogers584cc792014-09-29 10:49:11 -0700785 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700786
787 // EF EXECUTE_INLINE_RANGE
Ian Rogers584cc792014-09-29 10:49:11 -0700788 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700789
790 // F0 INVOKE_OBJECT_INIT_RANGE
Ian Rogers584cc792014-09-29 10:49:11 -0700791 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700792
793 // F1 RETURN_VOID_BARRIER
Ian Rogers584cc792014-09-29 10:49:11 -0700794 kAnBranch,
buzbeeee17e0a2013-07-31 10:47:37 -0700795
796 // F2 IGET_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700797 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700798
799 // F3 IGET_WIDE_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700800 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700801
802 // F4 IGET_OBJECT_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700803 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700804
805 // F5 IPUT_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700806 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700807
808 // F6 IPUT_WIDE_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700809 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700810
811 // F7 IPUT_OBJECT_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700812 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700813
814 // F8 INVOKE_VIRTUAL_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700815 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700816
817 // F9 INVOKE_VIRTUAL_QUICK_RANGE
Ian Rogers584cc792014-09-29 10:49:11 -0700818 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700819
820 // FA INVOKE_SUPER_QUICK
Ian Rogers584cc792014-09-29 10:49:11 -0700821 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700822
823 // FB INVOKE_SUPER_QUICK_RANGE
Ian Rogers584cc792014-09-29 10:49:11 -0700824 kAnInvoke | kAnHeavyWeight,
buzbeeee17e0a2013-07-31 10:47:37 -0700825
826 // FC IPUT_OBJECT_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700827 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700828
829 // FD SGET_OBJECT_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700830 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700831
832 // FE SPUT_OBJECT_VOLATILE
Ian Rogers584cc792014-09-29 10:49:11 -0700833 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700834
835 // FF UNUSED_FF
Ian Rogers584cc792014-09-29 10:49:11 -0700836 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700837
838 // Beginning of extended MIR opcodes
839 // 100 MIR_PHI
Ian Rogers584cc792014-09-29 10:49:11 -0700840 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700841
842 // 101 MIR_COPY
Ian Rogers584cc792014-09-29 10:49:11 -0700843 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700844
845 // 102 MIR_FUSED_CMPL_FLOAT
Ian Rogers584cc792014-09-29 10:49:11 -0700846 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700847
848 // 103 MIR_FUSED_CMPG_FLOAT
Ian Rogers584cc792014-09-29 10:49:11 -0700849 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700850
851 // 104 MIR_FUSED_CMPL_DOUBLE
Ian Rogers584cc792014-09-29 10:49:11 -0700852 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700853
854 // 105 MIR_FUSED_CMPG_DOUBLE
Ian Rogers584cc792014-09-29 10:49:11 -0700855 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700856
857 // 106 MIR_FUSED_CMP_LONG
Ian Rogers584cc792014-09-29 10:49:11 -0700858 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700859
860 // 107 MIR_NOP
Ian Rogers584cc792014-09-29 10:49:11 -0700861 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700862
863 // 108 MIR_NULL_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700864 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700865
866 // 109 MIR_RANGE_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700867 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700868
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700869 // 10A MIR_DIV_ZERO_CHECK
Ian Rogers584cc792014-09-29 10:49:11 -0700870 kAnNone,
buzbeeee17e0a2013-07-31 10:47:37 -0700871
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700872 // 10B MIR_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 // 10C MIR_CHECKPART2
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 // 10D MIR_SELECT
Ian Rogers584cc792014-09-29 10:49:11 -0700879 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900880
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700881 // 10E MirOpConstVector
Ian Rogers584cc792014-09-29 10:49:11 -0700882 kAnNone,
Junmo Parke1fa1dd2014-08-04 17:57:57 +0900883
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700884 // 10F MirOpMoveVector
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 // 110 MirOpPackedMultiply
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 // 111 MirOpPackedAddition
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 // 112 MirOpPackedSubtract
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 // 113 MirOpPackedShiftLeft
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 // 114 MirOpPackedSignedShiftRight
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 // 115 MirOpPackedUnsignedShiftRight
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 // 116 MirOpPackedAnd
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 // 117 MirOpPackedOr
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 // 118 MirOpPackedXor
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 // 119 MirOpPackedAddReduce
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 // 11A MirOpPackedReduce
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 // 11B MirOpPackedSet
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 // 11C MirOpReserveVectorRegisters
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 // 11D MirOpReturnVectorRegisters
Ian Rogers584cc792014-09-29 10:49:11 -0700927 kAnNone,
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700928
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700929 // 11E MirOpMemBarrier
Ian Rogers584cc792014-09-29 10:49:11 -0700930 kAnNone,
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700931
932 // 11F MirOpPackedArrayGet
Ian Rogers584cc792014-09-29 10:49:11 -0700933 kAnArrayOp,
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700934
935 // 120 MirOpPackedArrayPut
Ian Rogers584cc792014-09-29 10:49:11 -0700936 kAnArrayOp,
buzbeeee17e0a2013-07-31 10:47:37 -0700937};
938
939struct MethodStats {
940 int dex_instructions;
941 int math_ops;
942 int fp_ops;
943 int array_ops;
944 int branch_ops;
945 int heavyweight_ops;
946 bool has_computational_loop;
buzbeefe9ca402013-08-21 09:48:11 -0700947 bool has_switch;
buzbeeee17e0a2013-07-31 10:47:37 -0700948 float math_ratio;
949 float fp_ratio;
950 float array_ratio;
951 float branch_ratio;
952 float heavyweight_ratio;
953};
954
955void MIRGraph::AnalyzeBlock(BasicBlock* bb, MethodStats* stats) {
956 if (bb->visited || (bb->block_type != kDalvikByteCode)) {
957 return;
958 }
959 bool computational_block = true;
960 bool has_math = false;
961 /*
962 * For the purposes of this scan, we want to treat the set of basic blocks broken
963 * by an exception edge as a single basic block. We'll scan forward along the fallthrough
964 * edges until we reach an explicit branch or return.
965 */
966 BasicBlock* ending_bb = bb;
967 if (ending_bb->last_mir_insn != NULL) {
Ian Rogers584cc792014-09-29 10:49:11 -0700968 uint32_t ending_flags = kAnalysisAttributes[ending_bb->last_mir_insn->dalvikInsn.opcode];
969 while ((ending_flags & kAnBranch) == 0) {
buzbee0d829482013-10-11 15:24:55 -0700970 ending_bb = GetBasicBlock(ending_bb->fall_through);
Ian Rogers584cc792014-09-29 10:49:11 -0700971 ending_flags = kAnalysisAttributes[ending_bb->last_mir_insn->dalvikInsn.opcode];
buzbeeee17e0a2013-07-31 10:47:37 -0700972 }
973 }
974 /*
975 * Ideally, we'd weight the operations by loop nesting level, but to do so we'd
976 * first need to do some expensive loop detection - and the point of this is to make
977 * an informed guess before investing in computation. However, we can cheaply detect
978 * many simple loop forms without having to do full dataflow analysis.
979 */
980 int loop_scale_factor = 1;
981 // Simple for and while loops
buzbee0d829482013-10-11 15:24:55 -0700982 if ((ending_bb->taken != NullBasicBlockId) && (ending_bb->fall_through == NullBasicBlockId)) {
983 if ((GetBasicBlock(ending_bb->taken)->taken == bb->id) ||
984 (GetBasicBlock(ending_bb->taken)->fall_through == bb->id)) {
buzbeeee17e0a2013-07-31 10:47:37 -0700985 loop_scale_factor = 25;
986 }
987 }
988 // Simple do-while loop
buzbee0d829482013-10-11 15:24:55 -0700989 if ((ending_bb->taken != NullBasicBlockId) && (ending_bb->taken == bb->id)) {
buzbeeee17e0a2013-07-31 10:47:37 -0700990 loop_scale_factor = 25;
991 }
992
993 BasicBlock* tbb = bb;
994 bool done = false;
995 while (!done) {
996 tbb->visited = true;
997 for (MIR* mir = tbb->first_mir_insn; mir != NULL; mir = mir->next) {
Jean Christophe Beyler2ab40eb2014-06-02 09:03:14 -0700998 if (MIR::DecodedInstruction::IsPseudoMirOp(mir->dalvikInsn.opcode)) {
buzbeeee17e0a2013-07-31 10:47:37 -0700999 // Skip any MIR pseudo-op.
1000 continue;
1001 }
Ian Rogers584cc792014-09-29 10:49:11 -07001002 uint16_t flags = kAnalysisAttributes[mir->dalvikInsn.opcode];
buzbeeee17e0a2013-07-31 10:47:37 -07001003 stats->dex_instructions += loop_scale_factor;
Ian Rogers584cc792014-09-29 10:49:11 -07001004 if ((flags & kAnBranch) == 0) {
1005 computational_block &= ((flags & kAnComputational) != 0);
buzbeeee17e0a2013-07-31 10:47:37 -07001006 } else {
1007 stats->branch_ops += loop_scale_factor;
1008 }
Ian Rogers584cc792014-09-29 10:49:11 -07001009 if ((flags & kAnMath) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001010 stats->math_ops += loop_scale_factor;
1011 has_math = true;
1012 }
Ian Rogers584cc792014-09-29 10:49:11 -07001013 if ((flags & kAnFp) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001014 stats->fp_ops += loop_scale_factor;
1015 }
Ian Rogers584cc792014-09-29 10:49:11 -07001016 if ((flags & kAnArrayOp) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001017 stats->array_ops += loop_scale_factor;
1018 }
Ian Rogers584cc792014-09-29 10:49:11 -07001019 if ((flags & kAnHeavyWeight) != 0) {
buzbeeee17e0a2013-07-31 10:47:37 -07001020 stats->heavyweight_ops += loop_scale_factor;
1021 }
Ian Rogers584cc792014-09-29 10:49:11 -07001022 if ((flags & kAnSwitch) != 0) {
buzbeefe9ca402013-08-21 09:48:11 -07001023 stats->has_switch = true;
1024 }
buzbeeee17e0a2013-07-31 10:47:37 -07001025 }
1026 if (tbb == ending_bb) {
1027 done = true;
1028 } else {
buzbee0d829482013-10-11 15:24:55 -07001029 tbb = GetBasicBlock(tbb->fall_through);
buzbeeee17e0a2013-07-31 10:47:37 -07001030 }
1031 }
1032 if (has_math && computational_block && (loop_scale_factor > 1)) {
1033 stats->has_computational_loop = true;
1034 }
1035}
1036
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001037bool MIRGraph::ComputeSkipCompilation(MethodStats* stats, bool skip_default,
1038 std::string* skip_message) {
buzbeeee17e0a2013-07-31 10:47:37 -07001039 float count = stats->dex_instructions;
1040 stats->math_ratio = stats->math_ops / count;
1041 stats->fp_ratio = stats->fp_ops / count;
1042 stats->branch_ratio = stats->branch_ops / count;
1043 stats->array_ratio = stats->array_ops / count;
1044 stats->heavyweight_ratio = stats->heavyweight_ops / count;
1045
1046 if (cu_->enable_debug & (1 << kDebugShowFilterStats)) {
1047 LOG(INFO) << "STATS " << stats->dex_instructions << ", math:"
1048 << stats->math_ratio << ", fp:"
1049 << stats->fp_ratio << ", br:"
1050 << stats->branch_ratio << ", hw:"
buzbeefe9ca402013-08-21 09:48:11 -07001051 << stats->heavyweight_ratio << ", arr:"
buzbeeee17e0a2013-07-31 10:47:37 -07001052 << stats->array_ratio << ", hot:"
1053 << stats->has_computational_loop << ", "
1054 << PrettyMethod(cu_->method_idx, *cu_->dex_file);
1055 }
1056
1057 // Computation intensive?
1058 if (stats->has_computational_loop && (stats->heavyweight_ratio < 0.04)) {
1059 return false;
1060 }
1061
1062 // Complex, logic-intensive?
Brian Carlstrom6449c622014-02-10 23:48:36 -08001063 if (cu_->compiler_driver->GetCompilerOptions().IsSmallMethod(GetNumDalvikInsns()) &&
buzbeeee17e0a2013-07-31 10:47:37 -07001064 stats->branch_ratio > 0.3) {
1065 return false;
1066 }
1067
1068 // Significant floating point?
1069 if (stats->fp_ratio > 0.05) {
1070 return false;
1071 }
1072
1073 // Significant generic math?
1074 if (stats->math_ratio > 0.3) {
1075 return false;
1076 }
1077
1078 // If array-intensive, compiling is probably worthwhile.
1079 if (stats->array_ratio > 0.1) {
1080 return false;
1081 }
1082
buzbeefe9ca402013-08-21 09:48:11 -07001083 // Switch operations benefit greatly from compilation, so go ahead and spend the cycles.
1084 if (stats->has_switch) {
1085 return false;
1086 }
1087
1088 // If significant in size and high proportion of expensive operations, skip.
Brian Carlstrom6449c622014-02-10 23:48:36 -08001089 if (cu_->compiler_driver->GetCompilerOptions().IsSmallMethod(GetNumDalvikInsns()) &&
buzbeefe9ca402013-08-21 09:48:11 -07001090 (stats->heavyweight_ratio > 0.3)) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001091 *skip_message = "Is a small method with heavyweight ratio " +
1092 std::to_string(stats->heavyweight_ratio);
buzbeeee17e0a2013-07-31 10:47:37 -07001093 return true;
1094 }
1095
1096 return skip_default;
1097}
1098
1099 /*
1100 * Will eventually want this to be a bit more sophisticated and happen at verification time.
buzbeeee17e0a2013-07-31 10:47:37 -07001101 */
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001102bool MIRGraph::SkipCompilation(std::string* skip_message) {
Brian Carlstrom6449c622014-02-10 23:48:36 -08001103 const CompilerOptions& compiler_options = cu_->compiler_driver->GetCompilerOptions();
1104 CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
1105 if (compiler_filter == CompilerOptions::kEverything) {
buzbeeee17e0a2013-07-31 10:47:37 -07001106 return false;
1107 }
1108
buzbeeb1f1d642014-02-27 12:55:32 -08001109 // Contains a pattern we don't want to compile?
buzbee8c7a02a2014-06-14 12:33:09 -07001110 if (PuntToInterpreter()) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001111 *skip_message = "Punt to interpreter set";
buzbeeb1f1d642014-02-27 12:55:32 -08001112 return true;
1113 }
1114
Ian Rogersaaf29b32014-11-07 17:05:19 -08001115 DCHECK(compiler_options.IsCompilationEnabled());
buzbeeee17e0a2013-07-31 10:47:37 -07001116
buzbeefe9ca402013-08-21 09:48:11 -07001117 // Set up compilation cutoffs based on current filter mode.
Ian Rogersaaf29b32014-11-07 17:05:19 -08001118 size_t small_cutoff;
1119 size_t default_cutoff;
buzbeefe9ca402013-08-21 09:48:11 -07001120 switch (compiler_filter) {
Brian Carlstrom6449c622014-02-10 23:48:36 -08001121 case CompilerOptions::kBalanced:
1122 small_cutoff = compiler_options.GetSmallMethodThreshold();
1123 default_cutoff = compiler_options.GetLargeMethodThreshold();
buzbeefe9ca402013-08-21 09:48:11 -07001124 break;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001125 case CompilerOptions::kSpace:
1126 small_cutoff = compiler_options.GetTinyMethodThreshold();
1127 default_cutoff = compiler_options.GetSmallMethodThreshold();
buzbeefe9ca402013-08-21 09:48:11 -07001128 break;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001129 case CompilerOptions::kSpeed:
Nicolas Geoffray88157ef2014-09-12 10:29:53 +01001130 case CompilerOptions::kTime:
Brian Carlstrom6449c622014-02-10 23:48:36 -08001131 small_cutoff = compiler_options.GetHugeMethodThreshold();
1132 default_cutoff = compiler_options.GetHugeMethodThreshold();
buzbeefe9ca402013-08-21 09:48:11 -07001133 break;
1134 default:
1135 LOG(FATAL) << "Unexpected compiler_filter_: " << compiler_filter;
Ian Rogersaaf29b32014-11-07 17:05:19 -08001136 UNREACHABLE();
buzbeefe9ca402013-08-21 09:48:11 -07001137 }
1138
1139 // If size < cutoff, assume we'll compile - but allow removal.
1140 bool skip_compilation = (GetNumDalvikInsns() >= default_cutoff);
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001141 if (skip_compilation) {
1142 *skip_message = "#Insns >= default_cutoff: " + std::to_string(GetNumDalvikInsns());
1143 }
buzbeefe9ca402013-08-21 09:48:11 -07001144
1145 /*
1146 * Filter 1: Huge methods are likely to be machine generated, but some aren't.
1147 * If huge, assume we won't compile, but allow futher analysis to turn it back on.
1148 */
Brian Carlstrom6449c622014-02-10 23:48:36 -08001149 if (compiler_options.IsHugeMethod(GetNumDalvikInsns())) {
buzbeefe9ca402013-08-21 09:48:11 -07001150 skip_compilation = true;
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001151 *skip_message = "Huge method: " + std::to_string(GetNumDalvikInsns());
buzbeeb48819d2013-09-14 16:15:25 -07001152 // If we're got a huge number of basic blocks, don't bother with further analysis.
Brian Carlstrom6449c622014-02-10 23:48:36 -08001153 if (static_cast<size_t>(num_blocks_) > (compiler_options.GetHugeMethodThreshold() / 2)) {
buzbeeb48819d2013-09-14 16:15:25 -07001154 return true;
1155 }
Brian Carlstrom6449c622014-02-10 23:48:36 -08001156 } else if (compiler_options.IsLargeMethod(GetNumDalvikInsns()) &&
buzbeeb48819d2013-09-14 16:15:25 -07001157 /* If it's large and contains no branches, it's likely to be machine generated initialization */
1158 (GetBranchCount() == 0)) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001159 *skip_message = "Large method with no branches";
buzbeeb48819d2013-09-14 16:15:25 -07001160 return true;
Brian Carlstrom6449c622014-02-10 23:48:36 -08001161 } else if (compiler_filter == CompilerOptions::kSpeed) {
buzbeefe9ca402013-08-21 09:48:11 -07001162 // If not huge, compile.
1163 return false;
buzbeeee17e0a2013-07-31 10:47:37 -07001164 }
1165
1166 // Filter 2: Skip class initializers.
1167 if (((cu_->access_flags & kAccConstructor) != 0) && ((cu_->access_flags & kAccStatic) != 0)) {
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001168 *skip_message = "Class initializer";
buzbeeee17e0a2013-07-31 10:47:37 -07001169 return true;
1170 }
1171
1172 // Filter 3: if this method is a special pattern, go ahead and emit the canned pattern.
Vladimir Marko5816ed42013-11-27 17:04:20 +00001173 if (cu_->compiler_driver->GetMethodInlinerMap() != nullptr &&
1174 cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file)
1175 ->IsSpecial(cu_->method_idx)) {
buzbeeee17e0a2013-07-31 10:47:37 -07001176 return false;
1177 }
1178
buzbeefe9ca402013-08-21 09:48:11 -07001179 // Filter 4: if small, just compile.
buzbeeee17e0a2013-07-31 10:47:37 -07001180 if (GetNumDalvikInsns() < small_cutoff) {
1181 return false;
1182 }
1183
1184 // Analyze graph for:
1185 // o floating point computation
1186 // o basic blocks contained in loop with heavy arithmetic.
1187 // o proportion of conditional branches.
1188
1189 MethodStats stats;
1190 memset(&stats, 0, sizeof(stats));
1191
1192 ClearAllVisitedFlags();
buzbee56c71782013-09-05 17:13:19 -07001193 AllNodesIterator iter(this);
buzbeeee17e0a2013-07-31 10:47:37 -07001194 for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) {
1195 AnalyzeBlock(bb, &stats);
1196 }
1197
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001198 return ComputeSkipCompilation(&stats, skip_compilation, skip_message);
buzbeeee17e0a2013-07-31 10:47:37 -07001199}
1200
Vladimir Markobe0e5462014-02-26 11:24:15 +00001201void MIRGraph::DoCacheFieldLoweringInfo() {
Vladimir Markoa24122d2014-03-07 10:18:14 +00001202 // 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 -07001203 const uint32_t max_refs = (GetNumDalvikInsns() - 1u) / 2u;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001204 ScopedArenaAllocator allocator(&cu_->arena_stack);
1205 uint16_t* field_idxs =
1206 reinterpret_cast<uint16_t*>(allocator.Alloc(max_refs * sizeof(uint16_t), kArenaAllocMisc));
Vladimir Markobe0e5462014-02-26 11:24:15 +00001207
1208 // Find IGET/IPUT/SGET/SPUT insns, store IGET/IPUT fields at the beginning, SGET/SPUT at the end.
1209 size_t ifield_pos = 0u;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001210 size_t sfield_pos = max_refs;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001211 AllNodesIterator iter(this);
1212 for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
1213 if (bb->block_type != kDalvikByteCode) {
1214 continue;
1215 }
1216 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
1217 if (mir->dalvikInsn.opcode >= Instruction::IGET &&
1218 mir->dalvikInsn.opcode <= Instruction::SPUT_SHORT) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001219 // Get field index and try to find it among existing indexes. If found, it's usually among
1220 // the last few added, so we'll start the search from ifield_pos/sfield_pos. Though this
1221 // is a linear search, it actually performs much better than map based approach.
1222 if (mir->dalvikInsn.opcode <= Instruction::IPUT_SHORT) {
Razvan A Lupusoru75035972014-09-11 15:24:59 -07001223 uint16_t field_idx = mir->dalvikInsn.vC;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001224 size_t i = ifield_pos;
1225 while (i != 0u && field_idxs[i - 1] != field_idx) {
1226 --i;
1227 }
1228 if (i != 0u) {
1229 mir->meta.ifield_lowering_info = i - 1;
1230 } else {
1231 mir->meta.ifield_lowering_info = ifield_pos;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001232 field_idxs[ifield_pos++] = field_idx;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001233 }
1234 } else {
Razvan A Lupusoru75035972014-09-11 15:24:59 -07001235 uint16_t field_idx = mir->dalvikInsn.vB;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001236 size_t i = sfield_pos;
Vladimir Markoa24122d2014-03-07 10:18:14 +00001237 while (i != max_refs && field_idxs[i] != field_idx) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001238 ++i;
1239 }
Vladimir Markoa24122d2014-03-07 10:18:14 +00001240 if (i != max_refs) {
1241 mir->meta.sfield_lowering_info = max_refs - i - 1u;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001242 } else {
Vladimir Markoa24122d2014-03-07 10:18:14 +00001243 mir->meta.sfield_lowering_info = max_refs - sfield_pos;
Vladimir Markobe0e5462014-02-26 11:24:15 +00001244 field_idxs[--sfield_pos] = field_idx;
1245 }
1246 }
1247 DCHECK_LE(ifield_pos, sfield_pos);
1248 }
1249 }
1250 }
1251
1252 if (ifield_pos != 0u) {
1253 // Resolve instance field infos.
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001254 DCHECK_EQ(ifield_lowering_infos_.size(), 0u);
1255 ifield_lowering_infos_.reserve(ifield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001256 for (size_t pos = 0u; pos != ifield_pos; ++pos) {
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001257 ifield_lowering_infos_.push_back(MirIFieldLoweringInfo(field_idxs[pos]));
Vladimir Markobe0e5462014-02-26 11:24:15 +00001258 }
1259 MirIFieldLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(),
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001260 ifield_lowering_infos_.data(), ifield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001261 }
1262
Vladimir Markoa24122d2014-03-07 10:18:14 +00001263 if (sfield_pos != max_refs) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001264 // Resolve static field infos.
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001265 DCHECK_EQ(sfield_lowering_infos_.size(), 0u);
1266 sfield_lowering_infos_.reserve(max_refs - sfield_pos);
Vladimir Markoa24122d2014-03-07 10:18:14 +00001267 for (size_t pos = max_refs; pos != sfield_pos;) {
Vladimir Markobe0e5462014-02-26 11:24:15 +00001268 --pos;
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001269 sfield_lowering_infos_.push_back(MirSFieldLoweringInfo(field_idxs[pos]));
Vladimir Markobe0e5462014-02-26 11:24:15 +00001270 }
1271 MirSFieldLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(),
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001272 sfield_lowering_infos_.data(), max_refs - sfield_pos);
Vladimir Markobe0e5462014-02-26 11:24:15 +00001273 }
1274}
1275
Vladimir Markof096aad2014-01-23 15:51:58 +00001276void MIRGraph::DoCacheMethodLoweringInfo() {
1277 static constexpr uint16_t invoke_types[] = { kVirtual, kSuper, kDirect, kStatic, kInterface };
1278
1279 // Embed the map value in the entry to avoid extra padding in 64-bit builds.
1280 struct MapEntry {
1281 // Map key: target_method_idx, invoke_type, devirt_target. Ordered to avoid padding.
1282 const MethodReference* devirt_target;
1283 uint16_t target_method_idx;
1284 uint16_t invoke_type;
1285 // Map value.
1286 uint32_t lowering_info_index;
1287 };
1288
1289 // Sort INVOKEs by method index, then by opcode, then by devirtualization target.
1290 struct MapEntryComparator {
1291 bool operator()(const MapEntry& lhs, const MapEntry& rhs) const {
1292 if (lhs.target_method_idx != rhs.target_method_idx) {
1293 return lhs.target_method_idx < rhs.target_method_idx;
1294 }
1295 if (lhs.invoke_type != rhs.invoke_type) {
1296 return lhs.invoke_type < rhs.invoke_type;
1297 }
1298 if (lhs.devirt_target != rhs.devirt_target) {
1299 if (lhs.devirt_target == nullptr) {
1300 return true;
1301 }
1302 if (rhs.devirt_target == nullptr) {
1303 return false;
1304 }
1305 return devirt_cmp(*lhs.devirt_target, *rhs.devirt_target);
1306 }
1307 return false;
1308 }
1309 MethodReferenceComparator devirt_cmp;
1310 };
1311
Vladimir Markof096aad2014-01-23 15:51:58 +00001312 ScopedArenaAllocator allocator(&cu_->arena_stack);
1313
1314 // All INVOKE instructions take 3 code units and there must also be a RETURN.
Razvan A Lupusoru75035972014-09-11 15:24:59 -07001315 uint32_t max_refs = (GetNumDalvikInsns() - 1u) / 3u;
Vladimir Markof096aad2014-01-23 15:51:58 +00001316
Vladimir Marko69f08ba2014-04-11 12:28:11 +01001317 // Map invoke key (see MapEntry) to lowering info index and vice versa.
Vladimir Markof096aad2014-01-23 15:51:58 +00001318 // The invoke_map and sequential entries are essentially equivalent to Boost.MultiIndex's
1319 // multi_index_container with one ordered index and one sequential index.
Vladimir Marko69f08ba2014-04-11 12:28:11 +01001320 ScopedArenaSet<MapEntry, MapEntryComparator> invoke_map(MapEntryComparator(),
1321 allocator.Adapter());
Vladimir Markof096aad2014-01-23 15:51:58 +00001322 const MapEntry** sequential_entries = reinterpret_cast<const MapEntry**>(
1323 allocator.Alloc(max_refs * sizeof(sequential_entries[0]), kArenaAllocMisc));
1324
1325 // Find INVOKE insns and their devirtualization targets.
1326 AllNodesIterator iter(this);
1327 for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
1328 if (bb->block_type != kDalvikByteCode) {
1329 continue;
1330 }
1331 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
1332 if (mir->dalvikInsn.opcode >= Instruction::INVOKE_VIRTUAL &&
1333 mir->dalvikInsn.opcode <= Instruction::INVOKE_INTERFACE_RANGE &&
1334 mir->dalvikInsn.opcode != Instruction::RETURN_VOID_BARRIER) {
1335 // Decode target method index and invoke type.
Vladimir Markof096aad2014-01-23 15:51:58 +00001336 uint16_t target_method_idx;
1337 uint16_t invoke_type_idx;
1338 if (mir->dalvikInsn.opcode <= Instruction::INVOKE_INTERFACE) {
Razvan A Lupusoru75035972014-09-11 15:24:59 -07001339 target_method_idx = mir->dalvikInsn.vB;
Vladimir Markof096aad2014-01-23 15:51:58 +00001340 invoke_type_idx = mir->dalvikInsn.opcode - Instruction::INVOKE_VIRTUAL;
1341 } else {
Razvan A Lupusoru75035972014-09-11 15:24:59 -07001342 target_method_idx = mir->dalvikInsn.vB;
Vladimir Markof096aad2014-01-23 15:51:58 +00001343 invoke_type_idx = mir->dalvikInsn.opcode - Instruction::INVOKE_VIRTUAL_RANGE;
1344 }
1345
1346 // Find devirtualization target.
1347 // TODO: The devirt map is ordered by the dex pc here. Is there a way to get INVOKEs
1348 // ordered by dex pc as well? That would allow us to keep an iterator to devirt targets
1349 // and increment it as needed instead of making O(log n) lookups.
1350 const VerifiedMethod* verified_method = GetCurrentDexCompilationUnit()->GetVerifiedMethod();
1351 const MethodReference* devirt_target = verified_method->GetDevirtTarget(mir->offset);
1352
1353 // Try to insert a new entry. If the insertion fails, we will have found an old one.
1354 MapEntry entry = {
1355 devirt_target,
1356 target_method_idx,
1357 invoke_types[invoke_type_idx],
1358 static_cast<uint32_t>(invoke_map.size())
1359 };
1360 auto it = invoke_map.insert(entry).first; // Iterator to either the old or the new entry.
1361 mir->meta.method_lowering_info = it->lowering_info_index;
1362 // If we didn't actually insert, this will just overwrite an existing value with the same.
1363 sequential_entries[it->lowering_info_index] = &*it;
1364 }
1365 }
1366 }
1367
1368 if (invoke_map.empty()) {
1369 return;
1370 }
1371
1372 // Prepare unique method infos, set method info indexes for their MIRs.
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001373 DCHECK_EQ(method_lowering_infos_.size(), 0u);
Vladimir Markof096aad2014-01-23 15:51:58 +00001374 const size_t count = invoke_map.size();
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001375 method_lowering_infos_.reserve(count);
Vladimir Markof096aad2014-01-23 15:51:58 +00001376 for (size_t pos = 0u; pos != count; ++pos) {
1377 const MapEntry* entry = sequential_entries[pos];
1378 MirMethodLoweringInfo method_info(entry->target_method_idx,
1379 static_cast<InvokeType>(entry->invoke_type));
1380 if (entry->devirt_target != nullptr) {
1381 method_info.SetDevirtualizationTarget(*entry->devirt_target);
1382 }
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001383 method_lowering_infos_.push_back(method_info);
Vladimir Markof096aad2014-01-23 15:51:58 +00001384 }
1385 MirMethodLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(),
Vladimir Markoe39c54e2014-09-22 14:50:02 +01001386 method_lowering_infos_.data(), count);
Vladimir Markof096aad2014-01-23 15:51:58 +00001387}
1388
Andreas Gampe060e6fe2014-06-19 11:34:06 -07001389bool MIRGraph::SkipCompilationByName(const std::string& methodname) {
Dave Allison39c3bfb2014-01-28 18:33:52 -08001390 return cu_->compiler_driver->SkipCompilation(methodname);
1391}
1392
buzbeeee17e0a2013-07-31 10:47:37 -07001393} // namespace art