| Index: src/compiler/machine-operator-reducer.cc
|
| diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
|
| index 3803af5e34f99dfb64de1b6180c3fa5781e3c8d6..1f73262f95f63a6a25cee83bcbe2d355c3bb58b2 100644
|
| --- a/src/compiler/machine-operator-reducer.cc
|
| +++ b/src/compiler/machine-operator-reducer.cc
|
| @@ -49,11 +49,13 @@ Node* MachineOperatorReducer::Word32And(Node* lhs, uint32_t rhs) {
|
|
|
|
|
| Node* MachineOperatorReducer::Word32Sar(Node* lhs, uint32_t rhs) {
|
| + if (rhs == 0) return lhs;
|
| return graph()->NewNode(machine()->Word32Sar(), lhs, Uint32Constant(rhs));
|
| }
|
|
|
|
|
| Node* MachineOperatorReducer::Word32Shr(Node* lhs, uint32_t rhs) {
|
| + if (rhs == 0) return lhs;
|
| return graph()->NewNode(machine()->Word32Shr(), lhs, Uint32Constant(rhs));
|
| }
|
|
|
| @@ -78,7 +80,8 @@ Node* MachineOperatorReducer::Int32Mul(Node* lhs, Node* rhs) {
|
| }
|
|
|
|
|
| -Node* MachineOperatorReducer::TruncatingDiv(Node* dividend, int32_t divisor) {
|
| +Node* MachineOperatorReducer::Int32Div(Node* dividend, int32_t divisor) {
|
| + DCHECK_NE(0, divisor);
|
| DCHECK_NE(std::numeric_limits<int32_t>::min(), divisor);
|
| base::MagicNumbersForDivision<uint32_t> const mag =
|
| base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
|
| @@ -89,10 +92,25 @@ Node* MachineOperatorReducer::TruncatingDiv(Node* dividend, int32_t divisor) {
|
| } else if (divisor < 0 && bit_cast<int32_t>(mag.multiplier) > 0) {
|
| quotient = Int32Sub(quotient, dividend);
|
| }
|
| - if (mag.shift) {
|
| - quotient = Word32Sar(quotient, mag.shift);
|
| + return Int32Add(Word32Sar(quotient, mag.shift), Word32Shr(dividend, 31));
|
| +}
|
| +
|
| +
|
| +Node* MachineOperatorReducer::Uint32Div(Node* dividend, uint32_t divisor) {
|
| + DCHECK_LT(0, divisor);
|
| + base::MagicNumbersForDivision<uint32_t> const mag =
|
| + base::UnsignedDivisionByConstant(bit_cast<uint32_t>(divisor));
|
| + Node* quotient = graph()->NewNode(machine()->Uint32MulHigh(), dividend,
|
| + Uint32Constant(mag.multiplier));
|
| + if (mag.add) {
|
| + DCHECK_LE(1, mag.shift);
|
| + quotient = Word32Shr(
|
| + Int32Add(Word32Shr(Int32Sub(dividend, quotient), 1), quotient),
|
| + mag.shift - 1);
|
| + } else {
|
| + quotient = Word32Shr(quotient, mag.shift);
|
| }
|
| - return Int32Add(quotient, Word32Shr(dividend, 31));
|
| + return quotient;
|
| }
|
|
|
|
|
| @@ -572,7 +590,7 @@ Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
|
| quotient = Int32Add(Word32Shr(quotient, 32u - shift), dividend);
|
| quotient = Word32Sar(quotient, shift);
|
| } else {
|
| - quotient = TruncatingDiv(quotient, Abs(divisor));
|
| + quotient = Int32Div(quotient, Abs(divisor));
|
| }
|
| if (divisor < 0) {
|
| node->set_op(machine()->Int32Sub());
|
| @@ -600,11 +618,17 @@ Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) {
|
| Node* const zero = Int32Constant(0);
|
| return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
|
| }
|
| - if (m.right().IsPowerOf2()) { // x / 2^n => x >> n
|
| - node->TrimInputCount(2);
|
| - node->set_op(machine()->Word32Shr());
|
| - node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
|
| - return Changed(node);
|
| + if (m.right().HasValue()) {
|
| + Node* const dividend = m.left().node();
|
| + uint32_t const divisor = m.right().Value();
|
| + if (base::bits::IsPowerOfTwo32(divisor)) { // x / 2^n => x >> n
|
| + node->set_op(machine()->Word32Shr());
|
| + node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
|
| + node->TrimInputCount(2);
|
| + return Changed(node);
|
| + } else {
|
| + return Replace(Uint32Div(dividend, divisor));
|
| + }
|
| }
|
| return NoChange();
|
| }
|
| @@ -640,17 +664,20 @@ Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) {
|
| Node* pos = Word32And(dividend, mask);
|
|
|
| Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
| - Node* phi =
|
| - graph()->NewNode(common()->Phi(kMachInt32, 2), neg, pos, merge);
|
| - return Replace(phi);
|
| +
|
| + DCHECK_EQ(3, node->InputCount());
|
| + node->set_op(common()->Phi(kMachInt32, 2));
|
| + node->ReplaceInput(0, neg);
|
| + node->ReplaceInput(1, pos);
|
| + node->ReplaceInput(2, merge);
|
| } else {
|
| - Node* quotient = TruncatingDiv(dividend, divisor);
|
| + Node* quotient = Int32Div(dividend, divisor);
|
| node->set_op(machine()->Int32Sub());
|
| DCHECK_EQ(dividend, node->InputAt(0));
|
| node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
|
| node->TrimInputCount(2);
|
| - return Changed(node);
|
| }
|
| + return Changed(node);
|
| }
|
| return NoChange();
|
| }
|
| @@ -666,10 +693,19 @@ Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
|
| return ReplaceUint32(
|
| base::bits::UnsignedMod32(m.left().Value(), m.right().Value()));
|
| }
|
| - if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1
|
| + if (m.right().HasValue()) {
|
| + Node* const dividend = m.left().node();
|
| + uint32_t const divisor = m.right().Value();
|
| + if (base::bits::IsPowerOfTwo32(divisor)) { // x % 2^n => x & 2^n-1
|
| + node->set_op(machine()->Word32And());
|
| + node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
|
| + } else {
|
| + Node* quotient = Uint32Div(dividend, divisor);
|
| + node->set_op(machine()->Int32Sub());
|
| + DCHECK_EQ(dividend, node->InputAt(0));
|
| + node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor)));
|
| + }
|
| node->TrimInputCount(2);
|
| - node->set_op(machine()->Word32And());
|
| - node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
|
| return Changed(node);
|
| }
|
| return NoChange();
|
|
|