| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/machine-operator-reducer.h" | 5 #include "src/compiler/machine-operator-reducer.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/compiler/diamond.h" | 10 #include "src/compiler/diamond.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 Node* MachineOperatorReducer::Int32Constant(int32_t value) { | 36 Node* MachineOperatorReducer::Int32Constant(int32_t value) { |
| 37 return jsgraph()->Int32Constant(value); | 37 return jsgraph()->Int32Constant(value); |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 Node* MachineOperatorReducer::Int64Constant(int64_t value) { | 41 Node* MachineOperatorReducer::Int64Constant(int64_t value) { |
| 42 return graph()->NewNode(common()->Int64Constant(value)); | 42 return graph()->NewNode(common()->Int64Constant(value)); |
| 43 } | 43 } |
| 44 | 44 |
| 45 | 45 |
| 46 Node* MachineOperatorReducer::Word32And(Node* lhs, uint32_t rhs) { | 46 Node* MachineOperatorReducer::Word32And(Node* lhs, Node* rhs) { |
| 47 return graph()->NewNode(machine()->Word32And(), lhs, Uint32Constant(rhs)); | 47 Node* const node = graph()->NewNode(machine()->Word32And(), lhs, rhs); |
| 48 Reduction const reduction = ReduceWord32And(node); |
| 49 return reduction.Changed() ? reduction.replacement() : node; |
| 48 } | 50 } |
| 49 | 51 |
| 50 | 52 |
| 51 Node* MachineOperatorReducer::Word32Sar(Node* lhs, uint32_t rhs) { | 53 Node* MachineOperatorReducer::Word32Sar(Node* lhs, uint32_t rhs) { |
| 52 if (rhs == 0) return lhs; | 54 if (rhs == 0) return lhs; |
| 53 return graph()->NewNode(machine()->Word32Sar(), lhs, Uint32Constant(rhs)); | 55 return graph()->NewNode(machine()->Word32Sar(), lhs, Uint32Constant(rhs)); |
| 54 } | 56 } |
| 55 | 57 |
| 56 | 58 |
| 57 Node* MachineOperatorReducer::Word32Shr(Node* lhs, uint32_t rhs) { | 59 Node* MachineOperatorReducer::Word32Shr(Node* lhs, uint32_t rhs) { |
| 58 if (rhs == 0) return lhs; | 60 if (rhs == 0) return lhs; |
| 59 return graph()->NewNode(machine()->Word32Shr(), lhs, Uint32Constant(rhs)); | 61 return graph()->NewNode(machine()->Word32Shr(), lhs, Uint32Constant(rhs)); |
| 60 } | 62 } |
| 61 | 63 |
| 62 | 64 |
| 63 Node* MachineOperatorReducer::Word32Equal(Node* lhs, Node* rhs) { | 65 Node* MachineOperatorReducer::Word32Equal(Node* lhs, Node* rhs) { |
| 64 return graph()->NewNode(machine()->Word32Equal(), lhs, rhs); | 66 return graph()->NewNode(machine()->Word32Equal(), lhs, rhs); |
| 65 } | 67 } |
| 66 | 68 |
| 67 | 69 |
| 68 Node* MachineOperatorReducer::Int32Add(Node* lhs, Node* rhs) { | 70 Node* MachineOperatorReducer::Int32Add(Node* lhs, Node* rhs) { |
| 69 return graph()->NewNode(machine()->Int32Add(), lhs, rhs); | 71 Node* const node = graph()->NewNode(machine()->Int32Add(), lhs, rhs); |
| 72 Reduction const reduction = ReduceInt32Add(node); |
| 73 return reduction.Changed() ? reduction.replacement() : node; |
| 70 } | 74 } |
| 71 | 75 |
| 72 | 76 |
| 73 Node* MachineOperatorReducer::Int32Sub(Node* lhs, Node* rhs) { | 77 Node* MachineOperatorReducer::Int32Sub(Node* lhs, Node* rhs) { |
| 74 return graph()->NewNode(machine()->Int32Sub(), lhs, rhs); | 78 return graph()->NewNode(machine()->Int32Sub(), lhs, rhs); |
| 75 } | 79 } |
| 76 | 80 |
| 77 | 81 |
| 78 Node* MachineOperatorReducer::Int32Mul(Node* lhs, Node* rhs) { | 82 Node* MachineOperatorReducer::Int32Mul(Node* lhs, Node* rhs) { |
| 79 return graph()->NewNode(machine()->Int32Mul(), lhs, rhs); | 83 return graph()->NewNode(machine()->Int32Mul(), lhs, rhs); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 if (m.left().IsInt64Sub() && m.right().Is(0)) { // x - y == 0 => x == y | 207 if (m.left().IsInt64Sub() && m.right().Is(0)) { // x - y == 0 => x == y |
| 204 Int64BinopMatcher msub(m.left().node()); | 208 Int64BinopMatcher msub(m.left().node()); |
| 205 node->ReplaceInput(0, msub.left().node()); | 209 node->ReplaceInput(0, msub.left().node()); |
| 206 node->ReplaceInput(1, msub.right().node()); | 210 node->ReplaceInput(1, msub.right().node()); |
| 207 return Changed(node); | 211 return Changed(node); |
| 208 } | 212 } |
| 209 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares | 213 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares |
| 210 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true | 214 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true |
| 211 break; | 215 break; |
| 212 } | 216 } |
| 213 case IrOpcode::kInt32Add: { | 217 case IrOpcode::kInt32Add: |
| 214 Int32BinopMatcher m(node); | 218 return ReduceInt32Add(node); |
| 215 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x | |
| 216 if (m.IsFoldable()) { // K + K => K | |
| 217 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) + | |
| 218 static_cast<uint32_t>(m.right().Value())); | |
| 219 } | |
| 220 break; | |
| 221 } | |
| 222 case IrOpcode::kInt32Sub: { | 219 case IrOpcode::kInt32Sub: { |
| 223 Int32BinopMatcher m(node); | 220 Int32BinopMatcher m(node); |
| 224 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x | 221 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x |
| 225 if (m.IsFoldable()) { // K - K => K | 222 if (m.IsFoldable()) { // K - K => K |
| 226 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - | 223 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - |
| 227 static_cast<uint32_t>(m.right().Value())); | 224 static_cast<uint32_t>(m.right().Value())); |
| 228 } | 225 } |
| 229 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0 | 226 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0 |
| 230 break; | 227 break; |
| 231 } | 228 } |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 456 } |
| 460 case IrOpcode::kStore: | 457 case IrOpcode::kStore: |
| 461 return ReduceStore(node); | 458 return ReduceStore(node); |
| 462 default: | 459 default: |
| 463 break; | 460 break; |
| 464 } | 461 } |
| 465 return NoChange(); | 462 return NoChange(); |
| 466 } | 463 } |
| 467 | 464 |
| 468 | 465 |
| 466 Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) { |
| 467 DCHECK_EQ(IrOpcode::kInt32Add, node->opcode()); |
| 468 Int32BinopMatcher m(node); |
| 469 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x |
| 470 if (m.IsFoldable()) { // K + K => K |
| 471 return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) + |
| 472 bit_cast<uint32_t>(m.right().Value())); |
| 473 } |
| 474 return NoChange(); |
| 475 } |
| 476 |
| 477 |
| 469 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) { | 478 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) { |
| 470 Int32BinopMatcher m(node); | 479 Int32BinopMatcher m(node); |
| 471 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 | 480 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 |
| 472 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 | 481 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 |
| 473 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x | 482 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x |
| 474 if (m.IsFoldable()) { // K / K => K | 483 if (m.IsFoldable()) { // K / K => K |
| 475 return ReplaceInt32( | 484 return ReplaceInt32( |
| 476 base::bits::SignedDiv32(m.left().Value(), m.right().Value())); | 485 base::bits::SignedDiv32(m.left().Value(), m.right().Value())); |
| 477 } | 486 } |
| 478 if (m.LeftEqualsRight()) { // x / x => x != 0 | 487 if (m.LeftEqualsRight()) { // x / x => x != 0 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 if (m.IsFoldable()) { // K & K => K | 773 if (m.IsFoldable()) { // K & K => K |
| 765 return ReplaceInt32(m.left().Value() & m.right().Value()); | 774 return ReplaceInt32(m.left().Value() & m.right().Value()); |
| 766 } | 775 } |
| 767 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x | 776 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x |
| 768 if (m.left().IsWord32And() && m.right().HasValue()) { | 777 if (m.left().IsWord32And() && m.right().HasValue()) { |
| 769 Int32BinopMatcher mleft(m.left().node()); | 778 Int32BinopMatcher mleft(m.left().node()); |
| 770 if (mleft.right().HasValue()) { // (x & K) & K => x & K | 779 if (mleft.right().HasValue()) { // (x & K) & K => x & K |
| 771 node->ReplaceInput(0, mleft.left().node()); | 780 node->ReplaceInput(0, mleft.left().node()); |
| 772 node->ReplaceInput( | 781 node->ReplaceInput( |
| 773 1, Int32Constant(m.right().Value() & mleft.right().Value())); | 782 1, Int32Constant(m.right().Value() & mleft.right().Value())); |
| 774 Reduction reduction = ReduceWord32And(node); | 783 Reduction const reduction = ReduceWord32And(node); |
| 775 return reduction.Changed() ? reduction : Changed(node); | 784 return reduction.Changed() ? reduction : Changed(node); |
| 776 } | 785 } |
| 777 } | 786 } |
| 778 if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) { | 787 if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) { |
| 779 Int32BinopMatcher mleft(m.left().node()); | 788 Int32BinopMatcher mleft(m.left().node()); |
| 780 if (mleft.right().HasValue() && | 789 if (mleft.right().HasValue() && |
| 781 (mleft.right().Value() & m.right().Value()) == mleft.right().Value()) { | 790 (mleft.right().Value() & m.right().Value()) == mleft.right().Value()) { |
| 782 // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L) | 791 // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L) |
| 783 return Replace(graph()->NewNode( | 792 node->set_op(machine()->Int32Add()); |
| 784 machine()->Int32Add(), | 793 node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node())); |
| 785 graph()->NewNode(machine()->Word32And(), mleft.left().node(), | 794 node->ReplaceInput(1, mleft.right().node()); |
| 786 m.right().node()), | 795 Reduction const reduction = ReduceInt32Add(node); |
| 787 mleft.right().node())); | 796 return reduction.Changed() ? reduction : Changed(node); |
| 788 } | 797 } |
| 789 if (mleft.left().IsWord32Shl()) { | 798 if (mleft.left().IsWord32Shl()) { |
| 790 Int32BinopMatcher mleftleft(mleft.left().node()); | 799 Int32BinopMatcher mleftleft(mleft.left().node()); |
| 791 if (mleftleft.right().Is( | 800 if (mleftleft.right().Is( |
| 792 base::bits::CountTrailingZeros32(m.right().Value()))) { | 801 base::bits::CountTrailingZeros32(m.right().Value()))) { |
| 793 // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L | 802 // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L |
| 794 return Replace(graph()->NewNode( | 803 node->set_op(machine()->Int32Add()); |
| 795 machine()->Int32Add(), | 804 node->ReplaceInput(0, |
| 796 graph()->NewNode(machine()->Word32And(), mleft.right().node(), | 805 Word32And(mleft.right().node(), m.right().node())); |
| 797 m.right().node()), | 806 node->ReplaceInput(1, mleftleft.node()); |
| 798 mleftleft.node())); | 807 Reduction const reduction = ReduceInt32Add(node); |
| 808 return reduction.Changed() ? reduction : Changed(node); |
| 799 } | 809 } |
| 800 } | 810 } |
| 801 if (mleft.right().IsWord32Shl()) { | 811 if (mleft.right().IsWord32Shl()) { |
| 802 Int32BinopMatcher mleftright(mleft.right().node()); | 812 Int32BinopMatcher mleftright(mleft.right().node()); |
| 803 if (mleftright.right().Is( | 813 if (mleftright.right().Is( |
| 804 base::bits::CountTrailingZeros32(m.right().Value()))) { | 814 base::bits::CountTrailingZeros32(m.right().Value()))) { |
| 805 // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L | 815 // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L |
| 806 return Replace(graph()->NewNode( | 816 node->set_op(machine()->Int32Add()); |
| 807 machine()->Int32Add(), | 817 node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node())); |
| 808 graph()->NewNode(machine()->Word32And(), mleft.left().node(), | 818 node->ReplaceInput(1, mleftright.node()); |
| 809 m.right().node()), | 819 Reduction const reduction = ReduceInt32Add(node); |
| 810 mleftright.node())); | 820 return reduction.Changed() ? reduction : Changed(node); |
| 811 } | 821 } |
| 812 } | 822 } |
| 813 } | 823 } |
| 814 return NoChange(); | 824 return NoChange(); |
| 815 } | 825 } |
| 816 | 826 |
| 817 | 827 |
| 818 Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { | 828 Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { |
| 819 DCHECK_EQ(IrOpcode::kWord32Or, node->opcode()); | 829 DCHECK_EQ(IrOpcode::kWord32Or, node->opcode()); |
| 820 Int32BinopMatcher m(node); | 830 Int32BinopMatcher m(node); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 890 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
| 881 return jsgraph()->machine(); | 891 return jsgraph()->machine(); |
| 882 } | 892 } |
| 883 | 893 |
| 884 | 894 |
| 885 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 895 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
| 886 | 896 |
| 887 } // namespace compiler | 897 } // namespace compiler |
| 888 } // namespace internal | 898 } // namespace internal |
| 889 } // namespace v8 | 899 } // namespace v8 |
| OLD | NEW |