Tweak one hint and one split in the linear scan.
- Return a hinted register if it is available. Otherwise
another move will be necessary.
- Use SplitBetween instead of raw split when a register
is not fully available. This will find the best split
position.
Change-Id: Ie464e536204ab556eb09345fe6426621eb86e5ac
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc
index 250eb04..d5f977f 100644
--- a/compiler/optimizing/ssa_liveness_analysis.cc
+++ b/compiler/optimizing/ssa_liveness_analysis.cc
@@ -341,6 +341,7 @@
// starts at. If one location is a register we return it as a hint. This
// will avoid a move between the two blocks.
HBasicBlock* block = liveness.GetBlockFromPosition(GetStart() / 2);
+ size_t next_register_use = FirstRegisterUse();
for (size_t i = 0; i < block->GetPredecessors().Size(); ++i) {
size_t position = block->GetPredecessors().Get(i)->GetLifetimeEnd() - 1;
// We know positions above GetStart() do not have a location yet.
@@ -348,7 +349,9 @@
LiveInterval* existing = GetParent()->GetSiblingAt(position);
if (existing != nullptr
&& existing->HasRegister()
- && (free_until[existing->GetRegister()] > GetStart())) {
+ // It's worth using that register if it is available until
+ // the next use.
+ && (free_until[existing->GetRegister()] >= next_register_use)) {
return existing->GetRegister();
}
}