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