blob: fcf4716c1a32acef526752b3b67d38e6de185488 [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
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080021#include "base/dumpable.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080022#include "base/logging.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080023#include "base/macros.h"
24#include "base/timing_logger.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070025#include "compiler.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080026#include "dex_file-inl.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080027#include "dex_file_to_method_inliner_map.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080028#include "dex/compiler_ir.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080029#include "dex/dex_flags.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070030#include "dex/mir_graph.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080031#include "dex/pass_driver_me_opts.h"
Mathieu Chartier5bdab122015-01-26 18:30:19 -080032#include "dex/pass_driver_me_post_opt.h"
33#include "dex/pass_manager.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070034#include "dex/quick/mir_to_lir.h"
35#include "driver/compiler_driver.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080036#include "driver/compiler_options.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070037#include "elf_writer_quick.h"
38#include "jni/quick/jni_compiler.h"
Andreas Gampe9c462082015-01-27 14:31:40 -080039#include "mir_to_lir.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070040#include "mirror/art_method-inl.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.
90 ~0U
91};
Andreas Gampe785d2f22014-11-03 22:57:30 -080092static_assert(sizeof(kDisabledOptimizationsPerISA) == 8 * sizeof(uint32_t),
93 "kDisabledOpts unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -070094
95// Supported shorty types per instruction set. nullptr means that all are available.
96// Z : boolean
97// B : byte
98// S : short
99// C : char
100// I : int
101// J : long
102// F : float
103// D : double
104// L : reference(object, array)
105// V : void
106static const char* kSupportedTypes[] = {
107 // 0 = kNone.
108 "",
109 // 1 = kArm, unused (will use kThumb2).
110 "",
111 // 2 = kArm64.
112 nullptr,
113 // 3 = kThumb2.
114 nullptr,
115 // 4 = kX86.
116 nullptr,
117 // 5 = kX86_64.
118 nullptr,
119 // 6 = kMips.
120 nullptr,
121 // 7 = kMips64.
122 ""
123};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800124static_assert(sizeof(kSupportedTypes) == 8 * sizeof(char*), "kSupportedTypes unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700125
126static int kAllOpcodes[] = {
127 Instruction::NOP,
128 Instruction::MOVE,
129 Instruction::MOVE_FROM16,
130 Instruction::MOVE_16,
131 Instruction::MOVE_WIDE,
132 Instruction::MOVE_WIDE_FROM16,
133 Instruction::MOVE_WIDE_16,
134 Instruction::MOVE_OBJECT,
135 Instruction::MOVE_OBJECT_FROM16,
136 Instruction::MOVE_OBJECT_16,
137 Instruction::MOVE_RESULT,
138 Instruction::MOVE_RESULT_WIDE,
139 Instruction::MOVE_RESULT_OBJECT,
140 Instruction::MOVE_EXCEPTION,
141 Instruction::RETURN_VOID,
142 Instruction::RETURN,
143 Instruction::RETURN_WIDE,
144 Instruction::RETURN_OBJECT,
145 Instruction::CONST_4,
146 Instruction::CONST_16,
147 Instruction::CONST,
148 Instruction::CONST_HIGH16,
149 Instruction::CONST_WIDE_16,
150 Instruction::CONST_WIDE_32,
151 Instruction::CONST_WIDE,
152 Instruction::CONST_WIDE_HIGH16,
153 Instruction::CONST_STRING,
154 Instruction::CONST_STRING_JUMBO,
155 Instruction::CONST_CLASS,
156 Instruction::MONITOR_ENTER,
157 Instruction::MONITOR_EXIT,
158 Instruction::CHECK_CAST,
159 Instruction::INSTANCE_OF,
160 Instruction::ARRAY_LENGTH,
161 Instruction::NEW_INSTANCE,
162 Instruction::NEW_ARRAY,
163 Instruction::FILLED_NEW_ARRAY,
164 Instruction::FILLED_NEW_ARRAY_RANGE,
165 Instruction::FILL_ARRAY_DATA,
166 Instruction::THROW,
167 Instruction::GOTO,
168 Instruction::GOTO_16,
169 Instruction::GOTO_32,
170 Instruction::PACKED_SWITCH,
171 Instruction::SPARSE_SWITCH,
172 Instruction::CMPL_FLOAT,
173 Instruction::CMPG_FLOAT,
174 Instruction::CMPL_DOUBLE,
175 Instruction::CMPG_DOUBLE,
176 Instruction::CMP_LONG,
177 Instruction::IF_EQ,
178 Instruction::IF_NE,
179 Instruction::IF_LT,
180 Instruction::IF_GE,
181 Instruction::IF_GT,
182 Instruction::IF_LE,
183 Instruction::IF_EQZ,
184 Instruction::IF_NEZ,
185 Instruction::IF_LTZ,
186 Instruction::IF_GEZ,
187 Instruction::IF_GTZ,
188 Instruction::IF_LEZ,
189 Instruction::UNUSED_3E,
190 Instruction::UNUSED_3F,
191 Instruction::UNUSED_40,
192 Instruction::UNUSED_41,
193 Instruction::UNUSED_42,
194 Instruction::UNUSED_43,
195 Instruction::AGET,
196 Instruction::AGET_WIDE,
197 Instruction::AGET_OBJECT,
198 Instruction::AGET_BOOLEAN,
199 Instruction::AGET_BYTE,
200 Instruction::AGET_CHAR,
201 Instruction::AGET_SHORT,
202 Instruction::APUT,
203 Instruction::APUT_WIDE,
204 Instruction::APUT_OBJECT,
205 Instruction::APUT_BOOLEAN,
206 Instruction::APUT_BYTE,
207 Instruction::APUT_CHAR,
208 Instruction::APUT_SHORT,
209 Instruction::IGET,
210 Instruction::IGET_WIDE,
211 Instruction::IGET_OBJECT,
212 Instruction::IGET_BOOLEAN,
213 Instruction::IGET_BYTE,
214 Instruction::IGET_CHAR,
215 Instruction::IGET_SHORT,
216 Instruction::IPUT,
217 Instruction::IPUT_WIDE,
218 Instruction::IPUT_OBJECT,
219 Instruction::IPUT_BOOLEAN,
220 Instruction::IPUT_BYTE,
221 Instruction::IPUT_CHAR,
222 Instruction::IPUT_SHORT,
223 Instruction::SGET,
224 Instruction::SGET_WIDE,
225 Instruction::SGET_OBJECT,
226 Instruction::SGET_BOOLEAN,
227 Instruction::SGET_BYTE,
228 Instruction::SGET_CHAR,
229 Instruction::SGET_SHORT,
230 Instruction::SPUT,
231 Instruction::SPUT_WIDE,
232 Instruction::SPUT_OBJECT,
233 Instruction::SPUT_BOOLEAN,
234 Instruction::SPUT_BYTE,
235 Instruction::SPUT_CHAR,
236 Instruction::SPUT_SHORT,
237 Instruction::INVOKE_VIRTUAL,
238 Instruction::INVOKE_SUPER,
239 Instruction::INVOKE_DIRECT,
240 Instruction::INVOKE_STATIC,
241 Instruction::INVOKE_INTERFACE,
242 Instruction::RETURN_VOID_BARRIER,
243 Instruction::INVOKE_VIRTUAL_RANGE,
244 Instruction::INVOKE_SUPER_RANGE,
245 Instruction::INVOKE_DIRECT_RANGE,
246 Instruction::INVOKE_STATIC_RANGE,
247 Instruction::INVOKE_INTERFACE_RANGE,
248 Instruction::UNUSED_79,
249 Instruction::UNUSED_7A,
250 Instruction::NEG_INT,
251 Instruction::NOT_INT,
252 Instruction::NEG_LONG,
253 Instruction::NOT_LONG,
254 Instruction::NEG_FLOAT,
255 Instruction::NEG_DOUBLE,
256 Instruction::INT_TO_LONG,
257 Instruction::INT_TO_FLOAT,
258 Instruction::INT_TO_DOUBLE,
259 Instruction::LONG_TO_INT,
260 Instruction::LONG_TO_FLOAT,
261 Instruction::LONG_TO_DOUBLE,
262 Instruction::FLOAT_TO_INT,
263 Instruction::FLOAT_TO_LONG,
264 Instruction::FLOAT_TO_DOUBLE,
265 Instruction::DOUBLE_TO_INT,
266 Instruction::DOUBLE_TO_LONG,
267 Instruction::DOUBLE_TO_FLOAT,
268 Instruction::INT_TO_BYTE,
269 Instruction::INT_TO_CHAR,
270 Instruction::INT_TO_SHORT,
271 Instruction::ADD_INT,
272 Instruction::SUB_INT,
273 Instruction::MUL_INT,
274 Instruction::DIV_INT,
275 Instruction::REM_INT,
276 Instruction::AND_INT,
277 Instruction::OR_INT,
278 Instruction::XOR_INT,
279 Instruction::SHL_INT,
280 Instruction::SHR_INT,
281 Instruction::USHR_INT,
282 Instruction::ADD_LONG,
283 Instruction::SUB_LONG,
284 Instruction::MUL_LONG,
285 Instruction::DIV_LONG,
286 Instruction::REM_LONG,
287 Instruction::AND_LONG,
288 Instruction::OR_LONG,
289 Instruction::XOR_LONG,
290 Instruction::SHL_LONG,
291 Instruction::SHR_LONG,
292 Instruction::USHR_LONG,
293 Instruction::ADD_FLOAT,
294 Instruction::SUB_FLOAT,
295 Instruction::MUL_FLOAT,
296 Instruction::DIV_FLOAT,
297 Instruction::REM_FLOAT,
298 Instruction::ADD_DOUBLE,
299 Instruction::SUB_DOUBLE,
300 Instruction::MUL_DOUBLE,
301 Instruction::DIV_DOUBLE,
302 Instruction::REM_DOUBLE,
303 Instruction::ADD_INT_2ADDR,
304 Instruction::SUB_INT_2ADDR,
305 Instruction::MUL_INT_2ADDR,
306 Instruction::DIV_INT_2ADDR,
307 Instruction::REM_INT_2ADDR,
308 Instruction::AND_INT_2ADDR,
309 Instruction::OR_INT_2ADDR,
310 Instruction::XOR_INT_2ADDR,
311 Instruction::SHL_INT_2ADDR,
312 Instruction::SHR_INT_2ADDR,
313 Instruction::USHR_INT_2ADDR,
314 Instruction::ADD_LONG_2ADDR,
315 Instruction::SUB_LONG_2ADDR,
316 Instruction::MUL_LONG_2ADDR,
317 Instruction::DIV_LONG_2ADDR,
318 Instruction::REM_LONG_2ADDR,
319 Instruction::AND_LONG_2ADDR,
320 Instruction::OR_LONG_2ADDR,
321 Instruction::XOR_LONG_2ADDR,
322 Instruction::SHL_LONG_2ADDR,
323 Instruction::SHR_LONG_2ADDR,
324 Instruction::USHR_LONG_2ADDR,
325 Instruction::ADD_FLOAT_2ADDR,
326 Instruction::SUB_FLOAT_2ADDR,
327 Instruction::MUL_FLOAT_2ADDR,
328 Instruction::DIV_FLOAT_2ADDR,
329 Instruction::REM_FLOAT_2ADDR,
330 Instruction::ADD_DOUBLE_2ADDR,
331 Instruction::SUB_DOUBLE_2ADDR,
332 Instruction::MUL_DOUBLE_2ADDR,
333 Instruction::DIV_DOUBLE_2ADDR,
334 Instruction::REM_DOUBLE_2ADDR,
335 Instruction::ADD_INT_LIT16,
336 Instruction::RSUB_INT,
337 Instruction::MUL_INT_LIT16,
338 Instruction::DIV_INT_LIT16,
339 Instruction::REM_INT_LIT16,
340 Instruction::AND_INT_LIT16,
341 Instruction::OR_INT_LIT16,
342 Instruction::XOR_INT_LIT16,
343 Instruction::ADD_INT_LIT8,
344 Instruction::RSUB_INT_LIT8,
345 Instruction::MUL_INT_LIT8,
346 Instruction::DIV_INT_LIT8,
347 Instruction::REM_INT_LIT8,
348 Instruction::AND_INT_LIT8,
349 Instruction::OR_INT_LIT8,
350 Instruction::XOR_INT_LIT8,
351 Instruction::SHL_INT_LIT8,
352 Instruction::SHR_INT_LIT8,
353 Instruction::USHR_INT_LIT8,
354 Instruction::IGET_QUICK,
355 Instruction::IGET_WIDE_QUICK,
356 Instruction::IGET_OBJECT_QUICK,
357 Instruction::IPUT_QUICK,
358 Instruction::IPUT_WIDE_QUICK,
359 Instruction::IPUT_OBJECT_QUICK,
360 Instruction::INVOKE_VIRTUAL_QUICK,
361 Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
Fred Shih37f05ef2014-07-16 18:38:08 -0700362 Instruction::IPUT_BOOLEAN_QUICK,
363 Instruction::IPUT_BYTE_QUICK,
364 Instruction::IPUT_CHAR_QUICK,
365 Instruction::IPUT_SHORT_QUICK,
Mathieu Chartierffc605c2014-12-10 10:35:44 -0800366 Instruction::IGET_BOOLEAN_QUICK,
367 Instruction::IGET_BYTE_QUICK,
368 Instruction::IGET_CHAR_QUICK,
369 Instruction::IGET_SHORT_QUICK,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700370 Instruction::UNUSED_F3,
371 Instruction::UNUSED_F4,
372 Instruction::UNUSED_F5,
373 Instruction::UNUSED_F6,
374 Instruction::UNUSED_F7,
375 Instruction::UNUSED_F8,
376 Instruction::UNUSED_F9,
377 Instruction::UNUSED_FA,
378 Instruction::UNUSED_FB,
379 Instruction::UNUSED_FC,
380 Instruction::UNUSED_FD,
381 Instruction::UNUSED_FE,
382 Instruction::UNUSED_FF,
383 // ----- ExtendedMIROpcode -----
384 kMirOpPhi,
385 kMirOpCopy,
386 kMirOpFusedCmplFloat,
387 kMirOpFusedCmpgFloat,
388 kMirOpFusedCmplDouble,
389 kMirOpFusedCmpgDouble,
390 kMirOpFusedCmpLong,
391 kMirOpNop,
392 kMirOpNullCheck,
393 kMirOpRangeCheck,
394 kMirOpDivZeroCheck,
395 kMirOpCheck,
396 kMirOpCheckPart2,
397 kMirOpSelect,
398};
399
Zheng Xu5667fdb2014-10-23 18:29:55 +0800400static int kInvokeOpcodes[] = {
401 Instruction::INVOKE_VIRTUAL,
402 Instruction::INVOKE_SUPER,
403 Instruction::INVOKE_DIRECT,
404 Instruction::INVOKE_STATIC,
405 Instruction::INVOKE_INTERFACE,
406 Instruction::INVOKE_VIRTUAL_RANGE,
407 Instruction::INVOKE_SUPER_RANGE,
408 Instruction::INVOKE_DIRECT_RANGE,
409 Instruction::INVOKE_STATIC_RANGE,
410 Instruction::INVOKE_INTERFACE_RANGE,
411 Instruction::INVOKE_VIRTUAL_QUICK,
412 Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
413};
414
Andreas Gampe53c913b2014-08-12 23:19:23 -0700415// Unsupported opcodes. nullptr can be used when everything is supported. Size of the lists is
416// recorded below.
417static const int* kUnsupportedOpcodes[] = {
418 // 0 = kNone.
419 kAllOpcodes,
420 // 1 = kArm, unused (will use kThumb2).
421 kAllOpcodes,
422 // 2 = kArm64.
423 nullptr,
424 // 3 = kThumb2.
425 nullptr,
426 // 4 = kX86.
427 nullptr,
428 // 5 = kX86_64.
429 nullptr,
430 // 6 = kMips.
431 nullptr,
432 // 7 = kMips64.
433 kAllOpcodes
434};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800435static_assert(sizeof(kUnsupportedOpcodes) == 8 * sizeof(int*), "kUnsupportedOpcodes unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700436
437// Size of the arrays stored above.
438static const size_t kUnsupportedOpcodesSize[] = {
439 // 0 = kNone.
440 arraysize(kAllOpcodes),
441 // 1 = kArm, unused (will use kThumb2).
442 arraysize(kAllOpcodes),
443 // 2 = kArm64.
444 0,
445 // 3 = kThumb2.
446 0,
447 // 4 = kX86.
448 0,
449 // 5 = kX86_64.
450 0,
451 // 6 = kMips.
452 0,
453 // 7 = kMips64.
454 arraysize(kAllOpcodes),
455};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800456static_assert(sizeof(kUnsupportedOpcodesSize) == 8 * sizeof(size_t),
457 "kUnsupportedOpcodesSize unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700458
459// The maximum amount of Dalvik register in a method for which we will start compiling. Tries to
460// avoid an abort when we need to manage more SSA registers than we can.
461static constexpr size_t kMaxAllowedDalvikRegisters = INT16_MAX / 2;
462
463static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) {
464 const char* supported_types = kSupportedTypes[instruction_set];
465 if (supported_types == nullptr) {
466 // Everything available.
467 return true;
468 }
469
470 uint32_t shorty_size = strlen(shorty);
471 CHECK_GE(shorty_size, 1u);
472
473 for (uint32_t i = 0; i < shorty_size; i++) {
474 if (strchr(supported_types, shorty[i]) == nullptr) {
475 return false;
476 }
477 }
478 return true;
Andreas Gampec8ccf682014-09-29 20:07:43 -0700479}
Andreas Gampe53c913b2014-08-12 23:19:23 -0700480
481// Skip the method that we do not support currently.
482bool QuickCompiler::CanCompileMethod(uint32_t method_idx, const DexFile& dex_file,
483 CompilationUnit* cu) const {
484 // This is a limitation in mir_graph. See MirGraph::SetNumSSARegs.
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -0700485 if (cu->mir_graph->GetNumOfCodeAndTempVRs() > kMaxAllowedDalvikRegisters) {
486 VLOG(compiler) << "Too many dalvik registers : " << cu->mir_graph->GetNumOfCodeAndTempVRs();
Andreas Gampe53c913b2014-08-12 23:19:23 -0700487 return false;
488 }
489
490 // Check whether we do have limitations at all.
491 if (kSupportedTypes[cu->instruction_set] == nullptr &&
492 kUnsupportedOpcodesSize[cu->instruction_set] == 0U) {
493 return true;
494 }
495
496 // Check if we can compile the prototype.
497 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
498 if (!CanCompileShorty(shorty, cu->instruction_set)) {
499 VLOG(compiler) << "Unsupported shorty : " << shorty;
500 return false;
501 }
502
503 const int *unsupport_list = kUnsupportedOpcodes[cu->instruction_set];
504 int unsupport_list_size = kUnsupportedOpcodesSize[cu->instruction_set];
505
506 for (unsigned int idx = 0; idx < cu->mir_graph->GetNumBlocks(); idx++) {
507 BasicBlock* bb = cu->mir_graph->GetBasicBlock(idx);
508 if (bb == NULL) continue;
509 if (bb->block_type == kDead) continue;
510 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
511 int opcode = mir->dalvikInsn.opcode;
512 // Check if we support the byte code.
Zheng Xu5667fdb2014-10-23 18:29:55 +0800513 if (std::find(unsupport_list, unsupport_list + unsupport_list_size, opcode)
514 != unsupport_list + unsupport_list_size) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700515 if (!MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
516 VLOG(compiler) << "Unsupported dalvik byte code : "
517 << mir->dalvikInsn.opcode;
518 } else {
519 VLOG(compiler) << "Unsupported extended MIR opcode : "
520 << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst];
521 }
522 return false;
523 }
524 // Check if it invokes a prototype that we cannot support.
Zheng Xu5667fdb2014-10-23 18:29:55 +0800525 if (std::find(kInvokeOpcodes, kInvokeOpcodes + arraysize(kInvokeOpcodes), opcode)
526 != kInvokeOpcodes + arraysize(kInvokeOpcodes)) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700527 uint32_t invoke_method_idx = mir->dalvikInsn.vB;
528 const char* invoke_method_shorty = dex_file.GetMethodShorty(
529 dex_file.GetMethodId(invoke_method_idx));
530 if (!CanCompileShorty(invoke_method_shorty, cu->instruction_set)) {
531 VLOG(compiler) << "Unsupported to invoke '"
532 << PrettyMethod(invoke_method_idx, dex_file)
533 << "' with shorty : " << invoke_method_shorty;
534 return false;
535 }
536 }
537 }
538 }
539 return true;
540}
541
542void QuickCompiler::InitCompilationUnit(CompilationUnit& cu) const {
543 // Disable optimizations according to instruction set.
544 cu.disable_opt |= kDisabledOptimizationsPerISA[cu.instruction_set];
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800545 if (Runtime::Current()->UseJit()) {
546 // Disable these optimizations for JIT until quickened byte codes are done being implemented.
547 // TODO: Find a cleaner way to do this.
548 cu.disable_opt |= 1u << kLocalValueNumbering;
549 }
Andreas Gampe53c913b2014-08-12 23:19:23 -0700550}
551
David Brazdilee690a32014-12-01 17:04:16 +0000552void QuickCompiler::Init() {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700553 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr);
554}
555
556void QuickCompiler::UnInit() const {
557 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr);
558}
559
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800560/* Default optimizer/debug setting for the compiler. */
561static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations
562 // (1 << kLoadStoreElimination) |
563 // (1 << kLoadHoisting) |
564 // (1 << kSuppressLoads) |
565 // (1 << kNullCheckElimination) |
566 // (1 << kClassInitCheckElimination) |
567 // (1 << kGlobalValueNumbering) |
Vladimir Marko37e05bf2015-02-18 14:06:43 +0000568 (1 << kGvnDeadCodeElimination) |
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800569 // (1 << kLocalValueNumbering) |
570 // (1 << kPromoteRegs) |
571 // (1 << kTrackLiveTemps) |
572 // (1 << kSafeOptimizations) |
573 // (1 << kBBOpt) |
574 // (1 << kSuspendCheckElimination) |
575 // (1 << kMatch) |
576 // (1 << kPromoteCompilerTemps) |
577 // (1 << kSuppressExceptionEdges) |
578 // (1 << kSuppressMethodInlining) |
579 0;
580
581static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes
582 // (1 << kDebugDisplayMissingTargets) |
583 // (1 << kDebugVerbose) |
584 // (1 << kDebugDumpCFG) |
585 // (1 << kDebugSlowFieldPath) |
586 // (1 << kDebugSlowInvokePath) |
587 // (1 << kDebugSlowStringPath) |
588 // (1 << kDebugSlowestFieldPath) |
589 // (1 << kDebugSlowestStringPath) |
590 // (1 << kDebugExerciseResolveMethod) |
591 // (1 << kDebugVerifyDataflow) |
592 // (1 << kDebugShowMemoryUsage) |
593 // (1 << kDebugShowNops) |
594 // (1 << kDebugCountOpcodes) |
595 // (1 << kDebugDumpCheckStats) |
596 // (1 << kDebugShowSummaryMemoryUsage) |
597 // (1 << kDebugShowFilterStats) |
598 // (1 << kDebugTimings) |
599 // (1 << kDebugCodegenDump) |
600 0;
601
Andreas Gampe53c913b2014-08-12 23:19:23 -0700602CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item,
603 uint32_t access_flags,
604 InvokeType invoke_type,
605 uint16_t class_def_idx,
606 uint32_t method_idx,
607 jobject class_loader,
608 const DexFile& dex_file) const {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700609 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use
610 // build default.
611 CompilerDriver* driver = GetCompilerDriver();
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800612
613 VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
614 if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
615 return nullptr;
616 }
617
618 DCHECK(driver->GetCompilerOptions().IsCompilationEnabled());
619
620 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
621 InstructionSet instruction_set = driver->GetInstructionSet();
622 if (instruction_set == kArm) {
623 instruction_set = kThumb2;
624 }
625 CompilationUnit cu(driver->GetArenaPool(), instruction_set, driver, class_linker);
626
627 // TODO: Mips64 is not yet implemented.
628 CHECK((cu.instruction_set == kThumb2) ||
629 (cu.instruction_set == kArm64) ||
630 (cu.instruction_set == kX86) ||
631 (cu.instruction_set == kX86_64) ||
632 (cu.instruction_set == kMips));
633
634 // TODO: set this from command line
635 constexpr bool compiler_flip_match = false;
636 const std::string compiler_method_match = "";
637
638 bool use_match = !compiler_method_match.empty();
639 bool match = use_match && (compiler_flip_match ^
640 (PrettyMethod(method_idx, dex_file).find(compiler_method_match) != std::string::npos));
641 if (!use_match || match) {
642 cu.disable_opt = kCompilerOptimizerDisableFlags;
643 cu.enable_debug = kCompilerDebugFlags;
644 cu.verbose = VLOG_IS_ON(compiler) ||
645 (cu.enable_debug & (1 << kDebugVerbose));
646 }
647
648 if (driver->GetCompilerOptions().HasVerboseMethods()) {
649 cu.verbose = driver->GetCompilerOptions().IsVerboseMethod(PrettyMethod(method_idx, dex_file));
650 }
651
652 if (cu.verbose) {
653 cu.enable_debug |= (1 << kDebugCodegenDump);
654 }
655
656 /*
657 * TODO: rework handling of optimization and debug flags. Should we split out
658 * MIR and backend flags? Need command-line setting as well.
659 */
660
661 InitCompilationUnit(cu);
662
663 cu.StartTimingSplit("BuildMIRGraph");
664 cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena));
665
666 /*
667 * After creation of the MIR graph, also create the code generator.
668 * The reason we do this is that optimizations on the MIR graph may need to get information
669 * that is only available if a CG exists.
670 */
671 cu.cg.reset(GetCodeGenerator(&cu, nullptr));
672
673 /* Gathering opcode stats? */
674 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
675 cu.mir_graph->EnableOpcodeCounting();
676 }
677
678 /* Build the raw MIR graph */
679 cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
680 class_loader, dex_file);
681
682 if (!CanCompileMethod(method_idx, dex_file, &cu)) {
683 VLOG(compiler) << cu.instruction_set << ": Cannot compile method : "
684 << PrettyMethod(method_idx, dex_file);
685 cu.EndTiming();
686 return nullptr;
687 }
688
689 cu.NewTimingSplit("MIROpt:CheckFilters");
690 std::string skip_message;
691 if (cu.mir_graph->SkipCompilation(&skip_message)) {
692 VLOG(compiler) << cu.instruction_set << ": Skipping method : "
693 << PrettyMethod(method_idx, dex_file) << " Reason = " << skip_message;
694 cu.EndTiming();
695 return nullptr;
696 }
697
698 /* Create the pass driver and launch it */
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800699 PassDriverMEOpts pass_driver(GetPreOptPassManager(), &cu);
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800700 pass_driver.Launch();
701
702 /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */
703 if (cu.compiler_driver->ProfilePresent()
704 && !cu.mir_graph->MethodIsLeaf()
705 && cu.mir_graph->SkipCompilationByName(PrettyMethod(method_idx, dex_file))) {
706 cu.EndTiming();
707 return nullptr;
708 }
709
710 if (cu.enable_debug & (1 << kDebugDumpCheckStats)) {
711 cu.mir_graph->DumpCheckStats();
712 }
713
714 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
715 cu.mir_graph->ShowOpcodeStats();
716 }
717
718 /* Reassociate sreg names with original Dalvik vreg names. */
719 cu.mir_graph->RemapRegLocations();
720
721 /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */
722 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
723 if (cu.arena_stack.PeakBytesAllocated() > 1 * 1024 * 1024) {
724 MemStats stack_stats(cu.arena_stack.GetPeakStats());
725 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats);
726 }
727 }
728 cu.arena_stack.Reset();
729
730 CompiledMethod* result = nullptr;
731
732 if (cu.mir_graph->PuntToInterpreter()) {
733 VLOG(compiler) << cu.instruction_set << ": Punted method to interpreter: "
734 << PrettyMethod(method_idx, dex_file);
735 cu.EndTiming();
736 return nullptr;
737 }
738
739 cu.cg->Materialize();
740
741 cu.NewTimingSplit("Dedupe"); /* deduping takes up the vast majority of time in GetCompiledMethod(). */
742 result = cu.cg->GetCompiledMethod();
743 cu.NewTimingSplit("Cleanup");
744
745 if (result) {
746 VLOG(compiler) << cu.instruction_set << ": Compiled " << PrettyMethod(method_idx, dex_file);
747 } else {
748 VLOG(compiler) << cu.instruction_set << ": Deferred " << PrettyMethod(method_idx, dex_file);
749 }
750
751 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
752 if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) {
753 MemStats mem_stats(cu.arena.GetMemStats());
754 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats);
755 }
756 }
757
758 if (cu.enable_debug & (1 << kDebugShowSummaryMemoryUsage)) {
759 LOG(INFO) << "MEMINFO " << cu.arena.BytesAllocated() << " " << cu.mir_graph->GetNumBlocks()
760 << " " << PrettyMethod(method_idx, dex_file);
761 }
762
763 cu.EndTiming();
764 driver->GetTimingsLogger()->AddLogger(cu.timings);
765 return result;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700766}
767
768CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags,
769 uint32_t method_idx,
770 const DexFile& dex_file) const {
771 return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
772}
773
774uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const {
Mathieu Chartier130914e2014-11-18 15:34:09 -0800775 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
776 InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
Andreas Gampe53c913b2014-08-12 23:19:23 -0700777}
778
779bool QuickCompiler::WriteElf(art::File* file,
780 OatWriter* oat_writer,
781 const std::vector<const art::DexFile*>& dex_files,
782 const std::string& android_root,
783 bool is_host) const {
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000784 return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host,
785 *GetCompilerDriver());
Andreas Gampe53c913b2014-08-12 23:19:23 -0700786}
787
Andreas Gampe9c462082015-01-27 14:31:40 -0800788Mir2Lir* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700789 UNUSED(compilation_unit);
Andreas Gampe53c913b2014-08-12 23:19:23 -0700790 Mir2Lir* mir_to_lir = nullptr;
791 switch (cu->instruction_set) {
792 case kThumb2:
793 mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
794 break;
795 case kArm64:
796 mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
797 break;
798 case kMips:
799 mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
800 break;
801 case kX86:
802 // Fall-through.
803 case kX86_64:
804 mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
805 break;
806 default:
807 LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set;
808 }
809
810 /* The number of compiler temporaries depends on backend so set it up now if possible */
811 if (mir_to_lir) {
812 size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps();
813 bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps);
814 CHECK(set_max);
815 }
816 return mir_to_lir;
817}
818
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800819QuickCompiler::QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {
820 const auto& compiler_options = driver->GetCompilerOptions();
821 auto* pass_manager_options = compiler_options.GetPassManagerOptions();
822 pre_opt_pass_manager_.reset(new PassManager(*pass_manager_options));
823 CHECK(pre_opt_pass_manager_.get() != nullptr);
824 PassDriverMEOpts::SetupPasses(pre_opt_pass_manager_.get());
825 pre_opt_pass_manager_->CreateDefaultPassList();
826 if (pass_manager_options->GetPrintPassOptions()) {
827 PassDriverMEOpts::PrintPassOptions(pre_opt_pass_manager_.get());
828 }
829 // TODO: Different options for pre vs post opts?
830 post_opt_pass_manager_.reset(new PassManager(PassManagerOptions()));
831 CHECK(post_opt_pass_manager_.get() != nullptr);
832 PassDriverMEPostOpt::SetupPasses(post_opt_pass_manager_.get());
833 post_opt_pass_manager_->CreateDefaultPassList();
834 if (pass_manager_options->GetPrintPassOptions()) {
835 PassDriverMEPostOpt::PrintPassOptions(post_opt_pass_manager_.get());
836 }
837}
838
839QuickCompiler::~QuickCompiler() {
840}
Andreas Gampe53c913b2014-08-12 23:19:23 -0700841
842Compiler* CreateQuickCompiler(CompilerDriver* driver) {
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800843 return QuickCompiler::Create(driver);
844}
845
846Compiler* QuickCompiler::Create(CompilerDriver* driver) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700847 return new QuickCompiler(driver);
848}
849
850} // namespace art