diff options
Diffstat (limited to 'deps/v8/src/compiler/x64/instruction-selector-x64.cc')
-rw-r--r-- | deps/v8/src/compiler/x64/instruction-selector-x64.cc | 419 |
1 files changed, 291 insertions, 128 deletions
diff --git a/deps/v8/src/compiler/x64/instruction-selector-x64.cc b/deps/v8/src/compiler/x64/instruction-selector-x64.cc index d3a2a8e753..f46ff5946d 100644 --- a/deps/v8/src/compiler/x64/instruction-selector-x64.cc +++ b/deps/v8/src/compiler/x64/instruction-selector-x64.cc @@ -36,6 +36,37 @@ class X64OperandGenerator final : public OperandGenerator { } } + bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input, + int effect_level) { + if (input->opcode() != IrOpcode::kLoad || + !selector()->CanCover(node, input)) { + return false; + } + if (effect_level != selector()->GetEffectLevel(input)) { + return false; + } + MachineRepresentation rep = + LoadRepresentationOf(input->op()).representation(); + switch (opcode) { + case kX64Cmp: + case kX64Test: + return rep == MachineRepresentation::kWord64 || + rep == MachineRepresentation::kTagged; + case kX64Cmp32: + case kX64Test32: + return rep == MachineRepresentation::kWord32; + case kX64Cmp16: + case kX64Test16: + return rep == MachineRepresentation::kWord16; + case kX64Cmp8: + case kX64Test8: + return rep == MachineRepresentation::kWord8; + default: + break; + } + return false; + } + AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent, Node* base, Node* displacement, InstructionOperand inputs[], @@ -173,9 +204,7 @@ void InstructionSelector::VisitStore(Node* node) { inputs[input_count++] = g.UseUniqueRegister(index); addressing_mode = kMode_MR1; } - inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) - ? g.UseRegister(value) - : g.UseUniqueRegister(value); + inputs[input_count++] = g.UseUniqueRegister(value); RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; switch (write_barrier_kind) { case kNoWriteBarrier: @@ -399,8 +428,13 @@ 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); + } } @@ -588,6 +622,75 @@ void InstructionSelector::VisitWord32Sar(Node* node) { void InstructionSelector::VisitWord64Sar(Node* node) { + X64OperandGenerator g(this); + Int64BinopMatcher m(node); + if (CanCover(m.node(), m.left().node()) && m.left().IsLoad() && + m.right().Is(32)) { + // Just load and sign-extend the interesting 4 bytes instead. This happens, + // for example, when we're loading and untagging SMIs. + BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(), true); + if (mleft.matches() && (mleft.displacement() == nullptr || + g.CanBeImmediate(mleft.displacement()))) { + size_t input_count = 0; + InstructionOperand inputs[3]; + AddressingMode mode = g.GetEffectiveAddressMemoryOperand( + m.left().node(), inputs, &input_count); + if (mleft.displacement() == nullptr) { + // Make sure that the addressing mode indicates the presence of an + // immediate displacement. It seems that we never use M1 and M2, but we + // handle them here anyways. + switch (mode) { + case kMode_MR: + mode = kMode_MRI; + break; + case kMode_MR1: + mode = kMode_MR1I; + break; + case kMode_MR2: + mode = kMode_MR2I; + break; + case kMode_MR4: + mode = kMode_MR4I; + break; + case kMode_MR8: + mode = kMode_MR8I; + break; + case kMode_M1: + mode = kMode_M1I; + break; + case kMode_M2: + mode = kMode_M2I; + break; + case kMode_M4: + mode = kMode_M4I; + break; + case kMode_M8: + mode = kMode_M8I; + break; + case kMode_None: + case kMode_MRI: + case kMode_MR1I: + case kMode_MR2I: + case kMode_MR4I: + case kMode_MR8I: + case kMode_M1I: + case kMode_M2I: + case kMode_M4I: + case kMode_M8I: + UNREACHABLE(); + } + inputs[input_count++] = ImmediateOperand(ImmediateOperand::INLINE, 4); + } else { + ImmediateOperand* op = ImmediateOperand::cast(&inputs[input_count - 1]); + int32_t displacement = sequence()->GetImmediate(op).ToInt32(); + *op = ImmediateOperand(ImmediateOperand::INLINE, displacement + 4); + } + InstructionOperand outputs[] = {g.DefineAsRegister(node)}; + InstructionCode code = kX64Movsxlq | AddressingModeField::encode(mode); + Emit(code, 1, outputs, input_count, inputs); + return; + } + } VisitWord64Shift(this, node, kX64Sar); } @@ -668,8 +771,8 @@ void InstructionSelector::VisitInt64Add(Node* node) { void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) { - FlagsContinuation cont(kOverflow, ovf); - VisitBinop(this, node, kX64Add, &cont); + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); + return VisitBinop(this, node, kX64Add, &cont); } FlagsContinuation cont; VisitBinop(this, node, kX64Add, &cont); @@ -708,7 +811,7 @@ void InstructionSelector::VisitInt64Sub(Node* node) { void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) { - FlagsContinuation cont(kOverflow, ovf); + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); return VisitBinop(this, node, kX64Sub, &cont); } FlagsContinuation cont; @@ -865,9 +968,15 @@ void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { X64OperandGenerator g(this); - Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0))); + Emit(kSSEFloat64ToUint32 | MiscField::encode(1), g.DefineAsRegister(node), + g.Use(node->InputAt(0))); } +void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) { + X64OperandGenerator g(this); + Emit(kSSEFloat64ToUint32 | MiscField::encode(0), g.DefineAsRegister(node), + g.Use(node->InputAt(0))); +} void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) { X64OperandGenerator g(this); @@ -1336,6 +1445,7 @@ void InstructionSelector::EmitPrepareArguments( bool InstructionSelector::IsTailCallAddressImmediate() { return true; } +int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } namespace { @@ -1357,6 +1467,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()); @@ -1364,23 +1477,6 @@ void VisitCompareWithMemoryOperand(InstructionSelector* selector, } } -// Determines if {input} of {node} can be replaced by a memory operand. -bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode, - Node* node, Node* input) { - if (input->opcode() != IrOpcode::kLoad || !selector->CanCover(node, input)) { - return false; - } - MachineRepresentation rep = - LoadRepresentationOf(input->op()).representation(); - if (rep == MachineRepresentation::kWord64 || - rep == MachineRepresentation::kTagged) { - return opcode == kX64Cmp || opcode == kX64Test; - } else if (rep == MachineRepresentation::kWord32) { - return opcode == kX64Cmp32 || opcode == kX64Test32; - } - return false; -} - // Shared routine for multiple compare operations. void VisitCompare(InstructionSelector* selector, InstructionCode opcode, InstructionOperand left, InstructionOperand right, @@ -1390,6 +1486,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); @@ -1408,6 +1507,37 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); } +// Tries to match the size of the given opcode to that of the operands, if +// possible. +InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, + Node* right) { + if (opcode != kX64Cmp32 && opcode != kX64Test32) { + return opcode; + } + // Currently, if one of the two operands is not a Load, we don't know what its + // machine representation is, so we bail out. + // TODO(epertoso): we can probably get some size information out of immediates + // and phi nodes. + if (left->opcode() != IrOpcode::kLoad || right->opcode() != IrOpcode::kLoad) { + return opcode; + } + // If the load representations don't match, both operands will be + // zero/sign-extended to 32bit. + LoadRepresentation left_representation = LoadRepresentationOf(left->op()); + if (left_representation != LoadRepresentationOf(right->op())) { + return opcode; + } + switch (left_representation.representation()) { + case MachineRepresentation::kBit: + case MachineRepresentation::kWord8: + return opcode == kX64Cmp32 ? kX64Cmp8 : kX64Test8; + case MachineRepresentation::kWord16: + return opcode == kX64Cmp32 ? kX64Cmp16 : kX64Test16; + default: + return opcode; + } +} + // Shared routine for multiple word compare operations. void VisitWordCompare(InstructionSelector* selector, Node* node, InstructionCode opcode, FlagsContinuation* cont) { @@ -1415,15 +1545,26 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, Node* left = node->InputAt(0); Node* right = node->InputAt(1); - // If one of the two inputs is an immediate, make sure it's on the right. - if (!g.CanBeImmediate(right) && g.CanBeImmediate(left)) { + opcode = TryNarrowOpcodeSize(opcode, left, right); + + // If one of the two inputs is an immediate, make sure it's on the right, or + // if one of the two inputs is a memory operand, make sure it's on the left. + int effect_level = selector->GetEffectLevel(node); + if (cont->IsBranch()) { + effect_level = selector->GetEffectLevel( + cont->true_block()->PredecessorAt(0)->control_input()); + } + + if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || + (g.CanBeMemoryOperand(opcode, node, right, effect_level) && + !g.CanBeMemoryOperand(opcode, node, left, effect_level))) { if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); std::swap(left, right); } // Match immediates on right side of comparison. if (g.CanBeImmediate(right)) { - if (CanUseMemoryOperand(selector, opcode, node, left)) { + if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) { return VisitCompareWithMemoryOperand(selector, opcode, left, g.UseImmediate(right), cont); } @@ -1431,15 +1572,17 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, cont); } + // Match memory operands on left side of comparison. + if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) { + return VisitCompareWithMemoryOperand(selector, opcode, left, + g.UseRegister(right), cont); + } + if (g.CanBeBetterLeftOperand(right)) { if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); std::swap(left, right); } - if (CanUseMemoryOperand(selector, opcode, node, left)) { - return VisitCompareWithMemoryOperand(selector, opcode, left, - g.UseRegister(right), cont); - } return VisitCompare(selector, opcode, left, right, cont, node->op()->HasProperty(Operator::kCommutative)); } @@ -1460,6 +1603,9 @@ void VisitWord64Compare(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())); @@ -1500,98 +1646,87 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node, VisitCompare(selector, opcode, right, left, cont, false); } -} // namespace - - -void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, - BasicBlock* fbranch) { - X64OperandGenerator g(this); - Node* user = branch; - Node* value = branch->InputAt(0); - - FlagsContinuation cont(kNotEqual, tbranch, fbranch); - - // Try to combine with comparisons against 0 by simply inverting the branch. - while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) { - Int32BinopMatcher m(value); - if (m.right().Is(0)) { - user = value; - value = m.left().node(); - cont.Negate(); - } else { - break; - } - } - - // Try to combine the branch with a comparison. - if (CanCover(user, value)) { +// Shared routine for word comparison against zero. +void VisitWordCompareZero(InstructionSelector* selector, Node* user, + Node* value, FlagsContinuation* cont) { + while (selector->CanCover(user, value)) { switch (value->opcode()) { - case IrOpcode::kWord32Equal: - cont.OverwriteAndNegateIfEqual(kEqual); - return VisitWordCompare(this, value, kX64Cmp32, &cont); + case IrOpcode::kWord32Equal: { + // Combine with comparisons against 0 by simply inverting the + // continuation. + Int32BinopMatcher m(value); + if (m.right().Is(0)) { + user = value; + value = m.left().node(); + cont->Negate(); + continue; + } + cont->OverwriteAndNegateIfEqual(kEqual); + return VisitWordCompare(selector, value, kX64Cmp32, cont); + } case IrOpcode::kInt32LessThan: - cont.OverwriteAndNegateIfEqual(kSignedLessThan); - return VisitWordCompare(this, value, kX64Cmp32, &cont); + cont->OverwriteAndNegateIfEqual(kSignedLessThan); + return VisitWordCompare(selector, value, kX64Cmp32, cont); case IrOpcode::kInt32LessThanOrEqual: - cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); - return VisitWordCompare(this, value, kX64Cmp32, &cont); + cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); + return VisitWordCompare(selector, value, kX64Cmp32, cont); case IrOpcode::kUint32LessThan: - cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitWordCompare(this, value, kX64Cmp32, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); + return VisitWordCompare(selector, value, kX64Cmp32, cont); case IrOpcode::kUint32LessThanOrEqual: - cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitWordCompare(this, value, kX64Cmp32, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); + return VisitWordCompare(selector, value, kX64Cmp32, cont); case IrOpcode::kWord64Equal: { - cont.OverwriteAndNegateIfEqual(kEqual); + cont->OverwriteAndNegateIfEqual(kEqual); Int64BinopMatcher m(value); if (m.right().Is(0)) { // Try to combine the branch with a comparison. Node* const user = m.node(); Node* const value = m.left().node(); - if (CanCover(user, value)) { + if (selector->CanCover(user, value)) { switch (value->opcode()) { case IrOpcode::kInt64Sub: - return VisitWord64Compare(this, value, &cont); + return VisitWord64Compare(selector, value, cont); case IrOpcode::kWord64And: - return VisitWordCompare(this, value, kX64Test, &cont); + return VisitWordCompare(selector, value, kX64Test, cont); default: break; } } - return VisitCompareZero(this, value, kX64Cmp, &cont); + return VisitCompareZero(selector, value, kX64Cmp, cont); } - return VisitWord64Compare(this, value, &cont); + return VisitWord64Compare(selector, value, cont); } case IrOpcode::kInt64LessThan: - cont.OverwriteAndNegateIfEqual(kSignedLessThan); - return VisitWord64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kSignedLessThan); + return VisitWord64Compare(selector, value, cont); case IrOpcode::kInt64LessThanOrEqual: - cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); - return VisitWord64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); + return VisitWord64Compare(selector, value, cont); case IrOpcode::kUint64LessThan: - cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitWord64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); + return VisitWord64Compare(selector, value, cont); case IrOpcode::kUint64LessThanOrEqual: - cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitWord64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); + return VisitWord64Compare(selector, value, cont); case IrOpcode::kFloat32Equal: - cont.OverwriteAndNegateIfEqual(kUnorderedEqual); - return VisitFloat32Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnorderedEqual); + return VisitFloat32Compare(selector, value, cont); case IrOpcode::kFloat32LessThan: - cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan); - return VisitFloat32Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); + return VisitFloat32Compare(selector, value, cont); case IrOpcode::kFloat32LessThanOrEqual: - cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); - return VisitFloat32Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); + return VisitFloat32Compare(selector, value, cont); case IrOpcode::kFloat64Equal: - cont.OverwriteAndNegateIfEqual(kUnorderedEqual); - return VisitFloat64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnorderedEqual); + return VisitFloat64Compare(selector, value, cont); case IrOpcode::kFloat64LessThan: - cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan); - return VisitFloat64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); + return VisitFloat64Compare(selector, value, cont); case IrOpcode::kFloat64LessThanOrEqual: - cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); - return VisitFloat64Compare(this, value, &cont); + cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); + return VisitFloat64Compare(selector, value, cont); case IrOpcode::kProjection: // Check if this is the overflow output projection of an // <Operation>WithOverflow node. @@ -1603,20 +1738,20 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, // *AFTER* this branch). Node* const node = value->InputAt(0); Node* const result = NodeProperties::FindProjection(node, 0); - if (result == nullptr || IsDefined(result)) { + if (result == nullptr || selector->IsDefined(result)) { switch (node->opcode()) { case IrOpcode::kInt32AddWithOverflow: - cont.OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop(this, node, kX64Add32, &cont); + cont->OverwriteAndNegateIfEqual(kOverflow); + return VisitBinop(selector, node, kX64Add32, cont); case IrOpcode::kInt32SubWithOverflow: - cont.OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop(this, node, kX64Sub32, &cont); + cont->OverwriteAndNegateIfEqual(kOverflow); + return VisitBinop(selector, node, kX64Sub32, cont); case IrOpcode::kInt64AddWithOverflow: - cont.OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop(this, node, kX64Add, &cont); + cont->OverwriteAndNegateIfEqual(kOverflow); + return VisitBinop(selector, node, kX64Add, cont); case IrOpcode::kInt64SubWithOverflow: - cont.OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop(this, node, kX64Sub, &cont); + cont->OverwriteAndNegateIfEqual(kOverflow); + return VisitBinop(selector, node, kX64Sub, cont); default: break; } @@ -1624,22 +1759,42 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, } break; case IrOpcode::kInt32Sub: - return VisitWordCompare(this, value, kX64Cmp32, &cont); + return VisitWordCompare(selector, value, kX64Cmp32, cont); case IrOpcode::kInt64Sub: - return VisitWord64Compare(this, value, &cont); + return VisitWord64Compare(selector, value, cont); case IrOpcode::kWord32And: - return VisitWordCompare(this, value, kX64Test32, &cont); + return VisitWordCompare(selector, value, kX64Test32, cont); case IrOpcode::kWord64And: - return VisitWordCompare(this, value, kX64Test, &cont); + return VisitWordCompare(selector, value, kX64Test, cont); default: break; } + break; } // Branch could not be combined with a compare, emit compare against 0. - VisitCompareZero(this, value, kX64Cmp32, &cont); + VisitCompareZero(selector, value, kX64Cmp32, cont); +} + +} // 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) { X64OperandGenerator g(this); @@ -1674,7 +1829,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { void InstructionSelector::VisitWord32Equal(Node* const node) { Node* user = node; - FlagsContinuation cont(kEqual, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); Int32BinopMatcher m(user); if (m.right().Is(0)) { Node* value = m.left().node(); @@ -1709,31 +1864,33 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { void InstructionSelector::VisitInt32LessThan(Node* node) { - FlagsContinuation cont(kSignedLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); VisitWordCompare(this, node, kX64Cmp32, &cont); } void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { - FlagsContinuation cont(kSignedLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); VisitWordCompare(this, node, kX64Cmp32, &cont); } void InstructionSelector::VisitUint32LessThan(Node* node) { - FlagsContinuation cont(kUnsignedLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); VisitWordCompare(this, node, kX64Cmp32, &cont); } void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { - FlagsContinuation cont(kUnsignedLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); VisitWordCompare(this, node, kX64Cmp32, &cont); } void InstructionSelector::VisitWord64Equal(Node* const node) { - FlagsContinuation cont(kEqual, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); Int64BinopMatcher m(node); if (m.right().Is(0)) { // Try to combine the equality check with a comparison. @@ -1756,8 +1913,8 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) { - FlagsContinuation cont(kOverflow, ovf); - VisitBinop(this, node, kX64Add32, &cont); + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); + return VisitBinop(this, node, kX64Add32, &cont); } FlagsContinuation cont; VisitBinop(this, node, kX64Add32, &cont); @@ -1766,7 +1923,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, kX64Sub32, &cont); } FlagsContinuation cont; @@ -1775,61 +1932,67 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { void InstructionSelector::VisitInt64LessThan(Node* node) { - FlagsContinuation cont(kSignedLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); VisitWord64Compare(this, node, &cont); } void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { - FlagsContinuation cont(kSignedLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); VisitWord64Compare(this, node, &cont); } void InstructionSelector::VisitUint64LessThan(Node* node) { - FlagsContinuation cont(kUnsignedLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); VisitWord64Compare(this, node, &cont); } void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { - FlagsContinuation cont(kUnsignedLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); VisitWord64Compare(this, node, &cont); } 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); } |