am 3d661949: Real fix for 064
* commit '3d661949dba4a2f3311e6f74a3c42b5addf1f534':
Real fix for 064
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index bd4c156..5750913 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -414,6 +414,14 @@
struct ArenaMemBlock* currentArena;
int numArenaBlocks;
struct Memstats* mstats;
+#ifndef NDEBUG
+ /*
+ * Sanity checking for the register temp tracking. The same ssa
+ * name should never be associated with one temp register per
+ * instruction compilation.
+ */
+ int liveSReg;
+#endif
};
enum OpSize {
diff --git a/src/compiler/SSATransformation.cc b/src/compiler/SSATransformation.cc
index bd5f83b..c5a6b8f 100644
--- a/src/compiler/SSATransformation.cc
+++ b/src/compiler/SSATransformation.cc
@@ -26,14 +26,22 @@
if (block->visited || block->hidden) return;
block->visited = true;
+ // Can this block be reached only via previous block fallthrough?
+ if ((block->blockType == kDalvikByteCode) &&
+ (block->predecessors->numUsed == 1)) {
+ DCHECK_GE(cUnit->dfsOrder.numUsed, 1U);
+ int prevIdx = cUnit->dfsOrder.numUsed - 1;
+ int prevId = cUnit->dfsOrder.elemList[prevIdx];
+ BasicBlock* predBB = (BasicBlock*)block->predecessors->elemList[0];
+ if (predBB->id == prevId) {
+ block->fallThroughTarget = true;
+ }
+ }
+
/* Enqueue the preOrder block id */
oatInsertGrowableList(cUnit, &cUnit->dfsOrder, block->id);
if (block->fallThrough) {
-#if 0
- // Temporary bug workaround
- block->fallThrough->fallThroughTarget = true;
-#endif
recordDFSOrders(cUnit, block->fallThrough);
}
if (block->taken) recordDFSOrders(cUnit, block->taken);
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index 5444816..eebaaf3 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -134,6 +134,16 @@
void storeValue(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
{
+#ifndef NDEBUG
+ /*
+ * Sanity checking - should never try to store to the same
+ * ssa name during the compilation of a single instruction
+ * without an intervening oatClobberSReg().
+ */
+ DCHECK((cUnit->liveSReg == INVALID_SREG) ||
+ (rlDest.sRegLow != cUnit->liveSReg));
+ cUnit->liveSReg = rlDest.sRegLow;
+#endif
LIR* defStart;
LIR* defEnd;
DCHECK(!rlDest.wide);
@@ -195,6 +205,16 @@
void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest,
RegLocation rlSrc)
{
+#ifndef NDEBUG
+ /*
+ * Sanity checking - should never try to store to the same
+ * ssa name during the compilation of a single instruction
+ * without an intervening oatClobberSReg().
+ */
+ DCHECK((cUnit->liveSReg == INVALID_SREG) ||
+ (rlDest.sRegLow != cUnit->liveSReg));
+ cUnit->liveSReg = rlDest.sRegLow;
+#endif
LIR* defStart;
LIR* defEnd;
DCHECK_EQ(FPREG(rlSrc.lowReg), FPREG(rlSrc.highReg));
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 1dc4a39..aee5b50 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -870,6 +870,11 @@
NULL);
// Resolved, store and hop over following code
storeValue(cUnit, rlDest, rlResult);
+ /*
+ * Because we have stores of the target value on two paths,
+ * clobber temp tracking for the destination using the ssa name
+ */
+ oatClobberSReg(cUnit, rlDest.sRegLow);
LIR* branch2 = opUnconditionalBranch(cUnit,0);
// TUNING: move slow path to end & remove unconditional branch
LIR* target1 = newLIR0(cUnit, kPseudoTargetLabel);
@@ -881,6 +886,11 @@
callRuntimeHelper(cUnit, rTgt);
RegLocation rlResult = oatGetReturn(cUnit, false);
storeValue(cUnit, rlDest, rlResult);
+ /*
+ * Because we have stores of the target value on two paths,
+ * clobber temp tracking for the destination using the ssa name
+ */
+ oatClobberSReg(cUnit, rlDest.sRegLow);
// Rejoin code paths
LIR* target2 = newLIR0(cUnit, kPseudoTargetLabel);
branch1->target = (LIR*)target1;
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 21a6613..eff4199 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -801,6 +801,11 @@
oatResetDefTracking(cUnit);
}
+#ifndef NDEBUG
+ /* Reset temp tracking sanity check */
+ cUnit->liveSReg = INVALID_SREG;
+#endif
+
if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
handleExtendedMethodMIR(cUnit, mir);
continue;
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index 8f5d1bb..d5f6720 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -141,6 +141,12 @@
/* Clobber any temp associated with an sReg. Could be in either class */
extern void oatClobberSReg(CompilationUnit* cUnit, int sReg)
{
+#ifndef NDEBUG
+ /* Reset live temp tracking sanity checker */
+ if (sReg == cUnit->liveSReg) {
+ cUnit->liveSReg = INVALID_SREG;
+ }
+#endif
clobberSRegBody(cUnit->regPool->coreRegs, cUnit->regPool->numCoreRegs,
sReg);
clobberSRegBody(cUnit->regPool->FPRegs, cUnit->regPool->numFPRegs,