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