Inliner: make sure the returned value is in the outer graph.

The returned value may be a constant or a parameter value. If so, it
will be in the inlined entry_block and (before this CL) we would not
update its block or graph. This CL fixes this and makes sure that the
returned value belongs to the outer graph.

Change-Id: Ie296f0d5a320c33f39eb187df6d328371ccf6500
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index f3b5f08..e2aca30 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -495,6 +495,9 @@
   number_of_inlined_instructions_ += number_of_instructions;
 
   HInstruction* return_replacement = callee_graph->InlineInto(graph_, invoke_instruction);
+  if (return_replacement != nullptr) {
+    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
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index ed401b6..98c3096 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1591,7 +1591,6 @@
     // Replace the invoke with the return value of the inlined graph.
     if (last->IsReturn()) {
       return_value = last->InputAt(0);
-      invoke->ReplaceWith(return_value);
     } else {
       DCHECK(last->IsReturnVoid());
     }
@@ -1639,10 +1638,6 @@
       }
     }
 
-    if (return_value != nullptr) {
-      invoke->ReplaceWith(return_value);
-    }
-
     // Update the meta information surrounding blocks:
     // (1) the graph they are now in,
     // (2) the reverse post order of that graph,
@@ -1712,20 +1707,21 @@
   size_t parameter_index = 0;
   for (HInstructionIterator it(entry_block_->GetInstructions()); !it.Done(); it.Advance()) {
     HInstruction* current = it.Current();
+    HInstruction* replacement = nullptr;
     if (current->IsNullConstant()) {
-      current->ReplaceWith(outer_graph->GetNullConstant(current->GetDexPc()));
+      replacement = outer_graph->GetNullConstant(current->GetDexPc());
     } else if (current->IsIntConstant()) {
-      current->ReplaceWith(outer_graph->GetIntConstant(
-          current->AsIntConstant()->GetValue(), current->GetDexPc()));
+      replacement = outer_graph->GetIntConstant(
+          current->AsIntConstant()->GetValue(), current->GetDexPc());
     } else if (current->IsLongConstant()) {
-      current->ReplaceWith(outer_graph->GetLongConstant(
-          current->AsLongConstant()->GetValue(), current->GetDexPc()));
+      replacement = outer_graph->GetLongConstant(
+          current->AsLongConstant()->GetValue(), current->GetDexPc());
     } else if (current->IsFloatConstant()) {
-      current->ReplaceWith(outer_graph->GetFloatConstant(
-          current->AsFloatConstant()->GetValue(), current->GetDexPc()));
+      replacement = outer_graph->GetFloatConstant(
+          current->AsFloatConstant()->GetValue(), current->GetDexPc());
     } else if (current->IsDoubleConstant()) {
-      current->ReplaceWith(outer_graph->GetDoubleConstant(
-          current->AsDoubleConstant()->GetValue(), current->GetDexPc()));
+      replacement = outer_graph->GetDoubleConstant(
+          current->AsDoubleConstant()->GetValue(), current->GetDexPc());
     } else if (current->IsParameterValue()) {
       if (kIsDebugBuild
           && invoke->IsInvokeStaticOrDirect()
@@ -1735,13 +1731,25 @@
         size_t last_input_index = invoke->InputCount() - 1;
         DCHECK(parameter_index != last_input_index);
       }
-      current->ReplaceWith(invoke->InputAt(parameter_index++));
+      replacement = invoke->InputAt(parameter_index++);
     } else if (current->IsCurrentMethod()) {
-      current->ReplaceWith(outer_graph->GetCurrentMethod());
+      replacement = outer_graph->GetCurrentMethod();
     } else {
       DCHECK(current->IsGoto() || current->IsSuspendCheck());
       entry_block_->RemoveInstruction(current);
     }
+    if (replacement != nullptr) {
+      current->ReplaceWith(replacement);
+      // If the current is the return value then we need to update the latter.
+      if (current == return_value) {
+        DCHECK_EQ(entry_block_, return_value->GetBlock());
+        return_value = replacement;
+      }
+    }
+  }
+
+  if (return_value != nullptr) {
+    invoke->ReplaceWith(return_value);
   }
 
   // Finally remove the invoke from the caller.