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/code_generator.cc b/compiler/optimizing/code_generator.cc
index 01fc23b..56342aa 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -26,9 +26,11 @@
 namespace art {
 
 void CodeGenerator::Compile(CodeAllocator* allocator) {
-  GenerateFrameEntry();
   const GrowableArray<HBasicBlock*>* blocks = graph()->blocks();
-  for (size_t i = 0; i < blocks->Size(); i++) {
+  DCHECK(blocks->Get(0) == graph()->entry_block());
+  DCHECK(GoesToNextBlock(graph()->entry_block(), blocks->Get(1)));
+  CompileEntryBlock();
+  for (size_t i = 1; i < blocks->Size(); i++) {
     CompileBlock(blocks->Get(i));
   }
   size_t code_size = assembler_->CodeSize();
@@ -37,17 +39,54 @@
   assembler_->FinalizeInstructions(code);
 }
 
+void CodeGenerator::CompileEntryBlock() {
+  HGraphVisitor* location_builder = GetLocationBuilder();
+  // The entry block contains all locals for this method. By visiting the entry block,
+  // we're computing the required frame size.
+  for (HInstructionIterator it(graph()->entry_block()); !it.Done(); it.Advance()) {
+    HInstruction* current = it.Current();
+    // Instructions in the entry block should not generate code.
+    if (kIsDebugBuild) {
+      current->Accept(location_builder);
+      DCHECK(current->locations() == nullptr);
+    }
+    current->Accept(this);
+  }
+  GenerateFrameEntry();
+}
+
 void CodeGenerator::CompileBlock(HBasicBlock* block) {
   Bind(GetLabelOf(block));
+  HGraphVisitor* location_builder = GetLocationBuilder();
   for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
-    it.Current()->Accept(this);
+    // For each instruction, we emulate a stack-based machine, where the inputs are popped from
+    // the runtime stack, and the result is pushed on the stack. We currently can do this because
+    // we do not perform any code motion, and the Dex format does not reference individual
+    // instructions but uses registers instead (our equivalent of HLocal).
+    HInstruction* current = it.Current();
+    current->Accept(location_builder);
+    InitLocations(current);
+    current->Accept(this);
+    if (current->locations() != nullptr && current->locations()->Out().IsValid()) {
+      Push(current, current->locations()->Out());
+    }
   }
 }
 
-bool CodeGenerator::GoesToNextBlock(HGoto* goto_instruction) const {
-  HBasicBlock* successor = goto_instruction->GetSuccessor();
+void CodeGenerator::InitLocations(HInstruction* instruction) {
+  if (instruction->locations() == nullptr) return;
+  for (int i = 0; i < instruction->InputCount(); i++) {
+    Location location = instruction->locations()->InAt(i);
+    if (location.IsValid()) {
+      // Move the input to the desired location.
+      Move(instruction->InputAt(i), location);
+    }
+  }
+}
+
+bool CodeGenerator::GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const {
   // We currently iterate over the block in insertion order.
-  return goto_instruction->block()->block_id() + 1 == successor->block_id();
+  return current->block_id() + 1 == next->block_id();
 }
 
 Label* CodeGenerator::GetLabelOf(HBasicBlock* block) const {