Index: src/compiler/machine-operator-reducer.cc |
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc |
index fe579689bf9ccca7015bb395c5788859ebe7ddd4..00c998d81a04be79a8606a74d9657d238714d4e4 100644 |
--- a/src/compiler/machine-operator-reducer.cc |
+++ b/src/compiler/machine-operator-reducer.cc |
@@ -119,38 +119,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { |
switch (node->opcode()) { |
case IrOpcode::kProjection: |
return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0)); |
- case IrOpcode::kWord32And: { |
- 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.IsFoldable()) { // K & K => K |
- return ReplaceInt32(m.left().Value() & m.right().Value()); |
- } |
- if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x |
- if (m.left().IsWord32And() && m.right().HasValue()) { |
- Int32BinopMatcher mleft(m.left().node()); |
- if (mleft.right().HasValue()) { // (x & K) & K => x & K |
- node->ReplaceInput(0, mleft.left().node()); |
- node->ReplaceInput( |
- 1, Int32Constant(m.right().Value() & mleft.right().Value())); |
- return 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) & K => (x & K) + K |
- return Replace(graph()->NewNode( |
- machine()->Int32Add(), |
- graph()->NewNode(machine()->Word32And(), mleft.left().node(), |
- m.right().node()), |
- mleft.right().node())); |
- } |
- } |
- break; |
- } |
+ case IrOpcode::kWord32And: |
+ return ReduceWord32And(node); |
case IrOpcode::kWord32Or: |
return ReduceWord32Or(node); |
case IrOpcode::kWord32Xor: { |
@@ -168,28 +138,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { |
} |
break; |
} |
- case IrOpcode::kWord32Shl: { |
- 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.right().IsInRange(1, 31)) { |
- // (x >>> K) << K => x & ~(2^K - 1) |
- // (x >> K) << K => x & ~(2^K - 1) |
- 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))); |
- return Changed(node); |
- } |
- } |
- } |
- return ReduceWord32Shifts(node); |
- } |
+ case IrOpcode::kWord32Shl: |
+ return ReduceWord32Shl(node); |
case IrOpcode::kWord32Shr: { |
Uint32BinopMatcher m(node); |
if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x |
@@ -295,7 +245,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { |
if (m.right().IsPowerOf2()) { // x * 2^n => x << n |
node->set_op(machine()->Word32Shl()); |
node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); |
- return Changed(node); |
+ Reduction reduction = ReduceWord32Shl(node); |
+ return reduction.Changed() ? reduction : Changed(node); |
} |
break; |
} |
@@ -763,7 +714,6 @@ Reduction MachineOperatorReducer::ReduceWord32Shifts(Node* node) { |
DCHECK((node->opcode() == IrOpcode::kWord32Shl) || |
(node->opcode() == IrOpcode::kWord32Shr) || |
(node->opcode() == IrOpcode::kWord32Sar)); |
- |
if (machine()->Word32ShiftIsSafe()) { |
// Remove the explicit 'and' with 0x1f if the shift provided by the machine |
// instruction matches that required by JavaScript. |
@@ -780,9 +730,69 @@ Reduction MachineOperatorReducer::ReduceWord32Shifts(Node* node) { |
} |
-Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { |
- DCHECK(node->opcode() == IrOpcode::kWord32Or); |
+Reduction MachineOperatorReducer::ReduceWord32Shl(Node* node) { |
+ DCHECK_EQ(IrOpcode::kWord32Shl, 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(m.left().Value() << m.right().Value()); |
+ } |
+ if (m.right().IsInRange(1, 31)) { |
+ // (x >>> K) << K => x & ~(2^K - 1) |
+ // (x >> K) << K => x & ~(2^K - 1) |
+ 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))); |
+ Reduction reduction = ReduceWord32And(node); |
+ return reduction.Changed() ? reduction : Changed(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.IsFoldable()) { // K & K => K |
+ return ReplaceInt32(m.left().Value() & m.right().Value()); |
+ } |
+ if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x |
+ if (m.left().IsWord32And() && m.right().HasValue()) { |
+ Int32BinopMatcher mleft(m.left().node()); |
+ if (mleft.right().HasValue()) { // (x & K) & K => x & K |
+ node->ReplaceInput(0, mleft.left().node()); |
+ node->ReplaceInput( |
+ 1, Int32Constant(m.right().Value() & mleft.right().Value())); |
+ Reduction reduction = ReduceWord32And(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) & K => (x & K) + K |
+ return Replace(graph()->NewNode( |
+ machine()->Int32Add(), |
+ graph()->NewNode(machine()->Word32And(), mleft.left().node(), |
+ m.right().node()), |
+ mleft.right().node())); |
+ } |
+ } |
+ return NoChange(); |
+} |
+ |
+ |
+Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { |
+ DCHECK_EQ(IrOpcode::kWord32Or, node->opcode()); |
Int32BinopMatcher m(node); |
if (m.right().Is(0)) return Replace(m.left().node()); // x | 0 => x |
if (m.right().Is(-1)) return Replace(m.right().node()); // x | -1 => -1 |