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/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
9 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x | 59 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x |
60 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { | 60 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { |
61 Int32BinopMatcher mleft(m.left().node()); | 61 Int32BinopMatcher mleft(m.left().node()); |
62 Int32BinopMatcher mright(m.right().node()); | 62 Int32BinopMatcher mright(m.right().node()); |
63 if (mleft.left().node() == mright.left().node()) { | 63 if (mleft.left().node() == mright.left().node()) { |
64 // (x << y) | (x >> (32 - y)) => x ror y | 64 // (x << y) | (x >> (32 - y)) => x ror y |
65 if (mright.right().IsInt32Sub()) { | 65 if (mright.right().IsInt32Sub()) { |
66 Int32BinopMatcher mrightright(mright.right().node()); | 66 Int32BinopMatcher mrightright(mright.right().node()); |
67 if (mrightright.left().Is(32) && | 67 if (mrightright.left().Is(32) && |
68 mrightright.right().node() == mleft.right().node()) { | 68 mrightright.right().node() == mleft.right().node()) { |
69 graph()->ChangeOperator(node, machine()->Word32Ror()); | 69 node->set_op(machine()->Word32Ror()); |
70 node->ReplaceInput(0, mleft.left().node()); | 70 node->ReplaceInput(0, mleft.left().node()); |
71 node->ReplaceInput(1, mleft.right().node()); | 71 node->ReplaceInput(1, mleft.right().node()); |
72 return Changed(node); | 72 return Changed(node); |
73 } | 73 } |
74 } | 74 } |
75 // (x << K) | (x >> (32 - K)) => x ror K | 75 // (x << K) | (x >> (32 - K)) => x ror K |
76 if (mleft.right().IsInRange(0, 31) && | 76 if (mleft.right().IsInRange(0, 31) && |
77 mright.right().Is(32 - mleft.right().Value())) { | 77 mright.right().Is(32 - mleft.right().Value())) { |
78 graph()->ChangeOperator(node, machine()->Word32Ror()); | 78 node->set_op(machine()->Word32Ror()); |
79 node->ReplaceInput(0, mleft.left().node()); | 79 node->ReplaceInput(0, mleft.left().node()); |
80 node->ReplaceInput(1, mleft.right().node()); | 80 node->ReplaceInput(1, mleft.right().node()); |
81 return Changed(node); | 81 return Changed(node); |
82 } | 82 } |
83 } | 83 } |
84 } | 84 } |
85 if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { | 85 if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { |
86 // (x >> (32 - y)) | (x << y) => x ror y | 86 // (x >> (32 - y)) | (x << y) => x ror y |
87 Int32BinopMatcher mleft(m.left().node()); | 87 Int32BinopMatcher mleft(m.left().node()); |
88 Int32BinopMatcher mright(m.right().node()); | 88 Int32BinopMatcher mright(m.right().node()); |
89 if (mleft.left().node() == mright.left().node()) { | 89 if (mleft.left().node() == mright.left().node()) { |
90 if (mleft.right().IsInt32Sub()) { | 90 if (mleft.right().IsInt32Sub()) { |
91 Int32BinopMatcher mleftright(mleft.right().node()); | 91 Int32BinopMatcher mleftright(mleft.right().node()); |
92 if (mleftright.left().Is(32) && | 92 if (mleftright.left().Is(32) && |
93 mleftright.right().node() == mright.right().node()) { | 93 mleftright.right().node() == mright.right().node()) { |
94 graph()->ChangeOperator(node, machine()->Word32Ror()); | 94 node->set_op(machine()->Word32Ror()); |
95 node->ReplaceInput(0, mright.left().node()); | 95 node->ReplaceInput(0, mright.left().node()); |
96 node->ReplaceInput(1, mright.right().node()); | 96 node->ReplaceInput(1, mright.right().node()); |
97 return Changed(node); | 97 return Changed(node); |
98 } | 98 } |
99 } | 99 } |
100 // (x >> (32 - K)) | (x << K) => x ror K | 100 // (x >> (32 - K)) | (x << K) => x ror K |
101 if (mright.right().IsInRange(0, 31) && | 101 if (mright.right().IsInRange(0, 31) && |
102 mleft.right().Is(32 - mright.right().Value())) { | 102 mleft.right().Is(32 - mright.right().Value())) { |
103 graph()->ChangeOperator(node, machine()->Word32Ror()); | 103 node->set_op(machine()->Word32Ror()); |
104 node->ReplaceInput(0, mright.left().node()); | 104 node->ReplaceInput(0, mright.left().node()); |
105 node->ReplaceInput(1, mright.right().node()); | 105 node->ReplaceInput(1, mright.right().node()); |
106 return Changed(node); | 106 return Changed(node); |
107 } | 107 } |
108 } | 108 } |
109 } | 109 } |
110 break; | 110 break; |
111 } | 111 } |
112 case IrOpcode::kWord32Xor: { | 112 case IrOpcode::kWord32Xor: { |
113 Int32BinopMatcher m(node); | 113 Int32BinopMatcher m(node); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 break; | 186 break; |
187 } | 187 } |
188 case IrOpcode::kInt32Mul: { | 188 case IrOpcode::kInt32Mul: { |
189 Int32BinopMatcher m(node); | 189 Int32BinopMatcher m(node); |
190 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 | 190 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 |
191 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x | 191 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x |
192 if (m.IsFoldable()) { // K * K => K | 192 if (m.IsFoldable()) { // K * K => K |
193 return ReplaceInt32(m.left().Value() * m.right().Value()); | 193 return ReplaceInt32(m.left().Value() * m.right().Value()); |
194 } | 194 } |
195 if (m.right().Is(-1)) { // x * -1 => 0 - x | 195 if (m.right().Is(-1)) { // x * -1 => 0 - x |
196 graph()->ChangeOperator(node, machine()->Int32Sub()); | 196 node->set_op(machine()->Int32Sub()); |
197 node->ReplaceInput(0, Int32Constant(0)); | 197 node->ReplaceInput(0, Int32Constant(0)); |
198 node->ReplaceInput(1, m.left().node()); | 198 node->ReplaceInput(1, m.left().node()); |
199 return Changed(node); | 199 return Changed(node); |
200 } | 200 } |
201 if (m.right().IsPowerOf2()) { // x * 2^n => x << n | 201 if (m.right().IsPowerOf2()) { // x * 2^n => x << n |
202 graph()->ChangeOperator(node, machine()->Word32Shl()); | 202 node->set_op(machine()->Word32Shl()); |
203 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); | 203 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); |
204 return Changed(node); | 204 return Changed(node); |
205 } | 205 } |
206 break; | 206 break; |
207 } | 207 } |
208 case IrOpcode::kInt32Div: { | 208 case IrOpcode::kInt32Div: { |
209 Int32BinopMatcher m(node); | 209 Int32BinopMatcher m(node); |
210 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x | 210 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x |
211 // TODO(turbofan): if (m.left().Is(0)) | 211 // TODO(turbofan): if (m.left().Is(0)) |
212 // TODO(turbofan): if (m.right().IsPowerOf2()) | 212 // TODO(turbofan): if (m.right().IsPowerOf2()) |
213 // TODO(turbofan): if (m.right().Is(0)) | 213 // TODO(turbofan): if (m.right().Is(0)) |
214 // TODO(turbofan): if (m.LeftEqualsRight()) | 214 // TODO(turbofan): if (m.LeftEqualsRight()) |
215 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K | 215 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K |
216 if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value()); | 216 if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value()); |
217 return ReplaceInt32(m.left().Value() / m.right().Value()); | 217 return ReplaceInt32(m.left().Value() / m.right().Value()); |
218 } | 218 } |
219 if (m.right().Is(-1)) { // x / -1 => 0 - x | 219 if (m.right().Is(-1)) { // x / -1 => 0 - x |
220 graph()->ChangeOperator(node, machine()->Int32Sub()); | 220 node->set_op(machine()->Int32Sub()); |
221 node->ReplaceInput(0, Int32Constant(0)); | 221 node->ReplaceInput(0, Int32Constant(0)); |
222 node->ReplaceInput(1, m.left().node()); | 222 node->ReplaceInput(1, m.left().node()); |
223 return Changed(node); | 223 return Changed(node); |
224 } | 224 } |
225 break; | 225 break; |
226 } | 226 } |
227 case IrOpcode::kInt32UDiv: { | 227 case IrOpcode::kInt32UDiv: { |
228 Uint32BinopMatcher m(node); | 228 Uint32BinopMatcher m(node); |
229 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x | 229 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x |
230 // TODO(turbofan): if (m.left().Is(0)) | 230 // TODO(turbofan): if (m.left().Is(0)) |
231 // TODO(turbofan): if (m.right().Is(0)) | 231 // TODO(turbofan): if (m.right().Is(0)) |
232 // TODO(turbofan): if (m.LeftEqualsRight()) | 232 // TODO(turbofan): if (m.LeftEqualsRight()) |
233 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K | 233 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K |
234 return ReplaceInt32(m.left().Value() / m.right().Value()); | 234 return ReplaceInt32(m.left().Value() / m.right().Value()); |
235 } | 235 } |
236 if (m.right().IsPowerOf2()) { // x / 2^n => x >> n | 236 if (m.right().IsPowerOf2()) { // x / 2^n => x >> n |
237 graph()->ChangeOperator(node, machine()->Word32Shr()); | 237 node->set_op(machine()->Word32Shr()); |
238 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); | 238 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); |
239 return Changed(node); | 239 return Changed(node); |
240 } | 240 } |
241 break; | 241 break; |
242 } | 242 } |
243 case IrOpcode::kInt32Mod: { | 243 case IrOpcode::kInt32Mod: { |
244 Int32BinopMatcher m(node); | 244 Int32BinopMatcher m(node); |
245 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 | 245 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 |
246 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0 | 246 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0 |
247 // TODO(turbofan): if (m.left().Is(0)) | 247 // TODO(turbofan): if (m.left().Is(0)) |
248 // TODO(turbofan): if (m.right().IsPowerOf2()) | 248 // TODO(turbofan): if (m.right().IsPowerOf2()) |
249 // TODO(turbofan): if (m.right().Is(0)) | 249 // TODO(turbofan): if (m.right().Is(0)) |
250 // TODO(turbofan): if (m.LeftEqualsRight()) | 250 // TODO(turbofan): if (m.LeftEqualsRight()) |
251 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K | 251 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K |
252 return ReplaceInt32(m.left().Value() % m.right().Value()); | 252 return ReplaceInt32(m.left().Value() % m.right().Value()); |
253 } | 253 } |
254 break; | 254 break; |
255 } | 255 } |
256 case IrOpcode::kInt32UMod: { | 256 case IrOpcode::kInt32UMod: { |
257 Uint32BinopMatcher m(node); | 257 Uint32BinopMatcher m(node); |
258 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 | 258 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 |
259 // TODO(turbofan): if (m.left().Is(0)) | 259 // TODO(turbofan): if (m.left().Is(0)) |
260 // TODO(turbofan): if (m.right().Is(0)) | 260 // TODO(turbofan): if (m.right().Is(0)) |
261 // TODO(turbofan): if (m.LeftEqualsRight()) | 261 // TODO(turbofan): if (m.LeftEqualsRight()) |
262 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K | 262 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K |
263 return ReplaceInt32(m.left().Value() % m.right().Value()); | 263 return ReplaceInt32(m.left().Value() % m.right().Value()); |
264 } | 264 } |
265 if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1 | 265 if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1 |
266 graph()->ChangeOperator(node, machine()->Word32And()); | 266 node->set_op(machine()->Word32And()); |
267 node->ReplaceInput(1, Int32Constant(m.right().Value() - 1)); | 267 node->ReplaceInput(1, Int32Constant(m.right().Value() - 1)); |
268 return Changed(node); | 268 return Changed(node); |
269 } | 269 } |
270 break; | 270 break; |
271 } | 271 } |
272 case IrOpcode::kInt32LessThan: { | 272 case IrOpcode::kInt32LessThan: { |
273 Int32BinopMatcher m(node); | 273 Int32BinopMatcher m(node); |
274 if (m.IsFoldable()) { // K < K => K | 274 if (m.IsFoldable()) { // K < K => K |
275 return ReplaceBool(m.left().Value() < m.right().Value()); | 275 return ReplaceBool(m.left().Value() < m.right().Value()); |
276 } | 276 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 CommonOperatorBuilder* MachineOperatorReducer::common() const { | 436 CommonOperatorBuilder* MachineOperatorReducer::common() const { |
437 return jsgraph()->common(); | 437 return jsgraph()->common(); |
438 } | 438 } |
439 | 439 |
440 | 440 |
441 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 441 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
442 | 442 |
443 } // namespace compiler | 443 } // namespace compiler |
444 } // namespace internal | 444 } // namespace internal |
445 } // namespace v8 | 445 } // namespace v8 |
OLD | NEW |