Commit 507e5743 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Fix Phi register state at end of blocks

When injecting locations for block-end gap moves into Phis, make sure to
maintain register frame state too, so that the subsequent
MergeRegisterValues call sees the result of these moves.

Bug: v8:7700
Change-Id: I4f68e386c5a6cc578d26904306cb9b0c2f7a90d6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3676861
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80879}
parent c7aef552
......@@ -197,6 +197,7 @@ class MaglevCodeGeneratingNodeProcessor {
void RecordGapMove(ValueNode* node, compiler::InstructionOperand source,
Register target_reg, RegisterMoves& register_moves,
RegisterReloads& register_reloads) {
DCHECK(!source.IsDoubleRegister());
if (source.IsAnyRegister()) {
// For reg->reg moves, don't emit the move yet, but instead record the
// move in the set of parallel register moves, to be resolved later.
......
......@@ -408,6 +408,7 @@ void StraightForwardRegisterAllocator::UpdateUse(
}
void StraightForwardRegisterAllocator::AllocateNode(Node* node) {
current_node_ = node;
if (FLAG_trace_maglev_regalloc) {
printing_visitor_->os()
<< "Allocating " << PrintNodeLabel(graph_labeller(), node)
......@@ -540,7 +541,7 @@ void StraightForwardRegisterAllocator::DropRegisterValue(
// If we are at the end of the current node, and the last use of the given
// node is the current node, allow it to be dropped.
if (stage == AllocationStage::kAtEnd &&
node->live_range().end == node_it_->id()) {
node->live_range().end == current_node_->id()) {
return;
}
......@@ -593,6 +594,7 @@ void StraightForwardRegisterAllocator::InitializeConditionalBranchRegisters(
void StraightForwardRegisterAllocator::AllocateControlNode(ControlNode* node,
BasicBlock* block) {
current_node_ = node;
AssignInputs(node);
AssignTemporaries(node);
VerifyInputs(node);
......@@ -611,14 +613,27 @@ void StraightForwardRegisterAllocator::AllocateControlNode(ControlNode* node,
for (Phi* phi : *phis) {
Input& input = phi->input(block->predecessor_id());
input.InjectLocation(input.node()->allocation());
// Write the node to the phi's register (if any), to make sure
// register state is accurate for MergeRegisterValues later.
if (phi->result().operand().IsAnyRegister()) {
DCHECK(!phi->result().operand().IsDoubleRegister());
Register reg = phi->result().AssignedGeneralRegister();
if (!general_registers_.free().has(reg)) {
// Drop the value currently in the register, using AtStart to treat
// pre-jump gap moves as if they were inputs.
DropRegisterValue(general_registers_, reg,
AllocationStage::kAtStart);
} else {
general_registers_.RemoveFromFree(reg);
}
general_registers_.SetValue(reg, input.node());
}
}
for (Phi* phi : *phis) UpdateUse(&phi->input(block->predecessor_id()));
}
}
// TODO(verwaest): This isn't a good idea :)
if (node->properties().can_eager_deopt()) SpillRegisters();
// Merge register values. Values only flowing into phis and not being
// independently live will be killed as part of the merge.
if (node->Is<JumpToInlined>()) {
......@@ -892,7 +907,7 @@ void StraightForwardRegisterAllocator::FreeSomeRegister(
// will already be dead after being used as an input to this node, allow
// and indeed prefer using this register.
if (stage == AllocationStage::kAtEnd &&
value->live_range().end == node_it_->id()) {
value->live_range().end == current_node_->id()) {
best = reg;
break;
}
......
......@@ -200,6 +200,8 @@ class StraightForwardRegisterAllocator {
std::unique_ptr<MaglevPrintingVisitor> printing_visitor_;
BlockConstIterator block_it_;
NodeIterator node_it_;
// The current node, whether a Node in the body or the ControlNode.
NodeBase* current_node_;
};
} // namespace maglev
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment