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