ART: Refactor SsaBuilder for more precise typing info

This reverts commit 68289a531484d26214e09f1eadd9833531a3bc3c.

Now uses Primitive::Is64BitType instead of Primitive::ComponentSize
because it was incorrectly optimized by GCC.

Bug: 26208284
Bug: 24252151
Bug: 24252100
Bug: 22538329
Bug: 25786318

Change-Id: Ib39f3da2b92bc5be5d76f4240a77567d82c6bebe
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 9842137..0e50416 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -33,6 +33,7 @@
 #include "reference_type_propagation.h"
 #include "register_allocator.h"
 #include "sharpening.h"
+#include "ssa_builder.h"
 #include "ssa_phi_elimination.h"
 #include "scoped_thread_state_change.h"
 #include "thread.h"
@@ -526,7 +527,7 @@
     return false;
   }
 
-  if (!callee_graph->TryBuildingSsa()) {
+  if (callee_graph->TryBuildingSsa(handles_) != kBuildSsaSuccess) {
     VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
                    << " could not be transformed to SSA";
     return false;
@@ -561,14 +562,12 @@
   // Run simple optimizations on the graph.
   HDeadCodeElimination dce(callee_graph, stats_);
   HConstantFolding fold(callee_graph);
-  ReferenceTypePropagation type_propagation(callee_graph, handles_);
   HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_);
   InstructionSimplifier simplify(callee_graph, stats_);
   IntrinsicsRecognizer intrinsics(callee_graph, compiler_driver_);
 
   HOptimization* optimizations[] = {
     &intrinsics,
-    &type_propagation,
     &sharpening,
     &simplify,
     &fold,
@@ -689,42 +688,36 @@
     DCHECK_EQ(graph_, return_replacement->GetBlock()->GetGraph());
   }
 
-  // When merging the graph we might create a new NullConstant in the caller graph which does
-  // not have the chance to be typed. We assign the correct type here so that we can keep the
-  // assertion that every reference has a valid type. This also simplifies checks along the way.
-  HNullConstant* null_constant = graph_->GetNullConstant();
-  if (!null_constant->GetReferenceTypeInfo().IsValid()) {
-    ReferenceTypeInfo::TypeHandle obj_handle =
-        handles_->NewHandle(class_linker->GetClassRoot(ClassLinker::kJavaLangObject));
-    null_constant->SetReferenceTypeInfo(
-        ReferenceTypeInfo::Create(obj_handle, false /* is_exact */));
-  }
-
   // Check the integrity of reference types and run another type propagation if needed.
-  if ((return_replacement != nullptr)
-      && (return_replacement->GetType() == Primitive::kPrimNot)) {
-    if (!return_replacement->GetReferenceTypeInfo().IsValid()) {
-      // Make sure that we have a valid type for the return. We may get an invalid one when
-      // we inline invokes with multiple branches and create a Phi for the result.
-      // TODO: we could be more precise by merging the phi inputs but that requires
-      // some functionality from the reference type propagation.
-      DCHECK(return_replacement->IsPhi());
-      size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
-      ReferenceTypeInfo::TypeHandle return_handle =
-          handles_->NewHandle(resolved_method->GetReturnType(true /* resolve */, pointer_size));
-      return_replacement->SetReferenceTypeInfo(ReferenceTypeInfo::Create(
-         return_handle, return_handle->CannotBeAssignedFromOtherTypes() /* is_exact */));
-    }
+  if (return_replacement != nullptr) {
+    if (return_replacement->GetType() == Primitive::kPrimNot) {
+      if (!return_replacement->GetReferenceTypeInfo().IsValid()) {
+        // Make sure that we have a valid type for the return. We may get an invalid one when
+        // we inline invokes with multiple branches and create a Phi for the result.
+        // TODO: we could be more precise by merging the phi inputs but that requires
+        // some functionality from the reference type propagation.
+        DCHECK(return_replacement->IsPhi());
+        size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
+        ReferenceTypeInfo::TypeHandle return_handle =
+            handles_->NewHandle(resolved_method->GetReturnType(true /* resolve */, pointer_size));
+        return_replacement->SetReferenceTypeInfo(ReferenceTypeInfo::Create(
+            return_handle, return_handle->CannotBeAssignedFromOtherTypes() /* is_exact */));
+      }
 
-    if (do_rtp) {
-      // If the return type is a refinement of the declared type run the type propagation again.
-      ReferenceTypeInfo return_rti = return_replacement->GetReferenceTypeInfo();
-      ReferenceTypeInfo invoke_rti = invoke_instruction->GetReferenceTypeInfo();
-      if (invoke_rti.IsStrictSupertypeOf(return_rti)
-          || (return_rti.IsExact() && !invoke_rti.IsExact())
-          || !return_replacement->CanBeNull()) {
-        ReferenceTypePropagation rtp_fixup(graph_, handles_);
-        rtp_fixup.Run();
+      if (do_rtp) {
+        // If the return type is a refinement of the declared type run the type propagation again.
+        ReferenceTypeInfo return_rti = return_replacement->GetReferenceTypeInfo();
+        ReferenceTypeInfo invoke_rti = invoke_instruction->GetReferenceTypeInfo();
+        if (invoke_rti.IsStrictSupertypeOf(return_rti)
+            || (return_rti.IsExact() && !invoke_rti.IsExact())
+            || !return_replacement->CanBeNull()) {
+          ReferenceTypePropagation(graph_, handles_).Run();
+        }
+      }
+    } else if (return_replacement->IsInstanceOf()) {
+      if (do_rtp) {
+        // Inlining InstanceOf into an If may put a tighter bound on reference types.
+        ReferenceTypePropagation(graph_, handles_).Run();
       }
     }
   }