blob: 2523a83c398eb3de9be632fca6e49dde246141fd [file] [log] [blame]
Andreas Gampe53c913b2014-08-12 23:19:23 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "quick_compiler.h"
18
19#include <cstdint>
20
Mathieu Chartiere401d142015-04-22 13:56:20 -070021#include "art_method-inl.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080022#include "base/dumpable.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080023#include "base/logging.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080024#include "base/macros.h"
25#include "base/timing_logger.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070026#include "compiler.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080027#include "dex_file-inl.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080028#include "dex_file_to_method_inliner_map.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080029#include "dex/compiler_ir.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080030#include "dex/dex_flags.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070031#include "dex/mir_graph.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080032#include "dex/pass_driver_me_opts.h"
Mathieu Chartier5bdab122015-01-26 18:30:19 -080033#include "dex/pass_driver_me_post_opt.h"
34#include "dex/pass_manager.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070035#include "dex/quick/mir_to_lir.h"
36#include "driver/compiler_driver.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080037#include "driver/compiler_options.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070038#include "elf_writer_quick.h"
39#include "jni/quick/jni_compiler.h"
Andreas Gampe9c462082015-01-27 14:31:40 -080040#include "mir_to_lir.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080041#include "mirror/object.h"
42#include "runtime.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070043
44// Specific compiler backends.
45#include "dex/quick/arm/backend_arm.h"
46#include "dex/quick/arm64/backend_arm64.h"
47#include "dex/quick/mips/backend_mips.h"
48#include "dex/quick/x86/backend_x86.h"
49
50namespace art {
51
Andreas Gampe785d2f22014-11-03 22:57:30 -080052static_assert(0U == static_cast<size_t>(kNone), "kNone not 0");
53static_assert(1U == static_cast<size_t>(kArm), "kArm not 1");
54static_assert(2U == static_cast<size_t>(kArm64), "kArm64 not 2");
55static_assert(3U == static_cast<size_t>(kThumb2), "kThumb2 not 3");
56static_assert(4U == static_cast<size_t>(kX86), "kX86 not 4");
57static_assert(5U == static_cast<size_t>(kX86_64), "kX86_64 not 5");
58static_assert(6U == static_cast<size_t>(kMips), "kMips not 6");
59static_assert(7U == static_cast<size_t>(kMips64), "kMips64 not 7");
Andreas Gampe53c913b2014-08-12 23:19:23 -070060
61// Additional disabled optimizations (over generally disabled) per instruction set.
62static constexpr uint32_t kDisabledOptimizationsPerISA[] = {
63 // 0 = kNone.
64 ~0U,
65 // 1 = kArm, unused (will use kThumb2).
66 ~0U,
67 // 2 = kArm64.
68 0,
69 // 3 = kThumb2.
70 0,
71 // 4 = kX86.
72 (1 << kLoadStoreElimination) |
73 0,
74 // 5 = kX86_64.
75 (1 << kLoadStoreElimination) |
76 0,
77 // 6 = kMips.
78 (1 << kLoadStoreElimination) |
79 (1 << kLoadHoisting) |
80 (1 << kSuppressLoads) |
81 (1 << kNullCheckElimination) |
82 (1 << kPromoteRegs) |
83 (1 << kTrackLiveTemps) |
84 (1 << kSafeOptimizations) |
85 (1 << kBBOpt) |
86 (1 << kMatch) |
87 (1 << kPromoteCompilerTemps) |
88 0,
89 // 7 = kMips64.
Maja Gagic6ea651f2015-02-24 16:55:04 +010090 (1 << kLoadStoreElimination) |
91 (1 << kLoadHoisting) |
92 (1 << kSuppressLoads) |
93 (1 << kNullCheckElimination) |
94 (1 << kPromoteRegs) |
95 (1 << kTrackLiveTemps) |
96 (1 << kSafeOptimizations) |
97 (1 << kBBOpt) |
98 (1 << kMatch) |
99 (1 << kPromoteCompilerTemps) |
100 0
Andreas Gampe53c913b2014-08-12 23:19:23 -0700101};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800102static_assert(sizeof(kDisabledOptimizationsPerISA) == 8 * sizeof(uint32_t),
103 "kDisabledOpts unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700104
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700105// Supported shorty types per instruction set. null means that all are available.
Andreas Gampe53c913b2014-08-12 23:19:23 -0700106// Z : boolean
107// B : byte
108// S : short
109// C : char
110// I : int
111// J : long
112// F : float
113// D : double
114// L : reference(object, array)
115// V : void
116static const char* kSupportedTypes[] = {
117 // 0 = kNone.
118 "",
119 // 1 = kArm, unused (will use kThumb2).
120 "",
121 // 2 = kArm64.
122 nullptr,
123 // 3 = kThumb2.
124 nullptr,
125 // 4 = kX86.
126 nullptr,
127 // 5 = kX86_64.
128 nullptr,
129 // 6 = kMips.
130 nullptr,
131 // 7 = kMips64.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100132 nullptr
Andreas Gampe53c913b2014-08-12 23:19:23 -0700133};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800134static_assert(sizeof(kSupportedTypes) == 8 * sizeof(char*), "kSupportedTypes unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700135
136static int kAllOpcodes[] = {
137 Instruction::NOP,
138 Instruction::MOVE,
139 Instruction::MOVE_FROM16,
140 Instruction::MOVE_16,
141 Instruction::MOVE_WIDE,
142 Instruction::MOVE_WIDE_FROM16,
143 Instruction::MOVE_WIDE_16,
144 Instruction::MOVE_OBJECT,
145 Instruction::MOVE_OBJECT_FROM16,
146 Instruction::MOVE_OBJECT_16,
147 Instruction::MOVE_RESULT,
148 Instruction::MOVE_RESULT_WIDE,
149 Instruction::MOVE_RESULT_OBJECT,
150 Instruction::MOVE_EXCEPTION,
151 Instruction::RETURN_VOID,
152 Instruction::RETURN,
153 Instruction::RETURN_WIDE,
154 Instruction::RETURN_OBJECT,
155 Instruction::CONST_4,
156 Instruction::CONST_16,
157 Instruction::CONST,
158 Instruction::CONST_HIGH16,
159 Instruction::CONST_WIDE_16,
160 Instruction::CONST_WIDE_32,
161 Instruction::CONST_WIDE,
162 Instruction::CONST_WIDE_HIGH16,
163 Instruction::CONST_STRING,
164 Instruction::CONST_STRING_JUMBO,
165 Instruction::CONST_CLASS,
166 Instruction::MONITOR_ENTER,
167 Instruction::MONITOR_EXIT,
168 Instruction::CHECK_CAST,
169 Instruction::INSTANCE_OF,
170 Instruction::ARRAY_LENGTH,
171 Instruction::NEW_INSTANCE,
172 Instruction::NEW_ARRAY,
173 Instruction::FILLED_NEW_ARRAY,
174 Instruction::FILLED_NEW_ARRAY_RANGE,
175 Instruction::FILL_ARRAY_DATA,
176 Instruction::THROW,
177 Instruction::GOTO,
178 Instruction::GOTO_16,
179 Instruction::GOTO_32,
180 Instruction::PACKED_SWITCH,
181 Instruction::SPARSE_SWITCH,
182 Instruction::CMPL_FLOAT,
183 Instruction::CMPG_FLOAT,
184 Instruction::CMPL_DOUBLE,
185 Instruction::CMPG_DOUBLE,
186 Instruction::CMP_LONG,
187 Instruction::IF_EQ,
188 Instruction::IF_NE,
189 Instruction::IF_LT,
190 Instruction::IF_GE,
191 Instruction::IF_GT,
192 Instruction::IF_LE,
193 Instruction::IF_EQZ,
194 Instruction::IF_NEZ,
195 Instruction::IF_LTZ,
196 Instruction::IF_GEZ,
197 Instruction::IF_GTZ,
198 Instruction::IF_LEZ,
199 Instruction::UNUSED_3E,
200 Instruction::UNUSED_3F,
201 Instruction::UNUSED_40,
202 Instruction::UNUSED_41,
203 Instruction::UNUSED_42,
204 Instruction::UNUSED_43,
205 Instruction::AGET,
206 Instruction::AGET_WIDE,
207 Instruction::AGET_OBJECT,
208 Instruction::AGET_BOOLEAN,
209 Instruction::AGET_BYTE,
210 Instruction::AGET_CHAR,
211 Instruction::AGET_SHORT,
212 Instruction::APUT,
213 Instruction::APUT_WIDE,
214 Instruction::APUT_OBJECT,
215 Instruction::APUT_BOOLEAN,
216 Instruction::APUT_BYTE,
217 Instruction::APUT_CHAR,
218 Instruction::APUT_SHORT,
219 Instruction::IGET,
220 Instruction::IGET_WIDE,
221 Instruction::IGET_OBJECT,
222 Instruction::IGET_BOOLEAN,
223 Instruction::IGET_BYTE,
224 Instruction::IGET_CHAR,
225 Instruction::IGET_SHORT,
226 Instruction::IPUT,
227 Instruction::IPUT_WIDE,
228 Instruction::IPUT_OBJECT,
229 Instruction::IPUT_BOOLEAN,
230 Instruction::IPUT_BYTE,
231 Instruction::IPUT_CHAR,
232 Instruction::IPUT_SHORT,
233 Instruction::SGET,
234 Instruction::SGET_WIDE,
235 Instruction::SGET_OBJECT,
236 Instruction::SGET_BOOLEAN,
237 Instruction::SGET_BYTE,
238 Instruction::SGET_CHAR,
239 Instruction::SGET_SHORT,
240 Instruction::SPUT,
241 Instruction::SPUT_WIDE,
242 Instruction::SPUT_OBJECT,
243 Instruction::SPUT_BOOLEAN,
244 Instruction::SPUT_BYTE,
245 Instruction::SPUT_CHAR,
246 Instruction::SPUT_SHORT,
247 Instruction::INVOKE_VIRTUAL,
248 Instruction::INVOKE_SUPER,
249 Instruction::INVOKE_DIRECT,
250 Instruction::INVOKE_STATIC,
251 Instruction::INVOKE_INTERFACE,
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700252 Instruction::RETURN_VOID_NO_BARRIER,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700253 Instruction::INVOKE_VIRTUAL_RANGE,
254 Instruction::INVOKE_SUPER_RANGE,
255 Instruction::INVOKE_DIRECT_RANGE,
256 Instruction::INVOKE_STATIC_RANGE,
257 Instruction::INVOKE_INTERFACE_RANGE,
258 Instruction::UNUSED_79,
259 Instruction::UNUSED_7A,
260 Instruction::NEG_INT,
261 Instruction::NOT_INT,
262 Instruction::NEG_LONG,
263 Instruction::NOT_LONG,
264 Instruction::NEG_FLOAT,
265 Instruction::NEG_DOUBLE,
266 Instruction::INT_TO_LONG,
267 Instruction::INT_TO_FLOAT,
268 Instruction::INT_TO_DOUBLE,
269 Instruction::LONG_TO_INT,
270 Instruction::LONG_TO_FLOAT,
271 Instruction::LONG_TO_DOUBLE,
272 Instruction::FLOAT_TO_INT,
273 Instruction::FLOAT_TO_LONG,
274 Instruction::FLOAT_TO_DOUBLE,
275 Instruction::DOUBLE_TO_INT,
276 Instruction::DOUBLE_TO_LONG,
277 Instruction::DOUBLE_TO_FLOAT,
278 Instruction::INT_TO_BYTE,
279 Instruction::INT_TO_CHAR,
280 Instruction::INT_TO_SHORT,
281 Instruction::ADD_INT,
282 Instruction::SUB_INT,
283 Instruction::MUL_INT,
284 Instruction::DIV_INT,
285 Instruction::REM_INT,
286 Instruction::AND_INT,
287 Instruction::OR_INT,
288 Instruction::XOR_INT,
289 Instruction::SHL_INT,
290 Instruction::SHR_INT,
291 Instruction::USHR_INT,
292 Instruction::ADD_LONG,
293 Instruction::SUB_LONG,
294 Instruction::MUL_LONG,
295 Instruction::DIV_LONG,
296 Instruction::REM_LONG,
297 Instruction::AND_LONG,
298 Instruction::OR_LONG,
299 Instruction::XOR_LONG,
300 Instruction::SHL_LONG,
301 Instruction::SHR_LONG,
302 Instruction::USHR_LONG,
303 Instruction::ADD_FLOAT,
304 Instruction::SUB_FLOAT,
305 Instruction::MUL_FLOAT,
306 Instruction::DIV_FLOAT,
307 Instruction::REM_FLOAT,
308 Instruction::ADD_DOUBLE,
309 Instruction::SUB_DOUBLE,
310 Instruction::MUL_DOUBLE,
311 Instruction::DIV_DOUBLE,
312 Instruction::REM_DOUBLE,
313 Instruction::ADD_INT_2ADDR,
314 Instruction::SUB_INT_2ADDR,
315 Instruction::MUL_INT_2ADDR,
316 Instruction::DIV_INT_2ADDR,
317 Instruction::REM_INT_2ADDR,
318 Instruction::AND_INT_2ADDR,
319 Instruction::OR_INT_2ADDR,
320 Instruction::XOR_INT_2ADDR,
321 Instruction::SHL_INT_2ADDR,
322 Instruction::SHR_INT_2ADDR,
323 Instruction::USHR_INT_2ADDR,
324 Instruction::ADD_LONG_2ADDR,
325 Instruction::SUB_LONG_2ADDR,
326 Instruction::MUL_LONG_2ADDR,
327 Instruction::DIV_LONG_2ADDR,
328 Instruction::REM_LONG_2ADDR,
329 Instruction::AND_LONG_2ADDR,
330 Instruction::OR_LONG_2ADDR,
331 Instruction::XOR_LONG_2ADDR,
332 Instruction::SHL_LONG_2ADDR,
333 Instruction::SHR_LONG_2ADDR,
334 Instruction::USHR_LONG_2ADDR,
335 Instruction::ADD_FLOAT_2ADDR,
336 Instruction::SUB_FLOAT_2ADDR,
337 Instruction::MUL_FLOAT_2ADDR,
338 Instruction::DIV_FLOAT_2ADDR,
339 Instruction::REM_FLOAT_2ADDR,
340 Instruction::ADD_DOUBLE_2ADDR,
341 Instruction::SUB_DOUBLE_2ADDR,
342 Instruction::MUL_DOUBLE_2ADDR,
343 Instruction::DIV_DOUBLE_2ADDR,
344 Instruction::REM_DOUBLE_2ADDR,
345 Instruction::ADD_INT_LIT16,
346 Instruction::RSUB_INT,
347 Instruction::MUL_INT_LIT16,
348 Instruction::DIV_INT_LIT16,
349 Instruction::REM_INT_LIT16,
350 Instruction::AND_INT_LIT16,
351 Instruction::OR_INT_LIT16,
352 Instruction::XOR_INT_LIT16,
353 Instruction::ADD_INT_LIT8,
354 Instruction::RSUB_INT_LIT8,
355 Instruction::MUL_INT_LIT8,
356 Instruction::DIV_INT_LIT8,
357 Instruction::REM_INT_LIT8,
358 Instruction::AND_INT_LIT8,
359 Instruction::OR_INT_LIT8,
360 Instruction::XOR_INT_LIT8,
361 Instruction::SHL_INT_LIT8,
362 Instruction::SHR_INT_LIT8,
363 Instruction::USHR_INT_LIT8,
364 Instruction::IGET_QUICK,
365 Instruction::IGET_WIDE_QUICK,
366 Instruction::IGET_OBJECT_QUICK,
367 Instruction::IPUT_QUICK,
368 Instruction::IPUT_WIDE_QUICK,
369 Instruction::IPUT_OBJECT_QUICK,
370 Instruction::INVOKE_VIRTUAL_QUICK,
371 Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
Fred Shih37f05ef2014-07-16 18:38:08 -0700372 Instruction::IPUT_BOOLEAN_QUICK,
373 Instruction::IPUT_BYTE_QUICK,
374 Instruction::IPUT_CHAR_QUICK,
375 Instruction::IPUT_SHORT_QUICK,
Mathieu Chartierffc605c2014-12-10 10:35:44 -0800376 Instruction::IGET_BOOLEAN_QUICK,
377 Instruction::IGET_BYTE_QUICK,
378 Instruction::IGET_CHAR_QUICK,
379 Instruction::IGET_SHORT_QUICK,
Igor Murashkin158f35c2015-06-10 15:55:30 -0700380 Instruction::INVOKE_LAMBDA,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700381 Instruction::UNUSED_F4,
382 Instruction::UNUSED_F5,
Igor Murashkin158f35c2015-06-10 15:55:30 -0700383 Instruction::CREATE_LAMBDA,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700384 Instruction::UNUSED_F7,
Igor Murashkin2ee54e22015-06-18 10:05:11 -0700385 Instruction::BOX_LAMBDA,
386 Instruction::UNBOX_LAMBDA,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700387 Instruction::UNUSED_FA,
388 Instruction::UNUSED_FB,
389 Instruction::UNUSED_FC,
390 Instruction::UNUSED_FD,
391 Instruction::UNUSED_FE,
392 Instruction::UNUSED_FF,
393 // ----- ExtendedMIROpcode -----
394 kMirOpPhi,
395 kMirOpCopy,
396 kMirOpFusedCmplFloat,
397 kMirOpFusedCmpgFloat,
398 kMirOpFusedCmplDouble,
399 kMirOpFusedCmpgDouble,
400 kMirOpFusedCmpLong,
401 kMirOpNop,
402 kMirOpNullCheck,
403 kMirOpRangeCheck,
404 kMirOpDivZeroCheck,
405 kMirOpCheck,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700406 kMirOpSelect,
407};
408
Zheng Xu5667fdb2014-10-23 18:29:55 +0800409static int kInvokeOpcodes[] = {
410 Instruction::INVOKE_VIRTUAL,
411 Instruction::INVOKE_SUPER,
412 Instruction::INVOKE_DIRECT,
413 Instruction::INVOKE_STATIC,
414 Instruction::INVOKE_INTERFACE,
415 Instruction::INVOKE_VIRTUAL_RANGE,
416 Instruction::INVOKE_SUPER_RANGE,
417 Instruction::INVOKE_DIRECT_RANGE,
418 Instruction::INVOKE_STATIC_RANGE,
419 Instruction::INVOKE_INTERFACE_RANGE,
420 Instruction::INVOKE_VIRTUAL_QUICK,
421 Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
422};
423
Igor Murashkin158f35c2015-06-10 15:55:30 -0700424// TODO: Add support for lambda opcodes to the quick compiler.
425static const int kUnsupportedLambdaOpcodes[] = {
426 Instruction::INVOKE_LAMBDA,
427 Instruction::CREATE_LAMBDA,
Igor Murashkin2ee54e22015-06-18 10:05:11 -0700428 Instruction::BOX_LAMBDA,
429 Instruction::UNBOX_LAMBDA,
Igor Murashkin158f35c2015-06-10 15:55:30 -0700430};
431
432// Unsupported opcodes. Null can be used when everything is supported. Size of the lists is
Andreas Gampe53c913b2014-08-12 23:19:23 -0700433// recorded below.
434static const int* kUnsupportedOpcodes[] = {
435 // 0 = kNone.
436 kAllOpcodes,
437 // 1 = kArm, unused (will use kThumb2).
438 kAllOpcodes,
439 // 2 = kArm64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700440 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700441 // 3 = kThumb2.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700442 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700443 // 4 = kX86.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700444 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700445 // 5 = kX86_64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700446 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700447 // 6 = kMips.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700448 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700449 // 7 = kMips64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700450 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700451};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800452static_assert(sizeof(kUnsupportedOpcodes) == 8 * sizeof(int*), "kUnsupportedOpcodes unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700453
454// Size of the arrays stored above.
455static const size_t kUnsupportedOpcodesSize[] = {
456 // 0 = kNone.
457 arraysize(kAllOpcodes),
458 // 1 = kArm, unused (will use kThumb2).
459 arraysize(kAllOpcodes),
460 // 2 = kArm64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700461 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700462 // 3 = kThumb2.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700463 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700464 // 4 = kX86.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700465 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700466 // 5 = kX86_64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700467 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700468 // 6 = kMips.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700469 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700470 // 7 = kMips64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700471 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700472};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800473static_assert(sizeof(kUnsupportedOpcodesSize) == 8 * sizeof(size_t),
474 "kUnsupportedOpcodesSize unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700475
Igor Murashkin158f35c2015-06-10 15:55:30 -0700476static bool IsUnsupportedExperimentalLambdasOnly(size_t i) {
477 DCHECK_LE(i, arraysize(kUnsupportedOpcodes));
478 return kUnsupportedOpcodes[i] == kUnsupportedLambdaOpcodes;
479}
480
Andreas Gampe53c913b2014-08-12 23:19:23 -0700481// The maximum amount of Dalvik register in a method for which we will start compiling. Tries to
482// avoid an abort when we need to manage more SSA registers than we can.
483static constexpr size_t kMaxAllowedDalvikRegisters = INT16_MAX / 2;
484
485static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) {
486 const char* supported_types = kSupportedTypes[instruction_set];
487 if (supported_types == nullptr) {
488 // Everything available.
489 return true;
490 }
491
492 uint32_t shorty_size = strlen(shorty);
493 CHECK_GE(shorty_size, 1u);
494
495 for (uint32_t i = 0; i < shorty_size; i++) {
496 if (strchr(supported_types, shorty[i]) == nullptr) {
497 return false;
498 }
499 }
500 return true;
Andreas Gampec8ccf682014-09-29 20:07:43 -0700501}
Andreas Gampe53c913b2014-08-12 23:19:23 -0700502
Igor Murashkin158f35c2015-06-10 15:55:30 -0700503// If the ISA has unsupported opcodes, should we skip scanning over them?
504//
505// Most of the time we're compiling non-experimental files, so scanning just slows
506// performance down by as much as 6% with 4 threads.
507// In the rare cases we compile experimental opcodes, the runtime has an option to enable it,
508// which will force scanning for any unsupported opcodes.
509static bool SkipScanningUnsupportedOpcodes(InstructionSet instruction_set) {
510 if (UNLIKELY(kUnsupportedOpcodesSize[instruction_set] == 0U)) {
511 // All opcodes are supported no matter what. Usually not the case
512 // since experimental opcodes are not implemented in the quick compiler.
513 return true;
514 } else if (LIKELY(!Runtime::Current()->AreExperimentalLambdasEnabled())) {
515 // Experimental opcodes are disabled.
516 //
517 // If all unsupported opcodes are experimental we don't need to do scanning.
518 return IsUnsupportedExperimentalLambdasOnly(instruction_set);
519 } else {
520 // Experimental opcodes are enabled.
521 //
522 // Do the opcode scanning if the ISA has any unsupported opcodes.
523 return false;
524 }
525}
526
Andreas Gampe53c913b2014-08-12 23:19:23 -0700527// Skip the method that we do not support currently.
528bool QuickCompiler::CanCompileMethod(uint32_t method_idx, const DexFile& dex_file,
529 CompilationUnit* cu) const {
530 // This is a limitation in mir_graph. See MirGraph::SetNumSSARegs.
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -0700531 if (cu->mir_graph->GetNumOfCodeAndTempVRs() > kMaxAllowedDalvikRegisters) {
532 VLOG(compiler) << "Too many dalvik registers : " << cu->mir_graph->GetNumOfCodeAndTempVRs();
Andreas Gampe53c913b2014-08-12 23:19:23 -0700533 return false;
534 }
535
536 // Check whether we do have limitations at all.
537 if (kSupportedTypes[cu->instruction_set] == nullptr &&
Igor Murashkin158f35c2015-06-10 15:55:30 -0700538 SkipScanningUnsupportedOpcodes(cu->instruction_set)) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700539 return true;
540 }
541
542 // Check if we can compile the prototype.
543 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
544 if (!CanCompileShorty(shorty, cu->instruction_set)) {
545 VLOG(compiler) << "Unsupported shorty : " << shorty;
546 return false;
547 }
548
549 const int *unsupport_list = kUnsupportedOpcodes[cu->instruction_set];
550 int unsupport_list_size = kUnsupportedOpcodesSize[cu->instruction_set];
551
552 for (unsigned int idx = 0; idx < cu->mir_graph->GetNumBlocks(); idx++) {
553 BasicBlock* bb = cu->mir_graph->GetBasicBlock(idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700554 if (bb == nullptr) continue;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700555 if (bb->block_type == kDead) continue;
556 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
557 int opcode = mir->dalvikInsn.opcode;
558 // Check if we support the byte code.
Zheng Xu5667fdb2014-10-23 18:29:55 +0800559 if (std::find(unsupport_list, unsupport_list + unsupport_list_size, opcode)
560 != unsupport_list + unsupport_list_size) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700561 if (!MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
562 VLOG(compiler) << "Unsupported dalvik byte code : "
563 << mir->dalvikInsn.opcode;
564 } else {
565 VLOG(compiler) << "Unsupported extended MIR opcode : "
566 << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst];
567 }
568 return false;
569 }
570 // Check if it invokes a prototype that we cannot support.
Zheng Xu5667fdb2014-10-23 18:29:55 +0800571 if (std::find(kInvokeOpcodes, kInvokeOpcodes + arraysize(kInvokeOpcodes), opcode)
572 != kInvokeOpcodes + arraysize(kInvokeOpcodes)) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700573 uint32_t invoke_method_idx = mir->dalvikInsn.vB;
574 const char* invoke_method_shorty = dex_file.GetMethodShorty(
575 dex_file.GetMethodId(invoke_method_idx));
576 if (!CanCompileShorty(invoke_method_shorty, cu->instruction_set)) {
577 VLOG(compiler) << "Unsupported to invoke '"
578 << PrettyMethod(invoke_method_idx, dex_file)
579 << "' with shorty : " << invoke_method_shorty;
580 return false;
581 }
582 }
583 }
584 }
585 return true;
586}
587
588void QuickCompiler::InitCompilationUnit(CompilationUnit& cu) const {
589 // Disable optimizations according to instruction set.
590 cu.disable_opt |= kDisabledOptimizationsPerISA[cu.instruction_set];
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800591 if (Runtime::Current()->UseJit()) {
592 // Disable these optimizations for JIT until quickened byte codes are done being implemented.
593 // TODO: Find a cleaner way to do this.
594 cu.disable_opt |= 1u << kLocalValueNumbering;
595 }
Andreas Gampe53c913b2014-08-12 23:19:23 -0700596}
597
David Brazdilee690a32014-12-01 17:04:16 +0000598void QuickCompiler::Init() {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700599 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr);
600}
601
602void QuickCompiler::UnInit() const {
603 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr);
604}
605
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800606/* Default optimizer/debug setting for the compiler. */
607static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations
608 // (1 << kLoadStoreElimination) |
609 // (1 << kLoadHoisting) |
610 // (1 << kSuppressLoads) |
611 // (1 << kNullCheckElimination) |
612 // (1 << kClassInitCheckElimination) |
613 // (1 << kGlobalValueNumbering) |
Vladimir Markoa5e69e82015-04-24 19:03:51 +0100614 // (1 << kGvnDeadCodeElimination) |
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800615 // (1 << kLocalValueNumbering) |
616 // (1 << kPromoteRegs) |
617 // (1 << kTrackLiveTemps) |
618 // (1 << kSafeOptimizations) |
619 // (1 << kBBOpt) |
620 // (1 << kSuspendCheckElimination) |
621 // (1 << kMatch) |
622 // (1 << kPromoteCompilerTemps) |
623 // (1 << kSuppressExceptionEdges) |
624 // (1 << kSuppressMethodInlining) |
625 0;
626
627static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes
628 // (1 << kDebugDisplayMissingTargets) |
629 // (1 << kDebugVerbose) |
630 // (1 << kDebugDumpCFG) |
631 // (1 << kDebugSlowFieldPath) |
632 // (1 << kDebugSlowInvokePath) |
633 // (1 << kDebugSlowStringPath) |
634 // (1 << kDebugSlowestFieldPath) |
635 // (1 << kDebugSlowestStringPath) |
636 // (1 << kDebugExerciseResolveMethod) |
637 // (1 << kDebugVerifyDataflow) |
638 // (1 << kDebugShowMemoryUsage) |
639 // (1 << kDebugShowNops) |
640 // (1 << kDebugCountOpcodes) |
641 // (1 << kDebugDumpCheckStats) |
642 // (1 << kDebugShowSummaryMemoryUsage) |
643 // (1 << kDebugShowFilterStats) |
644 // (1 << kDebugTimings) |
645 // (1 << kDebugCodegenDump) |
646 0;
647
Andreas Gampe53c913b2014-08-12 23:19:23 -0700648CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item,
649 uint32_t access_flags,
650 InvokeType invoke_type,
651 uint16_t class_def_idx,
652 uint32_t method_idx,
653 jobject class_loader,
654 const DexFile& dex_file) const {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700655 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use
656 // build default.
657 CompilerDriver* driver = GetCompilerDriver();
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800658
659 VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
660 if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
661 return nullptr;
662 }
663
664 DCHECK(driver->GetCompilerOptions().IsCompilationEnabled());
665
Mathieu Chartier9b34b242015-03-09 11:30:17 -0700666 Runtime* const runtime = Runtime::Current();
667 ClassLinker* const class_linker = runtime->GetClassLinker();
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800668 InstructionSet instruction_set = driver->GetInstructionSet();
669 if (instruction_set == kArm) {
670 instruction_set = kThumb2;
671 }
Mathieu Chartier9b34b242015-03-09 11:30:17 -0700672 CompilationUnit cu(runtime->GetArenaPool(), instruction_set, driver, class_linker);
Vladimir Marko20f85592015-03-19 10:07:02 +0000673 cu.dex_file = &dex_file;
674 cu.class_def_idx = class_def_idx;
675 cu.method_idx = method_idx;
676 cu.access_flags = access_flags;
677 cu.invoke_type = invoke_type;
678 cu.shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800679
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800680 CHECK((cu.instruction_set == kThumb2) ||
681 (cu.instruction_set == kArm64) ||
682 (cu.instruction_set == kX86) ||
683 (cu.instruction_set == kX86_64) ||
Maja Gagic6ea651f2015-02-24 16:55:04 +0100684 (cu.instruction_set == kMips) ||
685 (cu.instruction_set == kMips64));
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800686
687 // TODO: set this from command line
688 constexpr bool compiler_flip_match = false;
689 const std::string compiler_method_match = "";
690
691 bool use_match = !compiler_method_match.empty();
692 bool match = use_match && (compiler_flip_match ^
693 (PrettyMethod(method_idx, dex_file).find(compiler_method_match) != std::string::npos));
694 if (!use_match || match) {
695 cu.disable_opt = kCompilerOptimizerDisableFlags;
696 cu.enable_debug = kCompilerDebugFlags;
697 cu.verbose = VLOG_IS_ON(compiler) ||
698 (cu.enable_debug & (1 << kDebugVerbose));
699 }
700
701 if (driver->GetCompilerOptions().HasVerboseMethods()) {
702 cu.verbose = driver->GetCompilerOptions().IsVerboseMethod(PrettyMethod(method_idx, dex_file));
703 }
704
705 if (cu.verbose) {
706 cu.enable_debug |= (1 << kDebugCodegenDump);
707 }
708
709 /*
710 * TODO: rework handling of optimization and debug flags. Should we split out
711 * MIR and backend flags? Need command-line setting as well.
712 */
713
714 InitCompilationUnit(cu);
715
716 cu.StartTimingSplit("BuildMIRGraph");
717 cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena));
718
719 /*
720 * After creation of the MIR graph, also create the code generator.
721 * The reason we do this is that optimizations on the MIR graph may need to get information
722 * that is only available if a CG exists.
723 */
724 cu.cg.reset(GetCodeGenerator(&cu, nullptr));
725
726 /* Gathering opcode stats? */
727 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
728 cu.mir_graph->EnableOpcodeCounting();
729 }
730
731 /* Build the raw MIR graph */
732 cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
733 class_loader, dex_file);
734
735 if (!CanCompileMethod(method_idx, dex_file, &cu)) {
736 VLOG(compiler) << cu.instruction_set << ": Cannot compile method : "
737 << PrettyMethod(method_idx, dex_file);
738 cu.EndTiming();
739 return nullptr;
740 }
741
742 cu.NewTimingSplit("MIROpt:CheckFilters");
743 std::string skip_message;
744 if (cu.mir_graph->SkipCompilation(&skip_message)) {
745 VLOG(compiler) << cu.instruction_set << ": Skipping method : "
746 << PrettyMethod(method_idx, dex_file) << " Reason = " << skip_message;
747 cu.EndTiming();
748 return nullptr;
749 }
750
751 /* Create the pass driver and launch it */
Nicolas Geoffray216eaa22015-03-17 17:09:30 +0000752 PassDriverMEOpts pass_driver(GetPreOptPassManager(), GetPostOptPassManager(), &cu);
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800753 pass_driver.Launch();
754
755 /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */
756 if (cu.compiler_driver->ProfilePresent()
757 && !cu.mir_graph->MethodIsLeaf()
758 && cu.mir_graph->SkipCompilationByName(PrettyMethod(method_idx, dex_file))) {
759 cu.EndTiming();
760 return nullptr;
761 }
762
763 if (cu.enable_debug & (1 << kDebugDumpCheckStats)) {
764 cu.mir_graph->DumpCheckStats();
765 }
766
767 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
768 cu.mir_graph->ShowOpcodeStats();
769 }
770
771 /* Reassociate sreg names with original Dalvik vreg names. */
772 cu.mir_graph->RemapRegLocations();
773
774 /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */
775 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
776 if (cu.arena_stack.PeakBytesAllocated() > 1 * 1024 * 1024) {
777 MemStats stack_stats(cu.arena_stack.GetPeakStats());
778 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats);
779 }
780 }
781 cu.arena_stack.Reset();
782
783 CompiledMethod* result = nullptr;
784
785 if (cu.mir_graph->PuntToInterpreter()) {
786 VLOG(compiler) << cu.instruction_set << ": Punted method to interpreter: "
787 << PrettyMethod(method_idx, dex_file);
788 cu.EndTiming();
789 return nullptr;
790 }
791
792 cu.cg->Materialize();
793
794 cu.NewTimingSplit("Dedupe"); /* deduping takes up the vast majority of time in GetCompiledMethod(). */
795 result = cu.cg->GetCompiledMethod();
796 cu.NewTimingSplit("Cleanup");
797
798 if (result) {
799 VLOG(compiler) << cu.instruction_set << ": Compiled " << PrettyMethod(method_idx, dex_file);
800 } else {
801 VLOG(compiler) << cu.instruction_set << ": Deferred " << PrettyMethod(method_idx, dex_file);
802 }
803
804 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
805 if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) {
806 MemStats mem_stats(cu.arena.GetMemStats());
807 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats);
808 }
809 }
810
811 if (cu.enable_debug & (1 << kDebugShowSummaryMemoryUsage)) {
812 LOG(INFO) << "MEMINFO " << cu.arena.BytesAllocated() << " " << cu.mir_graph->GetNumBlocks()
813 << " " << PrettyMethod(method_idx, dex_file);
814 }
815
816 cu.EndTiming();
817 driver->GetTimingsLogger()->AddLogger(cu.timings);
818 return result;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700819}
820
821CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags,
822 uint32_t method_idx,
823 const DexFile& dex_file) const {
824 return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
825}
826
Mathieu Chartiere401d142015-04-22 13:56:20 -0700827uintptr_t QuickCompiler::GetEntryPointOf(ArtMethod* method) const {
Mathieu Chartier130914e2014-11-18 15:34:09 -0800828 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
829 InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
Andreas Gampe53c913b2014-08-12 23:19:23 -0700830}
831
David Srbecky1109fb32015-04-07 20:21:06 +0100832Mir2Lir* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) {
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700833 UNUSED(compilation_unit);
Andreas Gampe53c913b2014-08-12 23:19:23 -0700834 Mir2Lir* mir_to_lir = nullptr;
835 switch (cu->instruction_set) {
836 case kThumb2:
837 mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
838 break;
839 case kArm64:
840 mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
841 break;
842 case kMips:
Goran Jakovljevic10957932015-03-24 18:42:56 +0100843 // Fall-through.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100844 case kMips64:
Goran Jakovljevic10957932015-03-24 18:42:56 +0100845 mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
Maja Gagic6ea651f2015-02-24 16:55:04 +0100846 break;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700847 case kX86:
848 // Fall-through.
849 case kX86_64:
850 mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
851 break;
852 default:
853 LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set;
854 }
855
856 /* The number of compiler temporaries depends on backend so set it up now if possible */
857 if (mir_to_lir) {
858 size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps();
859 bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps);
860 CHECK(set_max);
861 }
862 return mir_to_lir;
863}
864
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800865QuickCompiler::QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {
866 const auto& compiler_options = driver->GetCompilerOptions();
867 auto* pass_manager_options = compiler_options.GetPassManagerOptions();
868 pre_opt_pass_manager_.reset(new PassManager(*pass_manager_options));
869 CHECK(pre_opt_pass_manager_.get() != nullptr);
870 PassDriverMEOpts::SetupPasses(pre_opt_pass_manager_.get());
871 pre_opt_pass_manager_->CreateDefaultPassList();
872 if (pass_manager_options->GetPrintPassOptions()) {
873 PassDriverMEOpts::PrintPassOptions(pre_opt_pass_manager_.get());
874 }
875 // TODO: Different options for pre vs post opts?
876 post_opt_pass_manager_.reset(new PassManager(PassManagerOptions()));
877 CHECK(post_opt_pass_manager_.get() != nullptr);
878 PassDriverMEPostOpt::SetupPasses(post_opt_pass_manager_.get());
879 post_opt_pass_manager_->CreateDefaultPassList();
880 if (pass_manager_options->GetPrintPassOptions()) {
881 PassDriverMEPostOpt::PrintPassOptions(post_opt_pass_manager_.get());
882 }
883}
884
885QuickCompiler::~QuickCompiler() {
886}
Andreas Gampe53c913b2014-08-12 23:19:23 -0700887
888Compiler* CreateQuickCompiler(CompilerDriver* driver) {
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800889 return QuickCompiler::Create(driver);
890}
891
892Compiler* QuickCompiler::Create(CompilerDriver* driver) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700893 return new QuickCompiler(driver);
894}
895
896} // namespace art