More code generation for the optimizing compiler.

- Add HReturn instruction
- Generate code for locals/if/return
- Setup infrastructure for register allocation. Currently
  emulate a stack.

Change-Id: Ib28c2dba80f6c526177ed9a7b09c0689ac8122fb
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 190c925..8c6a8cb 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -28,19 +28,25 @@
   for (int i = 0; i < count; i++) {
     HLocal* local = new (arena_) HLocal(i);
     entry_block_->AddInstruction(local);
-    locals_.Put(0, local);
+    locals_.Put(i, local);
   }
 }
 
 static bool CanHandleCodeItem(const DexFile::CodeItem& code_item) {
-  if (code_item.tries_size_ > 0) return false;
-  if (code_item.outs_size_ > 0) return false;
-  if (code_item.ins_size_ > 0) return false;
+  if (code_item.tries_size_ > 0) {
+    return false;
+  } else if (code_item.outs_size_ > 0) {
+    return false;
+  } else if (code_item.ins_size_ > 0) {
+    return false;
+  }
   return true;
 }
 
 HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
-  if (!CanHandleCodeItem(code_item)) return nullptr;
+  if (!CanHandleCodeItem(code_item)) {
+    return nullptr;
+  }
 
   const uint16_t* code_ptr = code_item.insns_;
   const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_;
@@ -78,7 +84,9 @@
 
 void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) {
   HBasicBlock* block = FindBlockStartingAt(index);
-  if (block == nullptr) return;
+  if (block == nullptr) {
+    return;
+  }
 
   if (current_block_ != nullptr) {
     // Branching instructions clear current_block, so we know
@@ -131,7 +139,9 @@
 }
 
 bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_t dex_offset) {
-  if (current_block_ == nullptr) return true;  // Dead code
+  if (current_block_ == nullptr) {
+    return true;  // Dead code
+  }
 
   switch (instruction.Opcode()) {
     case Instruction::CONST_4: {
@@ -140,11 +150,14 @@
       UpdateLocal(register_index, constant);
       break;
     }
-    case Instruction::RETURN_VOID:
+
+    case Instruction::RETURN_VOID: {
       current_block_->AddInstruction(new (arena_) HReturnVoid());
       current_block_->AddSuccessor(exit_block_);
       current_block_ = nullptr;
       break;
+    }
+
     case Instruction::IF_EQ: {
       HInstruction* first = LoadLocal(instruction.VRegA());
       HInstruction* second = LoadLocal(instruction.VRegB());
@@ -159,6 +172,7 @@
       current_block_ = nullptr;
       break;
     }
+
     case Instruction::GOTO:
     case Instruction::GOTO_16:
     case Instruction::GOTO_32: {
@@ -169,8 +183,18 @@
       current_block_ = nullptr;
       break;
     }
+
+    case Instruction::RETURN: {
+      HInstruction* value = LoadLocal(instruction.VRegA());
+      current_block_->AddInstruction(new (arena_) HReturn(value));
+      current_block_->AddSuccessor(exit_block_);
+      current_block_ = nullptr;
+      break;
+    }
+
     case Instruction::NOP:
       break;
+
     default:
       return false;
   }
@@ -178,15 +202,27 @@
 }
 
 HIntConstant* HGraphBuilder::GetConstant0() {
-  if (constant0_ != nullptr) return constant0_;
-  HIntConstant* constant = new(arena_) HIntConstant(0);
-  entry_block_->AddInstruction(constant);
-  return constant;
+  if (constant0_ != nullptr) {
+    return constant0_;
+  }
+  constant0_ = new(arena_) HIntConstant(0);
+  entry_block_->AddInstruction(constant0_);
+  return constant0_;
+}
+
+HIntConstant* HGraphBuilder::GetConstant1() {
+  if (constant1_ != nullptr) {
+    return constant1_;
+  }
+  constant1_ = new(arena_) HIntConstant(1);
+  entry_block_->AddInstruction(constant1_);
+  return constant1_;
 }
 
 HIntConstant* HGraphBuilder::GetConstant(int constant) {
   switch (constant) {
     case 0: return GetConstant0();
+    case 1: return GetConstant1();
     default: {
       HIntConstant* instruction = new (arena_) HIntConstant(constant);
       entry_block_->AddInstruction(instruction);