Fix null check elimination
The existing null check elimination mechanism suffered from the same
limitation as the SSA renaming: it took shortcuts that were valid in
a trace compilation world, but not in a method compilation world.
This CL replaces the old mechanism, and additionally takes advantage
of some the fact that "this" is always non-null, as are objects returned
from OP_NEW_* (thanks Ian!).
Two test cases added. The one for ensuring that unnecessary null checks
are elminated requires manual inspection. The other - that we don't
eliminate a necessary null check - is disabled until exceptions are working.
Change-Id: I2a9b72741f56617bf609e4d7c20244796c988f28
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index 34a333d..8012d7d 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -70,19 +70,14 @@
return branch;
}
-/*
- * Perform null-check on a register. sReg is the ssa register being checked,
- * and mReg is the machine register holding the actual value. If internal state
- * indicates that sReg has been checked before the check request is ignored.
- */
+/* Perform null-check on a register. */
static ArmLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
MIR* mir)
{
- if (oatIsBitSet(cUnit->regPool->nullCheckedRegs, sReg)) {
- /* This particular Dalvik register has been null-checked */
+ if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
+ mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
return NULL;
}
- oatSetBit(cUnit->regPool->nullCheckedRegs, sReg);
return genImmedCheck(cUnit, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
}