Commit e916dad3 authored by rodolph.perfetta's avatar rodolph.perfetta Committed by Commit bot

[turbofan] fix deopt's input life span

Mark deopt's input alive till the end of the deopt instruction so
they cannot be reused as output.

BUG=v8:5158

Review-Url: https://codereview.chromium.org/2247303007
Cr-Commit-Position: refs/heads/master@{#38875}
parent dc330f2b
......@@ -252,14 +252,7 @@ void VisitBinop(InstructionSelector* selector, Node* node,
inputs[input_count++] = g.Label(cont->false_block());
}
if (cont->IsDeoptimize()) {
// If we can deoptimize as a result of the binop, we need to make sure that
// the deopt inputs are not overwritten by the binop result. One way
// to achieve that is to declare the output register as same-as-first.
outputs[output_count++] = g.DefineSameAsFirst(node);
} else {
outputs[output_count++] = g.DefineAsRegister(node);
}
outputs[output_count++] = g.DefineAsRegister(node);
if (cont->IsSet()) {
outputs[output_count++] = g.DefineAsRegister(cont->result());
}
......
......@@ -434,24 +434,18 @@ void VisitBinop(InstructionSelector* selector, Node* node,
} else if (TryMatchAnyShift(selector, node, right_node, &opcode,
!is_add_sub)) {
Matcher m_shift(right_node);
inputs[input_count++] = cont->IsDeoptimize()
? g.UseRegister(left_node)
: g.UseRegisterOrImmediateZero(left_node);
inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
inputs[input_count++] = g.UseRegister(m_shift.left().node());
inputs[input_count++] = g.UseImmediate(m_shift.right().node());
} else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode,
!is_add_sub)) {
if (must_commute_cond) cont->Commute();
Matcher m_shift(left_node);
inputs[input_count++] = cont->IsDeoptimize()
? g.UseRegister(right_node)
: g.UseRegisterOrImmediateZero(right_node);
inputs[input_count++] = g.UseRegisterOrImmediateZero(right_node);
inputs[input_count++] = g.UseRegister(m_shift.left().node());
inputs[input_count++] = g.UseImmediate(m_shift.right().node());
} else {
inputs[input_count++] = cont->IsDeoptimize()
? g.UseRegister(left_node)
: g.UseRegisterOrImmediateZero(left_node);
inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
inputs[input_count++] = g.UseRegister(right_node);
}
......@@ -461,14 +455,7 @@ void VisitBinop(InstructionSelector* selector, Node* node,
}
if (!IsComparisonField::decode(properties)) {
if (cont->IsDeoptimize()) {
// If we can deoptimize as a result of the binop, we need to make sure
// that the deopt inputs are not overwritten by the binop result. One way
// to achieve that is to declare the output register as same-as-first.
outputs[output_count++] = g.DefineSameAsFirst(node);
} else {
outputs[output_count++] = g.DefineAsRegister(node);
}
outputs[output_count++] = g.DefineAsRegister(node);
}
if (cont->IsSet()) {
......
......@@ -90,6 +90,12 @@ class OperandGenerator {
GetVReg(node)));
}
InstructionOperand UseAnyAtEnd(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::ANY,
UnallocatedOperand::USED_AT_END,
GetVReg(node)));
}
InstructionOperand UseAny(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::ANY,
UnallocatedOperand::USED_AT_START,
......
......@@ -369,7 +369,9 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
case FrameStateInputKind::kStackSlot:
return g->UseUniqueSlot(input);
case FrameStateInputKind::kAny:
return g->UseAny(input);
// Currently deopts "wrap" other operations, so the deopt's inputs
// are potentially needed untill the end of the deoptimising code.
return g->UseAnyAtEnd(input);
}
}
}
......
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