Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Unified Diff: src/compiler/simplified-lowering.cc

Issue 681133004: [turbofan] Complete support for integer division/modulus in simplified lowering. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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));
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698