| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 break; | 433 break; |
| 434 case IrOpcode::kCheckBounds: | 434 case IrOpcode::kCheckBounds: |
| 435 state = LowerCheckBounds(node, frame_state, *effect, *control); | 435 state = LowerCheckBounds(node, frame_state, *effect, *control); |
| 436 break; | 436 break; |
| 437 case IrOpcode::kCheckTaggedPointer: | 437 case IrOpcode::kCheckTaggedPointer: |
| 438 state = LowerCheckTaggedPointer(node, frame_state, *effect, *control); | 438 state = LowerCheckTaggedPointer(node, frame_state, *effect, *control); |
| 439 break; | 439 break; |
| 440 case IrOpcode::kCheckTaggedSigned: | 440 case IrOpcode::kCheckTaggedSigned: |
| 441 state = LowerCheckTaggedSigned(node, frame_state, *effect, *control); | 441 state = LowerCheckTaggedSigned(node, frame_state, *effect, *control); |
| 442 break; | 442 break; |
| 443 case IrOpcode::kCheckedInt32Add: |
| 444 state = LowerCheckedInt32Add(node, frame_state, *effect, *control); |
| 445 break; |
| 446 case IrOpcode::kCheckedInt32Sub: |
| 447 state = LowerCheckedInt32Sub(node, frame_state, *effect, *control); |
| 448 break; |
| 443 case IrOpcode::kCheckedUint32ToInt32: | 449 case IrOpcode::kCheckedUint32ToInt32: |
| 444 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); | 450 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); |
| 445 break; | 451 break; |
| 446 case IrOpcode::kCheckedFloat64ToInt32: | 452 case IrOpcode::kCheckedFloat64ToInt32: |
| 447 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); | 453 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); |
| 448 break; | 454 break; |
| 449 case IrOpcode::kCheckedTaggedToInt32: | 455 case IrOpcode::kCheckedTaggedToInt32: |
| 450 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); | 456 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); |
| 451 break; | 457 break; |
| 452 case IrOpcode::kCheckedTaggedToFloat64: | 458 case IrOpcode::kCheckedTaggedToFloat64: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 469 break; | 475 break; |
| 470 case IrOpcode::kObjectIsString: | 476 case IrOpcode::kObjectIsString: |
| 471 state = LowerObjectIsString(node, *effect, *control); | 477 state = LowerObjectIsString(node, *effect, *control); |
| 472 break; | 478 break; |
| 473 case IrOpcode::kObjectIsUndetectable: | 479 case IrOpcode::kObjectIsUndetectable: |
| 474 state = LowerObjectIsUndetectable(node, *effect, *control); | 480 state = LowerObjectIsUndetectable(node, *effect, *control); |
| 475 break; | 481 break; |
| 476 case IrOpcode::kStringFromCharCode: | 482 case IrOpcode::kStringFromCharCode: |
| 477 state = LowerStringFromCharCode(node, *effect, *control); | 483 state = LowerStringFromCharCode(node, *effect, *control); |
| 478 break; | 484 break; |
| 479 case IrOpcode::kCheckIf: | |
| 480 state = LowerCheckIf(node, frame_state, *effect, *control); | |
| 481 break; | |
| 482 case IrOpcode::kCheckFloat64Hole: | 485 case IrOpcode::kCheckFloat64Hole: |
| 483 state = LowerCheckFloat64Hole(node, frame_state, *effect, *control); | 486 state = LowerCheckFloat64Hole(node, frame_state, *effect, *control); |
| 484 break; | 487 break; |
| 485 case IrOpcode::kCheckTaggedHole: | 488 case IrOpcode::kCheckTaggedHole: |
| 486 state = LowerCheckTaggedHole(node, frame_state, *effect, *control); | 489 state = LowerCheckTaggedHole(node, frame_state, *effect, *control); |
| 487 break; | 490 break; |
| 488 case IrOpcode::kPlainPrimitiveToNumber: | 491 case IrOpcode::kPlainPrimitiveToNumber: |
| 489 state = LowerPlainPrimitiveToNumber(node, *effect, *control); | 492 state = LowerPlainPrimitiveToNumber(node, *effect, *control); |
| 490 break; | 493 break; |
| 491 case IrOpcode::kPlainPrimitiveToWord32: | 494 case IrOpcode::kPlainPrimitiveToWord32: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 | 550 |
| 548 // We need to create a box for negative 0. | 551 // We need to create a box for negative 0. |
| 549 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); | 552 if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative); |
| 550 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); | 553 if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative); |
| 551 | 554 |
| 552 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit | 555 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit |
| 553 // machines we need to deal with potential overflow and fallback to boxing. | 556 // machines we need to deal with potential overflow and fallback to boxing. |
| 554 if (machine()->Is64()) { | 557 if (machine()->Is64()) { |
| 555 vsmi = ChangeInt32ToSmi(value32); | 558 vsmi = ChangeInt32ToSmi(value32); |
| 556 } else { | 559 } else { |
| 557 Node* smi_tag = | 560 Node* smi_tag = graph()->NewNode(machine()->Int32AddWithOverflow(), value32, |
| 558 graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32); | 561 value32, if_smi); |
| 559 | 562 |
| 560 Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag); | 563 Node* check_ovf = |
| 564 graph()->NewNode(common()->Projection(1), smi_tag, if_smi); |
| 561 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 565 Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 562 check_ovf, if_smi); | 566 check_ovf, if_smi); |
| 563 | 567 |
| 564 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); | 568 Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf); |
| 565 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); | 569 if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box); |
| 566 | 570 |
| 567 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); | 571 if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf); |
| 568 vsmi = graph()->NewNode(common()->Projection(0), smi_tag); | 572 vsmi = graph()->NewNode(common()->Projection(0), smi_tag, if_smi); |
| 569 } | 573 } |
| 570 | 574 |
| 571 // Allocate the box for the {value}. | 575 // Allocate the box for the {value}. |
| 572 ValueEffectControl box = AllocateHeapNumberWithValue(value, effect, if_box); | 576 ValueEffectControl box = AllocateHeapNumberWithValue(value, effect, if_box); |
| 573 | 577 |
| 574 control = graph()->NewNode(common()->Merge(2), if_smi, box.control); | 578 control = graph()->NewNode(common()->Merge(2), if_smi, box.control); |
| 575 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 579 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 576 vsmi, box.value, control); | 580 vsmi, box.value, control); |
| 577 effect = | 581 effect = |
| 578 graph()->NewNode(common()->EffectPhi(2), effect, box.effect, control); | 582 graph()->NewNode(common()->EffectPhi(2), effect, box.effect, control); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 | 614 |
| 611 EffectControlLinearizer::ValueEffectControl | 615 EffectControlLinearizer::ValueEffectControl |
| 612 EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect, | 616 EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect, |
| 613 Node* control) { | 617 Node* control) { |
| 614 Node* value = node->InputAt(0); | 618 Node* value = node->InputAt(0); |
| 615 | 619 |
| 616 if (machine()->Is64()) { | 620 if (machine()->Is64()) { |
| 617 return ValueEffectControl(ChangeInt32ToSmi(value), effect, control); | 621 return ValueEffectControl(ChangeInt32ToSmi(value), effect, control); |
| 618 } | 622 } |
| 619 | 623 |
| 620 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); | 624 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value, |
| 625 control); |
| 621 | 626 |
| 622 Node* ovf = graph()->NewNode(common()->Projection(1), add); | 627 Node* ovf = graph()->NewNode(common()->Projection(1), add, control); |
| 623 Node* branch = | 628 Node* branch = |
| 624 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); | 629 graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); |
| 625 | 630 |
| 626 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 631 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 627 ValueEffectControl alloc = | 632 ValueEffectControl alloc = |
| 628 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true); | 633 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true); |
| 629 | 634 |
| 630 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 635 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 631 Node* vfalse = graph()->NewNode(common()->Projection(0), add); | 636 Node* vfalse = graph()->NewNode(common()->Projection(0), add, if_false); |
| 632 | 637 |
| 633 Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false); | 638 Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false); |
| 634 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 639 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 635 alloc.value, vfalse, merge); | 640 alloc.value, vfalse, merge); |
| 636 Node* ephi = | 641 Node* ephi = |
| 637 graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge); | 642 graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge); |
| 638 | 643 |
| 639 return ValueEffectControl(phi, ephi, merge); | 644 return ValueEffectControl(phi, ephi, merge); |
| 640 } | 645 } |
| 641 | 646 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, | 833 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, |
| 829 frame_state, effect, control); | 834 frame_state, effect, control); |
| 830 | 835 |
| 831 // Make sure the lowered node does not appear in any use lists. | 836 // Make sure the lowered node does not appear in any use lists. |
| 832 node->TrimInputCount(0); | 837 node->TrimInputCount(0); |
| 833 | 838 |
| 834 return ValueEffectControl(value, effect, control); | 839 return ValueEffectControl(value, effect, control); |
| 835 } | 840 } |
| 836 | 841 |
| 837 EffectControlLinearizer::ValueEffectControl | 842 EffectControlLinearizer::ValueEffectControl |
| 843 EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state, |
| 844 Node* effect, Node* control) { |
| 845 Node* lhs = node->InputAt(0); |
| 846 Node* rhs = node->InputAt(1); |
| 847 |
| 848 Node* value = |
| 849 graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control); |
| 850 |
| 851 Node* check = graph()->NewNode(common()->Projection(1), value, control); |
| 852 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, |
| 853 frame_state, effect, control); |
| 854 |
| 855 value = graph()->NewNode(common()->Projection(0), value, control); |
| 856 |
| 857 // Make sure the lowered node does not appear in any use lists. |
| 858 node->TrimInputCount(0); |
| 859 |
| 860 return ValueEffectControl(value, effect, control); |
| 861 } |
| 862 |
| 863 EffectControlLinearizer::ValueEffectControl |
| 864 EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state, |
| 865 Node* effect, Node* control) { |
| 866 Node* lhs = node->InputAt(0); |
| 867 Node* rhs = node->InputAt(1); |
| 868 |
| 869 Node* value = |
| 870 graph()->NewNode(machine()->Int32SubWithOverflow(), lhs, rhs, control); |
| 871 |
| 872 Node* check = graph()->NewNode(common()->Projection(1), value, control); |
| 873 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, |
| 874 frame_state, effect, control); |
| 875 |
| 876 value = graph()->NewNode(common()->Projection(0), value, control); |
| 877 |
| 878 // Make sure the lowered node does not appear in any use lists. |
| 879 node->TrimInputCount(0); |
| 880 |
| 881 return ValueEffectControl(value, effect, control); |
| 882 } |
| 883 |
| 884 EffectControlLinearizer::ValueEffectControl |
| 838 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, | 885 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
| 839 Node* frame_state, | 886 Node* frame_state, |
| 840 Node* effect, | 887 Node* effect, |
| 841 Node* control) { | 888 Node* control) { |
| 842 Node* value = node->InputAt(0); | 889 Node* value = node->InputAt(0); |
| 843 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); | 890 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); |
| 844 Node* is_safe = | 891 Node* is_safe = |
| 845 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); | 892 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); |
| 846 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, | 893 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, |
| 847 frame_state, effect, control); | 894 frame_state, effect, control); |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 | 1412 |
| 1366 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 1413 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1367 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 1414 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| 1368 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 1415 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 1369 vtrue0, vfalse0, control); | 1416 vtrue0, vfalse0, control); |
| 1370 | 1417 |
| 1371 return ValueEffectControl(value, effect, control); | 1418 return ValueEffectControl(value, effect, control); |
| 1372 } | 1419 } |
| 1373 | 1420 |
| 1374 EffectControlLinearizer::ValueEffectControl | 1421 EffectControlLinearizer::ValueEffectControl |
| 1375 EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state, | |
| 1376 Node* effect, Node* control) { | |
| 1377 NodeProperties::ReplaceEffectInput(node, effect); | |
| 1378 NodeProperties::ReplaceControlInput(node, control); | |
| 1379 DCHECK_NOT_NULL(frame_state); | |
| 1380 node->InsertInput(graph()->zone(), 1, frame_state); | |
| 1381 NodeProperties::ChangeOp(node, common()->DeoptimizeIf()); | |
| 1382 return ValueEffectControl(node, node, node); | |
| 1383 } | |
| 1384 | |
| 1385 EffectControlLinearizer::ValueEffectControl | |
| 1386 EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state, | 1422 EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state, |
| 1387 Node* effect, Node* control) { | 1423 Node* effect, Node* control) { |
| 1388 // If we reach this point w/o eliminating the {node} that's marked | 1424 // If we reach this point w/o eliminating the {node} that's marked |
| 1389 // with allow-return-hole, we cannot do anything, so just deoptimize | 1425 // with allow-return-hole, we cannot do anything, so just deoptimize |
| 1390 // in case of the hole NaN (similar to Crankshaft). | 1426 // in case of the hole NaN (similar to Crankshaft). |
| 1391 Node* value = node->InputAt(0); | 1427 Node* value = node->InputAt(0); |
| 1392 Node* check = graph()->NewNode( | 1428 Node* check = graph()->NewNode( |
| 1393 machine()->Word32Equal(), | 1429 machine()->Word32Equal(), |
| 1394 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), | 1430 graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
| 1395 jsgraph()->Int32Constant(kHoleNanUpper32)); | 1431 jsgraph()->Int32Constant(kHoleNanUpper32)); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 1661 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 1626 Operator::kNoThrow); | 1662 Operator::kNoThrow); |
| 1627 to_number_operator_.set(common()->Call(desc)); | 1663 to_number_operator_.set(common()->Call(desc)); |
| 1628 } | 1664 } |
| 1629 return to_number_operator_.get(); | 1665 return to_number_operator_.get(); |
| 1630 } | 1666 } |
| 1631 | 1667 |
| 1632 } // namespace compiler | 1668 } // namespace compiler |
| 1633 } // namespace internal | 1669 } // namespace internal |
| 1634 } // namespace v8 | 1670 } // namespace v8 |
| OLD | NEW |