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)) {