Index: src/compiler/x87/instruction-selector-x87.cc |
diff --git a/src/compiler/x87/instruction-selector-x87.cc b/src/compiler/x87/instruction-selector-x87.cc |
index 079d5d202668c4c6a3ee00057245b2208af458a1..90f0f61e170674810501c7bb4e1f808e9226c930 100644 |
--- a/src/compiler/x87/instruction-selector-x87.cc |
+++ b/src/compiler/x87/instruction-selector-x87.cc |
@@ -365,10 +365,11 @@ void InstructionSelector::VisitCheckedStore(Node* node) { |
} |
} |
+namespace { |
// Shared routine for multiple binary operations. |
-static void VisitBinop(InstructionSelector* selector, Node* node, |
- InstructionCode opcode, FlagsContinuation* cont) { |
+void VisitBinop(InstructionSelector* selector, Node* node, |
+ InstructionCode opcode, FlagsContinuation* cont) { |
X87OperandGenerator g(selector); |
Int32BinopMatcher m(node); |
Node* left = m.left().node(); |
@@ -417,18 +418,24 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
DCHECK_GE(arraysize(inputs), input_count); |
DCHECK_GE(arraysize(outputs), output_count); |
- selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, |
- inputs); |
+ opcode = cont->Encode(opcode); |
+ if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
+ cont->frame_state()); |
+ } else { |
+ selector->Emit(opcode, output_count, outputs, input_count, inputs); |
+ } |
} |
// Shared routine for multiple binary operations. |
-static void VisitBinop(InstructionSelector* selector, Node* node, |
- InstructionCode opcode) { |
+void VisitBinop(InstructionSelector* selector, Node* node, |
+ InstructionCode opcode) { |
FlagsContinuation cont; |
VisitBinop(selector, node, opcode, &cont); |
} |
+} // namespace |
void InstructionSelector::VisitWord32And(Node* node) { |
VisitBinop(this, node, kX87And); |
@@ -1011,6 +1018,9 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector, |
inputs[input_count++] = g.Label(cont->true_block()); |
inputs[input_count++] = g.Label(cont->false_block()); |
selector->Emit(opcode, 0, nullptr, input_count, inputs); |
+ } else if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, |
+ cont->frame_state()); |
} else { |
DCHECK(cont->IsSet()); |
InstructionOperand output = g.DefineAsRegister(cont->result()); |
@@ -1038,13 +1048,16 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
InstructionOperand left, InstructionOperand right, |
FlagsContinuation* cont) { |
X87OperandGenerator g(selector); |
+ opcode = cont->Encode(opcode); |
if (cont->IsBranch()) { |
- selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, |
+ selector->Emit(opcode, g.NoOutput(), left, right, |
g.Label(cont->true_block()), g.Label(cont->false_block())); |
+ } else if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, |
+ cont->frame_state()); |
} else { |
DCHECK(cont->IsSet()); |
- selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()), |
- left, right); |
+ selector->Emit(opcode, g.DefineAsByteRegister(cont->result()), left, right); |
} |
} |
@@ -1070,6 +1083,10 @@ void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
if (cont->IsBranch()) { |
selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
g.Label(cont->true_block()), g.Label(cont->false_block())); |
+ } else if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(cont->Encode(kX87Float32Cmp), g.NoOutput(), |
+ g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), |
+ cont->frame_state()); |
} else { |
DCHECK(cont->IsSet()); |
selector->Emit(cont->Encode(kX87Float32Cmp), |
@@ -1087,6 +1104,10 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
if (cont->IsBranch()) { |
selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
g.Label(cont->true_block()), g.Label(cont->false_block())); |
+ } else if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(cont->Encode(kX87Float64Cmp), g.NoOutput(), |
+ g.Use(node->InputAt(0)), g.Use(node->InputAt(1)), |
+ cont->frame_state()); |
} else { |
DCHECK(cont->IsSet()); |
selector->Emit(cont->Encode(kX87Float64Cmp), |
@@ -1145,6 +1166,9 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, |
if (cont->IsBranch()) { |
selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), |
g.Label(cont->false_block())); |
+ } else if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, |
+ cont->frame_state()); |
} else { |
DCHECK(cont->IsSet()); |
selector->Emit(opcode, g.DefineAsRegister(cont->result())); |
@@ -1254,6 +1278,17 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
} |
+void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1)); |
+ VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
+} |
+ |
+void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1)); |
+ VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
+} |
void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
X87OperandGenerator g(this); |
@@ -1284,7 +1319,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
void InstructionSelector::VisitWord32Equal(Node* const node) { |
- FlagsContinuation cont(kEqual, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); |
Int32BinopMatcher m(node); |
if (m.right().Is(0)) { |
return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); |
@@ -1294,32 +1329,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { |
void InstructionSelector::VisitInt32LessThan(Node* node) { |
- FlagsContinuation cont(kSignedLessThan, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); |
VisitWordCompare(this, node, &cont); |
} |
void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { |
- FlagsContinuation cont(kSignedLessThanOrEqual, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); |
VisitWordCompare(this, node, &cont); |
} |
void InstructionSelector::VisitUint32LessThan(Node* node) { |
- FlagsContinuation cont(kUnsignedLessThan, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); |
VisitWordCompare(this, node, &cont); |
} |
void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { |
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); |
VisitWordCompare(this, node, &cont); |
} |
void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
- FlagsContinuation cont(kOverflow, ovf); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
return VisitBinop(this, node, kX87Add, &cont); |
} |
FlagsContinuation cont; |
@@ -1329,7 +1366,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
- FlagsContinuation cont(kOverflow, ovf); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
return VisitBinop(this, node, kX87Sub, &cont); |
} |
FlagsContinuation cont; |
@@ -1338,37 +1375,41 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
void InstructionSelector::VisitFloat32Equal(Node* node) { |
- FlagsContinuation cont(kUnorderedEqual, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node); |
VisitFloat32Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat32LessThan(Node* node) { |
- FlagsContinuation cont(kUnsignedGreaterThan, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kUnsignedGreaterThan, node); |
VisitFloat32Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
- FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); |
VisitFloat32Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat64Equal(Node* node) { |
- FlagsContinuation cont(kUnorderedEqual, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node); |
VisitFloat64Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat64LessThan(Node* node) { |
- FlagsContinuation cont(kUnsignedGreaterThan, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kUnsignedGreaterThan, node); |
VisitFloat64Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
- FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); |
VisitFloat64Compare(this, node, &cont); |
} |