diff options
Diffstat (limited to 'deps/v8/src/compiler/machine-operator-reducer.cc')
-rw-r--r-- | deps/v8/src/compiler/machine-operator-reducer.cc | 165 |
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); + } } } } |