aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/machine-operator-reducer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/machine-operator-reducer.cc')
-rw-r--r--deps/v8/src/compiler/machine-operator-reducer.cc165
1 files changed, 97 insertions, 68 deletions
diff --git a/deps/v8/src/compiler/machine-operator-reducer.cc b/deps/v8/src/compiler/machine-operator-reducer.cc
index c3e45a1b25..8f91d49f81 100644
--- a/deps/v8/src/compiler/machine-operator-reducer.cc
+++ b/deps/v8/src/compiler/machine-operator-reducer.cc
@@ -75,7 +75,9 @@ Node* MachineOperatorReducer::Int32Add(Node* lhs, Node* rhs) {
Node* MachineOperatorReducer::Int32Sub(Node* lhs, Node* rhs) {
- return graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+ Node* const node = graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+ Reduction const reduction = ReduceInt32Sub(node);
+ return reduction.Changed() ? reduction.replacement() : node;
}
@@ -101,13 +103,19 @@ Node* MachineOperatorReducer::Int32Div(Node* dividend, int32_t divisor) {
Node* MachineOperatorReducer::Uint32Div(Node* dividend, uint32_t divisor) {
- DCHECK_LT(0, divisor);
+ DCHECK_LT(0u, divisor);
+ // If the divisor is even, we can avoid using the expensive fixup by shifting
+ // the dividend upfront.
+ unsigned const shift = base::bits::CountTrailingZeros32(divisor);
+ dividend = Word32Shr(dividend, shift);
+ divisor >>= shift;
+ // Compute the magic number for the (shifted) divisor.
base::MagicNumbersForDivision<uint32_t> const mag =
- base::UnsignedDivisionByConstant(bit_cast<uint32_t>(divisor));
+ base::UnsignedDivisionByConstant(divisor, shift);
Node* quotient = graph()->NewNode(machine()->Uint32MulHigh(), dividend,
Uint32Constant(mag.multiplier));
if (mag.add) {
- DCHECK_LE(1, mag.shift);
+ DCHECK_LE(1u, mag.shift);
quotient = Word32Shr(
Int32Add(Word32Shr(Int32Sub(dividend, quotient), 1), quotient),
mag.shift - 1);
@@ -122,7 +130,7 @@ Node* MachineOperatorReducer::Uint32Div(Node* dividend, uint32_t divisor) {
Reduction MachineOperatorReducer::Reduce(Node* node) {
switch (node->opcode()) {
case IrOpcode::kProjection:
- return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0));
+ return ReduceProjection(ProjectionIndexOf(node->op()), node->InputAt(0));
case IrOpcode::kWord32And:
return ReduceWord32And(node);
case IrOpcode::kWord32Or:
@@ -216,16 +224,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
}
case IrOpcode::kInt32Add:
return ReduceInt32Add(node);
- case IrOpcode::kInt32Sub: {
- Int32BinopMatcher m(node);
- if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x
- if (m.IsFoldable()) { // K - K => K
- return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
- static_cast<uint32_t>(m.right().Value()));
- }
- if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0
- break;
- }
+ case IrOpcode::kInt32Sub:
+ return ReduceInt32Sub(node);
case IrOpcode::kInt32Mul: {
Int32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0
@@ -390,7 +390,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
case IrOpcode::kFloat64Mod: {
Float64BinopMatcher m(node);
if (m.right().Is(0)) { // x % 0 => NaN
- return ReplaceFloat64(base::OS::nan_value());
+ return ReplaceFloat64(std::numeric_limits<double>::quiet_NaN());
}
if (m.right().IsNaN()) { // x % NaN => NaN
return Replace(m.right().node());
@@ -475,6 +475,25 @@ Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) {
}
+Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
+ DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode());
+ Int32BinopMatcher m(node);
+ if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x
+ if (m.IsFoldable()) { // K - K => K
+ return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
+ static_cast<uint32_t>(m.right().Value()));
+ }
+ if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0
+ if (m.right().HasValue()) { // x - K => x + -K
+ node->set_op(machine()->Int32Add());
+ node->ReplaceInput(1, Int32Constant(-m.right().Value()));
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ return NoChange();
+}
+
+
Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
Int32BinopMatcher m(node);
if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
@@ -501,7 +520,7 @@ Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
Node* quotient = dividend;
if (base::bits::IsPowerOfTwo32(Abs(divisor))) {
uint32_t const shift = WhichPowerOf2Abs(divisor);
- DCHECK_NE(0, shift);
+ DCHECK_NE(0u, shift);
if (shift > 1) {
quotient = Word32Sar(quotient, 31);
}
@@ -784,63 +803,73 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
return reduction.Changed() ? reduction : Changed(node);
}
}
- if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) {
- Int32BinopMatcher mleft(m.left().node());
- if (mleft.right().HasValue() &&
- (mleft.right().Value() & m.right().Value()) == mleft.right().Value()) {
- // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
- node->set_op(machine()->Int32Add());
- node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
- node->ReplaceInput(1, mleft.right().node());
- Reduction const reduction = ReduceInt32Add(node);
- return reduction.Changed() ? reduction : Changed(node);
- }
- if (mleft.left().IsInt32Mul()) {
- Int32BinopMatcher mleftleft(mleft.left().node());
- if (mleftleft.right().IsMultipleOf(-m.right().Value())) {
- // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
- node->set_op(machine()->Int32Add());
- node->ReplaceInput(0,
- Word32And(mleft.right().node(), m.right().node()));
- node->ReplaceInput(1, mleftleft.node());
- Reduction const reduction = ReduceInt32Add(node);
- return reduction.Changed() ? reduction : Changed(node);
- }
- }
- if (mleft.right().IsInt32Mul()) {
- Int32BinopMatcher mleftright(mleft.right().node());
- if (mleftright.right().IsMultipleOf(-m.right().Value())) {
- // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+ if (m.right().IsNegativePowerOf2()) {
+ int32_t const mask = m.right().Value();
+ if (m.left().IsWord32Shl()) {
+ Uint32BinopMatcher mleft(m.left().node());
+ if (mleft.right().HasValue() &&
+ mleft.right().Value() >= base::bits::CountTrailingZeros32(mask)) {
+ // (x << L) & (-1 << K) => x << L iff K >= L
+ return Replace(mleft.node());
+ }
+ } else if (m.left().IsInt32Add()) {
+ Int32BinopMatcher mleft(m.left().node());
+ if (mleft.right().HasValue() &&
+ (mleft.right().Value() & mask) == mleft.right().Value()) {
+ // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
node->set_op(machine()->Int32Add());
node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
- node->ReplaceInput(1, mleftright.node());
+ node->ReplaceInput(1, mleft.right().node());
Reduction const reduction = ReduceInt32Add(node);
return reduction.Changed() ? reduction : Changed(node);
}
- }
- if (mleft.left().IsWord32Shl()) {
- Int32BinopMatcher mleftleft(mleft.left().node());
- if (mleftleft.right().Is(
- base::bits::CountTrailingZeros32(m.right().Value()))) {
- // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
- node->set_op(machine()->Int32Add());
- node->ReplaceInput(0,
- Word32And(mleft.right().node(), m.right().node()));
- node->ReplaceInput(1, mleftleft.node());
- Reduction const reduction = ReduceInt32Add(node);
- return reduction.Changed() ? reduction : Changed(node);
+ if (mleft.left().IsInt32Mul()) {
+ Int32BinopMatcher mleftleft(mleft.left().node());
+ if (mleftleft.right().IsMultipleOf(-mask)) {
+ // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+ node->set_op(machine()->Int32Add());
+ node->ReplaceInput(0,
+ Word32And(mleft.right().node(), m.right().node()));
+ node->ReplaceInput(1, mleftleft.node());
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
}
- }
- if (mleft.right().IsWord32Shl()) {
- Int32BinopMatcher mleftright(mleft.right().node());
- if (mleftright.right().Is(
- base::bits::CountTrailingZeros32(m.right().Value()))) {
- // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
- node->set_op(machine()->Int32Add());
- node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
- node->ReplaceInput(1, mleftright.node());
- Reduction const reduction = ReduceInt32Add(node);
- return reduction.Changed() ? reduction : Changed(node);
+ if (mleft.right().IsInt32Mul()) {
+ Int32BinopMatcher mleftright(mleft.right().node());
+ if (mleftright.right().IsMultipleOf(-mask)) {
+ // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+ node->set_op(machine()->Int32Add());
+ node->ReplaceInput(0,
+ Word32And(mleft.left().node(), m.right().node()));
+ node->ReplaceInput(1, mleftright.node());
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ }
+ if (mleft.left().IsWord32Shl()) {
+ Int32BinopMatcher mleftleft(mleft.left().node());
+ if (mleftleft.right().Is(base::bits::CountTrailingZeros32(mask))) {
+ // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
+ node->set_op(machine()->Int32Add());
+ node->ReplaceInput(0,
+ Word32And(mleft.right().node(), m.right().node()));
+ node->ReplaceInput(1, mleftleft.node());
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ }
+ if (mleft.right().IsWord32Shl()) {
+ Int32BinopMatcher mleftright(mleft.right().node());
+ if (mleftright.right().Is(base::bits::CountTrailingZeros32(mask))) {
+ // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
+ node->set_op(machine()->Int32Add());
+ node->ReplaceInput(0,
+ Word32And(mleft.left().node(), m.right().node()));
+ node->ReplaceInput(1, mleftright.node());
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
}
}
}