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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 143 |
144 // Perform constant folding and strength reduction on machine operators. | 144 // Perform constant folding and strength reduction on machine operators. |
145 Reduction MachineOperatorReducer::Reduce(Node* node) { | 145 Reduction MachineOperatorReducer::Reduce(Node* node) { |
146 switch (node->opcode()) { | 146 switch (node->opcode()) { |
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 Int32BinopMatcher m(node); |
| 155 if (m.right().Is(0)) return Replace(m.left().node()); // x ^ 0 => x |
| 156 if (m.IsFoldable()) { // K ^ K => K |
| 157 return ReplaceInt32(m.left().Value() ^ m.right().Value()); |
| 158 } |
| 159 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x ^ x => 0 |
| 160 if (m.left().IsWord32Xor() && m.right().Is(-1)) { |
| 161 Int32BinopMatcher mleft(m.left().node()); |
| 162 if (mleft.right().Is(-1)) { // (x ^ -1) ^ -1 => x |
| 163 return Replace(mleft.left().node()); |
| 164 } |
| 165 } |
| 166 break; |
| 167 } |
155 case IrOpcode::kWord32Shl: | 168 case IrOpcode::kWord32Shl: |
156 return ReduceWord32Shl(node); | 169 return ReduceWord32Shl(node); |
157 case IrOpcode::kWord32Shr: | 170 case IrOpcode::kWord32Shr: |
158 return ReduceWord32Shr(node); | 171 return ReduceWord32Shr(node); |
159 case IrOpcode::kWord32Sar: | 172 case IrOpcode::kWord32Sar: |
160 return ReduceWord32Sar(node); | 173 return ReduceWord32Sar(node); |
161 case IrOpcode::kWord32Ror: { | 174 case IrOpcode::kWord32Ror: { |
162 Int32BinopMatcher m(node); | 175 Int32BinopMatcher m(node); |
163 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x | 176 if (m.right().Is(0)) return Replace(m.left().node()); // x ror 0 => x |
164 if (m.IsFoldable()) { // K ror K => K | 177 if (m.IsFoldable()) { // K ror K => K |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 Int32BinopMatcher mleft(m.left().node()); | 1099 Int32BinopMatcher mleft(m.left().node()); |
1087 if (mleft.right().IsMultipleOf(-mask)) { | 1100 if (mleft.right().IsMultipleOf(-mask)) { |
1088 // (x * (K << L)) & (-1 << L) => x * (K << L) | 1101 // (x * (K << L)) & (-1 << L) => x * (K << L) |
1089 return Replace(mleft.node()); | 1102 return Replace(mleft.node()); |
1090 } | 1103 } |
1091 } | 1104 } |
1092 } | 1105 } |
1093 return NoChange(); | 1106 return NoChange(); |
1094 } | 1107 } |
1095 | 1108 |
1096 Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { | 1109 |
1097 DCHECK(IrOpcode::kWord32Or == node->opcode() || | 1110 Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { |
1098 IrOpcode::kWord32Xor == node->opcode()); | 1111 DCHECK_EQ(IrOpcode::kWord32Or, node->opcode()); |
1099 Int32BinopMatcher m(node); | 1112 Int32BinopMatcher m(node); |
| 1113 if (m.right().Is(0)) return Replace(m.left().node()); // x | 0 => x |
| 1114 if (m.right().Is(-1)) return Replace(m.right().node()); // x | -1 => -1 |
| 1115 if (m.IsFoldable()) { // K | K => K |
| 1116 return ReplaceInt32(m.left().Value() | m.right().Value()); |
| 1117 } |
| 1118 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x |
| 1119 |
1100 Node* shl = nullptr; | 1120 Node* shl = nullptr; |
1101 Node* shr = nullptr; | 1121 Node* shr = nullptr; |
1102 // Recognize rotation, we are matching: | 1122 // Recognize rotation, we are matching either: |
1103 // * x << y | x >>> (32 - y) => x ror (32 - y), i.e x rol y | 1123 // * x << y | x >>> (32 - y) => x ror (32 - y), i.e x rol y |
1104 // * x << (32 - y) | x >>> y => x ror y | 1124 // * x << (32 - y) | x >>> y => x ror y |
1105 // * x << y ^ x >>> (32 - y) => x ror (32 - y), i.e. x rol y | |
1106 // * x << (32 - y) ^ x >>> y => x ror y | |
1107 // as well as their commuted form. | 1125 // as well as their commuted form. |
1108 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { | 1126 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { |
1109 shl = m.left().node(); | 1127 shl = m.left().node(); |
1110 shr = m.right().node(); | 1128 shr = m.right().node(); |
1111 } else if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { | 1129 } else if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { |
1112 shl = m.right().node(); | 1130 shl = m.right().node(); |
1113 shr = m.left().node(); | 1131 shr = m.left().node(); |
1114 } else { | 1132 } else { |
1115 return NoChange(); | 1133 return NoChange(); |
1116 } | 1134 } |
(...skipping 21 matching lines...) Expand all Loading... |
1138 Int32BinopMatcher msub(sub); | 1156 Int32BinopMatcher msub(sub); |
1139 if (!msub.left().Is(32) || msub.right().node() != y) return NoChange(); | 1157 if (!msub.left().Is(32) || msub.right().node() != y) return NoChange(); |
1140 } | 1158 } |
1141 | 1159 |
1142 node->ReplaceInput(0, mshl.left().node()); | 1160 node->ReplaceInput(0, mshl.left().node()); |
1143 node->ReplaceInput(1, mshr.right().node()); | 1161 node->ReplaceInput(1, mshr.right().node()); |
1144 NodeProperties::ChangeOp(node, machine()->Word32Ror()); | 1162 NodeProperties::ChangeOp(node, machine()->Word32Ror()); |
1145 return Changed(node); | 1163 return Changed(node); |
1146 } | 1164 } |
1147 | 1165 |
1148 Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { | |
1149 DCHECK_EQ(IrOpcode::kWord32Or, node->opcode()); | |
1150 Int32BinopMatcher m(node); | |
1151 if (m.right().Is(0)) return Replace(m.left().node()); // x | 0 => x | |
1152 if (m.right().Is(-1)) return Replace(m.right().node()); // x | -1 => -1 | |
1153 if (m.IsFoldable()) { // K | K => K | |
1154 return ReplaceInt32(m.left().Value() | m.right().Value()); | |
1155 } | |
1156 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x | |
1157 | |
1158 return TryMatchWord32Ror(node); | |
1159 } | |
1160 | |
1161 Reduction MachineOperatorReducer::ReduceWord32Xor(Node* node) { | |
1162 DCHECK_EQ(IrOpcode::kWord32Xor, node->opcode()); | |
1163 Int32BinopMatcher m(node); | |
1164 if (m.right().Is(0)) return Replace(m.left().node()); // x ^ 0 => x | |
1165 if (m.IsFoldable()) { // K ^ K => K | |
1166 return ReplaceInt32(m.left().Value() ^ m.right().Value()); | |
1167 } | |
1168 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x ^ x => 0 | |
1169 if (m.left().IsWord32Xor() && m.right().Is(-1)) { | |
1170 Int32BinopMatcher mleft(m.left().node()); | |
1171 if (mleft.right().Is(-1)) { // (x ^ -1) ^ -1 => x | |
1172 return Replace(mleft.left().node()); | |
1173 } | |
1174 } | |
1175 | |
1176 return TryMatchWord32Ror(node); | |
1177 } | |
1178 | 1166 |
1179 Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) { | 1167 Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) { |
1180 DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode()); | 1168 DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode()); |
1181 Float64Matcher mlhs(node->InputAt(0)); | 1169 Float64Matcher mlhs(node->InputAt(0)); |
1182 Uint32Matcher mrhs(node->InputAt(1)); | 1170 Uint32Matcher mrhs(node->InputAt(1)); |
1183 if (mlhs.HasValue() && mrhs.HasValue()) { | 1171 if (mlhs.HasValue() && mrhs.HasValue()) { |
1184 return ReplaceFloat64(bit_cast<double>( | 1172 return ReplaceFloat64(bit_cast<double>( |
1185 (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF00000000)) | | 1173 (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF00000000)) | |
1186 mrhs.Value())); | 1174 mrhs.Value())); |
1187 } | 1175 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 1255 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
1268 return jsgraph()->machine(); | 1256 return jsgraph()->machine(); |
1269 } | 1257 } |
1270 | 1258 |
1271 | 1259 |
1272 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 1260 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
1273 | 1261 |
1274 } // namespace compiler | 1262 } // namespace compiler |
1275 } // namespace internal | 1263 } // namespace internal |
1276 } // namespace v8 | 1264 } // namespace v8 |
OLD | NEW |