Compiler constant handling rework
In preparation for de-optimization, reworked the constant
handling mechanism. Also took advantage of knowledge of
constant operands (particularly for long operations).
Significant performance improvements for Mandelbrot
(~60 seconds to ~34 seconds). Minor improvements in other
benchmarks.
The new constant handling breaks two of the existing
optimization passes: "Skip Large Method" and "Load/Store
Elimization."
I don't intend to update the large method optimization
because it will be superceeded by the upcoming interpreter/
fingerprinting mechanism. Leaving the code in place for
now in order to compare compile-time improvements with
fingerprinting/interpret. All related code will be deleted
when that is complete.
The load/store elimination pass needs some rework to handle
uses of multiple-register loads and stores. It will be
updated & restored in a future CL.
Change-Id: Ia979abaf51b8ae81bbb0428031cbcea854625fac
diff --git a/src/compiler/codegen/gen_loadstore.cc b/src/compiler/codegen/gen_loadstore.cc
index b183f9e..c8f9c51 100644
--- a/src/compiler/codegen/gen_loadstore.cc
+++ b/src/compiler/codegen/gen_loadstore.cc
@@ -59,12 +59,20 @@
return;
}
}
+ int temp_reg = zero_reg;
+ if (temp_reg == INVALID_REG) {
+ temp_reg = AllocTemp(cu);
+ cu->cg->LoadConstant(cu, temp_reg, 0);
+ }
if (cu->promotion_map[pmap_index].core_location == kLocPhysReg) {
// Promoted - just copy in a zero
- OpRegCopy(cu, cu->promotion_map[pmap_index].core_reg, zero_reg);
+ OpRegCopy(cu, cu->promotion_map[pmap_index].core_reg, temp_reg);
} else {
// Lives in the frame, need to store.
- StoreBaseDisp(cu, TargetReg(kSp), SRegOffset(cu, rl_dest.s_reg_low), zero_reg, kWord);
+ StoreBaseDisp(cu, TargetReg(kSp), SRegOffset(cu, rl_dest.s_reg_low), temp_reg, kWord);
+ }
+ if (zero_reg == INVALID_REG) {
+ FreeTemp(cu, temp_reg);
}
}
}
@@ -92,14 +100,12 @@
rl_src = UpdateLoc(cu, rl_src);
if (rl_src.location == kLocPhysReg) {
OpRegCopy(cu, r_dest, rl_src.low_reg);
+ } else if (IsInexpensiveConstant(cu, rl_src)) {
+ LoadConstantNoClobber(cu, r_dest, ConstantValue(cu, rl_src));
} else {
DCHECK((rl_src.location == kLocDalvikFrame) ||
(rl_src.location == kLocCompilerTemp));
- if (rl_src.is_const && InexpensiveConstant(r_dest, cu->constant_values[rl_src.orig_sreg])) {
- LoadConstantNoClobber(cu, r_dest, cu->constant_values[rl_src.orig_sreg]);
- } else {
- LoadWordDisp(cu, TargetReg(kSp), SRegOffset(cu, rl_src.s_reg_low), r_dest);
- }
+ LoadWordDisp(cu, TargetReg(kSp), SRegOffset(cu, rl_src.s_reg_low), r_dest);
}
}
@@ -126,6 +132,8 @@
rl_src = UpdateLocWide(cu, rl_src);
if (rl_src.location == kLocPhysReg) {
OpRegCopyWide(cu, reg_lo, reg_hi, rl_src.low_reg, rl_src.high_reg);
+ } else if (IsInexpensiveConstant(cu, rl_src)) {
+ LoadConstantWide(cu, reg_lo, reg_hi, ConstantValueWide(cu, rl_src));
} else {
DCHECK((rl_src.location == kLocDalvikFrame) ||
(rl_src.location == kLocCompilerTemp));
@@ -152,9 +160,7 @@
RegLocation Codegen::LoadValue(CompilationUnit* cu, RegLocation rl_src, RegisterClass op_kind)
{
rl_src = EvalLoc(cu, rl_src, op_kind, false);
- if (rl_src.location != kLocPhysReg) {
- DCHECK((rl_src.location == kLocDalvikFrame) ||
- (rl_src.location == kLocCompilerTemp));
+ if (IsInexpensiveConstant(cu, rl_src) || rl_src.location != kLocPhysReg) {
LoadValueDirect(cu, rl_src, rl_src.low_reg);
rl_src.location = kLocPhysReg;
MarkLive(cu, rl_src.low_reg, rl_src.s_reg_low);
@@ -222,14 +228,11 @@
{
DCHECK(rl_src.wide);
rl_src = EvalLoc(cu, rl_src, op_kind, false);
- if (rl_src.location != kLocPhysReg) {
- DCHECK((rl_src.location == kLocDalvikFrame) ||
- (rl_src.location == kLocCompilerTemp));
+ if (IsInexpensiveConstant(cu, rl_src) || rl_src.location != kLocPhysReg) {
LoadValueDirectWide(cu, rl_src, rl_src.low_reg, rl_src.high_reg);
rl_src.location = kLocPhysReg;
MarkLive(cu, rl_src.low_reg, rl_src.s_reg_low);
- MarkLive(cu, rl_src.high_reg,
- GetSRegHi(rl_src.s_reg_low));
+ MarkLive(cu, rl_src.high_reg, GetSRegHi(rl_src.s_reg_low));
}
return rl_src;
}