| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index edb5a2c91de49e8957f89ded458b0758036bdf45..35707f287b95a9135cb3067190058942bb84a0ab 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -605,19 +605,17 @@ class RepresentationSelector {
|
| break;
|
| }
|
| case IrOpcode::kNumberDivide: {
|
| - NumberMatcher right(node->InputAt(1));
|
| - if (right.HasValue() && !right.Is(0) && !right.Is(-1)) {
|
| - if (CanLowerToInt32Binop(node, use)) {
|
| - // => signed Int32Div
|
| - VisitInt32Binop(node);
|
| - if (lower()) node->set_op(Int32Op(node));
|
| - break;
|
| - } else if (CanLowerToUint32Binop(node, use)) {
|
| - // => unsigned Uint32Div
|
| - VisitUint32Binop(node);
|
| - if (lower()) node->set_op(Uint32Op(node));
|
| - break;
|
| - }
|
| + if (CanLowerToInt32Binop(node, use)) {
|
| + // => signed Int32Div
|
| + VisitInt32Binop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Div(node));
|
| + break;
|
| + }
|
| + if (CanLowerToUint32Binop(node, use)) {
|
| + // => unsigned Uint32Div
|
| + VisitUint32Binop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
|
| + break;
|
| }
|
| // => Float64Div
|
| VisitFloat64Binop(node);
|
| @@ -625,20 +623,17 @@ class RepresentationSelector {
|
| break;
|
| }
|
| case IrOpcode::kNumberModulus: {
|
| - NumberMatcher right(node->InputAt(1));
|
| - if (right.HasValue() && !right.Is(0) && !right.Is(-1)) {
|
| - if (BothInputsAre(node, Type::Signed32()) &&
|
| - !CanObserveMinusZero(use)) {
|
| - // => signed Int32Mod
|
| - VisitInt32Binop(node);
|
| - if (lower()) node->set_op(Int32Op(node));
|
| - break;
|
| - } else if (BothInputsAre(node, Type::Unsigned32())) {
|
| - // => unsigned Uint32Mod
|
| - VisitUint32Binop(node);
|
| - if (lower()) node->set_op(Uint32Op(node));
|
| - break;
|
| - }
|
| + if (CanLowerToInt32Binop(node, use)) {
|
| + // => signed Int32Mod
|
| + VisitInt32Binop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
|
| + break;
|
| + }
|
| + if (CanLowerToUint32Binop(node, use)) {
|
| + // => unsigned Uint32Mod
|
| + VisitUint32Binop(node);
|
| + if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
|
| + break;
|
| }
|
| // => Float64Mod
|
| VisitFloat64Binop(node);
|
| @@ -1218,6 +1213,148 @@ Node* SimplifiedLowering::StringComparison(Node* node, bool requires_ordering) {
|
| }
|
|
|
|
|
| +Node* SimplifiedLowering::Int32Div(Node* const node) {
|
| + Int32BinopMatcher m(node);
|
| + Node* const zero = jsgraph()->Int32Constant(0);
|
| + Node* const lhs = m.left().node();
|
| + Node* const rhs = m.right().node();
|
| +
|
| + if (m.right().Is(-1)) {
|
| + return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
|
| + } else if (m.right().Is(0)) {
|
| + return rhs;
|
| + } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
|
| + return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
|
| + }
|
| +
|
| + Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
|
| + Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0,
|
| + graph()->start());
|
| +
|
| + Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
|
| + Node* true0 = zero;
|
| +
|
| + Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
|
| + Node* false0 = nullptr;
|
| + {
|
| + Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs,
|
| + jsgraph()->Int32Constant(-1));
|
| + Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
|
| + check1, if_false0);
|
| +
|
| + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
|
| + Node* true1 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
|
| +
|
| + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
|
| + Node* false1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false1);
|
| +
|
| + if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
|
| + false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1,
|
| + if_false0);
|
| + }
|
| +
|
| + Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
|
| + return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0, merge0);
|
| +}
|
| +
|
| +
|
| +Node* SimplifiedLowering::Int32Mod(Node* const node) {
|
| + Int32BinopMatcher m(node);
|
| + Node* const zero = jsgraph()->Int32Constant(0);
|
| + Node* const lhs = m.left().node();
|
| + Node* const rhs = m.right().node();
|
| +
|
| + if (m.right().Is(-1) || m.right().Is(0)) {
|
| + return zero;
|
| + } else if (machine()->Int32ModIsSafe() || m.right().HasValue()) {
|
| + return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
|
| + }
|
| +
|
| + Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
|
| + Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0,
|
| + graph()->start());
|
| +
|
| + Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
|
| + Node* true0 = zero;
|
| +
|
| + Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
|
| + Node* false0 = nullptr;
|
| + {
|
| + Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs,
|
| + jsgraph()->Int32Constant(-1));
|
| + Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
|
| + check1, if_false0);
|
| +
|
| + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
|
| + Node* true1 = zero;
|
| +
|
| + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
|
| + Node* false1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false1);
|
| +
|
| + if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
|
| + false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1,
|
| + if_false0);
|
| + }
|
| +
|
| + Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
|
| + return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0, merge0);
|
| +}
|
| +
|
| +
|
| +Node* SimplifiedLowering::Uint32Div(Node* const node) {
|
| + Uint32BinopMatcher m(node);
|
| + Node* const zero = jsgraph()->Uint32Constant(0);
|
| + Node* const lhs = m.left().node();
|
| + Node* const rhs = m.right().node();
|
| +
|
| + if (m.right().Is(0)) {
|
| + return zero;
|
| + } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
|
| + return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
|
| + }
|
| +
|
| + Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
|
| + Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check,
|
| + graph()->start());
|
| +
|
| + Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* vtrue = zero;
|
| +
|
| + Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* vfalse = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, if_false);
|
| +
|
| + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
| + return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse, merge);
|
| +}
|
| +
|
| +
|
| +Node* SimplifiedLowering::Uint32Mod(Node* const node) {
|
| + Uint32BinopMatcher m(node);
|
| + Node* const zero = jsgraph()->Uint32Constant(0);
|
| + Node* const lhs = m.left().node();
|
| + Node* const rhs = m.right().node();
|
| +
|
| + if (m.right().Is(0)) {
|
| + return zero;
|
| + } else if (machine()->Uint32ModIsSafe() || m.right().HasValue()) {
|
| + return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
|
| + }
|
| +
|
| + Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
|
| + Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check,
|
| + graph()->start());
|
| +
|
| + Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* vtrue = zero;
|
| +
|
| + Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* vfalse = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_false);
|
| +
|
| + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
| + return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse, merge);
|
| +}
|
| +
|
| +
|
| void SimplifiedLowering::DoStringEqual(Node* node) {
|
| node->set_op(machine()->WordEqual());
|
| node->ReplaceInput(0, StringComparison(node, false));
|
|
|