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