Local optimization fixes for diverences found by self verification.
1) Only optimize each block once. Strictly speaking this is not a
correctness issue however it triggers the subsequent problem.
2) Ignore dead instructions.
1: ldr r2, [r5, #8]
2: ldr r3, [r5, #8](nop)
3: str r3, [r5, #4]
4: movs r3, r2
When using instruction 1 to initiate redundant ld/st eliminations, if
instruction 2 (which is already dead) is not ignored, it will be turned
into a "mov r3, r2" and that will clobber r3 used by the str.
Change-Id: I6b9a88d3688889d917b90f4b8f55278df1701c6a
diff --git a/vm/compiler/codegen/arm/CodegenDriver.cpp b/vm/compiler/codegen/arm/CodegenDriver.cpp
index a722289..d170c8b 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.cpp
+++ b/vm/compiler/codegen/arm/CodegenDriver.cpp
@@ -4572,6 +4572,8 @@
*/
dvmCompilerApplyLocalOptimizations(cUnit, (LIR *) headLIR,
cUnit->lastLIRInsn);
+ /* Reset headLIR which is also the optimization boundary */
+ headLIR = NULL;
}
gen_fallthrough:
diff --git a/vm/compiler/codegen/arm/LocalOptimizations.cpp b/vm/compiler/codegen/arm/LocalOptimizations.cpp
index 4c0354a..ffeaa57 100644
--- a/vm/compiler/codegen/arm/LocalOptimizations.cpp
+++ b/vm/compiler/codegen/arm/LocalOptimizations.cpp
@@ -131,6 +131,12 @@
checkLIR != tailLIR;
checkLIR = NEXT_LIR(checkLIR)) {
+ /*
+ * Skip already dead instructions (whose dataflow information is
+ * outdated and misleading).
+ */
+ if (checkLIR->flags.isNop) continue;
+
u8 checkMemMask = (checkLIR->useMask | checkLIR->defMask) &
ENCODE_MEM;
u8 aliasCondition = thisMemMask & checkMemMask;
@@ -312,6 +318,10 @@
checkLIR != headLIR;
checkLIR = PREV_LIR(checkLIR)) {
+ /*
+ * Skip already dead instructions (whose dataflow information is
+ * outdated and misleading).
+ */
if (checkLIR->flags.isNop) continue;
u8 checkMemMask = checkLIR->defMask & ENCODE_MEM;