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)); |