| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 case IrOpcode::kWord32Shl: | 153 case IrOpcode::kWord32Shl: |
| 154 return ReduceWord32Shl(node); | 154 return ReduceWord32Shl(node); |
| 155 case IrOpcode::kWord32Shr: { | 155 case IrOpcode::kWord32Shr: { |
| 156 Uint32BinopMatcher m(node); | 156 Uint32BinopMatcher m(node); |
| 157 if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x | 157 if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x |
| 158 if (m.IsFoldable()) { // K >>> K => K | 158 if (m.IsFoldable()) { // K >>> K => K |
| 159 return ReplaceInt32(m.left().Value() >> m.right().Value()); | 159 return ReplaceInt32(m.left().Value() >> m.right().Value()); |
| 160 } | 160 } |
| 161 return ReduceWord32Shifts(node); | 161 return ReduceWord32Shifts(node); |
| 162 } | 162 } |
| 163 case IrOpcode::kWord32Sar: { | 163 case IrOpcode::kWord32Sar: |
| 164 Int32BinopMatcher m(node); | 164 return ReduceWord32Sar(node); |
| 165 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x | |
| 166 if (m.IsFoldable()) { // K >> K => K | |
| 167 return ReplaceInt32(m.left().Value() >> m.right().Value()); | |
| 168 } | |
| 169 if (m.left().IsWord32Shl()) { | |
| 170 Int32BinopMatcher mleft(m.left().node()); | |
| 171 if (mleft.left().IsLoad()) { | |
| 172 LoadRepresentation const rep = | |
| 173 OpParameter<LoadRepresentation>(mleft.left().node()); | |
| 174 if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) { | |
| 175 // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8] | |
| 176 return Replace(mleft.left().node()); | |
| 177 } | |
| 178 if (m.right().Is(16) && mleft.right().Is(16) && rep == kMachInt16) { | |
| 179 // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8] | |
| 180 return Replace(mleft.left().node()); | |
| 181 } | |
| 182 } | |
| 183 } | |
| 184 return ReduceWord32Shifts(node); | |
| 185 } | |
| 186 case IrOpcode::kWord32Ror: { | 165 case IrOpcode::kWord32Ror: { |
| 187 Int32BinopMatcher m(node); | 166 Int32BinopMatcher m(node); |
| 188 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x | 167 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x |
| 189 if (m.IsFoldable()) { // K ror K => K | 168 if (m.IsFoldable()) { // K ror K => K |
| 190 return ReplaceInt32( | 169 return ReplaceInt32( |
| 191 base::bits::RotateRight32(m.left().Value(), m.right().Value())); | 170 base::bits::RotateRight32(m.left().Value(), m.right().Value())); |
| 192 } | 171 } |
| 193 break; | 172 break; |
| 194 } | 173 } |
| 195 case IrOpcode::kWord32Equal: { | 174 case IrOpcode::kWord32Equal: { |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 443 |
| 465 | 444 |
| 466 Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) { | 445 Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) { |
| 467 DCHECK_EQ(IrOpcode::kInt32Add, node->opcode()); | 446 DCHECK_EQ(IrOpcode::kInt32Add, node->opcode()); |
| 468 Int32BinopMatcher m(node); | 447 Int32BinopMatcher m(node); |
| 469 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x | 448 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x |
| 470 if (m.IsFoldable()) { // K + K => K | 449 if (m.IsFoldable()) { // K + K => K |
| 471 return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) + | 450 return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) + |
| 472 bit_cast<uint32_t>(m.right().Value())); | 451 bit_cast<uint32_t>(m.right().Value())); |
| 473 } | 452 } |
| 453 if (m.left().IsInt32Sub()) { |
| 454 Int32BinopMatcher mleft(m.left().node()); |
| 455 if (mleft.left().Is(0)) { // (0 - x) + y => y - x |
| 456 node->set_op(machine()->Int32Sub()); |
| 457 node->ReplaceInput(0, m.right().node()); |
| 458 node->ReplaceInput(1, mleft.right().node()); |
| 459 Reduction const reduction = ReduceInt32Sub(node); |
| 460 return reduction.Changed() ? reduction : Changed(node); |
| 461 } |
| 462 } |
| 463 if (m.right().IsInt32Sub()) { |
| 464 Int32BinopMatcher mright(m.right().node()); |
| 465 if (mright.left().Is(0)) { // y + (0 - x) => y - x |
| 466 node->set_op(machine()->Int32Sub()); |
| 467 node->ReplaceInput(1, mright.right().node()); |
| 468 Reduction const reduction = ReduceInt32Sub(node); |
| 469 return reduction.Changed() ? reduction : Changed(node); |
| 470 } |
| 471 } |
| 474 return NoChange(); | 472 return NoChange(); |
| 475 } | 473 } |
| 476 | 474 |
| 477 | 475 |
| 478 Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) { | 476 Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) { |
| 479 DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode()); | 477 DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode()); |
| 480 Int32BinopMatcher m(node); | 478 Int32BinopMatcher m(node); |
| 481 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x | 479 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x |
| 482 if (m.IsFoldable()) { // K - K => K | 480 if (m.IsFoldable()) { // K - K => K |
| 483 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - | 481 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 Uint32Constant(~((1U << m.right().Value()) - 1U))); | 775 Uint32Constant(~((1U << m.right().Value()) - 1U))); |
| 778 Reduction reduction = ReduceWord32And(node); | 776 Reduction reduction = ReduceWord32And(node); |
| 779 return reduction.Changed() ? reduction : Changed(node); | 777 return reduction.Changed() ? reduction : Changed(node); |
| 780 } | 778 } |
| 781 } | 779 } |
| 782 } | 780 } |
| 783 return ReduceWord32Shifts(node); | 781 return ReduceWord32Shifts(node); |
| 784 } | 782 } |
| 785 | 783 |
| 786 | 784 |
| 785 Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) { |
| 786 Int32BinopMatcher m(node); |
| 787 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x |
| 788 if (m.IsFoldable()) { // K >> K => K |
| 789 return ReplaceInt32(m.left().Value() >> m.right().Value()); |
| 790 } |
| 791 if (m.left().IsWord32Shl()) { |
| 792 Int32BinopMatcher mleft(m.left().node()); |
| 793 if (mleft.left().IsComparison()) { |
| 794 if (m.right().Is(31) && mleft.right().Is(31)) { |
| 795 // Comparison << 31 >> 31 => 0 - Comparison |
| 796 node->set_op(machine()->Int32Sub()); |
| 797 node->ReplaceInput(0, Int32Constant(0)); |
| 798 node->ReplaceInput(1, mleft.left().node()); |
| 799 Reduction const reduction = ReduceInt32Sub(node); |
| 800 return reduction.Changed() ? reduction : Changed(node); |
| 801 } |
| 802 } else if (mleft.left().IsLoad()) { |
| 803 LoadRepresentation const rep = |
| 804 OpParameter<LoadRepresentation>(mleft.left().node()); |
| 805 if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) { |
| 806 // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8] |
| 807 return Replace(mleft.left().node()); |
| 808 } |
| 809 if (m.right().Is(16) && mleft.right().Is(16) && rep == kMachInt16) { |
| 810 // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8] |
| 811 return Replace(mleft.left().node()); |
| 812 } |
| 813 } |
| 814 } |
| 815 return ReduceWord32Shifts(node); |
| 816 } |
| 817 |
| 818 |
| 787 Reduction MachineOperatorReducer::ReduceWord32And(Node* node) { | 819 Reduction MachineOperatorReducer::ReduceWord32And(Node* node) { |
| 788 DCHECK_EQ(IrOpcode::kWord32And, node->opcode()); | 820 DCHECK_EQ(IrOpcode::kWord32And, node->opcode()); |
| 789 Int32BinopMatcher m(node); | 821 Int32BinopMatcher m(node); |
| 790 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0 | 822 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0 |
| 791 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x | 823 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x |
| 824 if (m.left().IsComparison() && m.right().Is(1)) { // CMP & 1 => CMP |
| 825 return Replace(m.left().node()); |
| 826 } |
| 792 if (m.IsFoldable()) { // K & K => K | 827 if (m.IsFoldable()) { // K & K => K |
| 793 return ReplaceInt32(m.left().Value() & m.right().Value()); | 828 return ReplaceInt32(m.left().Value() & m.right().Value()); |
| 794 } | 829 } |
| 795 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x | 830 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x |
| 796 if (m.left().IsWord32And() && m.right().HasValue()) { | 831 if (m.left().IsWord32And() && m.right().HasValue()) { |
| 797 Int32BinopMatcher mleft(m.left().node()); | 832 Int32BinopMatcher mleft(m.left().node()); |
| 798 if (mleft.right().HasValue()) { // (x & K) & K => x & K | 833 if (mleft.right().HasValue()) { // (x & K) & K => x & K |
| 799 node->ReplaceInput(0, mleft.left().node()); | 834 node->ReplaceInput(0, mleft.left().node()); |
| 800 node->ReplaceInput( | 835 node->ReplaceInput( |
| 801 1, Int32Constant(m.right().Value() & mleft.right().Value())); | 836 1, Int32Constant(m.right().Value() & mleft.right().Value())); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 977 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
| 943 return jsgraph()->machine(); | 978 return jsgraph()->machine(); |
| 944 } | 979 } |
| 945 | 980 |
| 946 | 981 |
| 947 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 982 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
| 948 | 983 |
| 949 } // namespace compiler | 984 } // namespace compiler |
| 950 } // namespace internal | 985 } // namespace internal |
| 951 } // namespace v8 | 986 } // namespace v8 |
| OLD | NEW |