quick_compiler.cc revision a5ca888d715cd0c6c421313211caa1928be3e399
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 "base/dumpable.h" 22#include "base/logging.h" 23#include "base/macros.h" 24#include "base/timing_logger.h" 25#include "compiler.h" 26#include "dex_file-inl.h" 27#include "dex_file_to_method_inliner_map.h" 28#include "dex/compiler_ir.h" 29#include "dex/dex_flags.h" 30#include "dex/mir_graph.h" 31#include "dex/pass_driver_me_opts.h" 32#include "dex/pass_driver_me_post_opt.h" 33#include "dex/pass_manager.h" 34#include "dex/quick/mir_to_lir.h" 35#include "driver/compiler_driver.h" 36#include "driver/compiler_options.h" 37#include "elf_writer_quick.h" 38#include "jni/quick/jni_compiler.h" 39#include "mir_to_lir.h" 40#include "mirror/art_method-inl.h" 41#include "mirror/object.h" 42#include "runtime.h" 43 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 52static_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"); 60 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}; 92static_assert(sizeof(kDisabledOptimizationsPerISA) == 8 * sizeof(uint32_t), 93 "kDisabledOpts unexpected"); 94 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}; 124static_assert(sizeof(kSupportedTypes) == 8 * sizeof(char*), "kSupportedTypes unexpected"); 125 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, 362 Instruction::IPUT_BOOLEAN_QUICK, 363 Instruction::IPUT_BYTE_QUICK, 364 Instruction::IPUT_CHAR_QUICK, 365 Instruction::IPUT_SHORT_QUICK, 366 Instruction::IGET_BOOLEAN_QUICK, 367 Instruction::IGET_BYTE_QUICK, 368 Instruction::IGET_CHAR_QUICK, 369 Instruction::IGET_SHORT_QUICK, 370 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 400static 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 415// 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}; 435static_assert(sizeof(kUnsupportedOpcodes) == 8 * sizeof(int*), "kUnsupportedOpcodes unexpected"); 436 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}; 456static_assert(sizeof(kUnsupportedOpcodesSize) == 8 * sizeof(size_t), 457 "kUnsupportedOpcodesSize unexpected"); 458 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; 479} 480 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. 485 if (cu->mir_graph->GetNumOfCodeAndTempVRs() > kMaxAllowedDalvikRegisters) { 486 VLOG(compiler) << "Too many dalvik registers : " << cu->mir_graph->GetNumOfCodeAndTempVRs(); 487 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. 513 if (std::find(unsupport_list, unsupport_list + unsupport_list_size, opcode) 514 != unsupport_list + unsupport_list_size) { 515 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. 525 if (std::find(kInvokeOpcodes, kInvokeOpcodes + arraysize(kInvokeOpcodes), opcode) 526 != kInvokeOpcodes + arraysize(kInvokeOpcodes)) { 527 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]; 545} 546 547void QuickCompiler::Init() { 548 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr); 549} 550 551void QuickCompiler::UnInit() const { 552 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr); 553} 554 555/* Default optimizer/debug setting for the compiler. */ 556static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations 557 // (1 << kLoadStoreElimination) | 558 // (1 << kLoadHoisting) | 559 // (1 << kSuppressLoads) | 560 // (1 << kNullCheckElimination) | 561 // (1 << kClassInitCheckElimination) | 562 // (1 << kGlobalValueNumbering) | 563 (1 << kGvnDeadCodeElimination) | 564 // (1 << kLocalValueNumbering) | 565 // (1 << kPromoteRegs) | 566 // (1 << kTrackLiveTemps) | 567 // (1 << kSafeOptimizations) | 568 // (1 << kBBOpt) | 569 // (1 << kSuspendCheckElimination) | 570 // (1 << kMatch) | 571 // (1 << kPromoteCompilerTemps) | 572 // (1 << kSuppressExceptionEdges) | 573 // (1 << kSuppressMethodInlining) | 574 0; 575 576static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes 577 // (1 << kDebugDisplayMissingTargets) | 578 // (1 << kDebugVerbose) | 579 // (1 << kDebugDumpCFG) | 580 // (1 << kDebugSlowFieldPath) | 581 // (1 << kDebugSlowInvokePath) | 582 // (1 << kDebugSlowStringPath) | 583 // (1 << kDebugSlowestFieldPath) | 584 // (1 << kDebugSlowestStringPath) | 585 // (1 << kDebugExerciseResolveMethod) | 586 // (1 << kDebugVerifyDataflow) | 587 // (1 << kDebugShowMemoryUsage) | 588 // (1 << kDebugShowNops) | 589 // (1 << kDebugCountOpcodes) | 590 // (1 << kDebugDumpCheckStats) | 591 // (1 << kDebugShowSummaryMemoryUsage) | 592 // (1 << kDebugShowFilterStats) | 593 // (1 << kDebugTimings) | 594 // (1 << kDebugCodegenDump) | 595 0; 596 597CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item, 598 uint32_t access_flags, 599 InvokeType invoke_type, 600 uint16_t class_def_idx, 601 uint32_t method_idx, 602 jobject class_loader, 603 const DexFile& dex_file) const { 604 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use 605 // build default. 606 CompilerDriver* driver = GetCompilerDriver(); 607 608 VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "..."; 609 if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) { 610 return nullptr; 611 } 612 613 DCHECK(driver->GetCompilerOptions().IsCompilationEnabled()); 614 615 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 616 InstructionSet instruction_set = driver->GetInstructionSet(); 617 if (instruction_set == kArm) { 618 instruction_set = kThumb2; 619 } 620 CompilationUnit cu(driver->GetArenaPool(), instruction_set, driver, class_linker); 621 622 // TODO: Mips64 is not yet implemented. 623 CHECK((cu.instruction_set == kThumb2) || 624 (cu.instruction_set == kArm64) || 625 (cu.instruction_set == kX86) || 626 (cu.instruction_set == kX86_64) || 627 (cu.instruction_set == kMips)); 628 629 // TODO: set this from command line 630 constexpr bool compiler_flip_match = false; 631 const std::string compiler_method_match = ""; 632 633 bool use_match = !compiler_method_match.empty(); 634 bool match = use_match && (compiler_flip_match ^ 635 (PrettyMethod(method_idx, dex_file).find(compiler_method_match) != std::string::npos)); 636 if (!use_match || match) { 637 cu.disable_opt = kCompilerOptimizerDisableFlags; 638 cu.enable_debug = kCompilerDebugFlags; 639 cu.verbose = VLOG_IS_ON(compiler) || 640 (cu.enable_debug & (1 << kDebugVerbose)); 641 } 642 643 if (driver->GetCompilerOptions().HasVerboseMethods()) { 644 cu.verbose = driver->GetCompilerOptions().IsVerboseMethod(PrettyMethod(method_idx, dex_file)); 645 } 646 647 if (cu.verbose) { 648 cu.enable_debug |= (1 << kDebugCodegenDump); 649 } 650 651 /* 652 * TODO: rework handling of optimization and debug flags. Should we split out 653 * MIR and backend flags? Need command-line setting as well. 654 */ 655 656 InitCompilationUnit(cu); 657 658 cu.StartTimingSplit("BuildMIRGraph"); 659 cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena)); 660 661 /* 662 * After creation of the MIR graph, also create the code generator. 663 * The reason we do this is that optimizations on the MIR graph may need to get information 664 * that is only available if a CG exists. 665 */ 666 cu.cg.reset(GetCodeGenerator(&cu, nullptr)); 667 668 /* Gathering opcode stats? */ 669 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) { 670 cu.mir_graph->EnableOpcodeCounting(); 671 } 672 673 /* Build the raw MIR graph */ 674 cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx, 675 class_loader, dex_file); 676 677 if (!CanCompileMethod(method_idx, dex_file, &cu)) { 678 VLOG(compiler) << cu.instruction_set << ": Cannot compile method : " 679 << PrettyMethod(method_idx, dex_file); 680 cu.EndTiming(); 681 return nullptr; 682 } 683 684 cu.NewTimingSplit("MIROpt:CheckFilters"); 685 std::string skip_message; 686 if (cu.mir_graph->SkipCompilation(&skip_message)) { 687 VLOG(compiler) << cu.instruction_set << ": Skipping method : " 688 << PrettyMethod(method_idx, dex_file) << " Reason = " << skip_message; 689 cu.EndTiming(); 690 return nullptr; 691 } 692 693 /* Create the pass driver and launch it */ 694 PassDriverMEOpts pass_driver(GetPreOptPassManager(), &cu); 695 pass_driver.Launch(); 696 697 /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */ 698 if (cu.compiler_driver->ProfilePresent() 699 && !cu.mir_graph->MethodIsLeaf() 700 && cu.mir_graph->SkipCompilationByName(PrettyMethod(method_idx, dex_file))) { 701 cu.EndTiming(); 702 return nullptr; 703 } 704 705 if (cu.enable_debug & (1 << kDebugDumpCheckStats)) { 706 cu.mir_graph->DumpCheckStats(); 707 } 708 709 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) { 710 cu.mir_graph->ShowOpcodeStats(); 711 } 712 713 /* Reassociate sreg names with original Dalvik vreg names. */ 714 cu.mir_graph->RemapRegLocations(); 715 716 /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */ 717 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) { 718 if (cu.arena_stack.PeakBytesAllocated() > 1 * 1024 * 1024) { 719 MemStats stack_stats(cu.arena_stack.GetPeakStats()); 720 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats); 721 } 722 } 723 cu.arena_stack.Reset(); 724 725 CompiledMethod* result = nullptr; 726 727 if (cu.mir_graph->PuntToInterpreter()) { 728 VLOG(compiler) << cu.instruction_set << ": Punted method to interpreter: " 729 << PrettyMethod(method_idx, dex_file); 730 cu.EndTiming(); 731 return nullptr; 732 } 733 734 cu.cg->Materialize(); 735 736 cu.NewTimingSplit("Dedupe"); /* deduping takes up the vast majority of time in GetCompiledMethod(). */ 737 result = cu.cg->GetCompiledMethod(); 738 cu.NewTimingSplit("Cleanup"); 739 740 if (result) { 741 VLOG(compiler) << cu.instruction_set << ": Compiled " << PrettyMethod(method_idx, dex_file); 742 } else { 743 VLOG(compiler) << cu.instruction_set << ": Deferred " << PrettyMethod(method_idx, dex_file); 744 } 745 746 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) { 747 if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) { 748 MemStats mem_stats(cu.arena.GetMemStats()); 749 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats); 750 } 751 } 752 753 if (cu.enable_debug & (1 << kDebugShowSummaryMemoryUsage)) { 754 LOG(INFO) << "MEMINFO " << cu.arena.BytesAllocated() << " " << cu.mir_graph->GetNumBlocks() 755 << " " << PrettyMethod(method_idx, dex_file); 756 } 757 758 cu.EndTiming(); 759 driver->GetTimingsLogger()->AddLogger(cu.timings); 760 return result; 761} 762 763CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags, 764 uint32_t method_idx, 765 const DexFile& dex_file) const { 766 return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file); 767} 768 769uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const { 770 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize( 771 InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet()))); 772} 773 774bool QuickCompiler::WriteElf(art::File* file, 775 OatWriter* oat_writer, 776 const std::vector<const art::DexFile*>& dex_files, 777 const std::string& android_root, 778 bool is_host) const { 779 return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host, 780 *GetCompilerDriver()); 781} 782 783Mir2Lir* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const { 784 UNUSED(compilation_unit); 785 Mir2Lir* mir_to_lir = nullptr; 786 switch (cu->instruction_set) { 787 case kThumb2: 788 mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 789 break; 790 case kArm64: 791 mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 792 break; 793 case kMips: 794 mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 795 break; 796 case kX86: 797 // Fall-through. 798 case kX86_64: 799 mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 800 break; 801 default: 802 LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set; 803 } 804 805 /* The number of compiler temporaries depends on backend so set it up now if possible */ 806 if (mir_to_lir) { 807 size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps(); 808 bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps); 809 CHECK(set_max); 810 } 811 return mir_to_lir; 812} 813 814QuickCompiler::QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) { 815 const auto& compiler_options = driver->GetCompilerOptions(); 816 auto* pass_manager_options = compiler_options.GetPassManagerOptions(); 817 pre_opt_pass_manager_.reset(new PassManager(*pass_manager_options)); 818 CHECK(pre_opt_pass_manager_.get() != nullptr); 819 PassDriverMEOpts::SetupPasses(pre_opt_pass_manager_.get()); 820 pre_opt_pass_manager_->CreateDefaultPassList(); 821 if (pass_manager_options->GetPrintPassOptions()) { 822 PassDriverMEOpts::PrintPassOptions(pre_opt_pass_manager_.get()); 823 } 824 // TODO: Different options for pre vs post opts? 825 post_opt_pass_manager_.reset(new PassManager(PassManagerOptions())); 826 CHECK(post_opt_pass_manager_.get() != nullptr); 827 PassDriverMEPostOpt::SetupPasses(post_opt_pass_manager_.get()); 828 post_opt_pass_manager_->CreateDefaultPassList(); 829 if (pass_manager_options->GetPrintPassOptions()) { 830 PassDriverMEPostOpt::PrintPassOptions(post_opt_pass_manager_.get()); 831 } 832} 833 834QuickCompiler::~QuickCompiler() { 835} 836 837Compiler* CreateQuickCompiler(CompilerDriver* driver) { 838 return QuickCompiler::Create(driver); 839} 840 841Compiler* QuickCompiler::Create(CompilerDriver* driver) { 842 return new QuickCompiler(driver); 843} 844 845} // namespace art 846