diff options
author | Vladimir Marko <vmarko@google.com> | 2014-05-12 16:22:14 +0100 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2014-05-12 16:48:58 +0100 |
commit | 0dc242d6fc1254e6ca1c31e08e612bbf45644b17 (patch) | |
tree | a3389b2a7642745cd71843e903a77ea4282be284 /compiler | |
parent | 6663c90d2f94b0035fabcaee1f26fd840c9f9161 (diff) | |
download | art-0dc242d6fc1254e6ca1c31e08e612bbf45644b17.tar.gz art-0dc242d6fc1254e6ca1c31e08e612bbf45644b17.tar.bz2 art-0dc242d6fc1254e6ca1c31e08e612bbf45644b17.zip |
Avoid unnecessary copy/load in EvalLoc() and LoadValue().
EvalLoc()/EvalLocWide() are used to prepare a register where
a value is subsequently stored, so they shouldn't copy the
old value to the new register for register class mismatch.
The only exception where we actually need a copy is
LoadValue()/LoadValueWide(), so we inline the old code that
makes the copy there. We also avoid loading inexpensive
constants when the value is already in the register.
Change-Id: I07519e9d4d9b3f7272233d196435f3035e4a3ca9
Diffstat (limited to 'compiler')
-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(); |