| 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 |