diff options
| author | 2014-04-28 20:02:38 -0700 | |
|---|---|---|
| committer | 2014-04-29 05:43:47 -0700 | |
| commit | 7a11ab09f93f54b1c07c0bf38dd65ed322e86bc6 (patch) | |
| tree | bfd392c07b08a5e0ce9ecb0c3569745935060063 | |
| parent | 0f73e2ee44977b9b5cfe42f6c4c3b6a407e92368 (diff) | |
Quick compiler: debugging assists
A few minor assists to ease A/B debugging in the Quick
compiler:
1. To save time, the assemblers for some targets only
update the object code offsets on instructions involved with
pc-relative fixups. We add code to fix up all offsets when
doing a verbose codegen listing.
2. Temp registers are normally allocated in a round-robin
fashion. When disabling liveness tracking, we now reset the
round-robin pool to 0 on each instruction boundary. This makes
it easier to spot real codegen differences.
3. Self-register copies were previously emitted, but
marked as nops. Minor change to avoid generating them in the
first place and reduce clutter.
Change-Id: I7954bba3b9f16ee690d663be510eac7034c93723
| -rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 55 | ||||
| -rw-r--r-- | compiler/dex/quick/codegen_util.cc | 14 | ||||
| -rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 55 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.cc | 3 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 4 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 85 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/utility_x86.cc | 3 |
10 files changed, 127 insertions, 98 deletions
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index a89b307d60..646859c03b 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -160,7 +160,7 @@ class ArmMir2Lir FINAL : public Mir2Lir { LIR* OpMem(OpKind op, RegStorage r_base, int disp); LIR* OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); - LIR* OpRegCopy(RegStorage r_dest, RegStorage r_src); + void OpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src); LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value); LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset); diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index f47e693e4d..a2d6373622 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -361,37 +361,40 @@ LIR* ArmMir2Lir::OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) { return res; } -LIR* ArmMir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) { - LIR* res = OpRegCopyNoInsert(r_dest, r_src); - AppendLIR(res); - return res; +void ArmMir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) { + if (r_dest != r_src) { + LIR* res = OpRegCopyNoInsert(r_dest, r_src); + AppendLIR(res); + } } void ArmMir2Lir::OpRegCopyWide(RegStorage r_dest, RegStorage r_src) { - bool dest_fp = ARM_FPREG(r_dest.GetLowReg()); - bool src_fp = ARM_FPREG(r_src.GetLowReg()); - if (dest_fp) { - if (src_fp) { - // FIXME: handle 64-bit solo's here. - OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())), - RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg()))); - } else { - NewLIR3(kThumb2Fmdrr, S2d(r_dest.GetLowReg(), r_dest.GetHighReg()), - r_src.GetLowReg(), r_src.GetHighReg()); - } - } else { - if (src_fp) { - NewLIR3(kThumb2Fmrrd, r_dest.GetLowReg(), r_dest.GetHighReg(), S2d(r_src.GetLowReg(), - r_src.GetHighReg())); + if (r_dest != r_src) { + bool dest_fp = ARM_FPREG(r_dest.GetLowReg()); + bool src_fp = ARM_FPREG(r_src.GetLowReg()); + if (dest_fp) { + if (src_fp) { + // FIXME: handle 64-bit solo's here. + OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())), + RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg()))); + } else { + NewLIR3(kThumb2Fmdrr, S2d(r_dest.GetLowReg(), r_dest.GetHighReg()), + r_src.GetLowReg(), r_src.GetHighReg()); + } } else { - // Handle overlap - if (r_src.GetHighReg() == r_dest.GetLowReg()) { - DCHECK_NE(r_src.GetLowReg(), r_dest.GetHighReg()); - OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); - OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + if (src_fp) { + NewLIR3(kThumb2Fmrrd, r_dest.GetLowReg(), r_dest.GetHighReg(), S2d(r_src.GetLowReg(), + r_src.GetHighReg())); } else { - OpRegCopy(r_dest.GetLow(), r_src.GetLow()); - OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + // Handle overlap + if (r_src.GetHighReg() == r_dest.GetLowReg()) { + DCHECK_NE(r_src.GetLowReg(), r_dest.GetHighReg()); + OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + } else { + OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + } } } } diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 677ee15462..501e4e204b 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -274,6 +274,19 @@ void Mir2Lir::DumpPromotionMap() { } } +void Mir2Lir::UpdateLIROffsets() { + // Only used for code listings. + size_t offset = 0; + for (LIR* lir = first_lir_insn_; lir != nullptr; lir = lir->next) { + lir->offset = offset; + if (!lir->flags.is_nop && !IsPseudoLirOp(lir->opcode)) { + offset += GetInsnSize(lir); + } else if (lir->opcode == kPseudoPseudoAlign4) { + offset += (offset & 0x2); + } + } +} + /* Dump instructions and constant pool contents */ void Mir2Lir::CodegenDump() { LOG(INFO) << "Dumping LIR insns for " @@ -293,6 +306,7 @@ void Mir2Lir::CodegenDump() { LOG(INFO) << "expansion factor: " << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2); DumpPromotionMap(); + UpdateLIROffsets(); for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) { DumpLIRInsn(lir_insn, 0); } diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h index da65f3424f..81d6782288 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -159,7 +159,7 @@ class MipsMir2Lir FINAL : public Mir2Lir { LIR* OpMem(OpKind op, RegStorage r_base, int disp); LIR* OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); - LIR* OpRegCopy(RegStorage r_dest, RegStorage r_src); + void OpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src); LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value); LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset); diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index 88d5d2bc41..7c0becd41a 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -177,37 +177,40 @@ LIR* MipsMir2Lir::OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) { return res; } -LIR* MipsMir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) { - LIR *res = OpRegCopyNoInsert(r_dest, r_src); - AppendLIR(res); - return res; +void MipsMir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) { + if (r_dest != r_src) { + LIR *res = OpRegCopyNoInsert(r_dest, r_src); + AppendLIR(res); + } } void MipsMir2Lir::OpRegCopyWide(RegStorage r_dest, RegStorage r_src) { - bool dest_fp = MIPS_FPREG(r_dest.GetLowReg()); - bool src_fp = MIPS_FPREG(r_src.GetLowReg()); - if (dest_fp) { - if (src_fp) { - // FIXME: handle this here - reserve OpRegCopy for 32-bit copies. - OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())), - RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg()))); - } else { - /* note the operands are swapped for the mtc1 instr */ - NewLIR2(kMipsMtc1, r_src.GetLowReg(), r_dest.GetLowReg()); - NewLIR2(kMipsMtc1, r_src.GetHighReg(), r_dest.GetHighReg()); - } - } else { - if (src_fp) { - NewLIR2(kMipsMfc1, r_dest.GetLowReg(), r_src.GetLowReg()); - NewLIR2(kMipsMfc1, r_dest.GetHighReg(), r_src.GetHighReg()); + if (r_dest != r_src) { + bool dest_fp = MIPS_FPREG(r_dest.GetLowReg()); + bool src_fp = MIPS_FPREG(r_src.GetLowReg()); + if (dest_fp) { + if (src_fp) { + // FIXME: handle this here - reserve OpRegCopy for 32-bit copies. + OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())), + RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg()))); + } else { + /* note the operands are swapped for the mtc1 instr */ + NewLIR2(kMipsMtc1, r_src.GetLowReg(), r_dest.GetLowReg()); + NewLIR2(kMipsMtc1, r_src.GetHighReg(), r_dest.GetHighReg()); + } } else { - // Handle overlap - if (r_src.GetHighReg() == r_dest.GetLowReg()) { - OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); - OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + if (src_fp) { + NewLIR2(kMipsMfc1, r_dest.GetLowReg(), r_src.GetLowReg()); + NewLIR2(kMipsMfc1, r_dest.GetHighReg(), r_src.GetHighReg()); } else { - OpRegCopy(r_dest.GetLow(), r_src.GetLow()); - OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + // Handle overlap + if (r_src.GetHighReg() == r_dest.GetLowReg()) { + OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + } else { + OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + } } } } diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index 6d3848841a..b8ab609f31 100644 --- a/compiler/dex/quick/mir_to_lir.cc +++ b/compiler/dex/quick/mir_to_lir.cc @@ -990,6 +990,9 @@ bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) { ResetRegPool(); if (cu_->disable_opt & (1 << kTrackLiveTemps)) { ClobberAllRegs(); + // Reset temp allocation to minimize differences when A/B testing. + reg_pool_->next_core_reg = 0; + reg_pool_->next_fp_reg = 0; } if (cu_->disable_opt & (1 << kSuppressLoads)) { diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 8d593ae664..2b6d78b35a 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -811,6 +811,8 @@ class Mir2Lir : public Backend { bool MethodBlockCodeGen(BasicBlock* bb); bool SpecialMIR2LIR(const InlineMethod& special); void MethodMIR2LIR(); + // Update LIR for verbose listings. + void UpdateLIROffsets(); /* * @brief Load the address of the dex method into the register. @@ -1050,7 +1052,7 @@ class Mir2Lir : public Backend { virtual LIR* OpMem(OpKind op, RegStorage r_base, int disp) = 0; virtual LIR* OpPcRelLoad(RegStorage reg, LIR* target) = 0; virtual LIR* OpReg(OpKind op, RegStorage r_dest_src) = 0; - virtual LIR* OpRegCopy(RegStorage r_dest, RegStorage r_src) = 0; + virtual void OpRegCopy(RegStorage r_dest, RegStorage r_src) = 0; virtual LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) = 0; virtual LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value) = 0; virtual LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) = 0; diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index fb61627c9e..760290cabe 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -232,7 +232,7 @@ class X86Mir2Lir FINAL : public Mir2Lir { LIR* OpMem(OpKind op, RegStorage r_base, int disp); LIR* OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); - LIR* OpRegCopy(RegStorage r_dest, RegStorage r_src); + void OpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src); LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value); LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset); diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index 5ba9709187..3bff4976bd 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -116,52 +116,55 @@ LIR* X86Mir2Lir::OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) { return res; } -LIR* X86Mir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) { - LIR *res = OpRegCopyNoInsert(r_dest, r_src); - AppendLIR(res); - return res; +void X86Mir2Lir::OpRegCopy(RegStorage r_dest, RegStorage r_src) { + if (r_dest != r_src) { + LIR *res = OpRegCopyNoInsert(r_dest, r_src); + AppendLIR(res); + } } void X86Mir2Lir::OpRegCopyWide(RegStorage r_dest, RegStorage r_src) { - // FIXME: handle k64BitSolo when we start using them. - DCHECK(r_dest.IsPair()); - DCHECK(r_src.IsPair()); - bool dest_fp = X86_FPREG(r_dest.GetLowReg()); - bool src_fp = X86_FPREG(r_src.GetLowReg()); - if (dest_fp) { - if (src_fp) { - // TODO: we ought to handle this case here - reserve OpRegCopy for 32-bit copies. - OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())), - RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg()))); - } else { - // TODO: Prevent this from happening in the code. The result is often - // unused or could have been loaded more easily from memory. - NewLIR2(kX86MovdxrRR, r_dest.GetLowReg(), r_src.GetLowReg()); - RegStorage r_tmp = AllocTempDouble(); - NewLIR2(kX86MovdxrRR, r_tmp.GetLowReg(), r_src.GetHighReg()); - NewLIR2(kX86PunpckldqRR, r_dest.GetLowReg(), r_tmp.GetLowReg()); - FreeTemp(r_tmp); - } - } else { - if (src_fp) { - NewLIR2(kX86MovdrxRR, r_dest.GetLowReg(), r_src.GetLowReg()); - NewLIR2(kX86PsrlqRI, r_src.GetLowReg(), 32); - NewLIR2(kX86MovdrxRR, r_dest.GetHighReg(), r_src.GetLowReg()); + if (r_dest != r_src) { + // FIXME: handle k64BitSolo when we start using them. + DCHECK(r_dest.IsPair()); + DCHECK(r_src.IsPair()); + bool dest_fp = X86_FPREG(r_dest.GetLowReg()); + bool src_fp = X86_FPREG(r_src.GetLowReg()); + if (dest_fp) { + if (src_fp) { + // TODO: we ought to handle this case here - reserve OpRegCopy for 32-bit copies. + OpRegCopy(RegStorage::Solo64(S2d(r_dest.GetLowReg(), r_dest.GetHighReg())), + RegStorage::Solo64(S2d(r_src.GetLowReg(), r_src.GetHighReg()))); + } else { + // TODO: Prevent this from happening in the code. The result is often + // unused or could have been loaded more easily from memory. + NewLIR2(kX86MovdxrRR, r_dest.GetLowReg(), r_src.GetLowReg()); + RegStorage r_tmp = AllocTempDouble(); + NewLIR2(kX86MovdxrRR, r_tmp.GetLowReg(), r_src.GetHighReg()); + NewLIR2(kX86PunpckldqRR, r_dest.GetLowReg(), r_tmp.GetLowReg()); + FreeTemp(r_tmp); + } } else { - // Handle overlap - if (r_src.GetHighReg() == r_dest.GetLowReg() && r_src.GetLowReg() == r_dest.GetHighReg()) { - // Deal with cycles. - RegStorage temp_reg = AllocTemp(); - OpRegCopy(temp_reg, r_dest.GetHigh()); - OpRegCopy(r_dest.GetHigh(), r_dest.GetLow()); - OpRegCopy(r_dest.GetLow(), temp_reg); - FreeTemp(temp_reg); - } else if (r_src.GetHighReg() == r_dest.GetLowReg()) { - OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); - OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + if (src_fp) { + NewLIR2(kX86MovdrxRR, r_dest.GetLowReg(), r_src.GetLowReg()); + NewLIR2(kX86PsrlqRI, r_src.GetLowReg(), 32); + NewLIR2(kX86MovdrxRR, r_dest.GetHighReg(), r_src.GetLowReg()); } else { - OpRegCopy(r_dest.GetLow(), r_src.GetLow()); - OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + // Handle overlap + if (r_src.GetHighReg() == r_dest.GetLowReg() && r_src.GetLowReg() == r_dest.GetHighReg()) { + // Deal with cycles. + RegStorage temp_reg = AllocTemp(); + OpRegCopy(temp_reg, r_dest.GetHigh()); + OpRegCopy(r_dest.GetHigh(), r_dest.GetLow()); + OpRegCopy(r_dest.GetLow(), temp_reg); + FreeTemp(temp_reg); + } else if (r_src.GetHighReg() == r_dest.GetLowReg()) { + OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + } else { + OpRegCopy(r_dest.GetLow(), r_src.GetLow()); + OpRegCopy(r_dest.GetHigh(), r_src.GetHigh()); + } } } } diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc index 00bebd2983..4d45055927 100644 --- a/compiler/dex/quick/x86/utility_x86.cc +++ b/compiler/dex/quick/x86/utility_x86.cc @@ -426,7 +426,8 @@ LIR* X86Mir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage t_reg = AllocTemp(); OpRegCopy(t_reg, r_src1); OpRegReg(op, t_reg, r_src2); - LIR* res = OpRegCopy(r_dest, t_reg); + LIR* res = OpRegCopyNoInsert(r_dest, t_reg); + AppendLIR(res); FreeTemp(t_reg); return res; } |