[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>
|
template <typename RegisterT>
|
||||||
void StraightForwardRegisterAllocator::DropRegisterValueAtEnd(RegisterT reg) {
|
void StraightForwardRegisterAllocator::DropRegisterValueAtEnd(RegisterT reg) {
|
||||||
RegisterFrameState<RegisterT>& list = GetRegisterFrameState<RegisterT>();
|
RegisterFrameState<RegisterT>& list = GetRegisterFrameState<RegisterT>();
|
||||||
|
list.unblock(reg);
|
||||||
if (!list.free().has(reg)) {
|
if (!list.free().has(reg)) {
|
||||||
ValueNode* node = list.GetValue(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()) {
|
if (node->live_range().end == current_node_->id()) {
|
||||||
node->RemoveRegister(reg);
|
node->RemoveRegister(reg);
|
||||||
list.AddToFree(reg);
|
} else {
|
||||||
|
DropRegisterValue(list, reg);
|
||||||
}
|
}
|
||||||
|
list.AddToFree(reg);
|
||||||
}
|
}
|
||||||
list.unblock(reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StraightForwardRegisterAllocator::AllocateNodeResult(ValueNode* node) {
|
void StraightForwardRegisterAllocator::AllocateNodeResult(ValueNode* node) {
|
||||||
@ -1185,7 +1188,14 @@ template <typename RegisterT>
|
|||||||
void StraightForwardRegisterAllocator::EnsureFreeRegisterAtEnd() {
|
void StraightForwardRegisterAllocator::EnsureFreeRegisterAtEnd() {
|
||||||
RegisterFrameState<RegisterT>& registers = GetRegisterFrameState<RegisterT>();
|
RegisterFrameState<RegisterT>& registers = GetRegisterFrameState<RegisterT>();
|
||||||
// If we still have free registers, pick one of those.
|
// 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
|
// If the current node is a last use of an input, pick a register containing
|
||||||
// the input.
|
// the input.
|
||||||
|
Loading…
Reference in New Issue
Block a user