diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/compiler_enums.h | 1 | ||||
-rw-r--r-- | compiler/dex/mir_graph.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 10 | ||||
-rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 18 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/codegen_arm64.h | 12 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/int_arm64.cc | 21 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 14 | ||||
-rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 10 | ||||
-rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 13 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.cc | 14 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 13 | ||||
-rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 23 | ||||
-rwxr-xr-x | compiler/dex/quick/x86/int_x86.cc | 49 | ||||
-rwxr-xr-x | compiler/dex/quick/x86/target_x86.cc | 2 |
14 files changed, 109 insertions, 92 deletions
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h index 78da420339..c6c5ca7d4f 100644 --- a/compiler/dex/compiler_enums.h +++ b/compiler/dex/compiler_enums.h @@ -306,6 +306,7 @@ enum MIROptimizationFlagPositions { kMIRIgnoreRangeCheck, kMIRRangeCheckOnly, kMIRIgnoreClInitCheck, + kMirIgnoreDivZeroCheck, kMIRInlined, // Invoke is inlined (ie dead). kMIRInlinedPred, // Invoke is inlined via prediction. kMIRCallee, // Instruction is inlined from callee. diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index a405af16a3..5c74e9e6bf 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -147,6 +147,7 @@ enum OatMethodAttributes { #define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck) #define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly) #define MIR_IGNORE_CLINIT_CHECK (1 << kMIRIgnoreClInitCheck) +#define MIR_IGNORE_DIV_ZERO_CHECK (1 << kMirIgnoreDivZeroCheck) #define MIR_INLINED (1 << kMIRInlined) #define MIR_INLINED_PRED (1 << kMIRInlinedPred) #define MIR_CALLEE (1 << kMIRCallee) diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index 1c87a0386c..6fd29f25dc 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -87,15 +87,15 @@ class ArmMir2Lir FINAL : public Mir2Lir { // Required for target - Dalvik-level generators. void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) OVERRIDE; + RegLocation rl_src2, int flags) OVERRIDE; void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); + RegLocation rl_src1, RegLocation rl_src2, int flags); void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_dest, int scale); void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark); void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_shift); + RegLocation rl_src1, RegLocation rl_shift, int flags); void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, @@ -224,8 +224,8 @@ class ArmMir2Lir FINAL : public Mir2Lir { void InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir); void AssignDataOffsets(); RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2, - bool is_div, bool check_zero); - RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div); + bool is_div, int flags) OVERRIDE; + RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE; typedef struct { OpKind op; uint32_t shift; diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 018dc1c0c6..9742243632 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -678,7 +678,7 @@ bool ArmMir2Lir::EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) } RegLocation ArmMir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div, bool check_zero) { + RegLocation rl_src2, bool is_div, int flags) { LOG(FATAL) << "Unexpected use of GenDivRem for Arm"; return rl_dest; } @@ -1264,7 +1264,7 @@ void ArmMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest, } void ArmMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) { + RegLocation rl_src2, int flags) { switch (opcode) { case Instruction::MUL_LONG: case Instruction::MUL_LONG_2ADDR: @@ -1279,7 +1279,7 @@ void ArmMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R } // Fallback for all other ops. - Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); } /* @@ -1464,7 +1464,8 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, - RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift) { + RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift, + int flags) { rl_src = LoadValueWide(rl_src, kCoreReg); // Per spec, we only care about low 6 bits of shift amount. int shift_amount = mir_graph_->ConstantValue(rl_shift) & 0x3f; @@ -1537,11 +1538,12 @@ void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, } void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode, - RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2, + int flags) { if ((opcode == Instruction::SUB_LONG_2ADDR) || (opcode == Instruction::SUB_LONG)) { if (!rl_src2.is_const) { // Don't bother with special handling for subtract from immediate. - GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); return; } } else { @@ -1552,7 +1554,7 @@ void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode, } } if (PartiallyIntersects(rl_src1, rl_dest)) { - GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); return; } DCHECK(rl_src2.is_const); @@ -1569,7 +1571,7 @@ void ArmMir2Lir::GenArithImmOpLong(Instruction::Code opcode, case Instruction::SUB_LONG: case Instruction::SUB_LONG_2ADDR: if ((mod_imm_lo < 0) || (mod_imm_hi < 0)) { - GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); return; } break; diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h index 510bd4c5de..9f0260635d 100644 --- a/compiler/dex/quick/arm64/codegen_arm64.h +++ b/compiler/dex/quick/arm64/codegen_arm64.h @@ -141,13 +141,13 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { void GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation lr_shift) OVERRIDE; void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) OVERRIDE; + RegLocation rl_src2, int flags) OVERRIDE; void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_dest, int scale) OVERRIDE; void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark) OVERRIDE; void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_shift) OVERRIDE; + RegLocation rl_shift, int flags) OVERRIDE; void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) OVERRIDE; void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, @@ -173,7 +173,7 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { bool GenInlinedArrayCopyCharArray(CallInfo* info) OVERRIDE; void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE; void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) OVERRIDE; + RegLocation rl_src2, int flags) OVERRIDE; RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div) OVERRIDE; RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div) @@ -363,8 +363,8 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { void InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir); void AssignDataOffsets(); RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2, - bool is_div, bool check_zero); - RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div); + bool is_div, int flags) OVERRIDE; + RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE; size_t GetLoadStoreSize(LIR* lir); bool SmallLiteralDivRem64(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, @@ -413,7 +413,7 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { void GenNotLong(RegLocation rl_dest, RegLocation rl_src); void GenNegLong(RegLocation rl_dest, RegLocation rl_src); void GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div); + RegLocation rl_src2, bool is_div, int flags); InToRegStorageMapping in_to_reg_storage_mapping_; static const A64EncodingMap EncodingMap[kA64Last]; diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc index abcb30f49a..6e7241dcd6 100644 --- a/compiler/dex/quick/arm64/int_arm64.cc +++ b/compiler/dex/quick/arm64/int_arm64.cc @@ -614,7 +614,7 @@ RegLocation Arm64Mir2Lir::GenDivRemLit(RegLocation rl_dest, RegStorage reg1, int } RegLocation Arm64Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div, bool check_zero) { + RegLocation rl_src2, bool is_div, int flags) { LOG(FATAL) << "Unexpected use of GenDivRem for Arm64"; return rl_dest; } @@ -1020,7 +1020,7 @@ void Arm64Mir2Lir::GenIntToLong(RegLocation rl_dest, RegLocation rl_src) { } void Arm64Mir2Lir::GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2, bool is_div) { + RegLocation rl_src1, RegLocation rl_src2, bool is_div, int flags) { if (rl_src2.is_const) { DCHECK(rl_src2.wide); int64_t lit = mir_graph_->ConstantValueWide(rl_src2); @@ -1032,7 +1032,9 @@ void Arm64Mir2Lir::GenDivRemLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_result; rl_src1 = LoadValueWide(rl_src1, kCoreReg); rl_src2 = LoadValueWide(rl_src2, kCoreReg); - GenDivZeroCheck(rl_src2.reg); + if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { + GenDivZeroCheck(rl_src2.reg); + } rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, is_div); StoreValueWide(rl_dest, rl_result); } @@ -1067,7 +1069,7 @@ void Arm64Mir2Lir::GenNotLong(RegLocation rl_dest, RegLocation rl_src) { } void Arm64Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_src1, RegLocation rl_src2, int flags) { switch (opcode) { case Instruction::NOT_LONG: GenNotLong(rl_dest, rl_src2); @@ -1086,11 +1088,11 @@ void Arm64Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, return; case Instruction::DIV_LONG: case Instruction::DIV_LONG_2ADDR: - GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true); + GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true, flags); return; case Instruction::REM_LONG: case Instruction::REM_LONG_2ADDR: - GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false); + GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false, flags); return; case Instruction::AND_LONG_2ADDR: case Instruction::AND_LONG: @@ -1312,7 +1314,8 @@ void Arm64Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, } void Arm64Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, - RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift) { + RegLocation rl_dest, RegLocation rl_src, RegLocation rl_shift, + int flags) { OpKind op = kOpBkpt; // Per spec, we only care about low 6 bits of shift amount. int shift_amount = mir_graph_->ConstantValue(rl_shift) & 0x3f; @@ -1344,7 +1347,7 @@ void Arm64Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, } void Arm64Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_src1, RegLocation rl_src2, int flags) { OpKind op = kOpBkpt; switch (opcode) { case Instruction::ADD_LONG: @@ -1373,7 +1376,7 @@ void Arm64Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_de if (op == kOpSub) { if (!rl_src2.is_const) { - return GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + return GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); } } else { // Associativity. diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index a33d15fb32..2abfcc3639 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -1501,7 +1501,7 @@ void Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest, void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_src1, RegLocation rl_src2, int flags) { DCHECK(cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64); OpKind op = kOpBkpt; bool is_div_rem = false; @@ -1600,7 +1600,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, if (cu_->instruction_set == kMips || cu_->instruction_set == kArm64) { rl_src1 = LoadValue(rl_src1, kCoreReg); rl_src2 = LoadValue(rl_src2, kCoreReg); - if (check_zero) { + if (check_zero && (flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { GenDivZeroCheck(rl_src2.reg); } rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv); @@ -1612,7 +1612,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, // calculate using a MUL and subtract. rl_src1 = LoadValue(rl_src1, kCoreReg); rl_src2 = LoadValue(rl_src2, kCoreReg); - if (check_zero) { + if (check_zero && (flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { GenDivZeroCheck(rl_src2.reg); } rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv); @@ -1626,7 +1626,7 @@ void Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, LoadValueDirectFixed(rl_src2, TargetReg(kArg1, kNotWide)); RegStorage r_tgt = CallHelperSetup(kQuickIdivmod); LoadValueDirectFixed(rl_src1, TargetReg(kArg0, kNotWide)); - if (check_zero) { + if (check_zero && (flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { GenDivZeroCheck(TargetReg(kArg1, kNotWide)); } // NOTE: callout here is not a safepoint. @@ -1914,7 +1914,7 @@ void Mir2Lir::GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, Re } void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_src1, RegLocation rl_src2, int flags) { RegLocation rl_result; OpKind first_op = kOpBkpt; OpKind second_op = kOpBkpt; @@ -1999,7 +1999,9 @@ void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegStorage r_tmp2 = TargetReg(kArg2, kWide); LoadValueDirectWideFixed(rl_src2, r_tmp2); RegStorage r_tgt = CallHelperSetup(target); - GenDivZeroCheckWide(r_tmp2); + if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { + GenDivZeroCheckWide(r_tmp2); + } LoadValueDirectWideFixed(rl_src1, r_tmp1); // NOTE: callout here is not a safepoint CallHelper(r_tgt, target, false /* not safepoint */); diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h index bd709f38ae..508d474404 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -86,13 +86,13 @@ class MipsMir2Lir FINAL : public Mir2Lir { // Required for target - Dalvik-level generators. void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); + RegLocation rl_src1, RegLocation rl_src2, int flags); void GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_dest, int scale); void GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark); void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_shift); + RegLocation rl_shift, int flags); void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); void GenArithOpFloat(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, @@ -108,7 +108,7 @@ class MipsMir2Lir FINAL : public Mir2Lir { bool GenInlinedPeek(CallInfo* info, OpSize size); bool GenInlinedPoke(CallInfo* info, OpSize size); void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) OVERRIDE; + RegLocation rl_src2, int flags) OVERRIDE; RegLocation GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegStorage reg_hi, bool is_div); RegLocation GenDivRemLit(RegLocation rl_dest, RegStorage reg_lo, int lit, bool is_div); void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); @@ -190,8 +190,8 @@ class MipsMir2Lir FINAL : public Mir2Lir { void ConvertShortToLongBranch(LIR* lir); RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div, bool check_zero); - RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div); + RegLocation rl_src2, bool is_div, int flags) OVERRIDE; + RegLocation GenDivRemLit(RegLocation rl_dest, RegLocation rl_src1, int lit, bool is_div) OVERRIDE; }; } // namespace art diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index 30aa611f9f..baf7311398 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -263,7 +263,7 @@ RegLocation MipsMir2Lir::GenDivRemLit(RegLocation rl_dest, RegStorage reg1, int } RegLocation MipsMir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div, bool check_zero) { + RegLocation rl_src2, bool is_div, int flags) { LOG(FATAL) << "Unexpected use of GenDivRem for Mips"; return rl_dest; } @@ -437,7 +437,7 @@ void MipsMir2Lir::GenSubLong(Instruction::Code opcode, RegLocation rl_dest, } void MipsMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) { + RegLocation rl_src2, int flags) { switch (opcode) { case Instruction::ADD_LONG: case Instruction::ADD_LONG_2ADDR: @@ -456,7 +456,7 @@ void MipsMir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, } // Fallback for all other ops. - Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); } void MipsMir2Lir::GenNegLong(RegLocation rl_dest, RegLocation rl_src) { @@ -628,15 +628,16 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, } void MipsMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_shift) { + RegLocation rl_src1, RegLocation rl_shift, int flags) { // Default implementation is just to ignore the constant case. GenShiftOpLong(opcode, rl_dest, rl_src1, rl_shift); } void MipsMir2Lir::GenArithImmOpLong(Instruction::Code opcode, - RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2, + int flags) { // Default - bail to non-const handler. - GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); } } // namespace art diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index 4399981272..408606d366 100644 --- a/compiler/dex/quick/mir_to_lir.cc +++ b/compiler/dex/quick/mir_to_lir.cc @@ -928,12 +928,12 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::NEG_INT: case Instruction::NOT_INT: - GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0]); + GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0], opt_flags); break; case Instruction::NEG_LONG: case Instruction::NOT_LONG: - GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0]); + GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0], opt_flags); break; case Instruction::NEG_FLOAT: @@ -993,7 +993,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list GenArithOpIntLit(opcode, rl_dest, rl_src[0], mir_graph_->ConstantValue(rl_src[1].orig_sreg)); } else { - GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]); + GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags); } break; @@ -1013,7 +1013,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]), opcode)) { GenArithOpIntLit(opcode, rl_dest, rl_src[0], mir_graph_->ConstantValue(rl_src[1])); } else { - GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]); + GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags); } break; @@ -1028,7 +1028,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::OR_LONG_2ADDR: case Instruction::XOR_LONG_2ADDR: if (rl_src[0].is_const || rl_src[1].is_const) { - GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); + GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags); break; } FALLTHROUGH_INTENDED; @@ -1038,7 +1038,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::MUL_LONG_2ADDR: case Instruction::DIV_LONG_2ADDR: case Instruction::REM_LONG_2ADDR: - GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); + GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags); break; case Instruction::SHL_LONG: @@ -1048,7 +1048,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::SHR_LONG_2ADDR: case Instruction::USHR_LONG_2ADDR: if (rl_src[1].is_const) { - GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); + GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1], opt_flags); } else { GenShiftOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); } diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index ea93bbe7f2..3e0844bec1 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -857,7 +857,7 @@ class Mir2Lir : public Backend { void GenArithOpIntLit(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src, int lit); virtual void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); + RegLocation rl_src1, RegLocation rl_src2, int flags); void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src); virtual void GenSuspendTest(int opt_flags); virtual void GenSuspendTestAndBranch(int opt_flags, LIR* target); @@ -865,7 +865,7 @@ class Mir2Lir : public Backend { // This will be overridden by x86 implementation. virtual void GenConstWide(RegLocation rl_dest, int64_t value); virtual void GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2); + RegLocation rl_src1, RegLocation rl_src2, int flags); // Shared by all targets - implemented in gen_invoke.cc. LIR* CallHelper(RegStorage r_tgt, QuickEntrypointEnum trampoline, bool safepoint_pc, @@ -1259,7 +1259,7 @@ class Mir2Lir : public Backend { // Required for target - Dalvik-level generators. virtual void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_src2) = 0; + RegLocation rl_src1, RegLocation rl_src2, int flags) = 0; virtual void GenArithOpDouble(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) = 0; @@ -1297,10 +1297,11 @@ class Mir2Lir : public Backend { * @param rl_src1 Numerator Location. * @param rl_src2 Divisor Location. * @param is_div 'true' if this is a division, 'false' for a remainder. - * @param check_zero 'true' if an exception should be generated if the divisor is 0. + * @param flags The instruction optimization flags. It can include information + * if exception check can be elided. */ virtual RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div, bool check_zero) = 0; + RegLocation rl_src2, bool is_div, int flags) = 0; /* * @brief Generate an integer div or rem operation by a literal. * @param rl_dest Destination Location. @@ -1382,7 +1383,7 @@ class Mir2Lir : public Backend { RegLocation rl_index, RegLocation rl_src, int scale, bool card_mark) = 0; virtual void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_shift) = 0; + RegLocation rl_src1, RegLocation rl_shift, int flags) = 0; // Required for target - single operation generators. virtual LIR* OpUnconditionalBranch(LIR* target) = 0; diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index b3544dafba..7b5b831e38 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -180,11 +180,11 @@ class X86Mir2Lir : public Mir2Lir { // Long instructions. void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) OVERRIDE; + RegLocation rl_src2, int flags) OVERRIDE; void GenArithImmOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) OVERRIDE; + RegLocation rl_src2, int flags) OVERRIDE; void GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src1, RegLocation rl_shift) OVERRIDE; + RegLocation rl_src1, RegLocation rl_shift, int flags) OVERRIDE; void GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) OVERRIDE; void GenIntToLong(RegLocation rl_dest, RegLocation rl_src) OVERRIDE; void GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest, @@ -314,9 +314,10 @@ class X86Mir2Lir : public Mir2Lir { * @param rl_dest Destination for the result. * @param rl_lhs Left hand operand. * @param rl_rhs Right hand operand. + * @param flags The instruction optimization flags. */ void GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_lhs, - RegLocation rl_rhs) OVERRIDE; + RegLocation rl_rhs, int flags) OVERRIDE; /* * @brief Load the Method* of a dex method into the register. @@ -768,10 +769,11 @@ class X86Mir2Lir : public Mir2Lir { * @param rl_src1 Numerator Location. * @param rl_src2 Divisor Location. * @param is_div 'true' if this is a division, 'false' for a remainder. - * @param check_zero 'true' if an exception should be generated if the divisor is 0. + * @param flags The instruction optimization flags. It can include information + * if exception check can be elided. */ RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2, - bool is_div, bool check_zero); + bool is_div, int flags); /* * @brief Generate an integer div or rem operation by a literal. @@ -788,10 +790,11 @@ class X86Mir2Lir : public Mir2Lir { * @param rl_dest The destination. * @param rl_src The value to be shifted. * @param shift_amount How much to shift. + * @param flags The instruction optimization flags. * @returns the RegLocation of the result. */ RegLocation GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src, int shift_amount); + RegLocation rl_src, int shift_amount, int flags); /* * Generate an imul of a register by a constant or a better sequence. * @param dest Destination Register. @@ -858,13 +861,13 @@ class X86Mir2Lir : public Mir2Lir { // Try to do a long multiplication where rl_src2 is a constant. This simplified setup might fail, // in which case false will be returned. - bool GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val); + bool GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val, int flags); void GenMulLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2); + RegLocation rl_src2, int flags); void GenNotLong(RegLocation rl_dest, RegLocation rl_src); void GenNegLong(RegLocation rl_dest, RegLocation rl_src); void GenDivRemLong(Instruction::Code, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div); + RegLocation rl_src2, bool is_div, int flags); void SpillCoreRegs(); void UnSpillCoreRegs(); diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index acf5599d5f..aa1bf7fe6d 100755 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -768,7 +768,7 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegStorage reg_lo, RegSto } RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div, bool check_zero) { + RegLocation rl_src2, bool is_div, int flags) { // We have to use fixed registers, so flush all the temps. // Prepare for explicit register usage. @@ -783,7 +783,7 @@ RegLocation X86Mir2Lir::GenDivRem(RegLocation rl_dest, RegLocation rl_src1, // Copy LHS sign bit into EDX. NewLIR0(kx86Cdq32Da); - if (check_zero) { + if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { // Handle division by zero case. GenDivZeroCheck(rs_r1); } @@ -1506,7 +1506,7 @@ void X86Mir2Lir::GenImulMemImm(RegStorage dest, int sreg, int displacement, int } void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) { + RegLocation rl_src2, int flags) { if (!cu_->target64) { // Some x86 32b ops are fallback. switch (opcode) { @@ -1515,7 +1515,7 @@ void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R case Instruction::DIV_LONG_2ADDR: case Instruction::REM_LONG: case Instruction::REM_LONG_2ADDR: - Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + Mir2Lir::GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); return; default: @@ -1541,17 +1541,17 @@ void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R case Instruction::MUL_LONG: case Instruction::MUL_LONG_2ADDR: - GenMulLong(opcode, rl_dest, rl_src1, rl_src2); + GenMulLong(opcode, rl_dest, rl_src1, rl_src2, flags); return; case Instruction::DIV_LONG: case Instruction::DIV_LONG_2ADDR: - GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true); + GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true, flags); return; case Instruction::REM_LONG: case Instruction::REM_LONG_2ADDR: - GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false); + GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false, flags); return; case Instruction::AND_LONG_2ADDR: @@ -1579,7 +1579,7 @@ void X86Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest, R } } -bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val) { +bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64_t val, int flags) { // All memory accesses below reference dalvik regs. ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); @@ -1597,14 +1597,14 @@ bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64 StoreValueWide(rl_dest, rl_src1); return true; } else if (val == 2) { - GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src1, rl_src1); + GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src1, rl_src1, flags); return true; } else if (IsPowerOfTwo(val)) { int shift_amount = LowestSetBit(val); if (!PartiallyIntersects(rl_src1, rl_dest)) { rl_src1 = LoadValueWide(rl_src1, kCoreReg); RegLocation rl_result = GenShiftImmOpLong(Instruction::SHL_LONG, rl_dest, rl_src1, - shift_amount); + shift_amount, flags); StoreValueWide(rl_dest, rl_result); return true; } @@ -1658,13 +1658,13 @@ bool X86Mir2Lir::GenMulLongConst(RegLocation rl_dest, RegLocation rl_src1, int64 } void X86Mir2Lir::GenMulLong(Instruction::Code, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2) { + RegLocation rl_src2, int flags) { if (rl_src1.is_const) { std::swap(rl_src1, rl_src2); } if (rl_src2.is_const) { - if (GenMulLongConst(rl_dest, rl_src1, mir_graph_->ConstantValueWide(rl_src2))) { + if (GenMulLongConst(rl_dest, rl_src1, mir_graph_->ConstantValueWide(rl_src2), flags)) { return; } } @@ -2164,7 +2164,7 @@ void X86Mir2Lir::GenDivRemLongLit(RegLocation rl_dest, RegLocation rl_src, } void X86Mir2Lir::GenDivRemLong(Instruction::Code, RegLocation rl_dest, RegLocation rl_src1, - RegLocation rl_src2, bool is_div) { + RegLocation rl_src2, bool is_div, int flags) { if (!cu_->target64) { LOG(FATAL) << "Unexpected use GenDivRemLong()"; return; @@ -2191,7 +2191,9 @@ void X86Mir2Lir::GenDivRemLong(Instruction::Code, RegLocation rl_dest, RegLocati NewLIR0(kx86Cqo64Da); // Handle division by zero case. - GenDivZeroCheckWide(rs_r1q); + if ((flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) { + GenDivZeroCheckWide(rs_r1q); + } // Have to catch 0x8000000000000000/-1 case, or we will get an exception! NewLIR2(kX86Cmp64RI8, rs_r1q.GetReg(), -1); @@ -2392,7 +2394,7 @@ void X86Mir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, } RegLocation X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src, int shift_amount) { + RegLocation rl_src, int shift_amount, int flags) { RegLocation rl_result = EvalLocWide(rl_dest, kCoreReg, true); if (cu_->target64) { OpKind op = static_cast<OpKind>(0); /* Make gcc happy */ @@ -2477,7 +2479,7 @@ RegLocation X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation } void X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_src, RegLocation rl_shift) { + RegLocation rl_src, RegLocation rl_shift, int flags) { // Per spec, we only care about low 6 bits of shift amount. int shift_amount = mir_graph_->ConstantValue(rl_shift) & 0x3f; if (shift_amount == 0) { @@ -2487,7 +2489,7 @@ void X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest } else if (shift_amount == 1 && (opcode == Instruction::SHL_LONG || opcode == Instruction::SHL_LONG_2ADDR)) { // Need to handle this here to avoid calling StoreValueWide twice. - GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src, rl_src); + GenArithOpLong(Instruction::ADD_LONG, rl_dest, rl_src, rl_src, flags); return; } if (PartiallyIntersects(rl_src, rl_dest)) { @@ -2495,12 +2497,13 @@ void X86Mir2Lir::GenShiftImmOpLong(Instruction::Code opcode, RegLocation rl_dest return; } rl_src = LoadValueWide(rl_src, kCoreReg); - RegLocation rl_result = GenShiftImmOpLong(opcode, rl_dest, rl_src, shift_amount); + RegLocation rl_result = GenShiftImmOpLong(opcode, rl_dest, rl_src, shift_amount, flags); StoreValueWide(rl_dest, rl_result); } void X86Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, - RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { + RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2, + int flags) { bool isConstSuccess = false; switch (opcode) { case Instruction::ADD_LONG: @@ -2519,7 +2522,7 @@ void X86Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, if (rl_src2.is_const) { isConstSuccess = GenLongLongImm(rl_dest, rl_src1, rl_src2, opcode); } else { - GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); isConstSuccess = true; } break; @@ -2545,7 +2548,7 @@ void X86Mir2Lir::GenArithImmOpLong(Instruction::Code opcode, if (!isConstSuccess) { // Default - bail to non-const handler. - GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2); + GenArithOpLong(opcode, rl_dest, rl_src1, rl_src2, flags); } } @@ -2917,7 +2920,7 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, } void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_lhs, RegLocation rl_rhs) { + RegLocation rl_lhs, RegLocation rl_rhs, int flags) { OpKind op = kOpBkpt; bool is_div_rem = false; bool unary = false; @@ -3022,7 +3025,7 @@ void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, // Get the div/rem stuff out of the way. if (is_div_rem) { - rl_result = GenDivRem(rl_dest, rl_lhs, rl_rhs, op == kOpDiv, true); + rl_result = GenDivRem(rl_dest, rl_lhs, rl_rhs, op == kOpDiv, flags); StoreValue(rl_dest, rl_result); return; } diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 2ef4c218c3..79d5eebe17 100755 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -2166,7 +2166,7 @@ void X86Mir2Lir::GenAddReduceVector(BasicBlock *bb, MIR *mir) { NewLIR2(kX86MovdrxRR, temp_loc.reg.GetHighReg(), vector_src.GetReg()); } - GenArithOpLong(Instruction::ADD_LONG_2ADDR, rl_dest, temp_loc, temp_loc); + GenArithOpLong(Instruction::ADD_LONG_2ADDR, rl_dest, temp_loc, temp_loc, mir->optimization_flags); } else if (opsize == kSignedByte || opsize == kUnsignedByte) { RegStorage rs_tmp = Get128BitRegister(AllocTempDouble()); NewLIR2(kX86PxorRR, rs_tmp.GetReg(), rs_tmp.GetReg()); |