[maglev] Spill values when freeing a register at-end
DropRegisterAtEnd is used to free a register, to make space for the result of a node. Normally this frees up an input that is dead at the end of the node's lifetime, but under high local variable pressure, we might not have a dead value to drop. In these cases we have to spill a register through the normal spilling mechanism. Additionally, allow freeing up a blocked free register (i.e. a temporary) if this is possible. Bug: v8:7700 Change-Id: I0099751918cf5cb65c2a09337a3f080eb2c4dd14 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3769833 Reviewed-by: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#81804}
This commit is contained in:
parent
cdf548dacc
commit
0ec8f227b6
@ -505,14 +505,17 @@ void StraightForwardRegisterAllocator::AllocateNode(Node* node) {
|
||||
template <typename RegisterT>
|
||||
void StraightForwardRegisterAllocator::DropRegisterValueAtEnd(RegisterT reg) {
|
||||
RegisterFrameState<RegisterT>& list = GetRegisterFrameState<RegisterT>();
|
||||
list.unblock(reg);
|
||||
if (!list.free().has(reg)) {
|
||||
ValueNode* node = list.GetValue(reg);
|
||||
// If the is not live after the current node, just remove its value.
|
||||
if (node->live_range().end == current_node_->id()) {
|
||||
node->RemoveRegister(reg);
|
||||
list.AddToFree(reg);
|
||||
} else {
|
||||
DropRegisterValue(list, reg);
|
||||
}
|
||||
list.AddToFree(reg);
|
||||
}
|
||||
list.unblock(reg);
|
||||
}
|
||||
|
||||
void StraightForwardRegisterAllocator::AllocateNodeResult(ValueNode* node) {
|
||||
@ -1185,7 +1188,14 @@ template <typename RegisterT>
|
||||
void StraightForwardRegisterAllocator::EnsureFreeRegisterAtEnd() {
|
||||
RegisterFrameState<RegisterT>& registers = GetRegisterFrameState<RegisterT>();
|
||||
// If we still have free registers, pick one of those.
|
||||
if (!registers.free().is_empty()) return;
|
||||
if (!registers.free().is_empty()) {
|
||||
// Make sure that at least one of the free registers is not blocked; this
|
||||
// effectively means freeing up a temporary.
|
||||
if (registers.unblocked_free().is_empty()) {
|
||||
registers.unblock(registers.free().first());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current node is a last use of an input, pick a register containing
|
||||
// the input.
|
||||
|
Loading…
Reference in New Issue
Block a user