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