Optimizations around escape analysis. With tests.

Details:
(1) added new intrinsics
(2) implemented optimizations
      more !can be null information
      more null check removals
      replace return-this uses with incoming parameter
      remove dead StringBuffer/Builder calls (with escape analysis)
(3) Fixed exposed bug in CanBeMoved()

Performance gain:
This improves CafeineString by about 360%
(removes null check from first loop, eliminates second loop completely)

Test: test-art-host

Change-Id: Iaf16a1b9cab6a7386f43d71c6b51dd59600e81c1
diff --git a/compiler/optimizing/escape.cc b/compiler/optimizing/escape.cc
index c80e19e..9df5bf1 100644
--- a/compiler/optimizing/escape.cc
+++ b/compiler/optimizing/escape.cc
@@ -23,16 +23,19 @@
 void CalculateEscape(HInstruction* reference,
                      bool (*no_escape)(HInstruction*, HInstruction*),
                      /*out*/ bool* is_singleton,
-                     /*out*/ bool* is_singleton_and_non_escaping) {
+                     /*out*/ bool* is_singleton_and_not_returned,
+                     /*out*/ bool* is_singleton_and_not_deopt_visible) {
   // For references not allocated in the method, don't assume anything.
   if (!reference->IsNewInstance() && !reference->IsNewArray()) {
     *is_singleton = false;
-    *is_singleton_and_non_escaping = false;
+    *is_singleton_and_not_returned = false;
+    *is_singleton_and_not_deopt_visible = false;
     return;
   }
   // Assume the best until proven otherwise.
   *is_singleton = true;
-  *is_singleton_and_non_escaping = true;
+  *is_singleton_and_not_returned = true;
+  *is_singleton_and_not_deopt_visible = true;
   // Visit all uses to determine if this reference can escape into the heap,
   // a method call, an alias, etc.
   for (const HUseListNode<HInstruction*>& use : reference->GetUses()) {
@@ -45,7 +48,8 @@
       // for the uncommon cases. Similarly, null checks are eventually eliminated for explicit
       // allocations, but if we see one before it is simplified, assume an alias.
       *is_singleton = false;
-      *is_singleton_and_non_escaping = false;
+      *is_singleton_and_not_returned = false;
+      *is_singleton_and_not_deopt_visible = false;
       return;
     } else if (user->IsPhi() || user->IsSelect() || user->IsInvoke() ||
                (user->IsInstanceFieldSet() && (reference == user->InputAt(1))) ||
@@ -56,7 +60,8 @@
       // The reference is merged to HPhi/HSelect, passed to a callee, or stored to heap.
       // Hence, the reference is no longer the only name that can refer to its value.
       *is_singleton = false;
-      *is_singleton_and_non_escaping = false;
+      *is_singleton_and_not_returned = false;
+      *is_singleton_and_not_deopt_visible = false;
       return;
     } else if ((user->IsUnresolvedInstanceFieldGet() && (reference == user->InputAt(0))) ||
                (user->IsUnresolvedInstanceFieldSet() && (reference == user->InputAt(0)))) {
@@ -64,37 +69,35 @@
       // Note that we could optimize this case and still perform some optimizations until
       // we hit the unresolved access, but the conservative assumption is the simplest.
       *is_singleton = false;
-      *is_singleton_and_non_escaping = false;
+      *is_singleton_and_not_returned = false;
+      *is_singleton_and_not_deopt_visible = false;
       return;
     } else if (user->IsReturn()) {
-      *is_singleton_and_non_escaping = false;
+      *is_singleton_and_not_returned = false;
     }
   }
 
-  // Need for further analysis?
-  if (!*is_singleton_and_non_escaping) {
-    return;
-  }
-
-  // Look at the environment uses and if it's for HDeoptimize, it's treated the
-  // same as a return which escapes at the end of executing the compiled code.
-  // Other environment uses are fine, as long as all client optimizations that
-  // rely on this informations are disabled for debuggable.
+  // Look at the environment uses if it's for HDeoptimize. Other environment uses are fine,
+  // as long as client optimizations that rely on this information are disabled for debuggable.
   for (const HUseListNode<HEnvironment*>& use : reference->GetEnvUses()) {
     HEnvironment* user = use.GetUser();
     if (user->GetHolder()->IsDeoptimize()) {
-      *is_singleton_and_non_escaping = false;
+      *is_singleton_and_not_deopt_visible = false;
       break;
     }
   }
 }
 
-bool IsNonEscapingSingleton(HInstruction* reference,
-                            bool (*no_escape)(HInstruction*, HInstruction*)) {
-  bool is_singleton = true;
-  bool is_singleton_and_non_escaping = true;
-  CalculateEscape(reference, no_escape, &is_singleton, &is_singleton_and_non_escaping);
-  return is_singleton_and_non_escaping;
+bool DoesNotEscape(HInstruction* reference, bool (*no_escape)(HInstruction*, HInstruction*)) {
+  bool is_singleton = false;
+  bool is_singleton_and_not_returned = false;
+  bool is_singleton_and_not_deopt_visible = false;  // not relevant for escape
+  CalculateEscape(reference,
+                  no_escape,
+                  &is_singleton,
+                  &is_singleton_and_not_returned,
+                  &is_singleton_and_not_deopt_visible);
+  return is_singleton_and_not_returned;
 }
 
 }  // namespace art