Finally implement Location::kNoOutputOverlap.
The [i, i + 1) interval scheme we chose for representing
lifetime positions is not optimal for doing this optimization.
It however doesn't prevent recognizing a non-split interval
during the TryAllocateFreeReg phase, and try to re-use
its inputs' registers.
Change-Id: I80a2823b0048d3310becfc5f5fb7b1230dfd8201
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h
index 8b06d60..68e3a30 100644
--- a/compiler/optimizing/locations.h
+++ b/compiler/optimizing/locations.h
@@ -482,16 +482,17 @@
}
void SetOut(Location location, Location::OutputOverlap overlaps = Location::kOutputOverlap) {
- DCHECK(output_.IsUnallocated() || output_.IsInvalid());
+ DCHECK(output_.IsInvalid());
output_overlaps_ = overlaps;
output_ = location;
}
void UpdateOut(Location location) {
- // The only reason for updating an output is for parameters where
- // we only know the exact stack slot after doing full register
- // allocation.
- DCHECK(output_.IsStackSlot() || output_.IsDoubleStackSlot());
+ // There are two reasons for updating an output:
+ // 1) Parameters, where we only know the exact stack slot after
+ // doing full register allocation.
+ // 2) Unallocated location.
+ DCHECK(output_.IsStackSlot() || output_.IsDoubleStackSlot() || output_.IsUnallocated());
output_ = location;
}
@@ -563,28 +564,22 @@
return live_registers_.GetNumberOfRegisters();
}
- bool InputOverlapsWithOutputOrTemp(uint32_t input_index, bool is_environment) const {
- if (is_environment) return true;
- if ((input_index == 0)
+ bool OutputUsesSameAs(uint32_t input_index) const {
+ return (input_index == 0)
&& output_.IsUnallocated()
- && (output_.GetPolicy() == Location::kSameAsFirstInput)) {
- return false;
- }
+ && (output_.GetPolicy() == Location::kSameAsFirstInput);
+ }
+
+ bool IsFixedInput(uint32_t input_index) const {
Location input = inputs_.Get(input_index);
- if (input.IsRegister()
+ return input.IsRegister()
|| input.IsFpuRegister()
|| input.IsPair()
|| input.IsStackSlot()
- || input.IsDoubleStackSlot()) {
- // For fixed locations, the register allocator requires to have inputs die before
- // the instruction, so that input moves use the location of the input just
- // before that instruction (and not potential moves due to splitting).
- return false;
- }
- return true;
+ || input.IsDoubleStackSlot();
}
- bool OutputOverlapsWithInputs() const {
+ bool OutputCanOverlapWithInputs() const {
return output_overlaps_ == Location::kOutputOverlap;
}