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/Dataflow.h b/src/compiler/Dataflow.h
index 235ad31..e4a3726 100644
--- a/src/compiler/Dataflow.h
+++ b/src/compiler/Dataflow.h
@@ -35,9 +35,15 @@
     kFormat35c,
     kFormat3rc,
     kPhi,
-    kNullNRangeCheck0,
-    kNullNRangeCheck1,
-    kNullNRangeCheck2,
+    kNullCheckSrc0,        // Null check of src[0]
+    kNullCheckSrc1,        // Null check of src[1]
+    kNullCheckOut0,        // Null check out outgoing arg0
+    kDstNonNull,           // May assume dst is non-null
+    kRetNonNull,           // May assume retval is non-null
+    kNullTransferSrc0,     // Object copy src[0] -> dst
+    kNullTransferSrcN,     // Phi null check state transfer
+    kRangeCheckSrc1,       // Range check of src[1]
+    kRangeCheckSrc2,       // Range check of src[2]
     kFPA,
     kFPB,
     kFPC,
@@ -60,9 +66,15 @@
 #define DF_FORMAT_35C           (1 << kFormat35c)
 #define DF_FORMAT_3RC           (1 << kFormat3rc)
 #define DF_PHI                  (1 << kPhi)
-#define DF_NULL_N_RANGE_CHECK_0 (1 << kNullNRangeCheck0)
-#define DF_NULL_N_RANGE_CHECK_1 (1 << kNullNRangeCheck1)
-#define DF_NULL_N_RANGE_CHECK_2 (1 << kNullNRangeCheck2)
+#define DF_NULL_CHK_0           (1 << kNullCheckSrc0)
+#define DF_NULL_CHK_1           (1 << kNullCheckSrc1)
+#define DF_NULL_CHK_OUT0        (1 << kNullCheckOut0)
+#define DF_NON_NULL_DST         (1 << kDstNonNull)
+#define DF_NON_NULL_RET         (1 << kRetNonNull)
+#define DF_NULL_TRANSFER_0      (1 << kNullTransferSrc0)
+#define DF_NULL_TRANSFER_N      (1 << kNullTransferSrcN)
+#define DF_RANGE_CHK_1          (1 << kRangeCheckSrc1)
+#define DF_RANGE_CHK_2          (1 << kRangeCheckSrc2)
 #define DF_FP_A                 (1 << kFPA)
 #define DF_FP_B                 (1 << kFPB)
 #define DF_FP_C                 (1 << kFPC)
@@ -74,9 +86,13 @@
 
 #define DF_HAS_DEFS             (DF_DA | DF_DA_WIDE)
 
-#define DF_HAS_NR_CHECKS        (DF_NULL_N_RANGE_CHECK_0 | \
-                                 DF_NULL_N_RANGE_CHECK_1 | \
-                                 DF_NULL_N_RANGE_CHECK_2)
+#define DF_HAS_NULL_CHKS        (DF_NULL_CHK_0 | \
+                                 DF_NULL_CHK_1 | \
+                                 DF_NULL_CHK_OUT0)
+
+#define DF_HAS_NR_CHKS          (DF_HAS_NULL_CHKS | \
+                                 DF_RANGE_CHK_1 | \
+                                 DF_RANGE_CHK_2)
 
 #define DF_A_IS_REG             (DF_UA | DF_UA_WIDE | DF_DA | DF_DA_WIDE)
 #define DF_B_IS_REG             (DF_UB | DF_UB_WIDE)
@@ -91,6 +107,7 @@
     ArenaBitVector* liveInV;
     ArenaBitVector* phiV;
     int* dalvikToSSAMap;
+    ArenaBitVector* endingNullCheckV;
 } BasicBlockDataFlow;
 
 typedef struct SSARepresentation {
@@ -125,4 +142,7 @@
 #define DECODE_REG(v)                   (v & 0xffff)
 #define DECODE_SUB(v)                   (((unsigned int) v) >> 16)
 
+
+void oatMethodNullCheckElimination(CompilationUnit*);
+
 #endif  // ART_SRC_COMPILER_DATAFLOW_H_