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" |
11 #include "src/compiler/diamond.h" | 11 #include "src/compiler/diamond.h" |
12 #include "src/compiler/graph.h" | 12 #include "src/compiler/graph.h" |
13 #include "src/compiler/js-graph.h" | 13 #include "src/compiler/js-graph.h" |
14 #include "src/compiler/node-matchers.h" | 14 #include "src/compiler/node-matchers.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace compiler { | 18 namespace compiler { |
19 | 19 |
20 MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph) | 20 MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph, |
21 : jsgraph_(jsgraph) {} | 21 bool allow_signalling_nan) |
22 | 22 : jsgraph_(jsgraph), allow_signalling_nan_(allow_signalling_nan) {} |
23 | 23 |
24 MachineOperatorReducer::~MachineOperatorReducer() {} | 24 MachineOperatorReducer::~MachineOperatorReducer() {} |
25 | 25 |
26 | 26 |
27 Node* MachineOperatorReducer::Float32Constant(volatile float value) { | 27 Node* MachineOperatorReducer::Float32Constant(volatile float value) { |
28 return graph()->NewNode(common()->Float32Constant(value)); | 28 return graph()->NewNode(common()->Float32Constant(value)); |
29 } | 29 } |
30 | 30 |
31 | 31 |
32 Node* MachineOperatorReducer::Float64Constant(volatile double value) { | 32 Node* MachineOperatorReducer::Float64Constant(volatile double value) { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true | 309 if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true |
310 if (m.right().Is(kMaxUInt32)) return ReplaceBool(true); // x <= M => true | 310 if (m.right().Is(kMaxUInt32)) return ReplaceBool(true); // x <= M => true |
311 if (m.IsFoldable()) { // K <= K => K | 311 if (m.IsFoldable()) { // K <= K => K |
312 return ReplaceBool(m.left().Value() <= m.right().Value()); | 312 return ReplaceBool(m.left().Value() <= m.right().Value()); |
313 } | 313 } |
314 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true | 314 if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true |
315 break; | 315 break; |
316 } | 316 } |
317 case IrOpcode::kFloat32Sub: { | 317 case IrOpcode::kFloat32Sub: { |
318 Float32BinopMatcher m(node); | 318 Float32BinopMatcher m(node); |
319 // TODO(ahaas): We could do x - 0.0 = x if we knew that x is not an sNaN. | 319 if (allow_signalling_nan_ && m.right().Is(0) && |
| 320 (copysign(1.0, m.right().Value()) > 0)) { |
| 321 return Replace(m.left().node()); // x - 0 => x |
| 322 } |
320 if (m.right().IsNaN()) { // x - NaN => NaN | 323 if (m.right().IsNaN()) { // x - NaN => NaN |
321 // Do some calculation to make a signalling NaN quiet. | 324 // Do some calculation to make a signalling NaN quiet. |
322 return ReplaceFloat32(m.right().Value() - m.right().Value()); | 325 return ReplaceFloat32(m.right().Value() - m.right().Value()); |
323 } | 326 } |
324 if (m.left().IsNaN()) { // NaN - x => NaN | 327 if (m.left().IsNaN()) { // NaN - x => NaN |
325 // Do some calculation to make a signalling NaN quiet. | 328 // Do some calculation to make a signalling NaN quiet. |
326 return ReplaceFloat32(m.left().Value() - m.left().Value()); | 329 return ReplaceFloat32(m.left().Value() - m.left().Value()); |
327 } | 330 } |
328 if (m.IsFoldable()) { // L - R => (L - R) | 331 if (m.IsFoldable()) { // L - R => (L - R) |
329 return ReplaceFloat32(m.left().Value() - m.right().Value()); | 332 return ReplaceFloat32(m.left().Value() - m.right().Value()); |
(...skipping 23 matching lines...) Expand all Loading... |
353 // Do some calculation to make a signalling NaN quiet. | 356 // Do some calculation to make a signalling NaN quiet. |
354 return ReplaceFloat64(m.right().Value() - m.right().Value()); | 357 return ReplaceFloat64(m.right().Value() - m.right().Value()); |
355 } | 358 } |
356 if (m.IsFoldable()) { // K + K => K | 359 if (m.IsFoldable()) { // K + K => K |
357 return ReplaceFloat64(m.left().Value() + m.right().Value()); | 360 return ReplaceFloat64(m.left().Value() + m.right().Value()); |
358 } | 361 } |
359 break; | 362 break; |
360 } | 363 } |
361 case IrOpcode::kFloat64Sub: { | 364 case IrOpcode::kFloat64Sub: { |
362 Float64BinopMatcher m(node); | 365 Float64BinopMatcher m(node); |
363 // TODO(ahaas): We could do x - 0.0 = x if we knew that x is not an sNaN. | 366 if (allow_signalling_nan_ && m.right().Is(0) && |
| 367 (Double(m.right().Value()).Sign() > 0)) { |
| 368 return Replace(m.left().node()); // x - 0 => x |
| 369 } |
364 if (m.right().IsNaN()) { // x - NaN => NaN | 370 if (m.right().IsNaN()) { // x - NaN => NaN |
365 // Do some calculation to make a signalling NaN quiet. | 371 // Do some calculation to make a signalling NaN quiet. |
366 return ReplaceFloat64(m.right().Value() - m.right().Value()); | 372 return ReplaceFloat64(m.right().Value() - m.right().Value()); |
367 } | 373 } |
368 if (m.left().IsNaN()) { // NaN - x => NaN | 374 if (m.left().IsNaN()) { // NaN - x => NaN |
369 // Do some calculation to make a signalling NaN quiet. | 375 // Do some calculation to make a signalling NaN quiet. |
370 return ReplaceFloat64(m.left().Value() - m.left().Value()); | 376 return ReplaceFloat64(m.left().Value() - m.left().Value()); |
371 } | 377 } |
372 if (m.IsFoldable()) { // L - R => (L - R) | 378 if (m.IsFoldable()) { // L - R => (L - R) |
373 return ReplaceFloat64(m.left().Value() - m.right().Value()); | 379 return ReplaceFloat64(m.left().Value() - m.right().Value()); |
(...skipping 12 matching lines...) Expand all Loading... |
386 } | 392 } |
387 // -0.0 - R => -R | 393 // -0.0 - R => -R |
388 node->RemoveInput(0); | 394 node->RemoveInput(0); |
389 NodeProperties::ChangeOp(node, machine()->Float64Neg()); | 395 NodeProperties::ChangeOp(node, machine()->Float64Neg()); |
390 return Changed(node); | 396 return Changed(node); |
391 } | 397 } |
392 break; | 398 break; |
393 } | 399 } |
394 case IrOpcode::kFloat64Mul: { | 400 case IrOpcode::kFloat64Mul: { |
395 Float64BinopMatcher m(node); | 401 Float64BinopMatcher m(node); |
396 // TODO(ahaas): We could do x * 1.0 = x if we knew that x is not an sNaN. | 402 if (allow_signalling_nan_ && m.right().Is(1)) |
| 403 return Replace(m.left().node()); // x * 1.0 => x |
397 if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x | 404 if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x |
398 node->ReplaceInput(0, Float64Constant(-0.0)); | 405 node->ReplaceInput(0, Float64Constant(-0.0)); |
399 node->ReplaceInput(1, m.left().node()); | 406 node->ReplaceInput(1, m.left().node()); |
400 NodeProperties::ChangeOp(node, machine()->Float64Sub()); | 407 NodeProperties::ChangeOp(node, machine()->Float64Sub()); |
401 return Changed(node); | 408 return Changed(node); |
402 } | 409 } |
403 if (m.right().IsNaN()) { // x * NaN => NaN | 410 if (m.right().IsNaN()) { // x * NaN => NaN |
404 // Do some calculation to make a signalling NaN quiet. | 411 // Do some calculation to make a signalling NaN quiet. |
405 return ReplaceFloat64(m.right().Value() - m.right().Value()); | 412 return ReplaceFloat64(m.right().Value() - m.right().Value()); |
406 } | 413 } |
407 if (m.IsFoldable()) { // K * K => K | 414 if (m.IsFoldable()) { // K * K => K |
408 return ReplaceFloat64(m.left().Value() * m.right().Value()); | 415 return ReplaceFloat64(m.left().Value() * m.right().Value()); |
409 } | 416 } |
410 if (m.right().Is(2)) { // x * 2.0 => x + x | 417 if (m.right().Is(2)) { // x * 2.0 => x + x |
411 node->ReplaceInput(1, m.left().node()); | 418 node->ReplaceInput(1, m.left().node()); |
412 NodeProperties::ChangeOp(node, machine()->Float64Add()); | 419 NodeProperties::ChangeOp(node, machine()->Float64Add()); |
413 return Changed(node); | 420 return Changed(node); |
414 } | 421 } |
415 break; | 422 break; |
416 } | 423 } |
417 case IrOpcode::kFloat64Div: { | 424 case IrOpcode::kFloat64Div: { |
418 Float64BinopMatcher m(node); | 425 Float64BinopMatcher m(node); |
| 426 if (allow_signalling_nan_ && m.right().Is(1)) |
| 427 return Replace(m.left().node()); // x / 1.0 => x |
419 // TODO(ahaas): We could do x / 1.0 = x if we knew that x is not an sNaN. | 428 // TODO(ahaas): We could do x / 1.0 = x if we knew that x is not an sNaN. |
420 if (m.right().IsNaN()) { // x / NaN => NaN | 429 if (m.right().IsNaN()) { // x / NaN => NaN |
421 // Do some calculation to make a signalling NaN quiet. | 430 // Do some calculation to make a signalling NaN quiet. |
422 return ReplaceFloat64(m.right().Value() - m.right().Value()); | 431 return ReplaceFloat64(m.right().Value() - m.right().Value()); |
423 } | 432 } |
424 if (m.left().IsNaN()) { // NaN / x => NaN | 433 if (m.left().IsNaN()) { // NaN / x => NaN |
425 // Do some calculation to make a signalling NaN quiet. | 434 // Do some calculation to make a signalling NaN quiet. |
426 return ReplaceFloat64(m.left().Value() - m.left().Value()); | 435 return ReplaceFloat64(m.left().Value() - m.left().Value()); |
427 } | 436 } |
428 if (m.IsFoldable()) { // K / K => K | 437 if (m.IsFoldable()) { // K / K => K |
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 1423 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
1415 return jsgraph()->machine(); | 1424 return jsgraph()->machine(); |
1416 } | 1425 } |
1417 | 1426 |
1418 | 1427 |
1419 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 1428 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
1420 | 1429 |
1421 } // namespace compiler | 1430 } // namespace compiler |
1422 } // namespace internal | 1431 } // namespace internal |
1423 } // namespace v8 | 1432 } // namespace v8 |
OLD | NEW |