Revert "Revert "Revert "Revert "Use the object class as top in reference type propagation""""

This reverts commit b734808d0c93af98ec4e3539fdb0a8c0787263b0.

Change-Id: Ifd925f166761bcb9be2268ff0fc9fa3a72f00c6f
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index c185b58..d6b8aa4 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -109,10 +109,8 @@
     receiver = receiver->InputAt(0);
   }
   ReferenceTypeInfo info = receiver->GetReferenceTypeInfo();
-  if (info.IsTop()) {
-    // We have no information on the receiver.
-    return nullptr;
-  } else if (!info.IsExact()) {
+  DCHECK(info.IsValid()) << "Invalid RTI for " << receiver->DebugName();
+  if (!info.IsExact()) {
     // We currently only support inlining with known receivers.
     // TODO: Remove this check, we should be able to inline final methods
     // on unknown receivers.
@@ -273,11 +271,11 @@
   const DexFile::CodeItem* code_item = resolved_method->GetCodeItem();
   const DexFile& callee_dex_file = *resolved_method->GetDexFile();
   uint32_t method_index = resolved_method->GetDexMethodIndex();
-
+  ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker();
   DexCompilationUnit dex_compilation_unit(
     nullptr,
     caller_compilation_unit_.GetClassLoader(),
-    caller_compilation_unit_.GetClassLinker(),
+    class_linker,
     *resolved_method->GetDexFile(),
     code_item,
     resolved_method->GetDeclaringClass()->GetDexClassDefIndex(),
@@ -450,7 +448,33 @@
     }
   }
 
-  callee_graph->InlineInto(graph_, invoke_instruction);
+  HInstruction* return_replacement = callee_graph->InlineInto(graph_, invoke_instruction);
+
+  // 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 */));
+  }
+
+  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());
+      ReferenceTypeInfo::TypeHandle return_handle =
+        handles_->NewHandle(resolved_method->GetReturnType());
+      return_replacement->SetReferenceTypeInfo(ReferenceTypeInfo::Create(
+         return_handle, return_handle->IsFinal() /* is_exact */));
+    }
+  }
 
   return true;
 }