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/Frontend.cc b/src/compiler/Frontend.cc
index c419f1a..086c0bb 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -619,6 +619,7 @@
BasicBlock *catchBlock = findBlock(cUnit, iterator.Get().address_,
false /* split*/,
false /* creat */);
+ catchBlock->catchEntry = true;
SuccessorBlockInfo *successorBlockInfo =
(SuccessorBlockInfo *) oatNew(sizeof(SuccessorBlockInfo),
false);
@@ -702,6 +703,7 @@
(1 << kLoadStoreElimination) |
(1 << kLoadHoisting) |
(1 << kSuppressLoads) |
+ (1 << kNullCheckElimination) |
(1 << kPromoteRegs) |
0;
#endif
@@ -841,6 +843,9 @@
/* Perform SSA transformation for the whole method */
oatMethodSSATransformation(&cUnit);
+ /* Perform null check elimination */
+ oatMethodNullCheckElimination(&cUnit);
+
oatInitializeRegAlloc(&cUnit); // Needs to happen after SSA naming
/* Allocate Registers using simple local allocation scheme */