Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
index c3e45a1..19ea062 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -75,7 +75,9 @@
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::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 @@
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:
@@ -152,29 +160,8 @@
}
return ReduceWord32Shifts(node);
}
- case IrOpcode::kWord32Sar: {
- Int32BinopMatcher m(node);
- if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x
- if (m.IsFoldable()) { // K >> K => K
- return ReplaceInt32(m.left().Value() >> m.right().Value());
- }
- if (m.left().IsWord32Shl()) {
- Int32BinopMatcher mleft(m.left().node());
- if (mleft.left().IsLoad()) {
- LoadRepresentation const rep =
- OpParameter<LoadRepresentation>(mleft.left().node());
- if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) {
- // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
- return Replace(mleft.left().node());
- }
- if (m.right().Is(16) && mleft.right().Is(16) && rep == kMachInt16) {
- // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
- return Replace(mleft.left().node());
- }
- }
- }
- return ReduceWord32Shifts(node);
- }
+ case IrOpcode::kWord32Sar:
+ return ReduceWord32Sar(node);
case IrOpcode::kWord32Ror: {
Int32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x
@@ -216,16 +203,8 @@
}
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
@@ -234,14 +213,14 @@
return ReplaceInt32(m.left().Value() * m.right().Value());
}
if (m.right().Is(-1)) { // x * -1 => 0 - x
- node->set_op(machine()->Int32Sub());
node->ReplaceInput(0, Int32Constant(0));
node->ReplaceInput(1, m.left().node());
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
return Changed(node);
}
if (m.right().IsPowerOf2()) { // x * 2^n => x << n
- node->set_op(machine()->Word32Shl());
node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
+ NodeProperties::ChangeOp(node, machine()->Word32Shl());
Reduction reduction = ReduceWord32Shl(node);
return reduction.Changed() ? reduction : Changed(node);
}
@@ -359,9 +338,9 @@
case IrOpcode::kFloat64Mul: {
Float64BinopMatcher m(node);
if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x
- node->set_op(machine()->Float64Sub());
node->ReplaceInput(0, Float64Constant(-0.0));
node->ReplaceInput(1, m.left().node());
+ NodeProperties::ChangeOp(node, machine()->Float64Sub());
return Changed(node);
}
if (m.right().Is(1)) return Replace(m.left().node()); // x * 1.0 => x
@@ -390,7 +369,7 @@
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());
@@ -454,8 +433,16 @@
if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
break;
}
+ case IrOpcode::kFloat64InsertLowWord32:
+ return ReduceFloat64InsertLowWord32(node);
+ case IrOpcode::kFloat64InsertHighWord32:
+ return ReduceFloat64InsertHighWord32(node);
case IrOpcode::kStore:
return ReduceStore(node);
+ case IrOpcode::kFloat64Equal:
+ case IrOpcode::kFloat64LessThan:
+ case IrOpcode::kFloat64LessThanOrEqual:
+ return ReduceFloat64Compare(node);
default:
break;
}
@@ -471,6 +458,44 @@
return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) +
bit_cast<uint32_t>(m.right().Value()));
}
+ if (m.left().IsInt32Sub()) {
+ Int32BinopMatcher mleft(m.left().node());
+ if (mleft.left().Is(0)) { // (0 - x) + y => y - x
+ node->ReplaceInput(0, m.right().node());
+ node->ReplaceInput(1, mleft.right().node());
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
+ Reduction const reduction = ReduceInt32Sub(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ }
+ if (m.right().IsInt32Sub()) {
+ Int32BinopMatcher mright(m.right().node());
+ if (mright.left().Is(0)) { // y + (0 - x) => y - x
+ node->ReplaceInput(1, mright.right().node());
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
+ Reduction const reduction = ReduceInt32Sub(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ }
+ return NoChange();
+}
+
+
+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->ReplaceInput(1, Int32Constant(-m.right().Value()));
+ NodeProperties::ChangeOp(node, machine()->Int32Add());
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
return NoChange();
}
@@ -489,10 +514,10 @@
return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
}
if (m.right().Is(-1)) { // x / -1 => 0 - x
- node->set_op(machine()->Int32Sub());
node->ReplaceInput(0, Int32Constant(0));
node->ReplaceInput(1, m.left().node());
node->TrimInputCount(2);
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
return Changed(node);
}
if (m.right().HasValue()) {
@@ -501,7 +526,7 @@
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);
}
@@ -511,10 +536,10 @@
quotient = Int32Div(quotient, Abs(divisor));
}
if (divisor < 0) {
- node->set_op(machine()->Int32Sub());
node->ReplaceInput(0, Int32Constant(0));
node->ReplaceInput(1, quotient);
node->TrimInputCount(2);
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
return Changed(node);
}
return Replace(quotient);
@@ -540,9 +565,9 @@
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);
+ NodeProperties::ChangeOp(node, machine()->Word32Shr());
return Changed(node);
} else {
return Replace(Uint32Div(dividend, divisor));
@@ -569,18 +594,20 @@
if (base::bits::IsPowerOfTwo32(divisor)) {
uint32_t const mask = divisor - 1;
Node* const zero = Int32Constant(0);
- node->set_op(common()->Select(kMachInt32, BranchHint::kFalse));
node->ReplaceInput(
0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero));
node->ReplaceInput(
1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)));
node->ReplaceInput(2, Word32And(dividend, mask));
+ NodeProperties::ChangeOp(
+ node,
+ common()->Select(MachineRepresentation::kWord32, BranchHint::kFalse));
} else {
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);
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
}
return Changed(node);
}
@@ -602,15 +629,16 @@
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));
+ node->TrimInputCount(2);
+ NodeProperties::ChangeOp(node, machine()->Word32And());
} 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);
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
}
- node->TrimInputCount(2);
return Changed(node);
}
return NoChange();
@@ -623,23 +651,24 @@
if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
if (m.IsPhi()) {
Node* const phi = m.node();
- DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi)));
+ DCHECK_EQ(MachineRepresentation::kFloat64, PhiRepresentationOf(phi->op()));
if (phi->OwnedBy(node)) {
- // TruncateFloat64ToInt32(Phi[Float64](x1,...,xn))
- // => Phi[Int32](TruncateFloat64ToInt32(x1),
+ // TruncateFloat64ToInt32[mode](Phi[Float64](x1,...,xn))
+ // => Phi[Int32](TruncateFloat64ToInt32[mode](x1),
// ...,
- // TruncateFloat64ToInt32(xn))
+ // TruncateFloat64ToInt32[mode](xn))
const int value_input_count = phi->InputCount() - 1;
for (int i = 0; i < value_input_count; ++i) {
- Node* input = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
- phi->InputAt(i));
+ Node* input = graph()->NewNode(node->op(), phi->InputAt(i));
// TODO(bmeurer): Reschedule input for reduction once we have Revisit()
// instead of recursing into ReduceTruncateFloat64ToInt32() here.
Reduction reduction = ReduceTruncateFloat64ToInt32(input);
if (reduction.Changed()) input = reduction.replacement();
phi->ReplaceInput(i, input);
}
- phi->set_op(common()->Phi(kMachInt32, value_input_count));
+ NodeProperties::ChangeOp(
+ phi,
+ common()->Phi(MachineRepresentation::kWord32, value_input_count));
return Replace(phi);
}
}
@@ -648,15 +677,16 @@
Reduction MachineOperatorReducer::ReduceStore(Node* node) {
- MachineType const rep =
- RepresentationOf(StoreRepresentationOf(node->op()).machine_type());
+ MachineRepresentation const rep =
+ StoreRepresentationOf(node->op()).representation();
Node* const value = node->InputAt(2);
switch (value->opcode()) {
case IrOpcode::kWord32And: {
Uint32BinopMatcher m(value);
- if (m.right().HasValue() &&
- ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
- (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
+ if (m.right().HasValue() && ((rep == MachineRepresentation::kWord8 &&
+ (m.right().Value() & 0xff) == 0xff) ||
+ (rep == MachineRepresentation::kWord16 &&
+ (m.right().Value() & 0xffff) == 0xffff))) {
node->ReplaceInput(2, m.left().node());
return Changed(node);
}
@@ -664,9 +694,10 @@
}
case IrOpcode::kWord32Sar: {
Int32BinopMatcher m(value);
- if (m.left().IsWord32Shl() &&
- ((rep == kRepWord8 && m.right().IsInRange(1, 24)) ||
- (rep == kRepWord16 && m.right().IsInRange(1, 16)))) {
+ if (m.left().IsWord32Shl() && ((rep == MachineRepresentation::kWord8 &&
+ m.right().IsInRange(1, 24)) ||
+ (rep == MachineRepresentation::kWord16 &&
+ m.right().IsInRange(1, 16)))) {
Int32BinopMatcher mleft(m.left().node());
if (mleft.right().Is(m.right().Value())) {
node->ReplaceInput(2, mleft.left().node());
@@ -752,10 +783,10 @@
if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) {
Int32BinopMatcher mleft(m.left().node());
if (mleft.right().Is(m.right().Value())) {
- node->set_op(machine()->Word32And());
node->ReplaceInput(0, mleft.left().node());
node->ReplaceInput(1,
Uint32Constant(~((1U << m.right().Value()) - 1U)));
+ NodeProperties::ChangeOp(node, machine()->Word32And());
Reduction reduction = ReduceWord32And(node);
return reduction.Changed() ? reduction : Changed(node);
}
@@ -765,11 +796,50 @@
}
+Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
+ Int32BinopMatcher m(node);
+ if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x
+ if (m.IsFoldable()) { // K >> K => K
+ return ReplaceInt32(m.left().Value() >> m.right().Value());
+ }
+ if (m.left().IsWord32Shl()) {
+ Int32BinopMatcher mleft(m.left().node());
+ if (mleft.left().IsComparison()) {
+ if (m.right().Is(31) && mleft.right().Is(31)) {
+ // Comparison << 31 >> 31 => 0 - Comparison
+ node->ReplaceInput(0, Int32Constant(0));
+ node->ReplaceInput(1, mleft.left().node());
+ NodeProperties::ChangeOp(node, machine()->Int32Sub());
+ Reduction const reduction = ReduceInt32Sub(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ } else if (mleft.left().IsLoad()) {
+ LoadRepresentation const rep =
+ LoadRepresentationOf(mleft.left().node()->op());
+ if (m.right().Is(24) && mleft.right().Is(24) &&
+ rep == MachineType::Int8()) {
+ // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
+ return Replace(mleft.left().node());
+ }
+ if (m.right().Is(16) && mleft.right().Is(16) &&
+ rep == MachineType::Int16()) {
+ // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
+ return Replace(mleft.left().node());
+ }
+ }
+ }
+ return ReduceWord32Shifts(node);
+}
+
+
Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
DCHECK_EQ(IrOpcode::kWord32And, node->opcode());
Int32BinopMatcher m(node);
if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0
if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x
+ if (m.left().IsComparison() && m.right().Is(1)) { // CMP & 1 => CMP
+ return Replace(m.left().node());
+ }
if (m.IsFoldable()) { // K & K => K
return ReplaceInt32(m.left().Value() & m.right().Value());
}
@@ -784,63 +854,79 @@
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 (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());
}
- }
- 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)
- node->set_op(machine()->Int32Add());
+ } 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->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
- node->ReplaceInput(1, mleftright.node());
+ node->ReplaceInput(1, mleft.right().node());
+ NodeProperties::ChangeOp(node, machine()->Int32Add());
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->ReplaceInput(0,
+ Word32And(mleft.right().node(), m.right().node()));
+ node->ReplaceInput(1, mleftleft.node());
+ NodeProperties::ChangeOp(node, machine()->Int32Add());
+ 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->ReplaceInput(0,
+ Word32And(mleft.left().node(), m.right().node()));
+ node->ReplaceInput(1, mleftright.node());
+ NodeProperties::ChangeOp(node, machine()->Int32Add());
+ 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->ReplaceInput(0,
+ Word32And(mleft.right().node(), m.right().node()));
+ node->ReplaceInput(1, mleftleft.node());
+ NodeProperties::ChangeOp(node, machine()->Int32Add());
+ 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->ReplaceInput(0,
+ Word32And(mleft.left().node(), m.right().node()));
+ node->ReplaceInput(1, mleftright.node());
+ NodeProperties::ChangeOp(node, machine()->Int32Add());
+ Reduction const reduction = ReduceInt32Add(node);
+ return reduction.Changed() ? reduction : Changed(node);
+ }
+ }
+ } else if (m.left().IsInt32Mul()) {
+ Int32BinopMatcher mleft(m.left().node());
+ if (mleft.right().IsMultipleOf(-mask)) {
+ // (x * (K << L)) & (-1 << L) => x * (K << L)
+ return Replace(mleft.node());
}
}
}
@@ -858,8 +944,8 @@
}
if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x
- Node* shl = NULL;
- Node* shr = NULL;
+ Node* shl = nullptr;
+ Node* shr = nullptr;
// Recognize rotation, we are matching either:
// * x << y | x >>> (32 - y) => x ror (32 - y), i.e x rol y
// * x << (32 - y) | x >>> y => x ror y
@@ -882,8 +968,8 @@
// Case where y is a constant.
if (mshl.right().Value() + mshr.right().Value() != 32) return NoChange();
} else {
- Node* sub = NULL;
- Node* y = NULL;
+ Node* sub = nullptr;
+ Node* y = nullptr;
if (mshl.right().IsInt32Sub()) {
sub = mshl.right().node();
y = mshr.right().node();
@@ -898,13 +984,96 @@
if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
}
- node->set_op(machine()->Word32Ror());
node->ReplaceInput(0, mshl.left().node());
node->ReplaceInput(1, mshr.right().node());
+ NodeProperties::ChangeOp(node, machine()->Word32Ror());
return Changed(node);
}
+Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) {
+ DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode());
+ Float64Matcher mlhs(node->InputAt(0));
+ Uint32Matcher mrhs(node->InputAt(1));
+ if (mlhs.HasValue() && mrhs.HasValue()) {
+ return ReplaceFloat64(bit_cast<double>(
+ (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF00000000)) |
+ mrhs.Value()));
+ }
+ return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceFloat64InsertHighWord32(Node* node) {
+ DCHECK_EQ(IrOpcode::kFloat64InsertHighWord32, node->opcode());
+ Float64Matcher mlhs(node->InputAt(0));
+ Uint32Matcher mrhs(node->InputAt(1));
+ if (mlhs.HasValue() && mrhs.HasValue()) {
+ return ReplaceFloat64(bit_cast<double>(
+ (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF)) |
+ (static_cast<uint64_t>(mrhs.Value()) << 32)));
+ }
+ return NoChange();
+}
+
+
+namespace {
+
+bool IsFloat64RepresentableAsFloat32(const Float64Matcher& m) {
+ if (m.HasValue()) {
+ double v = m.Value();
+ float fv = static_cast<float>(v);
+ return static_cast<double>(fv) == v;
+ }
+ return false;
+}
+
+} // namespace
+
+
+Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) {
+ DCHECK((IrOpcode::kFloat64Equal == node->opcode()) ||
+ (IrOpcode::kFloat64LessThan == node->opcode()) ||
+ (IrOpcode::kFloat64LessThanOrEqual == node->opcode()));
+ // As all Float32 values have an exact representation in Float64, comparing
+ // two Float64 values both converted from Float32 is equivalent to comparing
+ // the original Float32s, so we can ignore the conversions. We can also reduce
+ // comparisons of converted Float64 values against constants that can be
+ // represented exactly as Float32.
+ Float64BinopMatcher m(node);
+ if ((m.left().IsChangeFloat32ToFloat64() &&
+ m.right().IsChangeFloat32ToFloat64()) ||
+ (m.left().IsChangeFloat32ToFloat64() &&
+ IsFloat64RepresentableAsFloat32(m.right())) ||
+ (IsFloat64RepresentableAsFloat32(m.left()) &&
+ m.right().IsChangeFloat32ToFloat64())) {
+ switch (node->opcode()) {
+ case IrOpcode::kFloat64Equal:
+ NodeProperties::ChangeOp(node, machine()->Float32Equal());
+ break;
+ case IrOpcode::kFloat64LessThan:
+ NodeProperties::ChangeOp(node, machine()->Float32LessThan());
+ break;
+ case IrOpcode::kFloat64LessThanOrEqual:
+ NodeProperties::ChangeOp(node, machine()->Float32LessThanOrEqual());
+ break;
+ default:
+ return NoChange();
+ }
+ node->ReplaceInput(
+ 0, m.left().HasValue()
+ ? Float32Constant(static_cast<float>(m.left().Value()))
+ : m.left().InputAt(0));
+ node->ReplaceInput(
+ 1, m.right().HasValue()
+ ? Float32Constant(static_cast<float>(m.right().Value()))
+ : m.right().InputAt(0));
+ return Changed(node);
+ }
+ return NoChange();
+}
+
+
CommonOperatorBuilder* MachineOperatorReducer::common() const {
return jsgraph()->common();
}