Index: src/compiler/arm/instruction-selector-arm.cc |
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc |
index 14b30b1af08dbdfc0c0d6d52a8da8aecf1eccef0..5c5e3043192ede5f1e60baafbf4482c384a375cc 100644 |
--- a/src/compiler/arm/instruction-selector-arm.cc |
+++ b/src/compiler/arm/instruction-selector-arm.cc |
@@ -237,8 +237,13 @@ void VisitBinop(InstructionSelector* selector, Node* node, |
DCHECK_GE(arraysize(outputs), output_count); |
DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); |
- 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); |
+ } |
} |
@@ -691,8 +696,13 @@ void VisitShift(InstructionSelector* selector, Node* node, |
DCHECK_GE(arraysize(outputs), output_count); |
DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); |
- 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); |
+ } |
} |
@@ -1284,6 +1294,9 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
if (cont->IsBranch()) { |
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(opcode, g.DefineAsRegister(cont->result()), left, right); |
@@ -1357,8 +1370,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, |
if (cont->IsBranch()) { |
inputs[input_count++] = g.Label(cont->true_block()); |
inputs[input_count++] = g.Label(cont->false_block()); |
- } else { |
- DCHECK(cont->IsSet()); |
+ } else if (cont->IsSet()) { |
outputs[output_count++] = g.DefineAsRegister(cont->result()); |
} |
@@ -1366,8 +1378,13 @@ void VisitWordCompare(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); |
+ } |
} |
@@ -1482,7 +1499,11 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
if (cont->IsBranch()) { |
selector->Emit(opcode, g.NoOutput(), value_operand, value_operand, |
g.Label(cont->true_block()), g.Label(cont->false_block())); |
+ } else if (cont->IsDeoptimize()) { |
+ selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, value_operand, |
+ cont->frame_state()); |
} else { |
+ DCHECK(cont->IsSet()); |
selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, |
value_operand); |
} |
@@ -1490,13 +1511,23 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
} // namespace |
- |
void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
BasicBlock* fbranch) { |
FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
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) { |
ArmOperandGenerator g(this); |
@@ -1527,7 +1558,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); |
@@ -1537,32 +1568,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, kArmAdd, kArmAdd, &cont); |
} |
FlagsContinuation cont; |
@@ -1572,7 +1605,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, kArmSub, kArmRsb, &cont); |
} |
FlagsContinuation cont; |
@@ -1581,37 +1614,39 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
void InstructionSelector::VisitFloat32Equal(Node* node) { |
- FlagsContinuation cont(kEqual, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); |
VisitFloat32Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat32LessThan(Node* node) { |
- FlagsContinuation cont(kFloatLessThan, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node); |
VisitFloat32Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
- FlagsContinuation cont(kFloatLessThanOrEqual, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kFloatLessThanOrEqual, node); |
VisitFloat32Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat64Equal(Node* node) { |
- FlagsContinuation cont(kEqual, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); |
VisitFloat64Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat64LessThan(Node* node) { |
- FlagsContinuation cont(kFloatLessThan, node); |
+ FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node); |
VisitFloat64Compare(this, node, &cont); |
} |
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { |
- FlagsContinuation cont(kFloatLessThanOrEqual, node); |
+ FlagsContinuation cont = |
+ FlagsContinuation::ForSet(kFloatLessThanOrEqual, node); |
VisitFloat64Compare(this, node, &cont); |
} |