Implement LICM in optimizing compiler.

Change-Id: I9c8afb0a58ef45e568576015473cbfd5f011c242
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index fe9ce74..5fd75f6 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -707,7 +707,7 @@
   return os;
 }
 
-void HInstruction::InsertBefore(HInstruction* cursor) {
+void HInstruction::MoveBefore(HInstruction* cursor) {
   next_->previous_ = previous_;
   if (previous_ != nullptr) {
     previous_->next_ = next_;
@@ -715,6 +715,7 @@
   if (block_->instructions_.first_instruction_ == this) {
     block_->instructions_.first_instruction_ = next_;
   }
+  DCHECK_NE(block_->instructions_.last_instruction_, this);
 
   previous_ = cursor->previous_;
   if (previous_ != nullptr) {
@@ -723,6 +724,10 @@
   next_ = cursor;
   cursor->previous_ = this;
   block_ = cursor->block_;
+
+  if (block_->instructions_.first_instruction_ == cursor) {
+    block_->instructions_.first_instruction_ = this;
+  }
 }
 
 void HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
@@ -737,7 +742,7 @@
   for (HInstructionIterator it(entry_block_->GetInstructions()); !it.Done(); it.Advance()) {
     HInstruction* current = it.Current();
     if (current->IsConstant()) {
-      current->InsertBefore(outer_graph->GetEntryBlock()->GetLastInstruction());
+      current->MoveBefore(outer_graph->GetEntryBlock()->GetLastInstruction());
     } else if (current->IsParameterValue()) {
       current->ReplaceWith(invoke->InputAt(parameter_index++));
     } else {