diff options
-rw-r--r-- | compiler/dex/quick/gen_loadstore.cc | 47 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 8 | ||||
-rw-r--r-- | compiler/dex/quick/ralloc_util.cc | 6 | ||||
-rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 2 |
4 files changed, 44 insertions, 19 deletions
diff --git a/compiler/dex/quick/gen_loadstore.cc b/compiler/dex/quick/gen_loadstore.cc index faa9461728..8fcb09b955 100644 --- a/compiler/dex/quick/gen_loadstore.cc +++ b/compiler/dex/quick/gen_loadstore.cc @@ -139,12 +139,25 @@ void Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) { } RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) { - rl_src = EvalLoc(rl_src, op_kind, false); - if (IsInexpensiveConstant(rl_src) || rl_src.location != kLocPhysReg) { - LoadValueDirect(rl_src, rl_src.reg); - rl_src.location = kLocPhysReg; - MarkLive(rl_src); + rl_src = UpdateLoc(rl_src); + if (rl_src.location == kLocPhysReg) { + if (!RegClassMatches(op_kind, rl_src.reg)) { + // Wrong register class, realloc, copy and transfer ownership. + RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind); + OpRegCopy(new_reg, rl_src.reg); + // Associate the old sreg with the new register and clobber the old register. + GetRegInfo(new_reg)->SetSReg(GetRegInfo(rl_src.reg)->SReg()); + Clobber(rl_src.reg); + rl_src.reg = new_reg; + } + return rl_src; } + + DCHECK_NE(rl_src.s_reg_low, INVALID_SREG); + rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind); + LoadValueDirect(rl_src, rl_src.reg); + rl_src.location = kLocPhysReg; + MarkLive(rl_src); return rl_src; } @@ -203,12 +216,26 @@ void Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) { RegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) { DCHECK(rl_src.wide); - rl_src = EvalLoc(rl_src, op_kind, false); - if (IsInexpensiveConstant(rl_src) || rl_src.location != kLocPhysReg) { - LoadValueDirectWide(rl_src, rl_src.reg); - rl_src.location = kLocPhysReg; - MarkLive(rl_src); + rl_src = UpdateLocWide(rl_src); + if (rl_src.location == kLocPhysReg) { + if (!RegClassMatches(op_kind, rl_src.reg)) { + // Wrong register class, realloc, copy and transfer ownership. + RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind); + OpRegCopyWide(new_regs, rl_src.reg); + // Associate the old sreg with the new register and clobber the old register. + GetRegInfo(new_regs)->SetSReg(GetRegInfo(rl_src.reg)->SReg()); + Clobber(rl_src.reg); + rl_src.reg = new_regs; + } + return rl_src; } + + DCHECK_NE(rl_src.s_reg_low, INVALID_SREG); + DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG); + rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind); + LoadValueDirectWide(rl_src, rl_src.reg); + rl_src.location = kLocPhysReg; + MarkLive(rl_src); return rl_src; } diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 74245a4a06..5a824e7215 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -673,9 +673,9 @@ class Mir2Lir : public Backend { RegLocation UpdateRawLoc(RegLocation loc); /** - * @brief Used to load register location into a typed temporary or pair of temporaries. + * @brief Used to prepare a register location to receive a wide value. * @see EvalLoc - * @param loc The register location to load from. + * @param loc the location where the value will be stored. * @param reg_class Type of register needed. * @param update Whether the liveness information should be updated. * @return Returns the properly typed temporary in physical register pairs. @@ -683,8 +683,8 @@ class Mir2Lir : public Backend { RegLocation EvalLocWide(RegLocation loc, int reg_class, bool update); /** - * @brief Used to load register location into a typed temporary. - * @param loc The register location to load from. + * @brief Used to prepare a register location to receive a value. + * @param loc the location where the value will be stored. * @param reg_class Type of register needed. * @param update Whether the liveness information should be updated. * @return Returns the properly typed temporary in physical register. diff --git a/compiler/dex/quick/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc index ca9a3ab64f..04de286ae2 100644 --- a/compiler/dex/quick/ralloc_util.cc +++ b/compiler/dex/quick/ralloc_util.cc @@ -937,9 +937,8 @@ RegLocation Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update) { /* If already in registers, we can assume proper form. Right reg class? */ if (loc.location == kLocPhysReg) { if (!RegClassMatches(reg_class, loc.reg)) { - /* Wrong register class. Reallocate and copy */ + // Wrong register class. Reallocate and transfer ownership. RegStorage new_regs = AllocTypedTempWide(loc.fp, reg_class); - OpRegCopyWide(new_regs, loc.reg); // Associate the old sreg with the new register and clobber the old register. GetRegInfo(new_regs)->SetSReg(GetRegInfo(loc.reg)->SReg()); Clobber(loc.reg); @@ -971,9 +970,8 @@ RegLocation Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update) { if (loc.location == kLocPhysReg) { if (!RegClassMatches(reg_class, loc.reg)) { - /* Wrong register class. Realloc, copy and transfer ownership */ + // Wrong register class. Reallocate and transfer ownership. RegStorage new_reg = AllocTypedTemp(loc.fp, reg_class); - OpRegCopy(new_reg, loc.reg); // Associate the old sreg with the new register and clobber the old register. GetRegInfo(new_reg)->SetSReg(GetRegInfo(loc.reg)->SReg()); Clobber(loc.reg); diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index 698fce4178..b6e0841e6e 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -1196,7 +1196,7 @@ void X86Mir2Lir::GenLongRegOrMemOp(RegLocation rl_dest, RegLocation rl_src, if (rl_src.location == kLocPhysReg) { // Both operands are in registers. // But we must ensure that rl_src is in pair - rl_src = EvalLocWide(rl_src, kCoreReg, true); + rl_src = LoadValueWide(rl_src, kCoreReg); if (rl_dest.reg.GetLowReg() == rl_src.reg.GetHighReg()) { // The registers are the same, so we would clobber it before the use. RegStorage temp_reg = AllocTemp(); |