Fix longstanding bug around implicit NPEs and GC, version 2.

The TODO has been there since M (so forever :)):
https://android-review.googlesource.com/c/platform/art/+/122794/13//COMMIT_MSG#13

We hardly see the issue in our tests as we need to have:
1) A GC happening while creating the NPE object.
2) ParallelMoves between the NullCheck and implicit null check operation
   that moves references.

The CL piggy backs on the "IsEmittedAtUseSite" flag, to set implicit
null checks with it. The liveness analysis then special cases implicit
null checks to record environment uses at the location of the actual
instruction that will do the implicit null check.

Test: test.py --gcstress
Test: run-libcore-tests --gcstress
bug: 111545159
Change-Id: I3ecea4fe0d7e483e93db83281ca10db47da228c5
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 8b9e1da..d88b036 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2079,6 +2079,19 @@
     return false;
   }
 
+  // If this instruction will do an implicit null check, return the `HNullCheck` associated
+  // with it. Otherwise return null.
+  HNullCheck* GetImplicitNullCheck() const {
+    // Find the first previous instruction which is not a move.
+    HInstruction* first_prev_not_move = GetPreviousDisregardingMoves();
+    if (first_prev_not_move != nullptr &&
+        first_prev_not_move->IsNullCheck() &&
+        first_prev_not_move->IsEmittedAtUseSite()) {
+      return first_prev_not_move->AsNullCheck();
+    }
+    return nullptr;
+  }
+
   virtual bool IsActualObject() const {
     return GetType() == DataType::Type::kReference;
   }
@@ -4713,7 +4726,7 @@
 
   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
     // TODO: Add implicit null checks in intrinsics.
-    return (obj == InputAt(0)) && !GetLocations()->Intrinsified();
+    return (obj == InputAt(0)) && !IsIntrinsic();
   }
 
   uint32_t GetVTableIndex() const { return vtable_index_; }
@@ -4753,7 +4766,7 @@
 
   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
     // TODO: Add implicit null checks in intrinsics.
-    return (obj == InputAt(0)) && !GetLocations()->Intrinsified();
+    return (obj == InputAt(0)) && !IsIntrinsic();
   }
 
   bool NeedsDexCacheOfDeclaringClass() const OVERRIDE {