Fix LSRA bug with explicit register temporaries

A temporary with an explicit RegisterLocation, such as ESI on x86 didn't
have the register marked as allocated.  This caused it to not be
saved/restored in the prologue/epilogue, causing problems in the caller
routine, which expected it to be saved.  Found while implementing
https://android-review.googlesource.com/#/c/157522/.

Change-Id: I22ca2b24c2d21b1c6ab6cfb7dec26cb38034a891
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 4cecd61..eb63b49 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -294,6 +294,12 @@
     allocated_registers_.Add(location);
   }
 
+  bool HasAllocatedRegister(bool is_core, int reg) const {
+    return is_core
+        ? allocated_registers_.ContainsCoreRegister(reg)
+        : allocated_registers_.ContainsFloatingPointRegister(reg);
+  }
+
   void AllocateLocations(HInstruction* instruction);
 
   // Tells whether the stack frame of the compiled method is
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h
index f41a782..4b25046 100644
--- a/compiler/optimizing/locations.h
+++ b/compiler/optimizing/locations.h
@@ -427,11 +427,11 @@
     }
   }
 
-  bool ContainsCoreRegister(uint32_t id) {
+  bool ContainsCoreRegister(uint32_t id) const {
     return Contains(core_registers_, id);
   }
 
-  bool ContainsFloatingPointRegister(uint32_t id) {
+  bool ContainsFloatingPointRegister(uint32_t id) const {
     return Contains(floating_point_registers_, id);
   }
 
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index 7b23d02..a8e3c2f 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -209,6 +209,8 @@
     Location temp = locations->GetTemp(i);
     if (temp.IsRegister() || temp.IsFpuRegister()) {
       BlockRegister(temp, position, position + 1);
+      // Ensure that an explicit temporary register is marked as being allocated.
+      codegen_->AddAllocatedRegister(temp);
     } else {
       DCHECK(temp.IsUnallocated());
       switch (temp.GetPolicy()) {
@@ -507,6 +509,9 @@
       }
 
       if (current->HasRegister()) {
+        if (kIsDebugBuild && !current->IsFixed()) {
+          DCHECK(codegen.HasAllocatedRegister(processing_core_registers, current->GetRegister()));
+        }
         BitVector* liveness_of_register = liveness_of_values.Get(current->GetRegister());
         for (size_t j = it.CurrentRange()->GetStart(); j < it.CurrentRange()->GetEnd(); ++j) {
           if (liveness_of_register->IsBitSet(j)) {