diff options
| author | 2014-03-28 00:24:17 +0000 | |
|---|---|---|
| committer | 2014-03-28 00:24:17 +0000 | |
| commit | ad174d1b54bf2fa477bec71a0ca93595f54b8fe9 (patch) | |
| tree | 98d30d05a0973dc14caf1113eb5ae733f796024b | |
| parent | 5378924bef79144df62447b78c0a87895d7edb60 (diff) | |
| parent | 3654a6f50a948ead89627f398aaf86a2c2db0088 (diff) | |
Merge "Revert "Optimize easy multiply and easy div remainder.""
| -rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 15 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 146 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/utility_arm.cc | 49 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_common.cc | 25 | ||||
| -rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 3 | ||||
| -rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 5 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 1 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 3 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 5 |
9 files changed, 53 insertions, 199 deletions
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index 6df341bd93..0f1e17141c 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -22,14 +22,13 @@ namespace art { -class ArmMir2Lir FINAL : public Mir2Lir { +class ArmMir2Lir : public Mir2Lir { public: ArmMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); // Required for target - codegen helpers. bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, RegLocation rl_dest, int lit); - bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE; LIR* CheckSuspendUsingLoad() OVERRIDE; RegStorage LoadHelper(ThreadOffset offset); LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size, @@ -182,9 +181,8 @@ class ArmMir2Lir FINAL : public Mir2Lir { LIR* LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size, int s_reg); LIR* StoreBaseDispBody(RegStorage r_base, int displacement, RegStorage r_src, OpSize size); - LIR* OpRegRegRegShift(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2, - int shift); - LIR* OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_src2, int shift); + LIR* OpRegRegRegShift(OpKind op, int r_dest, int r_src1, int r_src2, int shift); + LIR* OpRegRegShift(OpKind op, int r_dest_src1, int r_src2, int shift); static const ArmEncodingMap EncodingMap[kArmLast]; int EncodeShift(int code, int amount); int ModifiedImmediate(uint32_t value); @@ -204,13 +202,6 @@ class ArmMir2Lir FINAL : public Mir2Lir { 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); - typedef struct { - OpKind op; - uint32_t shift; - } EasyMultiplyOp; - bool GetEasyMultiplyOp(int lit, EasyMultiplyOp* op); - bool GetEasyMultiplyTwoOps(int lit, EasyMultiplyOp* ops); - void GenEasyMultiplyTwoOps(RegStorage r_dest, RegStorage r_src, EasyMultiplyOp* ops); }; } // namespace art diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 964c2fb893..46db466136 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -425,6 +425,10 @@ bool ArmMir2Lir::SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div if (pattern == DivideNone) { return false; } + // Tuning: add rem patterns + if (!is_div) { + return false; + } RegStorage r_magic = AllocTemp(); LoadConstant(r_magic, magic_table[lit].magic); @@ -435,136 +439,23 @@ bool ArmMir2Lir::SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div NewLIR4(kThumb2Smull, r_lo.GetReg(), r_hi.GetReg(), r_magic.GetReg(), rl_src.reg.GetReg()); switch (pattern) { case Divide3: - OpRegRegRegShift(kOpSub, rl_result.reg, r_hi, rl_src.reg, EncodeShift(kArmAsr, 31)); + OpRegRegRegShift(kOpSub, rl_result.reg.GetReg(), r_hi.GetReg(), + rl_src.reg.GetReg(), EncodeShift(kArmAsr, 31)); break; case Divide5: OpRegRegImm(kOpAsr, r_lo, rl_src.reg, 31); - OpRegRegRegShift(kOpRsub, rl_result.reg, r_lo, r_hi, - EncodeShift(kArmAsr, magic_table[lit].shift)); + OpRegRegRegShift(kOpRsub, rl_result.reg.GetReg(), r_lo.GetReg(), r_hi.GetReg(), + EncodeShift(kArmAsr, magic_table[lit].shift)); break; case Divide7: OpRegReg(kOpAdd, r_hi, rl_src.reg); OpRegRegImm(kOpAsr, r_lo, rl_src.reg, 31); - OpRegRegRegShift(kOpRsub, rl_result.reg, r_lo, r_hi, - EncodeShift(kArmAsr, magic_table[lit].shift)); + OpRegRegRegShift(kOpRsub, rl_result.reg.GetReg(), r_lo.GetReg(), r_hi.GetReg(), + EncodeShift(kArmAsr, magic_table[lit].shift)); break; default: LOG(FATAL) << "Unexpected pattern: " << pattern; } - - if (!is_div) { - RegStorage tmp1 = r_lo; - EasyMultiplyOp ops[2]; - - bool canEasyMultiply = GetEasyMultiplyTwoOps(lit, ops); - DCHECK_NE(canEasyMultiply, false); - - GenEasyMultiplyTwoOps(tmp1, rl_result.reg, ops); - OpRegRegReg(kOpSub, rl_result.reg, rl_src.reg, tmp1); - } - - StoreValue(rl_dest, rl_result); - return true; -} - -// Try to convert *lit to 1 RegRegRegShift/RegRegShift form. -bool ArmMir2Lir::GetEasyMultiplyOp(int lit, ArmMir2Lir::EasyMultiplyOp* op) { - if (IsPowerOfTwo(lit)) { - op->op = kOpLsl; - op->shift = LowestSetBit(lit); - return true; - } - - if (IsPowerOfTwo(lit - 1)) { - op->op = kOpAdd; - op->shift = LowestSetBit(lit - 1); - return true; - } - - if (IsPowerOfTwo(lit + 1)) { - op->op = kOpRsub; - op->shift = LowestSetBit(lit + 1); - return true; - } - - op->op = kOpInvalid; - return false; -} - -// Try to convert *lit to 1~2 RegRegRegShift/RegRegShift forms. -bool ArmMir2Lir::GetEasyMultiplyTwoOps(int lit, EasyMultiplyOp* ops) { - GetEasyMultiplyOp(lit, &ops[0]); - if (GetEasyMultiplyOp(lit, &ops[0])) { - ops[1].op = kOpInvalid; - return true; - } - - int lit1 = lit; - uint32_t shift = LowestSetBit(lit1); - if (GetEasyMultiplyOp(lit1 >> shift, &ops[0])) { - ops[1].op = kOpLsl; - ops[1].shift = shift; - return true; - } - - lit1 = lit - 1; - shift = LowestSetBit(lit1); - if (GetEasyMultiplyOp(lit1 >> shift, &ops[0])) { - ops[1].op = kOpAdd; - ops[1].shift = shift; - return true; - } - - lit1 = lit + 1; - shift = LowestSetBit(lit1); - if (GetEasyMultiplyOp(lit1 >> shift, &ops[0])) { - ops[1].op = kOpRsub; - ops[1].shift = shift; - return true; - } - - return false; -} - -void ArmMir2Lir::GenEasyMultiplyTwoOps(RegStorage r_dest, RegStorage r_src, EasyMultiplyOp* ops) { - // dest = ( src << shift1) + [ src | -src | 0 ] - // dest = (dest << shift2) + [ src | -src | 0 ] - for (int i = 0; i < 2; i++) { - RegStorage r_src2; - if (i == 0) { - r_src2 = r_src; - } else { - r_src2 = r_dest; - } - switch (ops[i].op) { - case kOpLsl: - OpRegRegImm(kOpLsl, r_dest, r_src2, ops[i].shift); - break; - case kOpAdd: - OpRegRegRegShift(kOpAdd, r_dest, r_src, r_src2, EncodeShift(kArmLsl, ops[i].shift)); - break; - case kOpRsub: - OpRegRegRegShift(kOpRsub, r_dest, r_src, r_src2, EncodeShift(kArmLsl, ops[i].shift)); - break; - default: - DCHECK_NE(i, 0); - DCHECK_EQ(ops[i].op, kOpInvalid); - break; - } - } -} - -bool ArmMir2Lir::EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) { - EasyMultiplyOp ops[2]; - - if (!GetEasyMultiplyTwoOps(lit, ops)) { - return false; - } - - rl_src = LoadValue(rl_src, kCoreReg); - RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); - - GenEasyMultiplyTwoOps(rl_result.reg, rl_src.reg, ops); StoreValue(rl_dest, rl_result); return true; } @@ -861,7 +752,7 @@ LIR* ArmMir2Lir::OpVstm(RegStorage r_base, int count) { void ArmMir2Lir::GenMultiplyByTwoBitMultiplier(RegLocation rl_src, RegLocation rl_result, int lit, int first_bit, int second_bit) { - OpRegRegRegShift(kOpAdd, rl_result.reg, rl_src.reg, rl_src.reg, + OpRegRegRegShift(kOpAdd, rl_result.reg.GetReg(), rl_src.reg.GetReg(), rl_src.reg.GetReg(), EncodeShift(kArmLsl, second_bit - first_bit)); if (first_bit != 0) { OpRegRegImm(kOpLsl, rl_result.reg, rl_result.reg, first_bit); @@ -1007,7 +898,8 @@ void ArmMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest, NewLIR3(kThumb2MulRRR, tmp1.GetReg(), rl_src1.reg.GetLowReg(), rl_src1.reg.GetHighReg()); NewLIR4(kThumb2Umull, res_lo.GetReg(), res_hi.GetReg(), rl_src1.reg.GetLowReg(), rl_src1.reg.GetLowReg()); - OpRegRegRegShift(kOpAdd, res_hi, res_hi, tmp1, EncodeShift(kArmLsl, 1)); + OpRegRegRegShift(kOpAdd, res_hi.GetReg(), res_hi.GetReg(), tmp1.GetReg(), + EncodeShift(kArmLsl, 1)); } else { NewLIR3(kThumb2MulRRR, tmp1.GetReg(), rl_src2.reg.GetLowReg(), rl_src1.reg.GetHighReg()); if (reg_status == 2) { @@ -1117,7 +1009,8 @@ void ArmMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, } else { // No special indexed operation, lea + load w/ displacement reg_ptr = AllocTemp(); - OpRegRegRegShift(kOpAdd, reg_ptr, rl_array.reg, rl_index.reg, EncodeShift(kArmLsl, scale)); + OpRegRegRegShift(kOpAdd, reg_ptr.GetReg(), rl_array.reg.GetReg(), rl_index.reg.GetReg(), + EncodeShift(kArmLsl, scale)); FreeTemp(rl_index.reg.GetReg()); } rl_result = EvalLoc(rl_dest, reg_class, true); @@ -1224,7 +1117,8 @@ void ArmMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, rl_src = LoadValue(rl_src, reg_class); } if (!constant_index) { - OpRegRegRegShift(kOpAdd, reg_ptr, rl_array.reg, rl_index.reg, EncodeShift(kArmLsl, scale)); + OpRegRegRegShift(kOpAdd, reg_ptr.GetReg(), rl_array.reg.GetReg(), rl_index.reg.GetReg(), + EncodeShift(kArmLsl, scale)); } if (needs_range_check) { if (constant_index) { @@ -1289,7 +1183,7 @@ void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, LoadConstant(rl_result.reg.GetLow(), 0); } else { OpRegRegImm(kOpLsl, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), shift_amount); - OpRegRegRegShift(kOpOr, rl_result.reg.GetHigh(), rl_result.reg.GetHigh(), rl_src.reg.GetLow(), + OpRegRegRegShift(kOpOr, rl_result.reg.GetHighReg(), rl_result.reg.GetHighReg(), rl_src.reg.GetLowReg(), EncodeShift(kArmLsr, 32 - shift_amount)); OpRegRegImm(kOpLsl, rl_result.reg.GetLow(), rl_src.reg.GetLow(), shift_amount); } @@ -1305,7 +1199,7 @@ void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, } else { RegStorage t_reg = AllocTemp(); OpRegRegImm(kOpLsr, t_reg, rl_src.reg.GetLow(), shift_amount); - OpRegRegRegShift(kOpOr, rl_result.reg.GetLow(), t_reg, rl_src.reg.GetHigh(), + OpRegRegRegShift(kOpOr, rl_result.reg.GetLowReg(), t_reg.GetReg(), rl_src.reg.GetHighReg(), EncodeShift(kArmLsl, 32 - shift_amount)); FreeTemp(t_reg); OpRegRegImm(kOpAsr, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), shift_amount); @@ -1322,7 +1216,7 @@ void ArmMir2Lir::GenShiftImmOpLong(Instruction::Code opcode, } else { RegStorage t_reg = AllocTemp(); OpRegRegImm(kOpLsr, t_reg, rl_src.reg.GetLow(), shift_amount); - OpRegRegRegShift(kOpOr, rl_result.reg.GetLow(), t_reg, rl_src.reg.GetHigh(), + OpRegRegRegShift(kOpOr, rl_result.reg.GetLowReg(), t_reg.GetReg(), rl_src.reg.GetHighReg(), EncodeShift(kArmLsl, 32 - shift_amount)); FreeTemp(t_reg); OpRegRegImm(kOpLsr, rl_result.reg.GetHigh(), rl_src.reg.GetHigh(), shift_amount); diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc index cf90fb1b52..1ec0a2c65d 100644 --- a/compiler/dex/quick/arm/utility_arm.cc +++ b/compiler/dex/quick/arm/utility_arm.cc @@ -234,10 +234,9 @@ LIR* ArmMir2Lir::OpReg(OpKind op, RegStorage r_dest_src) { return NewLIR1(opcode, r_dest_src.GetReg()); } -LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_src2, +LIR* ArmMir2Lir::OpRegRegShift(OpKind op, int r_dest_src1, int r_src2, int shift) { - bool thumb_form = - ((shift == 0) && ARM_LOWREG(r_dest_src1.GetReg()) && ARM_LOWREG(r_src2.GetReg())); + bool thumb_form = ((shift == 0) && ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2)); ArmOpcode opcode = kThumbBkpt; switch (op) { case kOpAdc: @@ -256,9 +255,9 @@ LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_s case kOpCmp: if (thumb_form) opcode = kThumbCmpRR; - else if ((shift == 0) && !ARM_LOWREG(r_dest_src1.GetReg()) && !ARM_LOWREG(r_src2.GetReg())) + else if ((shift == 0) && !ARM_LOWREG(r_dest_src1) && !ARM_LOWREG(r_src2)) opcode = kThumbCmpHH; - else if ((shift == 0) && ARM_LOWREG(r_dest_src1.GetReg())) + else if ((shift == 0) && ARM_LOWREG(r_dest_src1)) opcode = kThumbCmpLH; else if (shift == 0) opcode = kThumbCmpHL; @@ -270,11 +269,11 @@ LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_s break; case kOpMov: DCHECK_EQ(shift, 0); - if (ARM_LOWREG(r_dest_src1.GetReg()) && ARM_LOWREG(r_src2.GetReg())) + if (ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2)) opcode = kThumbMovRR; - else if (!ARM_LOWREG(r_dest_src1.GetReg()) && !ARM_LOWREG(r_src2.GetReg())) + else if (!ARM_LOWREG(r_dest_src1) && !ARM_LOWREG(r_src2)) opcode = kThumbMovRR_H2H; - else if (ARM_LOWREG(r_dest_src1.GetReg())) + else if (ARM_LOWREG(r_dest_src1)) opcode = kThumbMovRR_H2L; else opcode = kThumbMovRR_L2H; @@ -325,7 +324,7 @@ LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_s DCHECK_EQ(shift, 0); if (!thumb_form) { // Binary, but rm is encoded twice. - return NewLIR3(kThumb2RevRR, r_dest_src1.GetReg(), r_src2.GetReg(), r_src2.GetReg()); + return NewLIR3(kThumb2RevRR, r_dest_src1, r_src2, r_src2); } opcode = kThumbRev; break; @@ -333,34 +332,34 @@ LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_s DCHECK_EQ(shift, 0); if (!thumb_form) { // Binary, but rm is encoded twice. - return NewLIR3(kThumb2RevshRR, r_dest_src1.GetReg(), r_src2.GetReg(), r_src2.GetReg()); + return NewLIR3(kThumb2RevshRR, r_dest_src1, r_src2, r_src2); } opcode = kThumbRevsh; break; case kOp2Byte: DCHECK_EQ(shift, 0); - return NewLIR4(kThumb2Sbfx, r_dest_src1.GetReg(), r_src2.GetReg(), 0, 8); + return NewLIR4(kThumb2Sbfx, r_dest_src1, r_src2, 0, 8); case kOp2Short: DCHECK_EQ(shift, 0); - return NewLIR4(kThumb2Sbfx, r_dest_src1.GetReg(), r_src2.GetReg(), 0, 16); + return NewLIR4(kThumb2Sbfx, r_dest_src1, r_src2, 0, 16); case kOp2Char: DCHECK_EQ(shift, 0); - return NewLIR4(kThumb2Ubfx, r_dest_src1.GetReg(), r_src2.GetReg(), 0, 16); + return NewLIR4(kThumb2Ubfx, r_dest_src1, r_src2, 0, 16); default: LOG(FATAL) << "Bad opcode: " << op; break; } DCHECK(!IsPseudoLirOp(opcode)); if (EncodingMap[opcode].flags & IS_BINARY_OP) { - return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg()); + return NewLIR2(opcode, r_dest_src1, r_src2); } else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) { if (EncodingMap[opcode].field_loc[2].kind == kFmtShift) { - return NewLIR3(opcode, r_dest_src1.GetReg(), r_src2.GetReg(), shift); + return NewLIR3(opcode, r_dest_src1, r_src2, shift); } else { - return NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), r_src2.GetReg()); + return NewLIR3(opcode, r_dest_src1, r_dest_src1, r_src2); } } else if (EncodingMap[opcode].flags & IS_QUAD_OP) { - return NewLIR4(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), r_src2.GetReg(), shift); + return NewLIR4(opcode, r_dest_src1, r_dest_src1, r_src2, shift); } else { LOG(FATAL) << "Unexpected encoding operand count"; return NULL; @@ -368,7 +367,7 @@ LIR* ArmMir2Lir::OpRegRegShift(OpKind op, RegStorage r_dest_src1, RegStorage r_s } LIR* ArmMir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) { - return OpRegRegShift(op, r_dest_src1, r_src2, 0); + return OpRegRegShift(op, r_dest_src1.GetReg(), r_src2.GetReg(), 0); } LIR* ArmMir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type) { @@ -386,11 +385,11 @@ LIR* ArmMir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, Re return NULL; } -LIR* ArmMir2Lir::OpRegRegRegShift(OpKind op, RegStorage r_dest, RegStorage r_src1, - RegStorage r_src2, int shift) { +LIR* ArmMir2Lir::OpRegRegRegShift(OpKind op, int r_dest, int r_src1, + int r_src2, int shift) { ArmOpcode opcode = kThumbBkpt; - bool thumb_form = (shift == 0) && ARM_LOWREG(r_dest.GetReg()) && ARM_LOWREG(r_src1.GetReg()) && - ARM_LOWREG(r_src2.GetReg()); + bool thumb_form = (shift == 0) && ARM_LOWREG(r_dest) && ARM_LOWREG(r_src1) && + ARM_LOWREG(r_src2); switch (op) { case kOpAdd: opcode = (thumb_form) ? kThumbAddRRR : kThumb2AddRRR; @@ -449,15 +448,15 @@ LIR* ArmMir2Lir::OpRegRegRegShift(OpKind op, RegStorage r_dest, RegStorage r_src } DCHECK(!IsPseudoLirOp(opcode)); if (EncodingMap[opcode].flags & IS_QUAD_OP) { - return NewLIR4(opcode, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg(), shift); + return NewLIR4(opcode, r_dest, r_src1, r_src2, shift); } else { DCHECK(EncodingMap[opcode].flags & IS_TERTIARY_OP); - return NewLIR3(opcode, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg()); + return NewLIR3(opcode, r_dest, r_src1, r_src2); } } LIR* ArmMir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2) { - return OpRegRegRegShift(op, r_dest, r_src1, r_src2, 0); + return OpRegRegRegShift(op, r_dest.GetReg(), r_src1.GetReg(), r_src2.GetReg(), 0); } LIR* ArmMir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value) { diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index b23e10f288..2afa5ca815 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -1626,31 +1626,14 @@ bool Mir2Lir::HandleEasyDivRem(Instruction::Code dalvik_opcode, bool is_div, // Returns true if it added instructions to 'cu' to multiply 'rl_src' by 'lit' // and store the result in 'rl_dest'. bool Mir2Lir::HandleEasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) { - if (lit < 0) { - return false; - } - if (lit == 0) { - RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); - LoadConstant(rl_result.reg, 0); - StoreValue(rl_dest, rl_result); - return true; - } - if (lit == 1) { - rl_src = LoadValue(rl_src, kCoreReg); - RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); - OpRegCopy(rl_result.reg, rl_src.reg); - StoreValue(rl_dest, rl_result); - return true; - } - // There is RegRegRegShift on Arm, so check for more special cases - if (cu_->instruction_set == kThumb2) { - return EasyMultiply(rl_src, rl_dest, lit); - } // Can we simplify this multiplication? bool power_of_two = false; bool pop_count_le2 = false; bool power_of_two_minus_one = false; - if (IsPowerOfTwo(lit)) { + if (lit < 2) { + // Avoid special cases. + return false; + } else if (IsPowerOfTwo(lit)) { power_of_two = true; } else if (IsPopCountLE2(lit)) { pop_count_le2 = true; diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h index 0ef43b3197..bc1ad02ce8 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -22,14 +22,13 @@ namespace art { -class MipsMir2Lir FINAL : public Mir2Lir { +class MipsMir2Lir : public Mir2Lir { public: MipsMir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); // Required for target - codegen utilities. bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, RegLocation rl_dest, int lit); - bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE; LIR* CheckSuspendUsingLoad() OVERRIDE; RegStorage LoadHelper(ThreadOffset offset); LIR* LoadBaseDisp(int r_base, int displacement, int r_dest, OpSize size, int s_reg); diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index 270d895194..dfe8b35277 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -368,11 +368,6 @@ bool MipsMir2Lir::SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_di return false; } -bool MipsMir2Lir::EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) { - LOG(FATAL) << "Unexpected use of easyMultiply in Mips"; - return false; -} - LIR* MipsMir2Lir::OpIT(ConditionCode cond, const char* guide) { LOG(FATAL) << "Unexpected use of OpIT in Mips"; return NULL; diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 946adc5e8a..bac35aad6e 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -811,7 +811,6 @@ class Mir2Lir : public Backend { // Required for target - codegen helpers. virtual bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, RegLocation rl_dest, int lit) = 0; - virtual bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) = 0; virtual LIR* CheckSuspendUsingLoad() = 0; virtual RegStorage LoadHelper(ThreadOffset offset) = 0; virtual LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size, diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index 4c495a16c9..6d427e7bcf 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -22,14 +22,13 @@ namespace art { -class X86Mir2Lir FINAL : public Mir2Lir { +class X86Mir2Lir : public Mir2Lir { public: X86Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena); // Required for target - codegen helpers. bool SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div, RegLocation rl_src, RegLocation rl_dest, int lit); - bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE; LIR* CheckSuspendUsingLoad() OVERRIDE; RegStorage LoadHelper(ThreadOffset offset); LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size, diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index 5ef7060731..37b2b37b45 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -909,11 +909,6 @@ bool X86Mir2Lir::SmallLiteralDivRem(Instruction::Code dalvik_opcode, bool is_div return false; } -bool X86Mir2Lir::EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) { - LOG(FATAL) << "Unexpected use of easyMultiply in x86"; - return false; -} - LIR* X86Mir2Lir::OpIT(ConditionCode cond, const char* guide) { LOG(FATAL) << "Unexpected use of OpIT in x86"; return NULL; |