diff options
author | Bill Buzbee <buzbee@android.com> | 2014-05-15 22:07:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-05-15 22:07:34 +0000 |
commit | e1a71b2a6e899645b006c29ba37695f521545a5b (patch) | |
tree | ab68aabb74810e4b1214edc7ea663e0957aa3c43 | |
parent | 922ddb30982d2597eab634d8b8598bec0eb7d3b7 (diff) | |
parent | 5678455bdf9ebf2bd88ab39a9aeb6e08b7c6e245 (diff) | |
download | art-e1a71b2a6e899645b006c29ba37695f521545a5b.zip art-e1a71b2a6e899645b006c29ba37695f521545a5b.tar.gz art-e1a71b2a6e899645b006c29ba37695f521545a5b.tar.bz2 |
Merge "ART: A Compile Filter for x86_64"
-rw-r--r-- | compiler/dex/frontend.cc | 332 |
1 files changed, 313 insertions, 19 deletions
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc index a224de2..144594e 100644 --- a/compiler/dex/frontend.cc +++ b/compiler/dex/frontend.cc @@ -410,28 +410,315 @@ int arm64_support_list[] = { }; // TODO: Remove this when we are able to compile everything. -static bool CanCompileShorty(const char* shorty) { +int x86_64_support_list[] = { + Instruction::NOP, + // Instruction::MOVE, + // Instruction::MOVE_FROM16, + // Instruction::MOVE_16, + // Instruction::MOVE_WIDE, + // Instruction::MOVE_WIDE_FROM16, + // Instruction::MOVE_WIDE_16, + // Instruction::MOVE_OBJECT, + // Instruction::MOVE_OBJECT_FROM16, + // Instruction::MOVE_OBJECT_16, + // Instruction::MOVE_RESULT, + // Instruction::MOVE_RESULT_WIDE, + // Instruction::MOVE_RESULT_OBJECT, + // Instruction::MOVE_EXCEPTION, + Instruction::RETURN_VOID, + Instruction::RETURN, + // Instruction::RETURN_WIDE, + Instruction::RETURN_OBJECT, + // Instruction::CONST_4, + // Instruction::CONST_16, + // Instruction::CONST, + // Instruction::CONST_HIGH16, + // Instruction::CONST_WIDE_16, + // Instruction::CONST_WIDE_32, + // Instruction::CONST_WIDE, + // Instruction::CONST_WIDE_HIGH16, + // Instruction::CONST_STRING, + // Instruction::CONST_STRING_JUMBO, + // Instruction::CONST_CLASS, + // Instruction::MONITOR_ENTER, + // Instruction::MONITOR_EXIT, + // Instruction::CHECK_CAST, + // Instruction::INSTANCE_OF, + // Instruction::ARRAY_LENGTH, + // Instruction::NEW_INSTANCE, + // Instruction::NEW_ARRAY, + // Instruction::FILLED_NEW_ARRAY, + // Instruction::FILLED_NEW_ARRAY_RANGE, + // Instruction::FILL_ARRAY_DATA, + // Instruction::THROW, + // Instruction::GOTO, + // Instruction::GOTO_16, + // Instruction::GOTO_32, + // Instruction::PACKED_SWITCH, + // Instruction::SPARSE_SWITCH, + // Instruction::CMPL_FLOAT, + // Instruction::CMPG_FLOAT, + // Instruction::CMPL_DOUBLE, + // Instruction::CMPG_DOUBLE, + // Instruction::CMP_LONG, + // Instruction::IF_EQ, + // Instruction::IF_NE, + // Instruction::IF_LT, + // Instruction::IF_GE, + // Instruction::IF_GT, + // Instruction::IF_LE, + // Instruction::IF_EQZ, + // Instruction::IF_NEZ, + // Instruction::IF_LTZ, + // Instruction::IF_GEZ, + // Instruction::IF_GTZ, + // Instruction::IF_LEZ, + // Instruction::UNUSED_3E, + // Instruction::UNUSED_3F, + // Instruction::UNUSED_40, + // Instruction::UNUSED_41, + // Instruction::UNUSED_42, + // Instruction::UNUSED_43, + // Instruction::AGET, + // Instruction::AGET_WIDE, + // Instruction::AGET_OBJECT, + // Instruction::AGET_BOOLEAN, + // Instruction::AGET_BYTE, + // Instruction::AGET_CHAR, + // Instruction::AGET_SHORT, + // Instruction::APUT, + // Instruction::APUT_WIDE, + // Instruction::APUT_OBJECT, + // Instruction::APUT_BOOLEAN, + // Instruction::APUT_BYTE, + // Instruction::APUT_CHAR, + // Instruction::APUT_SHORT, + // Instruction::IGET, + // Instruction::IGET_WIDE, + // Instruction::IGET_OBJECT, + // Instruction::IGET_BOOLEAN, + // Instruction::IGET_BYTE, + // Instruction::IGET_CHAR, + // Instruction::IGET_SHORT, + // Instruction::IPUT, + // Instruction::IPUT_WIDE, + // Instruction::IPUT_OBJECT, + // Instruction::IPUT_BOOLEAN, + // Instruction::IPUT_BYTE, + // Instruction::IPUT_CHAR, + // Instruction::IPUT_SHORT, + Instruction::SGET, + // Instruction::SGET_WIDE, + Instruction::SGET_OBJECT, + Instruction::SGET_BOOLEAN, + Instruction::SGET_BYTE, + Instruction::SGET_CHAR, + Instruction::SGET_SHORT, + Instruction::SPUT, + // Instruction::SPUT_WIDE, + Instruction::SPUT_OBJECT, + Instruction::SPUT_BOOLEAN, + Instruction::SPUT_BYTE, + Instruction::SPUT_CHAR, + Instruction::SPUT_SHORT, + Instruction::INVOKE_VIRTUAL, + Instruction::INVOKE_SUPER, + Instruction::INVOKE_DIRECT, + Instruction::INVOKE_STATIC, + Instruction::INVOKE_INTERFACE, + // Instruction::RETURN_VOID_BARRIER, + // Instruction::INVOKE_VIRTUAL_RANGE, + // Instruction::INVOKE_SUPER_RANGE, + // Instruction::INVOKE_DIRECT_RANGE, + // Instruction::INVOKE_STATIC_RANGE, + // Instruction::INVOKE_INTERFACE_RANGE, + // Instruction::UNUSED_79, + // Instruction::UNUSED_7A, + // Instruction::NEG_INT, + // Instruction::NOT_INT, + // Instruction::NEG_LONG, + // Instruction::NOT_LONG, + // Instruction::NEG_FLOAT, + // Instruction::NEG_DOUBLE, + // Instruction::INT_TO_LONG, + // Instruction::INT_TO_FLOAT, + // Instruction::INT_TO_DOUBLE, + // Instruction::LONG_TO_INT, + // Instruction::LONG_TO_FLOAT, + // Instruction::LONG_TO_DOUBLE, + // Instruction::FLOAT_TO_INT, + // Instruction::FLOAT_TO_LONG, + // Instruction::FLOAT_TO_DOUBLE, + // Instruction::DOUBLE_TO_INT, + // Instruction::DOUBLE_TO_LONG, + // Instruction::DOUBLE_TO_FLOAT, + // Instruction::INT_TO_BYTE, + // Instruction::INT_TO_CHAR, + // Instruction::INT_TO_SHORT, + // Instruction::ADD_INT, + // Instruction::SUB_INT, + // Instruction::MUL_INT, + // Instruction::DIV_INT, + // Instruction::REM_INT, + // Instruction::AND_INT, + // Instruction::OR_INT, + // Instruction::XOR_INT, + // Instruction::SHL_INT, + // Instruction::SHR_INT, + // Instruction::USHR_INT, + // Instruction::ADD_LONG, + // Instruction::SUB_LONG, + // Instruction::MUL_LONG, + // Instruction::DIV_LONG, + // Instruction::REM_LONG, + // Instruction::AND_LONG, + // Instruction::OR_LONG, + // Instruction::XOR_LONG, + // Instruction::SHL_LONG, + // Instruction::SHR_LONG, + // Instruction::USHR_LONG, + // Instruction::ADD_FLOAT, + // Instruction::SUB_FLOAT, + // Instruction::MUL_FLOAT, + // Instruction::DIV_FLOAT, + // Instruction::REM_FLOAT, + // Instruction::ADD_DOUBLE, + // Instruction::SUB_DOUBLE, + // Instruction::MUL_DOUBLE, + // Instruction::DIV_DOUBLE, + // Instruction::REM_DOUBLE, + // Instruction::ADD_INT_2ADDR, + // Instruction::SUB_INT_2ADDR, + // Instruction::MUL_INT_2ADDR, + // Instruction::DIV_INT_2ADDR, + // Instruction::REM_INT_2ADDR, + // Instruction::AND_INT_2ADDR, + // Instruction::OR_INT_2ADDR, + // Instruction::XOR_INT_2ADDR, + // Instruction::SHL_INT_2ADDR, + // Instruction::SHR_INT_2ADDR, + // Instruction::USHR_INT_2ADDR, + // Instruction::ADD_LONG_2ADDR, + // Instruction::SUB_LONG_2ADDR, + // Instruction::MUL_LONG_2ADDR, + // Instruction::DIV_LONG_2ADDR, + // Instruction::REM_LONG_2ADDR, + // Instruction::AND_LONG_2ADDR, + // Instruction::OR_LONG_2ADDR, + // Instruction::XOR_LONG_2ADDR, + // Instruction::SHL_LONG_2ADDR, + // Instruction::SHR_LONG_2ADDR, + // Instruction::USHR_LONG_2ADDR, + // Instruction::ADD_FLOAT_2ADDR, + // Instruction::SUB_FLOAT_2ADDR, + // Instruction::MUL_FLOAT_2ADDR, + // Instruction::DIV_FLOAT_2ADDR, + // Instruction::REM_FLOAT_2ADDR, + // Instruction::ADD_DOUBLE_2ADDR, + // Instruction::SUB_DOUBLE_2ADDR, + // Instruction::MUL_DOUBLE_2ADDR, + // Instruction::DIV_DOUBLE_2ADDR, + // Instruction::REM_DOUBLE_2ADDR, + // Instruction::ADD_INT_LIT16, + // Instruction::RSUB_INT, + // Instruction::MUL_INT_LIT16, + // Instruction::DIV_INT_LIT16, + // Instruction::REM_INT_LIT16, + // Instruction::AND_INT_LIT16, + // Instruction::OR_INT_LIT16, + // Instruction::XOR_INT_LIT16, + // Instruction::ADD_INT_LIT8, + // Instruction::RSUB_INT_LIT8, + // Instruction::MUL_INT_LIT8, + // Instruction::DIV_INT_LIT8, + // Instruction::REM_INT_LIT8, + // Instruction::AND_INT_LIT8, + // Instruction::OR_INT_LIT8, + // Instruction::XOR_INT_LIT8, + // Instruction::SHL_INT_LIT8, + // Instruction::SHR_INT_LIT8, + // Instruction::USHR_INT_LIT8, + // Instruction::IGET_QUICK, + // Instruction::IGET_WIDE_QUICK, + // Instruction::IGET_OBJECT_QUICK, + // Instruction::IPUT_QUICK, + // Instruction::IPUT_WIDE_QUICK, + // Instruction::IPUT_OBJECT_QUICK, + // Instruction::INVOKE_VIRTUAL_QUICK, + // Instruction::INVOKE_VIRTUAL_RANGE_QUICK, + // Instruction::UNUSED_EB, + // Instruction::UNUSED_EC, + // Instruction::UNUSED_ED, + // Instruction::UNUSED_EE, + // Instruction::UNUSED_EF, + // Instruction::UNUSED_F0, + // Instruction::UNUSED_F1, + // Instruction::UNUSED_F2, + // Instruction::UNUSED_F3, + // Instruction::UNUSED_F4, + // Instruction::UNUSED_F5, + // Instruction::UNUSED_F6, + // Instruction::UNUSED_F7, + // Instruction::UNUSED_F8, + // Instruction::UNUSED_F9, + // Instruction::UNUSED_FA, + // Instruction::UNUSED_FB, + // Instruction::UNUSED_FC, + // Instruction::UNUSED_FD, + // Instruction::UNUSED_FE, + // Instruction::UNUSED_FF, + + // ----- ExtendedMIROpcode ----- + // kMirOpPhi, + // kMirOpCopy, + // kMirOpFusedCmplFloat, + // kMirOpFusedCmpgFloat, + // kMirOpFusedCmplDouble, + // kMirOpFusedCmpgDouble, + // kMirOpFusedCmpLong, + // kMirOpNop, + // kMirOpNullCheck, + // kMirOpRangeCheck, + // kMirOpDivZeroCheck, + // kMirOpCheck, + // kMirOpCheckPart2, + // kMirOpSelect, + // kMirOpLast, +}; + +// Z : boolean +// B : byte +// S : short +// C : char +// I : int +// L : long +// F : float +// D : double +// L : reference(object, array) +// V : void +// (ARM64) Current calling conversion only support 32bit softfp +// which has problems with long, float, double +constexpr char arm64_supported_types[] = "ZBSCILV"; +// (x84_64) We still have troubles with compiling longs/doubles/floats +constexpr char x86_64_supported_types[] = "ZBSCILV"; + +// TODO: Remove this when we are able to compile everything. +static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) { uint32_t shorty_size = strlen(shorty); CHECK_GE(shorty_size, 1u); // Set a limitation on maximum number of parameters. // Note : there is an implied "method*" parameter, and probably "this" as well. // 1 is for the return type. Currently, we only accept 2 parameters at the most. + // (x86_64): For now we have the same limitation. But we might want to split this + // check in future into two separate cases for arm64 and x86_64. if (shorty_size > (1 + 2)) { return false; } - // Z : boolean - // B : byte - // S : short - // C : char - // I : int - // L : long - // F : float - // D : double - // L : reference(object, array) - // V : void - // Current calling conversion only support 32bit softfp - // which has problems with long, float, double - constexpr char supported_types[] = "ZBSCILV"; + + const char* supported_types = arm64_supported_types; + if (instruction_set == kX86_64) { + supported_types = x86_64_supported_types; + } for (uint32_t i = 0; i < shorty_size; i++) { if (strchr(supported_types, shorty[i]) == nullptr) { return false; @@ -445,14 +732,21 @@ static bool CanCompileShorty(const char* shorty) { static bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit& cu) { // There is some limitation with current ARM 64 backend. - if (cu.instruction_set == kArm64) { + if (cu.instruction_set == kArm64 || cu.instruction_set == kX86_64) { // Check if we can compile the prototype. const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); - if (!CanCompileShorty(shorty)) { + if (!CanCompileShorty(shorty, cu.instruction_set)) { VLOG(compiler) << "Unsupported shorty : " << shorty; return false; } + const int *support_list = arm64_support_list; + int support_list_size = arraysize(arm64_support_list); + if (cu.instruction_set == kX86_64) { + support_list = x86_64_support_list; + support_list_size = arraysize(x86_64_support_list); + } + for (int idx = 0; idx < cu.mir_graph->GetNumBlocks(); idx++) { BasicBlock *bb = cu.mir_graph->GetBasicBlock(idx); if (bb == NULL) continue; @@ -460,8 +754,8 @@ static bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) { int opcode = mir->dalvikInsn.opcode; // Check if we support the byte code. - if (std::find(arm64_support_list, arm64_support_list + arraysize(arm64_support_list), - opcode) == arm64_support_list + arraysize(arm64_support_list)) { + if (std::find(support_list, support_list + support_list_size, + opcode) == support_list + support_list_size) { if (opcode < kMirOpFirst) { VLOG(compiler) << "Unsupported dalvik byte code : " << mir->dalvikInsn.opcode; @@ -480,7 +774,7 @@ static bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, uint32_t invoke_method_idx = mir->dalvikInsn.vB; const char* invoke_method_shorty = dex_file.GetMethodShorty( dex_file.GetMethodId(invoke_method_idx)); - if (!CanCompileShorty(invoke_method_shorty)) { + if (!CanCompileShorty(invoke_method_shorty, cu.instruction_set)) { VLOG(compiler) << "Unsupported to invoke '" << PrettyMethod(invoke_method_idx, dex_file) << "' with shorty : " << invoke_method_shorty; |