frontend.cc revision 4439596b00c91f565370bf0813cc2f9165093693
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 "compiler.h" 18#include "compiler_internals.h" 19#include "driver/compiler_driver.h" 20#include "driver/compiler_options.h" 21#include "dataflow_iterator-inl.h" 22#include "leb128.h" 23#include "mirror/object.h" 24#include "pass_driver_me_opts.h" 25#include "runtime.h" 26#include "base/logging.h" 27#include "base/timing_logger.h" 28#include "driver/compiler_options.h" 29#include "dex/quick/dex_file_to_method_inliner_map.h" 30 31namespace art { 32 33extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver* driver) { 34 CHECK(driver->GetCompilerContext() == nullptr); 35} 36 37extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver* driver) { 38 CHECK(driver->GetCompilerContext() == nullptr); 39} 40 41/* Default optimizer/debug setting for the compiler. */ 42static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations 43 (1 << kLoadStoreElimination) | // TODO: this pass has been broken for awhile - fix or delete. 44 // (1 << kLoadHoisting) | 45 // (1 << kSuppressLoads) | 46 // (1 << kNullCheckElimination) | 47 // (1 << kClassInitCheckElimination) | 48 // (1 << kPromoteRegs) | 49 // (1 << kTrackLiveTemps) | 50 // (1 << kSafeOptimizations) | 51 // (1 << kBBOpt) | 52 // (1 << kMatch) | 53 // (1 << kPromoteCompilerTemps) | 54 // (1 << kSuppressExceptionEdges) | 55 // (1 << kSuppressMethodInlining) | 56 0; 57 58static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes 59 // (1 << kDebugDisplayMissingTargets) | 60 // (1 << kDebugVerbose) | 61 // (1 << kDebugDumpCFG) | 62 // (1 << kDebugSlowFieldPath) | 63 // (1 << kDebugSlowInvokePath) | 64 // (1 << kDebugSlowStringPath) | 65 // (1 << kDebugSlowestFieldPath) | 66 // (1 << kDebugSlowestStringPath) | 67 // (1 << kDebugExerciseResolveMethod) | 68 // (1 << kDebugVerifyDataflow) | 69 // (1 << kDebugShowMemoryUsage) | 70 // (1 << kDebugShowNops) | 71 // (1 << kDebugCountOpcodes) | 72 // (1 << kDebugDumpCheckStats) | 73 // (1 << kDebugDumpBitcodeFile) | 74 // (1 << kDebugVerifyBitcode) | 75 // (1 << kDebugShowSummaryMemoryUsage) | 76 // (1 << kDebugShowFilterStats) | 77 // (1 << kDebugTimings) | 78 // (1 << kDebugCodegenDump) | 79 0; 80 81CompilationUnit::CompilationUnit(ArenaPool* pool) 82 : compiler_driver(nullptr), 83 class_linker(nullptr), 84 dex_file(nullptr), 85 class_loader(nullptr), 86 class_def_idx(0), 87 method_idx(0), 88 code_item(nullptr), 89 access_flags(0), 90 invoke_type(kDirect), 91 shorty(nullptr), 92 disable_opt(0), 93 enable_debug(0), 94 verbose(false), 95 compiler(nullptr), 96 instruction_set(kNone), 97 target64(false), 98 num_dalvik_registers(0), 99 insns(nullptr), 100 num_ins(0), 101 num_outs(0), 102 num_regs(0), 103 compiler_flip_match(false), 104 arena(pool), 105 arena_stack(pool), 106 mir_graph(nullptr), 107 cg(nullptr), 108 timings("QuickCompiler", true, false), 109 print_pass(false) { 110} 111 112CompilationUnit::~CompilationUnit() { 113} 114 115void CompilationUnit::StartTimingSplit(const char* label) { 116 if (compiler_driver->GetDumpPasses()) { 117 timings.StartSplit(label); 118 } 119} 120 121void CompilationUnit::NewTimingSplit(const char* label) { 122 if (compiler_driver->GetDumpPasses()) { 123 timings.NewSplit(label); 124 } 125} 126 127void CompilationUnit::EndTiming() { 128 if (compiler_driver->GetDumpPasses()) { 129 timings.EndSplit(); 130 if (enable_debug & (1 << kDebugTimings)) { 131 LOG(INFO) << "TIMINGS " << PrettyMethod(method_idx, *dex_file); 132 LOG(INFO) << Dumpable<TimingLogger>(timings); 133 } 134 } 135} 136 137// Enable opcodes that mostly work, but produce assertion errors (thus breaking libartd.so). 138#define ARM64_USE_EXPERIMENTAL_OPCODES 0 139 140// TODO: Remove this when we are able to compile everything. 141int arm64_support_list[] = { 142 Instruction::NOP, 143 Instruction::MOVE, 144 Instruction::MOVE_FROM16, 145 Instruction::MOVE_16, 146 Instruction::MOVE_WIDE, 147 Instruction::MOVE_WIDE_FROM16, 148 Instruction::MOVE_WIDE_16, 149 Instruction::MOVE_OBJECT, 150 Instruction::MOVE_OBJECT_FROM16, 151 Instruction::MOVE_OBJECT_16, 152 Instruction::MOVE_EXCEPTION, 153 Instruction::RETURN_VOID, 154 Instruction::RETURN, 155 Instruction::RETURN_WIDE, 156 Instruction::RETURN_OBJECT, 157 Instruction::CONST_4, 158 Instruction::CONST_16, 159 Instruction::CONST, 160 Instruction::CONST_HIGH16, 161 Instruction::CONST_WIDE_16, 162 Instruction::CONST_WIDE_32, 163 Instruction::CONST_WIDE, 164 Instruction::CONST_WIDE_HIGH16, 165 Instruction::CONST_STRING, 166 Instruction::MONITOR_ENTER, 167 Instruction::MONITOR_EXIT, 168 Instruction::THROW, 169 Instruction::GOTO, 170 Instruction::GOTO_16, 171 Instruction::GOTO_32, 172 Instruction::PACKED_SWITCH, 173 Instruction::SPARSE_SWITCH, 174 Instruction::CMPL_FLOAT, 175 Instruction::CMPG_FLOAT, 176 Instruction::CMPL_DOUBLE, 177 Instruction::CMPG_DOUBLE, 178 Instruction::CMP_LONG, 179 Instruction::IF_EQ, 180 Instruction::IF_NE, 181 Instruction::IF_LT, 182 Instruction::IF_GE, 183 Instruction::IF_GT, 184 Instruction::IF_LE, 185 Instruction::IF_EQZ, 186 Instruction::IF_NEZ, 187 Instruction::IF_LTZ, 188 Instruction::IF_GEZ, 189 Instruction::IF_GTZ, 190 Instruction::IF_LEZ, 191 Instruction::NEG_INT, 192 Instruction::NOT_INT, 193 Instruction::NEG_FLOAT, 194 Instruction::INT_TO_BYTE, 195 Instruction::INT_TO_CHAR, 196 Instruction::INT_TO_SHORT, 197 Instruction::ADD_INT, 198 Instruction::SUB_INT, 199 Instruction::MUL_INT, 200 Instruction::DIV_INT, 201 Instruction::REM_INT, 202 Instruction::AND_INT, 203 Instruction::OR_INT, 204 Instruction::XOR_INT, 205 Instruction::SHL_INT, 206 Instruction::SHR_INT, 207 Instruction::USHR_INT, 208 Instruction::ADD_FLOAT, 209 Instruction::SUB_FLOAT, 210 Instruction::MUL_FLOAT, 211 Instruction::DIV_FLOAT, 212 Instruction::ADD_INT_2ADDR, 213 Instruction::SUB_INT_2ADDR, 214 Instruction::MUL_INT_2ADDR, 215 Instruction::DIV_INT_2ADDR, 216 Instruction::REM_INT_2ADDR, 217 Instruction::AND_INT_2ADDR, 218 Instruction::OR_INT_2ADDR, 219 Instruction::XOR_INT_2ADDR, 220 Instruction::SHL_INT_2ADDR, 221 Instruction::SHR_INT_2ADDR, 222 Instruction::USHR_INT_2ADDR, 223 Instruction::ADD_FLOAT_2ADDR, 224 Instruction::SUB_FLOAT_2ADDR, 225 Instruction::MUL_FLOAT_2ADDR, 226 Instruction::DIV_FLOAT_2ADDR, 227 Instruction::ADD_INT_LIT16, 228 Instruction::RSUB_INT, 229 Instruction::MUL_INT_LIT16, 230 Instruction::DIV_INT_LIT16, 231 Instruction::REM_INT_LIT16, 232 Instruction::AND_INT_LIT16, 233 Instruction::OR_INT_LIT16, 234 Instruction::XOR_INT_LIT16, 235 Instruction::ADD_INT_LIT8, 236 Instruction::RSUB_INT_LIT8, 237 Instruction::MUL_INT_LIT8, 238 Instruction::DIV_INT_LIT8, 239 Instruction::REM_INT_LIT8, 240 Instruction::AND_INT_LIT8, 241 Instruction::OR_INT_LIT8, 242 Instruction::XOR_INT_LIT8, 243 Instruction::SHL_INT_LIT8, 244 Instruction::SHR_INT_LIT8, 245 Instruction::USHR_INT_LIT8, 246 Instruction::SGET, 247 Instruction::SGET_BOOLEAN, 248 Instruction::SGET_BYTE, 249 Instruction::SGET_CHAR, 250 Instruction::SGET_SHORT, 251 Instruction::SGET_OBJECT, 252 Instruction::SPUT, 253 Instruction::SPUT_OBJECT, 254 Instruction::SPUT_BOOLEAN, 255 Instruction::SPUT_BYTE, 256 Instruction::SPUT_CHAR, 257 Instruction::SPUT_SHORT, 258 Instruction::CMPL_FLOAT, 259 Instruction::CMPG_FLOAT, 260 Instruction::IGET, 261 Instruction::IGET_OBJECT, 262 Instruction::IGET_BOOLEAN, 263 Instruction::IGET_BYTE, 264 Instruction::IGET_CHAR, 265 Instruction::IGET_SHORT, 266 Instruction::IPUT, 267 Instruction::IPUT_OBJECT, 268 Instruction::IPUT_BOOLEAN, 269 Instruction::IPUT_BYTE, 270 Instruction::IPUT_CHAR, 271 Instruction::IPUT_SHORT, 272 Instruction::NEG_LONG, 273 Instruction::NOT_LONG, 274 Instruction::NEG_DOUBLE, 275 Instruction::INT_TO_LONG, 276 Instruction::INT_TO_FLOAT, 277 Instruction::INT_TO_DOUBLE, 278 Instruction::LONG_TO_INT, 279 Instruction::LONG_TO_FLOAT, 280 Instruction::LONG_TO_DOUBLE, 281 Instruction::FLOAT_TO_INT, 282 Instruction::FLOAT_TO_LONG, 283 Instruction::FLOAT_TO_DOUBLE, 284 Instruction::DOUBLE_TO_INT, 285 Instruction::DOUBLE_TO_LONG, 286 Instruction::DOUBLE_TO_FLOAT, 287 Instruction::ADD_LONG, 288 Instruction::SUB_LONG, 289 Instruction::MUL_LONG, 290 Instruction::DIV_LONG, 291 Instruction::REM_LONG, 292 Instruction::AND_LONG, 293 Instruction::OR_LONG, 294 Instruction::XOR_LONG, 295 Instruction::SHL_LONG, 296 Instruction::SHR_LONG, 297 Instruction::USHR_LONG, 298 Instruction::REM_FLOAT, 299 Instruction::ADD_DOUBLE, 300 Instruction::SUB_DOUBLE, 301 Instruction::MUL_DOUBLE, 302 Instruction::DIV_DOUBLE, 303 Instruction::REM_DOUBLE, 304 Instruction::ADD_LONG_2ADDR, 305 Instruction::SUB_LONG_2ADDR, 306 Instruction::MUL_LONG_2ADDR, 307 Instruction::DIV_LONG_2ADDR, 308 Instruction::REM_LONG_2ADDR, 309 Instruction::AND_LONG_2ADDR, 310 Instruction::OR_LONG_2ADDR, 311 Instruction::XOR_LONG_2ADDR, 312 Instruction::SHL_LONG_2ADDR, 313 Instruction::SHR_LONG_2ADDR, 314 Instruction::USHR_LONG_2ADDR, 315 Instruction::REM_FLOAT_2ADDR, 316 Instruction::ADD_DOUBLE_2ADDR, 317 Instruction::SUB_DOUBLE_2ADDR, 318 Instruction::MUL_DOUBLE_2ADDR, 319 Instruction::DIV_DOUBLE_2ADDR, 320 Instruction::REM_DOUBLE_2ADDR, 321 // TODO(Arm64): Enable compiler pass 322 // ----- ExtendedMIROpcode ----- 323 kMirOpPhi, 324 kMirOpCopy, 325 kMirOpFusedCmplFloat, 326 kMirOpFusedCmpgFloat, 327 kMirOpFusedCmplDouble, 328 kMirOpFusedCmpgDouble, 329 kMirOpFusedCmpLong, 330 kMirOpNop, 331 kMirOpNullCheck, 332 kMirOpRangeCheck, 333 kMirOpDivZeroCheck, 334 kMirOpCheck, 335 kMirOpCheckPart2, 336 kMirOpSelect, 337 338#if ARM64_USE_EXPERIMENTAL_OPCODES 339 // Instruction::MOVE_RESULT, 340 // Instruction::MOVE_RESULT_WIDE, 341 // Instruction::MOVE_RESULT_OBJECT, 342 // Instruction::CONST_STRING_JUMBO, 343 // Instruction::CONST_CLASS, 344 // Instruction::CHECK_CAST, 345 // Instruction::INSTANCE_OF, 346 // Instruction::ARRAY_LENGTH, 347 // Instruction::NEW_INSTANCE, 348 // Instruction::NEW_ARRAY, 349 // Instruction::FILLED_NEW_ARRAY, 350 // Instruction::FILLED_NEW_ARRAY_RANGE, 351 // Instruction::FILL_ARRAY_DATA, 352 // Instruction::UNUSED_3E, 353 // Instruction::UNUSED_3F, 354 // Instruction::UNUSED_40, 355 // Instruction::UNUSED_41, 356 // Instruction::UNUSED_42, 357 // Instruction::UNUSED_43, 358 // Instruction::AGET, 359 // Instruction::AGET_WIDE, 360 // Instruction::AGET_OBJECT, 361 // Instruction::AGET_BOOLEAN, 362 // Instruction::AGET_BYTE, 363 // Instruction::AGET_CHAR, 364 // Instruction::AGET_SHORT, 365 // Instruction::APUT, 366 // Instruction::APUT_WIDE, 367 // Instruction::APUT_OBJECT, 368 // Instruction::APUT_BOOLEAN, 369 // Instruction::APUT_BYTE, 370 // Instruction::APUT_CHAR, 371 // Instruction::APUT_SHORT, 372 // Instruction::IPUT_WIDE, 373 // Instruction::IGET_WIDE, 374 // Instruction::SGET_WIDE, 375 // Instruction::SPUT_WIDE, 376 Instruction::INVOKE_VIRTUAL, 377 Instruction::INVOKE_SUPER, 378 Instruction::INVOKE_DIRECT, 379 Instruction::INVOKE_STATIC, 380 Instruction::INVOKE_INTERFACE, 381 // Instruction::RETURN_VOID_BARRIER, 382 // Instruction::INVOKE_VIRTUAL_RANGE, 383 // Instruction::INVOKE_SUPER_RANGE, 384 // Instruction::INVOKE_DIRECT_RANGE, 385 // Instruction::INVOKE_STATIC_RANGE, 386 // Instruction::INVOKE_INTERFACE_RANGE, 387 // Instruction::UNUSED_79, 388 // Instruction::UNUSED_7A, 389 // Instruction::IGET_QUICK, 390 // Instruction::IGET_WIDE_QUICK, 391 // Instruction::IGET_OBJECT_QUICK, 392 // Instruction::IPUT_QUICK, 393 // Instruction::IPUT_WIDE_QUICK, 394 // Instruction::IPUT_OBJECT_QUICK, 395 // Instruction::INVOKE_VIRTUAL_QUICK, 396 // Instruction::INVOKE_VIRTUAL_RANGE_QUICK, 397 // Instruction::UNUSED_EB, 398 // Instruction::UNUSED_EC, 399 // Instruction::UNUSED_ED, 400 // Instruction::UNUSED_EE, 401 // Instruction::UNUSED_EF, 402 // Instruction::UNUSED_F0, 403 // Instruction::UNUSED_F1, 404 // Instruction::UNUSED_F2, 405 // Instruction::UNUSED_F3, 406 // Instruction::UNUSED_F4, 407 // Instruction::UNUSED_F5, 408 // Instruction::UNUSED_F6, 409 // Instruction::UNUSED_F7, 410 // Instruction::UNUSED_F8, 411 // Instruction::UNUSED_F9, 412 // Instruction::UNUSED_FA, 413 // Instruction::UNUSED_FB, 414 // Instruction::UNUSED_FC, 415 // Instruction::UNUSED_FD, 416 // Instruction::UNUSED_FE, 417 // Instruction::UNUSED_FF, 418#endif /* ARM64_USE_EXPERIMENTAL_OPCODES */ 419}; 420 421// TODO: Remove this when we are able to compile everything. 422int x86_64_support_list[] = { 423 Instruction::NOP, 424 // Instruction::MOVE, 425 // Instruction::MOVE_FROM16, 426 // Instruction::MOVE_16, 427 // Instruction::MOVE_WIDE, 428 // Instruction::MOVE_WIDE_FROM16, 429 // Instruction::MOVE_WIDE_16, 430 // Instruction::MOVE_OBJECT, 431 // Instruction::MOVE_OBJECT_FROM16, 432 // Instruction::MOVE_OBJECT_16, 433 // Instruction::MOVE_RESULT, 434 // Instruction::MOVE_RESULT_WIDE, 435 // Instruction::MOVE_RESULT_OBJECT, 436 // Instruction::MOVE_EXCEPTION, 437 Instruction::RETURN_VOID, 438 Instruction::RETURN, 439 // Instruction::RETURN_WIDE, 440 Instruction::RETURN_OBJECT, 441 // Instruction::CONST_4, 442 // Instruction::CONST_16, 443 // Instruction::CONST, 444 // Instruction::CONST_HIGH16, 445 // Instruction::CONST_WIDE_16, 446 // Instruction::CONST_WIDE_32, 447 // Instruction::CONST_WIDE, 448 // Instruction::CONST_WIDE_HIGH16, 449 // Instruction::CONST_STRING, 450 // Instruction::CONST_STRING_JUMBO, 451 // Instruction::CONST_CLASS, 452 // Instruction::MONITOR_ENTER, 453 // Instruction::MONITOR_EXIT, 454 // Instruction::CHECK_CAST, 455 // Instruction::INSTANCE_OF, 456 // Instruction::ARRAY_LENGTH, 457 // Instruction::NEW_INSTANCE, 458 // Instruction::NEW_ARRAY, 459 // Instruction::FILLED_NEW_ARRAY, 460 // Instruction::FILLED_NEW_ARRAY_RANGE, 461 // Instruction::FILL_ARRAY_DATA, 462 // Instruction::THROW, 463 // Instruction::GOTO, 464 // Instruction::GOTO_16, 465 // Instruction::GOTO_32, 466 // Instruction::PACKED_SWITCH, 467 // Instruction::SPARSE_SWITCH, 468 // Instruction::CMPL_FLOAT, 469 // Instruction::CMPG_FLOAT, 470 // Instruction::CMPL_DOUBLE, 471 // Instruction::CMPG_DOUBLE, 472 // Instruction::CMP_LONG, 473 // Instruction::IF_EQ, 474 // Instruction::IF_NE, 475 // Instruction::IF_LT, 476 // Instruction::IF_GE, 477 // Instruction::IF_GT, 478 // Instruction::IF_LE, 479 // Instruction::IF_EQZ, 480 // Instruction::IF_NEZ, 481 // Instruction::IF_LTZ, 482 // Instruction::IF_GEZ, 483 // Instruction::IF_GTZ, 484 // Instruction::IF_LEZ, 485 // Instruction::UNUSED_3E, 486 // Instruction::UNUSED_3F, 487 // Instruction::UNUSED_40, 488 // Instruction::UNUSED_41, 489 // Instruction::UNUSED_42, 490 // Instruction::UNUSED_43, 491 // Instruction::AGET, 492 // Instruction::AGET_WIDE, 493 // Instruction::AGET_OBJECT, 494 // Instruction::AGET_BOOLEAN, 495 // Instruction::AGET_BYTE, 496 // Instruction::AGET_CHAR, 497 // Instruction::AGET_SHORT, 498 // Instruction::APUT, 499 // Instruction::APUT_WIDE, 500 // Instruction::APUT_OBJECT, 501 // Instruction::APUT_BOOLEAN, 502 // Instruction::APUT_BYTE, 503 // Instruction::APUT_CHAR, 504 // Instruction::APUT_SHORT, 505 // Instruction::IGET, 506 // Instruction::IGET_WIDE, 507 // Instruction::IGET_OBJECT, 508 // Instruction::IGET_BOOLEAN, 509 // Instruction::IGET_BYTE, 510 // Instruction::IGET_CHAR, 511 // Instruction::IGET_SHORT, 512 // Instruction::IPUT, 513 // Instruction::IPUT_WIDE, 514 // Instruction::IPUT_OBJECT, 515 // Instruction::IPUT_BOOLEAN, 516 // Instruction::IPUT_BYTE, 517 // Instruction::IPUT_CHAR, 518 // Instruction::IPUT_SHORT, 519 Instruction::SGET, 520 // Instruction::SGET_WIDE, 521 Instruction::SGET_OBJECT, 522 Instruction::SGET_BOOLEAN, 523 Instruction::SGET_BYTE, 524 Instruction::SGET_CHAR, 525 Instruction::SGET_SHORT, 526 Instruction::SPUT, 527 // Instruction::SPUT_WIDE, 528 Instruction::SPUT_OBJECT, 529 Instruction::SPUT_BOOLEAN, 530 Instruction::SPUT_BYTE, 531 Instruction::SPUT_CHAR, 532 Instruction::SPUT_SHORT, 533 Instruction::INVOKE_VIRTUAL, 534 Instruction::INVOKE_SUPER, 535 Instruction::INVOKE_DIRECT, 536 Instruction::INVOKE_STATIC, 537 Instruction::INVOKE_INTERFACE, 538 // Instruction::RETURN_VOID_BARRIER, 539 // Instruction::INVOKE_VIRTUAL_RANGE, 540 // Instruction::INVOKE_SUPER_RANGE, 541 // Instruction::INVOKE_DIRECT_RANGE, 542 // Instruction::INVOKE_STATIC_RANGE, 543 // Instruction::INVOKE_INTERFACE_RANGE, 544 // Instruction::UNUSED_79, 545 // Instruction::UNUSED_7A, 546 // Instruction::NEG_INT, 547 // Instruction::NOT_INT, 548 // Instruction::NEG_LONG, 549 // Instruction::NOT_LONG, 550 // Instruction::NEG_FLOAT, 551 // Instruction::NEG_DOUBLE, 552 // Instruction::INT_TO_LONG, 553 // Instruction::INT_TO_FLOAT, 554 // Instruction::INT_TO_DOUBLE, 555 // Instruction::LONG_TO_INT, 556 // Instruction::LONG_TO_FLOAT, 557 // Instruction::LONG_TO_DOUBLE, 558 // Instruction::FLOAT_TO_INT, 559 // Instruction::FLOAT_TO_LONG, 560 // Instruction::FLOAT_TO_DOUBLE, 561 // Instruction::DOUBLE_TO_INT, 562 // Instruction::DOUBLE_TO_LONG, 563 // Instruction::DOUBLE_TO_FLOAT, 564 // Instruction::INT_TO_BYTE, 565 // Instruction::INT_TO_CHAR, 566 // Instruction::INT_TO_SHORT, 567 // Instruction::ADD_INT, 568 // Instruction::SUB_INT, 569 // Instruction::MUL_INT, 570 // Instruction::DIV_INT, 571 // Instruction::REM_INT, 572 // Instruction::AND_INT, 573 // Instruction::OR_INT, 574 // Instruction::XOR_INT, 575 // Instruction::SHL_INT, 576 // Instruction::SHR_INT, 577 // Instruction::USHR_INT, 578 // Instruction::ADD_LONG, 579 // Instruction::SUB_LONG, 580 // Instruction::MUL_LONG, 581 // Instruction::DIV_LONG, 582 // Instruction::REM_LONG, 583 // Instruction::AND_LONG, 584 // Instruction::OR_LONG, 585 // Instruction::XOR_LONG, 586 // Instruction::SHL_LONG, 587 // Instruction::SHR_LONG, 588 // Instruction::USHR_LONG, 589 // Instruction::ADD_FLOAT, 590 // Instruction::SUB_FLOAT, 591 // Instruction::MUL_FLOAT, 592 // Instruction::DIV_FLOAT, 593 // Instruction::REM_FLOAT, 594 // Instruction::ADD_DOUBLE, 595 // Instruction::SUB_DOUBLE, 596 // Instruction::MUL_DOUBLE, 597 // Instruction::DIV_DOUBLE, 598 // Instruction::REM_DOUBLE, 599 // Instruction::ADD_INT_2ADDR, 600 // Instruction::SUB_INT_2ADDR, 601 // Instruction::MUL_INT_2ADDR, 602 // Instruction::DIV_INT_2ADDR, 603 // Instruction::REM_INT_2ADDR, 604 // Instruction::AND_INT_2ADDR, 605 // Instruction::OR_INT_2ADDR, 606 // Instruction::XOR_INT_2ADDR, 607 // Instruction::SHL_INT_2ADDR, 608 // Instruction::SHR_INT_2ADDR, 609 // Instruction::USHR_INT_2ADDR, 610 // Instruction::ADD_LONG_2ADDR, 611 // Instruction::SUB_LONG_2ADDR, 612 // Instruction::MUL_LONG_2ADDR, 613 // Instruction::DIV_LONG_2ADDR, 614 // Instruction::REM_LONG_2ADDR, 615 // Instruction::AND_LONG_2ADDR, 616 // Instruction::OR_LONG_2ADDR, 617 // Instruction::XOR_LONG_2ADDR, 618 // Instruction::SHL_LONG_2ADDR, 619 // Instruction::SHR_LONG_2ADDR, 620 // Instruction::USHR_LONG_2ADDR, 621 // Instruction::ADD_FLOAT_2ADDR, 622 // Instruction::SUB_FLOAT_2ADDR, 623 // Instruction::MUL_FLOAT_2ADDR, 624 // Instruction::DIV_FLOAT_2ADDR, 625 // Instruction::REM_FLOAT_2ADDR, 626 // Instruction::ADD_DOUBLE_2ADDR, 627 // Instruction::SUB_DOUBLE_2ADDR, 628 // Instruction::MUL_DOUBLE_2ADDR, 629 // Instruction::DIV_DOUBLE_2ADDR, 630 // Instruction::REM_DOUBLE_2ADDR, 631 // Instruction::ADD_INT_LIT16, 632 // Instruction::RSUB_INT, 633 // Instruction::MUL_INT_LIT16, 634 // Instruction::DIV_INT_LIT16, 635 // Instruction::REM_INT_LIT16, 636 // Instruction::AND_INT_LIT16, 637 // Instruction::OR_INT_LIT16, 638 // Instruction::XOR_INT_LIT16, 639 // Instruction::ADD_INT_LIT8, 640 // Instruction::RSUB_INT_LIT8, 641 // Instruction::MUL_INT_LIT8, 642 // Instruction::DIV_INT_LIT8, 643 // Instruction::REM_INT_LIT8, 644 // Instruction::AND_INT_LIT8, 645 // Instruction::OR_INT_LIT8, 646 // Instruction::XOR_INT_LIT8, 647 // Instruction::SHL_INT_LIT8, 648 // Instruction::SHR_INT_LIT8, 649 // Instruction::USHR_INT_LIT8, 650 // Instruction::IGET_QUICK, 651 // Instruction::IGET_WIDE_QUICK, 652 // Instruction::IGET_OBJECT_QUICK, 653 // Instruction::IPUT_QUICK, 654 // Instruction::IPUT_WIDE_QUICK, 655 // Instruction::IPUT_OBJECT_QUICK, 656 // Instruction::INVOKE_VIRTUAL_QUICK, 657 // Instruction::INVOKE_VIRTUAL_RANGE_QUICK, 658 // Instruction::UNUSED_EB, 659 // Instruction::UNUSED_EC, 660 // Instruction::UNUSED_ED, 661 // Instruction::UNUSED_EE, 662 // Instruction::UNUSED_EF, 663 // Instruction::UNUSED_F0, 664 // Instruction::UNUSED_F1, 665 // Instruction::UNUSED_F2, 666 // Instruction::UNUSED_F3, 667 // Instruction::UNUSED_F4, 668 // Instruction::UNUSED_F5, 669 // Instruction::UNUSED_F6, 670 // Instruction::UNUSED_F7, 671 // Instruction::UNUSED_F8, 672 // Instruction::UNUSED_F9, 673 // Instruction::UNUSED_FA, 674 // Instruction::UNUSED_FB, 675 // Instruction::UNUSED_FC, 676 // Instruction::UNUSED_FD, 677 // Instruction::UNUSED_FE, 678 // Instruction::UNUSED_FF, 679 680 // ----- ExtendedMIROpcode ----- 681 // kMirOpPhi, 682 // kMirOpCopy, 683 // kMirOpFusedCmplFloat, 684 // kMirOpFusedCmpgFloat, 685 // kMirOpFusedCmplDouble, 686 // kMirOpFusedCmpgDouble, 687 // kMirOpFusedCmpLong, 688 // kMirOpNop, 689 // kMirOpNullCheck, 690 // kMirOpRangeCheck, 691 // kMirOpDivZeroCheck, 692 // kMirOpCheck, 693 // kMirOpCheckPart2, 694 // kMirOpSelect, 695 // kMirOpLast, 696}; 697 698// Z : boolean 699// B : byte 700// S : short 701// C : char 702// I : int 703// J : long 704// F : float 705// D : double 706// L : reference(object, array) 707// V : void 708// (ARM64) Current calling conversion only support 32bit softfp 709// which has problems with long, float, double 710constexpr char arm64_supported_types[] = "ZBSCILVJFD"; 711// (x84_64) We still have troubles with compiling longs/doubles/floats 712constexpr char x86_64_supported_types[] = "ZBSCILVJFD"; 713 714// TODO: Remove this when we are able to compile everything. 715static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) { 716 uint32_t shorty_size = strlen(shorty); 717 CHECK_GE(shorty_size, 1u); 718 // Set a limitation on maximum number of parameters. 719 // Note : there is an implied "method*" parameter, and probably "this" as well. 720 // 1 is for the return type. Currently, we only accept 2 parameters at the most. 721 // (x86_64): For now we have the same limitation. But we might want to split this 722 // check in future into two separate cases for arm64 and x86_64. 723 if ((shorty_size > (1 + 2)) && (instruction_set != kX86_64)) { 724 return false; 725 } 726 727 const char* supported_types = arm64_supported_types; 728 if (instruction_set == kX86_64) { 729 supported_types = x86_64_supported_types; 730 } 731 for (uint32_t i = 0; i < shorty_size; i++) { 732 if (strchr(supported_types, shorty[i]) == nullptr) { 733 return false; 734 } 735 } 736 return true; 737}; 738 739// TODO: Remove this when we are able to compile everything. 740// Skip the method that we do not support currently. 741static bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, 742 CompilationUnit& cu) { 743 // There is some limitation with current ARM 64 backend. 744 if (cu.instruction_set == kArm64 || cu.instruction_set == kX86_64) { 745 // Check if we can compile the prototype. 746 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 747 if (!CanCompileShorty(shorty, cu.instruction_set)) { 748 VLOG(compiler) << "Unsupported shorty : " << shorty; 749 return false; 750 } 751 752 const int *support_list = arm64_support_list; 753 int support_list_size = arraysize(arm64_support_list); 754 if (cu.instruction_set == kX86_64) { 755 support_list = x86_64_support_list; 756 support_list_size = arraysize(x86_64_support_list); 757 } 758 759 for (unsigned int idx = 0; idx < cu.mir_graph->GetNumBlocks(); idx++) { 760 BasicBlock* bb = cu.mir_graph->GetBasicBlock(idx); 761 if (bb == NULL) continue; 762 if (bb->block_type == kDead) continue; 763 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) { 764 int opcode = mir->dalvikInsn.opcode; 765 // Check if we support the byte code. 766 if (std::find(support_list, support_list + support_list_size, 767 opcode) == support_list + support_list_size) { 768 if (!cu.mir_graph->IsPseudoMirOp(opcode)) { 769 VLOG(compiler) << "Unsupported dalvik byte code : " 770 << mir->dalvikInsn.opcode; 771 } else { 772 VLOG(compiler) << "Unsupported extended MIR opcode : " 773 << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst]; 774 } 775 return false; 776 } 777 // Check if it invokes a prototype that we cannot support. 778 if (Instruction::INVOKE_VIRTUAL == opcode || 779 Instruction::INVOKE_SUPER == opcode || 780 Instruction::INVOKE_DIRECT == opcode || 781 Instruction::INVOKE_STATIC == opcode || 782 Instruction::INVOKE_INTERFACE == opcode) { 783 uint32_t invoke_method_idx = mir->dalvikInsn.vB; 784 const char* invoke_method_shorty = dex_file.GetMethodShorty( 785 dex_file.GetMethodId(invoke_method_idx)); 786 if (!CanCompileShorty(invoke_method_shorty, cu.instruction_set)) { 787 VLOG(compiler) << "Unsupported to invoke '" 788 << PrettyMethod(invoke_method_idx, dex_file) 789 << "' with shorty : " << invoke_method_shorty; 790 return false; 791 } 792 } 793 } 794 } 795 796 LOG(INFO) << "Using experimental instruction set A64 for " 797 << PrettyMethod(method_idx, dex_file); 798 } 799 return true; 800} 801 802static CompiledMethod* CompileMethod(CompilerDriver& driver, 803 Compiler* compiler, 804 const DexFile::CodeItem* code_item, 805 uint32_t access_flags, InvokeType invoke_type, 806 uint16_t class_def_idx, uint32_t method_idx, 807 jobject class_loader, const DexFile& dex_file, 808 void* llvm_compilation_unit) { 809 VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "..."; 810 if (code_item->insns_size_in_code_units_ >= 0x10000) { 811 LOG(INFO) << "Method size exceeds compiler limits: " << code_item->insns_size_in_code_units_ 812 << " in " << PrettyMethod(method_idx, dex_file); 813 return NULL; 814 } 815 816 if (!driver.GetCompilerOptions().IsCompilationEnabled()) { 817 return nullptr; 818 } 819 820 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 821 CompilationUnit cu(driver.GetArenaPool()); 822 823 cu.compiler_driver = &driver; 824 cu.class_linker = class_linker; 825 cu.instruction_set = driver.GetInstructionSet(); 826 if (cu.instruction_set == kArm) { 827 cu.instruction_set = kThumb2; 828 } 829 cu.target64 = Is64BitInstructionSet(cu.instruction_set); 830 cu.compiler = compiler; 831 // TODO: x86_64 & arm64 are not yet implemented. 832 CHECK((cu.instruction_set == kThumb2) || 833 (cu.instruction_set == kArm64) || 834 (cu.instruction_set == kX86) || 835 (cu.instruction_set == kX86_64) || 836 (cu.instruction_set == kMips)); 837 838 /* Adjust this value accordingly once inlining is performed */ 839 cu.num_dalvik_registers = code_item->registers_size_; 840 // TODO: set this from command line 841 cu.compiler_flip_match = false; 842 bool use_match = !cu.compiler_method_match.empty(); 843 bool match = use_match && (cu.compiler_flip_match ^ 844 (PrettyMethod(method_idx, dex_file).find(cu.compiler_method_match) != 845 std::string::npos)); 846 if (!use_match || match) { 847 cu.disable_opt = kCompilerOptimizerDisableFlags; 848 cu.enable_debug = kCompilerDebugFlags; 849 cu.verbose = VLOG_IS_ON(compiler) || 850 (cu.enable_debug & (1 << kDebugVerbose)); 851 } 852 853 if (gVerboseMethods.size() != 0) { 854 cu.verbose = false; 855 for (size_t i = 0; i < gVerboseMethods.size(); ++i) { 856 if (PrettyMethod(method_idx, dex_file).find(gVerboseMethods[i]) 857 != std::string::npos) { 858 cu.verbose = true; 859 break; 860 } 861 } 862 } 863 864 if (cu.verbose) { 865 cu.enable_debug |= (1 << kDebugCodegenDump); 866 } 867 868 /* 869 * TODO: rework handling of optimization and debug flags. Should we split out 870 * MIR and backend flags? Need command-line setting as well. 871 */ 872 873 compiler->InitCompilationUnit(cu); 874 875 if (cu.instruction_set == kMips) { 876 // Disable some optimizations for mips for now 877 cu.disable_opt |= ( 878 (1 << kLoadStoreElimination) | 879 (1 << kLoadHoisting) | 880 (1 << kSuppressLoads) | 881 (1 << kNullCheckElimination) | 882 (1 << kPromoteRegs) | 883 (1 << kTrackLiveTemps) | 884 (1 << kSafeOptimizations) | 885 (1 << kBBOpt) | 886 (1 << kMatch) | 887 (1 << kPromoteCompilerTemps)); 888 } 889 890 if (cu.instruction_set == kArm64 || cu.instruction_set == kX86_64) { 891 // TODO(Arm64): enable optimizations once backend is mature enough. 892 // TODO(X86_64): enable optimizations once backend is mature enough. 893 cu.disable_opt = ~(uint32_t)0; 894 if (cu.instruction_set == kArm64) { 895 cu.enable_debug |= (1 << kDebugCodegenDump); 896 } 897 } 898 899 cu.StartTimingSplit("BuildMIRGraph"); 900 cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena)); 901 902 /* 903 * After creation of the MIR graph, also create the code generator. 904 * The reason we do this is that optimizations on the MIR graph may need to get information 905 * that is only available if a CG exists. 906 */ 907 cu.cg.reset(compiler->GetCodeGenerator(&cu, llvm_compilation_unit)); 908 909 /* Gathering opcode stats? */ 910 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) { 911 cu.mir_graph->EnableOpcodeCounting(); 912 } 913 914 // Check early if we should skip this compilation if the profiler is enabled. 915 if (cu.compiler_driver->ProfilePresent()) { 916 std::string methodname = PrettyMethod(method_idx, dex_file); 917 if (cu.mir_graph->SkipCompilation(methodname)) { 918 return NULL; 919 } 920 } 921 922 /* Build the raw MIR graph */ 923 cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx, 924 class_loader, dex_file); 925 926 // TODO(Arm64): Remove this when we are able to compile everything. 927 if (!CanCompileMethod(method_idx, dex_file, cu)) { 928 VLOG(compiler) << "Cannot compile method : " << PrettyMethod(method_idx, dex_file); 929 return nullptr; 930 } 931 932 cu.NewTimingSplit("MIROpt:CheckFilters"); 933 if (cu.mir_graph->SkipCompilation()) { 934 return NULL; 935 } 936 937 /* Create the pass driver and launch it */ 938 PassDriverMEOpts pass_driver(&cu); 939 pass_driver.Launch(); 940 941 if (cu.enable_debug & (1 << kDebugDumpCheckStats)) { 942 cu.mir_graph->DumpCheckStats(); 943 } 944 945 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) { 946 cu.mir_graph->ShowOpcodeStats(); 947 } 948 949 /* Reassociate sreg names with original Dalvik vreg names. */ 950 cu.mir_graph->RemapRegLocations(); 951 952 /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */ 953 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) { 954 if (cu.arena_stack.PeakBytesAllocated() > 256 * 1024) { 955 MemStats stack_stats(cu.arena_stack.GetPeakStats()); 956 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats); 957 } 958 } 959 cu.arena_stack.Reset(); 960 961 CompiledMethod* result = NULL; 962 963 cu.cg->Materialize(); 964 965 cu.NewTimingSplit("Dedupe"); /* deduping takes up the vast majority of time in GetCompiledMethod(). */ 966 result = cu.cg->GetCompiledMethod(); 967 cu.NewTimingSplit("Cleanup"); 968 969 if (result) { 970 VLOG(compiler) << "Compiled " << PrettyMethod(method_idx, dex_file); 971 } else { 972 VLOG(compiler) << "Deferred " << PrettyMethod(method_idx, dex_file); 973 } 974 975 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) { 976 if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) { 977 MemStats mem_stats(cu.arena.GetMemStats()); 978 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats); 979 } 980 } 981 982 if (cu.enable_debug & (1 << kDebugShowSummaryMemoryUsage)) { 983 LOG(INFO) << "MEMINFO " << cu.arena.BytesAllocated() << " " << cu.mir_graph->GetNumBlocks() 984 << " " << PrettyMethod(method_idx, dex_file); 985 } 986 987 cu.EndTiming(); 988 driver.GetTimingsLogger()->AddLogger(cu.timings); 989 return result; 990} 991 992CompiledMethod* CompileOneMethod(CompilerDriver& driver, 993 Compiler* compiler, 994 const DexFile::CodeItem* code_item, 995 uint32_t access_flags, 996 InvokeType invoke_type, 997 uint16_t class_def_idx, 998 uint32_t method_idx, 999 jobject class_loader, 1000 const DexFile& dex_file, 1001 void* compilation_unit) { 1002 return CompileMethod(driver, compiler, code_item, access_flags, invoke_type, class_def_idx, 1003 method_idx, class_loader, dex_file, compilation_unit); 1004} 1005 1006} // namespace art 1007 1008extern "C" art::CompiledMethod* 1009 ArtQuickCompileMethod(art::CompilerDriver& driver, 1010 const art::DexFile::CodeItem* code_item, 1011 uint32_t access_flags, art::InvokeType invoke_type, 1012 uint16_t class_def_idx, uint32_t method_idx, jobject class_loader, 1013 const art::DexFile& dex_file) { 1014 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use build default 1015 art::Compiler* compiler = driver.GetCompiler(); 1016 return art::CompileOneMethod(driver, compiler, code_item, access_flags, invoke_type, 1017 class_def_idx, method_idx, class_loader, dex_file, 1018 NULL /* use thread llvm_info */); 1019} 1020