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