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, ...@@ -252,14 +252,7 @@ void VisitBinop(InstructionSelector* selector, Node* node,
inputs[input_count++] = g.Label(cont->false_block()); inputs[input_count++] = g.Label(cont->false_block());
} }
if (cont->IsDeoptimize()) { outputs[output_count++] = g.DefineAsRegister(node);
// 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);
}
if (cont->IsSet()) { if (cont->IsSet()) {
outputs[output_count++] = g.DefineAsRegister(cont->result()); outputs[output_count++] = g.DefineAsRegister(cont->result());
} }
......
...@@ -434,24 +434,18 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -434,24 +434,18 @@ void VisitBinop(InstructionSelector* selector, Node* node,
} else if (TryMatchAnyShift(selector, node, right_node, &opcode, } else if (TryMatchAnyShift(selector, node, right_node, &opcode,
!is_add_sub)) { !is_add_sub)) {
Matcher m_shift(right_node); Matcher m_shift(right_node);
inputs[input_count++] = cont->IsDeoptimize() inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
? g.UseRegister(left_node)
: g.UseRegisterOrImmediateZero(left_node);
inputs[input_count++] = g.UseRegister(m_shift.left().node()); inputs[input_count++] = g.UseRegister(m_shift.left().node());
inputs[input_count++] = g.UseImmediate(m_shift.right().node()); inputs[input_count++] = g.UseImmediate(m_shift.right().node());
} else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode, } else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode,
!is_add_sub)) { !is_add_sub)) {
if (must_commute_cond) cont->Commute(); if (must_commute_cond) cont->Commute();
Matcher m_shift(left_node); Matcher m_shift(left_node);
inputs[input_count++] = cont->IsDeoptimize() inputs[input_count++] = g.UseRegisterOrImmediateZero(right_node);
? g.UseRegister(right_node)
: g.UseRegisterOrImmediateZero(right_node);
inputs[input_count++] = g.UseRegister(m_shift.left().node()); inputs[input_count++] = g.UseRegister(m_shift.left().node());
inputs[input_count++] = g.UseImmediate(m_shift.right().node()); inputs[input_count++] = g.UseImmediate(m_shift.right().node());
} else { } else {
inputs[input_count++] = cont->IsDeoptimize() inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
? g.UseRegister(left_node)
: g.UseRegisterOrImmediateZero(left_node);
inputs[input_count++] = g.UseRegister(right_node); inputs[input_count++] = g.UseRegister(right_node);
} }
...@@ -461,14 +455,7 @@ void VisitBinop(InstructionSelector* selector, Node* node, ...@@ -461,14 +455,7 @@ void VisitBinop(InstructionSelector* selector, Node* node,
} }
if (!IsComparisonField::decode(properties)) { if (!IsComparisonField::decode(properties)) {
if (cont->IsDeoptimize()) { outputs[output_count++] = g.DefineAsRegister(node);
// 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);
}
} }
if (cont->IsSet()) { if (cont->IsSet()) {
......
...@@ -90,6 +90,12 @@ class OperandGenerator { ...@@ -90,6 +90,12 @@ class OperandGenerator {
GetVReg(node))); GetVReg(node)));
} }
InstructionOperand UseAnyAtEnd(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::ANY,
UnallocatedOperand::USED_AT_END,
GetVReg(node)));
}
InstructionOperand UseAny(Node* node) { InstructionOperand UseAny(Node* node) {
return Use(node, UnallocatedOperand(UnallocatedOperand::ANY, return Use(node, UnallocatedOperand(UnallocatedOperand::ANY,
UnallocatedOperand::USED_AT_START, UnallocatedOperand::USED_AT_START,
......
...@@ -369,7 +369,9 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, ...@@ -369,7 +369,9 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
case FrameStateInputKind::kStackSlot: case FrameStateInputKind::kStackSlot:
return g->UseUniqueSlot(input); return g->UseUniqueSlot(input);
case FrameStateInputKind::kAny: 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