Runtime support for the new stack maps for the opt compiler.

Now most of the methods supported by the compiler can be optimized,
instead of using the baseline.

Change-Id: I80ab36a34913fa4e7dd576c7bf55af63594dc1fa
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 83035b5..33b1f1f 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -47,7 +47,7 @@
 };
 
 /**
- * A live range contains the start and end of a range where an instruction
+ * A live range contains the start and end of a range where an instruction or a temporary
  * is live.
  */
 class LiveRange : public ArenaObject {
@@ -76,7 +76,7 @@
 
  private:
   size_t start_;
-  size_t end_;
+  const size_t end_;
   LiveRange* next_;
 
   friend class LiveInterval;
@@ -133,7 +133,12 @@
  */
 class LiveInterval : public ArenaObject {
  public:
-  LiveInterval(ArenaAllocator* allocator, Primitive::Type type, HInstruction* defined_by = nullptr)
+  LiveInterval(ArenaAllocator* allocator,
+               Primitive::Type type,
+               HInstruction* defined_by = nullptr,
+               bool is_fixed = false,
+               int reg = kNoRegister,
+               bool is_temp = false)
       : allocator_(allocator),
         first_range_(nullptr),
         last_range_(nullptr),
@@ -141,16 +146,20 @@
         type_(type),
         next_sibling_(nullptr),
         parent_(this),
-        register_(kNoRegister),
+        register_(reg),
         spill_slot_(kNoSpillSlot),
-        is_fixed_(false),
+        is_fixed_(is_fixed),
+        is_temp_(is_temp),
         defined_by_(defined_by) {}
 
   static LiveInterval* MakeFixedInterval(ArenaAllocator* allocator, int reg, Primitive::Type type) {
-    LiveInterval* interval = new (allocator) LiveInterval(allocator, type);
-    interval->SetRegister(reg);
-    interval->is_fixed_ = true;
-    return interval;
+    return new (allocator) LiveInterval(allocator, type, nullptr, true, reg, false);
+  }
+
+  static LiveInterval* MakeTempInterval(ArenaAllocator* allocator,
+                                        HInstruction* defined_by,
+                                        Primitive::Type type) {
+    return new (allocator) LiveInterval(allocator, type, defined_by, false, kNoRegister, true);
   }
 
   bool IsFixed() const { return is_fixed_; }
@@ -192,8 +201,10 @@
     } else if (first_range_->GetStart() == end) {
       // There is a use in the following block.
       first_range_->start_ = start;
+    } else if (first_range_->GetStart() == start && first_range_->GetEnd() == end) {
+      DCHECK(is_fixed_);
     } else {
-      DCHECK(first_range_->GetStart() > end);
+      DCHECK_GT(first_range_->GetStart(), end);
       // There is a hole in the interval. Create a new range.
       first_range_ = new (allocator_) LiveRange(start, end, first_range_);
     }
@@ -215,7 +226,11 @@
   }
 
   bool HasSpillSlot() const { return spill_slot_ != kNoSpillSlot; }
-  void SetSpillSlot(int slot) { spill_slot_ = slot; }
+  void SetSpillSlot(int slot) {
+    DCHECK(!is_fixed_);
+    DCHECK(!is_temp_);
+    spill_slot_ = slot;
+  }
   int GetSpillSlot() const { return spill_slot_; }
 
   void SetFrom(size_t from) {
@@ -243,6 +258,9 @@
   }
 
   bool Covers(size_t position) const {
+    if (IsDeadAt(position)) {
+      return false;
+    }
     LiveRange* current = first_range_;
     while (current != nullptr) {
       if (position >= current->GetStart() && position < current->GetEnd()) {
@@ -288,6 +306,9 @@
   }
 
   size_t FirstRegisterUseAfter(size_t position) const {
+    if (is_temp_) {
+      return position == GetStart() ? position : kNoLifetime;
+    }
     if (position == GetStart() && defined_by_ != nullptr) {
       LocationSummary* locations = defined_by_->GetLocations();
       Location location = locations->Out();
@@ -342,6 +363,7 @@
    * [position ... end)
    */
   LiveInterval* SplitAt(size_t position) {
+    DCHECK(!is_temp_);
     DCHECK(!is_fixed_);
     DCHECK_GT(position, GetStart());
 
@@ -453,7 +475,10 @@
   int spill_slot_;
 
   // Whether the interval is for a fixed register.
-  bool is_fixed_;
+  const bool is_fixed_;
+
+  // Whether the interval is for a temporary.
+  const bool is_temp_;
 
   // The instruction represented by this interval.
   HInstruction* const defined_by_;