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/base/ieee754.h" | 9 #include "src/base/ieee754.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 case IrOpcode::kProjection: | 147 case IrOpcode::kProjection: |
148 return ReduceProjection(ProjectionIndexOf(node->op()), node->InputAt(0)); | 148 return ReduceProjection(ProjectionIndexOf(node->op()), node->InputAt(0)); |
149 case IrOpcode::kWord32And: | 149 case IrOpcode::kWord32And: |
150 return ReduceWord32And(node); | 150 return ReduceWord32And(node); |
151 case IrOpcode::kWord32Or: | 151 case IrOpcode::kWord32Or: |
152 return ReduceWord32Or(node); | 152 return ReduceWord32Or(node); |
153 case IrOpcode::kWord32Xor: | 153 case IrOpcode::kWord32Xor: |
154 return ReduceWord32Xor(node); | 154 return ReduceWord32Xor(node); |
155 case IrOpcode::kWord32Shl: | 155 case IrOpcode::kWord32Shl: |
156 return ReduceWord32Shl(node); | 156 return ReduceWord32Shl(node); |
| 157 case IrOpcode::kWord64Shl: |
| 158 return ReduceWord64Shl(node); |
157 case IrOpcode::kWord32Shr: | 159 case IrOpcode::kWord32Shr: |
158 return ReduceWord32Shr(node); | 160 return ReduceWord32Shr(node); |
| 161 case IrOpcode::kWord64Shr: |
| 162 return ReduceWord64Shr(node); |
159 case IrOpcode::kWord32Sar: | 163 case IrOpcode::kWord32Sar: |
160 return ReduceWord32Sar(node); | 164 return ReduceWord32Sar(node); |
| 165 case IrOpcode::kWord64Sar: |
| 166 return ReduceWord64Sar(node); |
161 case IrOpcode::kWord32Ror: { | 167 case IrOpcode::kWord32Ror: { |
162 Int32BinopMatcher m(node); | 168 Int32BinopMatcher m(node); |
163 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x | 169 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x |
164 if (m.IsFoldable()) { // K ror K => K | 170 if (m.IsFoldable()) { // K ror K => K |
165 return ReplaceInt32( | 171 return ReplaceInt32( |
166 base::bits::RotateRight32(m.left().Value(), m.right().Value())); | 172 base::bits::RotateRight32(m.left().Value(), m.right().Value())); |
167 } | 173 } |
168 break; | 174 break; |
169 } | 175 } |
170 case IrOpcode::kWord32Equal: { | 176 case IrOpcode::kWord32Equal: { |
(...skipping 21 matching lines...) Expand all Loading... |
192 node->ReplaceInput(0, msub.left().node()); | 198 node->ReplaceInput(0, msub.left().node()); |
193 node->ReplaceInput(1, msub.right().node()); | 199 node->ReplaceInput(1, msub.right().node()); |
194 return Changed(node); | 200 return Changed(node); |
195 } | 201 } |
196 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares | 202 // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares |
197 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true | 203 if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true |
198 break; | 204 break; |
199 } | 205 } |
200 case IrOpcode::kInt32Add: | 206 case IrOpcode::kInt32Add: |
201 return ReduceInt32Add(node); | 207 return ReduceInt32Add(node); |
| 208 case IrOpcode::kInt64Add: |
| 209 return ReduceInt64Add(node); |
202 case IrOpcode::kInt32Sub: | 210 case IrOpcode::kInt32Sub: |
203 return ReduceInt32Sub(node); | 211 return ReduceInt32Sub(node); |
| 212 case IrOpcode::kInt64Sub: |
| 213 return ReduceInt64Sub(node); |
204 case IrOpcode::kInt32Mul: { | 214 case IrOpcode::kInt32Mul: { |
205 Int32BinopMatcher m(node); | 215 Int32BinopMatcher m(node); |
206 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 | 216 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 |
207 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x | 217 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x |
208 if (m.IsFoldable()) { // K * K => K | 218 if (m.IsFoldable()) { // K * K => K |
209 return ReplaceInt32(m.left().Value() * m.right().Value()); | 219 return ReplaceInt32(m.left().Value() * m.right().Value()); |
210 } | 220 } |
211 if (m.right().Is(-1)) { // x * -1 => 0 - x | 221 if (m.right().Is(-1)) { // x * -1 => 0 - x |
212 node->ReplaceInput(0, Int32Constant(0)); | 222 node->ReplaceInput(0, Int32Constant(0)); |
213 node->ReplaceInput(1, m.left().node()); | 223 node->ReplaceInput(1, m.left().node()); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 if (mright.left().Is(0)) { // y + (0 - x) => y - x | 624 if (mright.left().Is(0)) { // y + (0 - x) => y - x |
615 node->ReplaceInput(1, mright.right().node()); | 625 node->ReplaceInput(1, mright.right().node()); |
616 NodeProperties::ChangeOp(node, machine()->Int32Sub()); | 626 NodeProperties::ChangeOp(node, machine()->Int32Sub()); |
617 Reduction const reduction = ReduceInt32Sub(node); | 627 Reduction const reduction = ReduceInt32Sub(node); |
618 return reduction.Changed() ? reduction : Changed(node); | 628 return reduction.Changed() ? reduction : Changed(node); |
619 } | 629 } |
620 } | 630 } |
621 return NoChange(); | 631 return NoChange(); |
622 } | 632 } |
623 | 633 |
| 634 Reduction MachineOperatorReducer::ReduceInt64Add(Node* node) { |
| 635 DCHECK_EQ(IrOpcode::kInt64Add, node->opcode()); |
| 636 Int64BinopMatcher m(node); |
| 637 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => 0 |
| 638 if (m.IsFoldable()) { |
| 639 return Replace(Uint64Constant(bit_cast<uint64_t>(m.left().Value()) + |
| 640 bit_cast<uint64_t>(m.right().Value()))); |
| 641 } |
| 642 return NoChange(); |
| 643 } |
624 | 644 |
625 Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) { | 645 Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) { |
626 DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode()); | 646 DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode()); |
627 Int32BinopMatcher m(node); | 647 Int32BinopMatcher m(node); |
628 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x | 648 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x |
629 if (m.IsFoldable()) { // K - K => K | 649 if (m.IsFoldable()) { // K - K => K |
630 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - | 650 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - |
631 static_cast<uint32_t>(m.right().Value())); | 651 static_cast<uint32_t>(m.right().Value())); |
632 } | 652 } |
633 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0 | 653 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0 |
634 if (m.right().HasValue()) { // x - K => x + -K | 654 if (m.right().HasValue()) { // x - K => x + -K |
635 node->ReplaceInput(1, Int32Constant(-m.right().Value())); | 655 node->ReplaceInput(1, Int32Constant(-m.right().Value())); |
636 NodeProperties::ChangeOp(node, machine()->Int32Add()); | 656 NodeProperties::ChangeOp(node, machine()->Int32Add()); |
637 Reduction const reduction = ReduceInt32Add(node); | 657 Reduction const reduction = ReduceInt32Add(node); |
638 return reduction.Changed() ? reduction : Changed(node); | 658 return reduction.Changed() ? reduction : Changed(node); |
639 } | 659 } |
640 return NoChange(); | 660 return NoChange(); |
641 } | 661 } |
642 | 662 |
| 663 Reduction MachineOperatorReducer::ReduceInt64Sub(Node* node) { |
| 664 DCHECK_EQ(IrOpcode::kInt64Sub, node->opcode()); |
| 665 Int64BinopMatcher m(node); |
| 666 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x |
| 667 if (m.IsFoldable()) { // K - K => K |
| 668 return Replace(Uint64Constant(bit_cast<uint64_t>(m.left().Value()) - |
| 669 bit_cast<uint64_t>(m.right().Value()))); |
| 670 } |
| 671 if (m.LeftEqualsRight()) return Replace(Int64Constant(0)); // x - x => 0 |
| 672 if (m.right().HasValue()) { // x - K => x + -K |
| 673 node->ReplaceInput(1, Int64Constant(-m.right().Value())); |
| 674 NodeProperties::ChangeOp(node, machine()->Int64Add()); |
| 675 Reduction const reduction = ReduceInt64Add(node); |
| 676 return reduction.Changed() ? reduction : Changed(node); |
| 677 } |
| 678 return NoChange(); |
| 679 } |
643 | 680 |
644 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) { | 681 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) { |
645 Int32BinopMatcher m(node); | 682 Int32BinopMatcher m(node); |
646 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 | 683 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 |
647 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 | 684 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 |
648 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x | 685 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x |
649 if (m.IsFoldable()) { // K / K => K | 686 if (m.IsFoldable()) { // K / K => K |
650 return ReplaceInt32( | 687 return ReplaceInt32( |
651 base::bits::SignedDiv32(m.left().Value(), m.right().Value())); | 688 base::bits::SignedDiv32(m.left().Value(), m.right().Value())); |
652 } | 689 } |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 Uint32Constant(~((1U << m.right().Value()) - 1U))); | 966 Uint32Constant(~((1U << m.right().Value()) - 1U))); |
930 NodeProperties::ChangeOp(node, machine()->Word32And()); | 967 NodeProperties::ChangeOp(node, machine()->Word32And()); |
931 Reduction reduction = ReduceWord32And(node); | 968 Reduction reduction = ReduceWord32And(node); |
932 return reduction.Changed() ? reduction : Changed(node); | 969 return reduction.Changed() ? reduction : Changed(node); |
933 } | 970 } |
934 } | 971 } |
935 } | 972 } |
936 return ReduceWord32Shifts(node); | 973 return ReduceWord32Shifts(node); |
937 } | 974 } |
938 | 975 |
| 976 Reduction MachineOperatorReducer::ReduceWord64Shl(Node* node) { |
| 977 DCHECK_EQ(IrOpcode::kWord64Shl, node->opcode()); |
| 978 Int64BinopMatcher m(node); |
| 979 if (m.right().Is(0)) return Replace(m.left().node()); // x << 0 => x |
| 980 if (m.IsFoldable()) { // K << K => K |
| 981 return ReplaceInt64(m.left().Value() << m.right().Value()); |
| 982 } |
| 983 return NoChange(); |
| 984 } |
| 985 |
939 Reduction MachineOperatorReducer::ReduceWord32Shr(Node* node) { | 986 Reduction MachineOperatorReducer::ReduceWord32Shr(Node* node) { |
940 Uint32BinopMatcher m(node); | 987 Uint32BinopMatcher m(node); |
941 if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x | 988 if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x |
942 if (m.IsFoldable()) { // K >>> K => K | 989 if (m.IsFoldable()) { // K >>> K => K |
943 return ReplaceInt32(m.left().Value() >> m.right().Value()); | 990 return ReplaceInt32(m.left().Value() >> m.right().Value()); |
944 } | 991 } |
945 if (m.left().IsWord32And() && m.right().HasValue()) { | 992 if (m.left().IsWord32And() && m.right().HasValue()) { |
946 Uint32BinopMatcher mleft(m.left().node()); | 993 Uint32BinopMatcher mleft(m.left().node()); |
947 if (mleft.right().HasValue()) { | 994 if (mleft.right().HasValue()) { |
948 uint32_t shift = m.right().Value() & 0x1f; | 995 uint32_t shift = m.right().Value() & 0x1f; |
949 uint32_t mask = mleft.right().Value(); | 996 uint32_t mask = mleft.right().Value(); |
950 if ((mask >> shift) == 0) { | 997 if ((mask >> shift) == 0) { |
951 // (m >>> s) == 0 implies ((x & m) >>> s) == 0 | 998 // (m >>> s) == 0 implies ((x & m) >>> s) == 0 |
952 return ReplaceInt32(0); | 999 return ReplaceInt32(0); |
953 } | 1000 } |
954 } | 1001 } |
955 } | 1002 } |
956 return ReduceWord32Shifts(node); | 1003 return ReduceWord32Shifts(node); |
957 } | 1004 } |
958 | 1005 |
| 1006 Reduction MachineOperatorReducer::ReduceWord64Shr(Node* node) { |
| 1007 DCHECK_EQ(IrOpcode::kWord64Shr, node->opcode()); |
| 1008 Uint64BinopMatcher m(node); |
| 1009 if (m.right().Is(0)) return Replace(m.left().node()); // x >>> 0 => x |
| 1010 if (m.IsFoldable()) { // K >> K => K |
| 1011 return ReplaceInt64(m.left().Value() >> m.right().Value()); |
| 1012 } |
| 1013 return NoChange(); |
| 1014 } |
| 1015 |
959 Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) { | 1016 Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) { |
960 Int32BinopMatcher m(node); | 1017 Int32BinopMatcher m(node); |
961 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x | 1018 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x |
962 if (m.IsFoldable()) { // K >> K => K | 1019 if (m.IsFoldable()) { // K >> K => K |
963 return ReplaceInt32(m.left().Value() >> m.right().Value()); | 1020 return ReplaceInt32(m.left().Value() >> m.right().Value()); |
964 } | 1021 } |
965 if (m.left().IsWord32Shl()) { | 1022 if (m.left().IsWord32Shl()) { |
966 Int32BinopMatcher mleft(m.left().node()); | 1023 Int32BinopMatcher mleft(m.left().node()); |
967 if (mleft.left().IsComparison()) { | 1024 if (mleft.left().IsComparison()) { |
968 if (m.right().Is(31) && mleft.right().Is(31)) { | 1025 if (m.right().Is(31) && mleft.right().Is(31)) { |
(...skipping 15 matching lines...) Expand all Loading... |
984 if (m.right().Is(16) && mleft.right().Is(16) && | 1041 if (m.right().Is(16) && mleft.right().Is(16) && |
985 rep == MachineType::Int16()) { | 1042 rep == MachineType::Int16()) { |
986 // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8] | 1043 // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8] |
987 return Replace(mleft.left().node()); | 1044 return Replace(mleft.left().node()); |
988 } | 1045 } |
989 } | 1046 } |
990 } | 1047 } |
991 return ReduceWord32Shifts(node); | 1048 return ReduceWord32Shifts(node); |
992 } | 1049 } |
993 | 1050 |
| 1051 Reduction MachineOperatorReducer::ReduceWord64Sar(Node* node) { |
| 1052 Int64BinopMatcher m(node); |
| 1053 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x |
| 1054 if (m.IsFoldable()) { |
| 1055 return ReplaceInt64(m.left().Value() >> m.right().Value()); |
| 1056 } |
| 1057 return NoChange(); |
| 1058 } |
994 | 1059 |
995 Reduction MachineOperatorReducer::ReduceWord32And(Node* node) { | 1060 Reduction MachineOperatorReducer::ReduceWord32And(Node* node) { |
996 DCHECK_EQ(IrOpcode::kWord32And, node->opcode()); | 1061 DCHECK_EQ(IrOpcode::kWord32And, node->opcode()); |
997 Int32BinopMatcher m(node); | 1062 Int32BinopMatcher m(node); |
998 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0 | 1063 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0 |
999 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x | 1064 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x |
1000 if (m.left().IsComparison() && m.right().Is(1)) { // CMP & 1 => CMP | 1065 if (m.left().IsComparison() && m.right().Is(1)) { // CMP & 1 => CMP |
1001 return Replace(m.left().node()); | 1066 return Replace(m.left().node()); |
1002 } | 1067 } |
1003 if (m.IsFoldable()) { // K & K => K | 1068 if (m.IsFoldable()) { // K & K => K |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 1332 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
1268 return jsgraph()->machine(); | 1333 return jsgraph()->machine(); |
1269 } | 1334 } |
1270 | 1335 |
1271 | 1336 |
1272 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 1337 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
1273 | 1338 |
1274 } // namespace compiler | 1339 } // namespace compiler |
1275 } // namespace internal | 1340 } // namespace internal |
1276 } // namespace v8 | 1341 } // namespace v8 |
OLD | NEW |