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/nodes.h b/compiler/optimizing/nodes.h
index bb08bd0..9418599 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -27,6 +27,7 @@
 class HInstruction;
 class HIntConstant;
 class HGraphVisitor;
+class LocationSummary;
 
 static const int kDefaultNumberOfBlocks = 8;
 static const int kDefaultNumberOfSuccessors = 2;
@@ -186,12 +187,18 @@
   M(IntConstant)                                           \
   M(LoadLocal)                                             \
   M(Local)                                                 \
+  M(Return)                                                \
   M(ReturnVoid)                                            \
   M(StoreLocal)                                            \
 
+#define FORWARD_DECLARATION(type) class H##type;
+FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
+#undef FORWARD_DECLARATION
+
 #define DECLARE_INSTRUCTION(type)                          \
   virtual void Accept(HGraphVisitor* visitor);             \
   virtual const char* DebugName() const { return #type; }  \
+  virtual H##type* As##type() { return this; }             \
 
 class HUseListNode : public ArenaObject {
  public:
@@ -210,7 +217,14 @@
 
 class HInstruction : public ArenaObject {
  public:
-  HInstruction() : previous_(nullptr), next_(nullptr), block_(nullptr), id_(-1), uses_(nullptr) { }
+  HInstruction()
+      : previous_(nullptr),
+        next_(nullptr),
+        block_(nullptr),
+        id_(-1),
+        uses_(nullptr),
+        locations_(nullptr) { }
+
   virtual ~HInstruction() { }
 
   HInstruction* next() const { return next_; }
@@ -236,6 +250,15 @@
   int id() const { return id_; }
   void set_id(int id) { id_ = id; }
 
+  LocationSummary* locations() const { return locations_; }
+  void set_locations(LocationSummary* locations) { locations_ = locations; }
+
+#define INSTRUCTION_TYPE_CHECK(type)                                           \
+  virtual H##type* As##type() { return nullptr; }
+
+  FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
+#undef INSTRUCTION_TYPE_CHECK
+
  private:
   HInstruction* previous_;
   HInstruction* next_;
@@ -248,6 +271,9 @@
 
   HUseListNode* uses_;
 
+  // Set by the code generator.
+  LocationSummary* locations_;
+
   friend class HBasicBlock;
 
   DISALLOW_COPY_AND_ASSIGN(HInstruction);
@@ -386,6 +412,20 @@
   DISALLOW_COPY_AND_ASSIGN(HReturnVoid);
 };
 
+// Represents dex's RETURN opcodes. A HReturn is a control flow
+// instruction that branches to the exit block.
+class HReturn : public HTemplateInstruction<1> {
+ public:
+  explicit HReturn(HInstruction* value) {
+    SetRawInputAt(0, value);
+  }
+
+  DECLARE_INSTRUCTION(Return)
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HReturn);
+};
+
 // The exit instruction is the only instruction of the exit block.
 // Instructions aborting the method (HTrow and HReturn) must branch to the
 // exit block.
@@ -422,6 +462,14 @@
     SetRawInputAt(0, input);
   }
 
+  HBasicBlock* IfTrueSuccessor() const {
+    return block()->successors()->Get(0);
+  }
+
+  HBasicBlock* IfFalseSuccessor() const {
+    return block()->successors()->Get(1);
+  }
+
   DECLARE_INSTRUCTION(If)
 
  private:
@@ -449,9 +497,11 @@
 
   DECLARE_INSTRUCTION(Local)
 
+  uint16_t reg_number() const { return reg_number_; }
+
  private:
-  // The register number in Dex.
-  uint16_t reg_number_;
+  // The Dex register number.
+  const uint16_t reg_number_;
 
   DISALLOW_COPY_AND_ASSIGN(HLocal);
 };
@@ -463,6 +513,8 @@
     SetRawInputAt(0, local);
   }
 
+  HLocal* GetLocal() const { return reinterpret_cast<HLocal*>(InputAt(0)); }
+
   DECLARE_INSTRUCTION(LoadLocal)
 
  private:
@@ -478,6 +530,8 @@
     SetRawInputAt(1, value);
   }
 
+  HLocal* GetLocal() const { return reinterpret_cast<HLocal*>(InputAt(0)); }
+
   DECLARE_INSTRUCTION(StoreLocal)
 
  private:
@@ -490,6 +544,8 @@
  public:
   explicit HIntConstant(int32_t value) : value_(value) { }
 
+  int32_t value() const { return value_; }
+
   DECLARE_INSTRUCTION(IntConstant)
 
  private: