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 |