Fix branch bug (showed up in codegen for debug)
There are a few "safe" optimizations in the compiler - removing
register copies where source and target are the same, deleting
branches to the next instruction, etc. One of the redundant
branch optimizations, however, was incorrect and resulted in
a good branch being deleted. This one showed up in the debug
build, and resulted in a failure to do a suspend check (because
the branch to the suspend check was deleted).
I had hoped that this but might also be the case of some
other unexpected failures, but unfortunately I was only able
to trigger it when doing a "codegen for debug" build.
The source of the bug was a confusion around 16 v/ 32-bit
unconditional branch encodings. For a 32-bit unconditional
branch, going to the next instruction means an displacement
of zero. However, for 16-bit branches, the next instruction
is represented by a displacement of -1.
To help track down this sort of thing in the future, this CL
also adds a new optimization disable flag: kSafeOptimizations.
This will allow us to really turn off all optimizations for A/B
testing.
Also in this CL we are re-enabling the ability to promote argument
registers and improving somewhat the code sequence for suspend
check when debug is enabled.
Change-Id: Ib6b202746eac751cab3b4609805a389c18cb67b2
diff --git a/src/compiler/codegen/mips/Codegen.h b/src/compiler/codegen/mips/Codegen.h
index 520d638..ca4e712 100644
--- a/src/compiler/codegen/mips/Codegen.h
+++ b/src/compiler/codegen/mips/Codegen.h
@@ -53,7 +53,6 @@
int loadHelper(CompilationUnit* cUnit, int offset);
LIR* callRuntimeHelper(CompilationUnit* cUnit, int reg);
-RegLocation getRetLoc(CompilationUnit* cUnit);
LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal);
void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
int srcLo, int srcHi);
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc
index ecc0180..360fbb7 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/Mips32/Factory.cc
@@ -74,7 +74,7 @@
}
}
LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rSrc, rDest);
- if (rDest == rSrc) {
+ if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
res->flags.isNop = true;
}
return res;
diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
index 2bb2f7a..e86a942 100644
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ b/src/compiler/codegen/mips/Mips32/Gen.cc
@@ -450,7 +450,7 @@
#endif
LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kMipsMove,
rDest, rSrc);
- if (rDest == rSrc) {
+ if (!(cUnit->disableOpt && (1 << kSafeOptimizations)) && rDest == rSrc) {
res->flags.isNop = true;
}
return res;
diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc
index 3cad4d9..22a19db 100644
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ b/src/compiler/codegen/mips/MipsRallocUtil.cc
@@ -140,17 +140,6 @@
oatClobber(cUnit, r_F15);
}
-extern RegLocation oatGetReturnWide(CompilationUnit* cUnit)
-{
- RegLocation res = LOC_C_RETURN_WIDE;
- oatClobber(cUnit, res.lowReg);
- oatClobber(cUnit, res.highReg);
- oatMarkInUse(cUnit, res.lowReg);
- oatMarkInUse(cUnit, res.highReg);
- oatMarkPair(cUnit, res.lowReg, res.highReg);
- return res;
-}
-
extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
{
RegLocation res = LOC_C_RETURN_WIDE_ALT;
@@ -170,14 +159,6 @@
return res;
}
-extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
-{
- RegLocation res = LOC_C_RETURN_ALT;
- oatClobber(cUnit, res.lowReg);
- oatMarkInUse(cUnit, res.lowReg);
- return res;
-}
-
extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
{
return FPREG(reg) ? &cUnit->regPool->FPRegs[reg & FP_REG_MASK]