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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| 11 #include "src/compiler/access-builder.h" |
11 #include "src/compiler/common-operator.h" | 12 #include "src/compiler/common-operator.h" |
12 #include "src/compiler/diamond.h" | 13 #include "src/compiler/diamond.h" |
13 #include "src/compiler/linkage.h" | 14 #include "src/compiler/linkage.h" |
14 #include "src/compiler/node-matchers.h" | 15 #include "src/compiler/node-matchers.h" |
15 #include "src/compiler/node-properties.h" | 16 #include "src/compiler/node-properties.h" |
16 #include "src/compiler/operator-properties.h" | 17 #include "src/compiler/operator-properties.h" |
17 #include "src/compiler/representation-change.h" | 18 #include "src/compiler/representation-change.h" |
18 #include "src/compiler/simplified-operator.h" | 19 #include "src/compiler/simplified-operator.h" |
19 #include "src/compiler/source-position.h" | 20 #include "src/compiler/source-position.h" |
20 #include "src/objects.h" | 21 #include "src/objects.h" |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 755 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
755 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 756 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
756 break; | 757 break; |
757 case IrOpcode::kSelect: | 758 case IrOpcode::kSelect: |
758 return VisitSelect(node, truncation, lowering); | 759 return VisitSelect(node, truncation, lowering); |
759 case IrOpcode::kPhi: | 760 case IrOpcode::kPhi: |
760 return VisitPhi(node, truncation, lowering); | 761 return VisitPhi(node, truncation, lowering); |
761 case IrOpcode::kCall: | 762 case IrOpcode::kCall: |
762 return VisitCall(node, lowering); | 763 return VisitCall(node, lowering); |
763 | 764 |
764 //------------------------------------------------------------------ | 765 //------------------------------------------------------------------ |
765 // JavaScript operators. | 766 // JavaScript operators. |
766 //------------------------------------------------------------------ | 767 //------------------------------------------------------------------ |
767 // For now, we assume that all JS operators were too complex to lower | 768 case IrOpcode::kJSToNumber: { |
768 // to Simplified and that they will always require tagged value inputs | |
769 // and produce tagged value outputs. | |
770 // TODO(turbofan): it might be possible to lower some JSOperators here, | |
771 // but that responsibility really lies in the typed lowering phase. | |
772 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | |
773 JS_OP_LIST(DEFINE_JS_CASE) | |
774 #undef DEFINE_JS_CASE | |
775 VisitInputs(node); | 769 VisitInputs(node); |
776 return SetOutput(node, MachineRepresentation::kTagged); | 770 // TODO(bmeurer): Optimize somewhat based on input type? |
| 771 if (truncation.TruncatesToWord32()) { |
| 772 SetOutput(node, MachineRepresentation::kWord32); |
| 773 if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this); |
| 774 } else if (truncation.TruncatesToFloat64()) { |
| 775 SetOutput(node, MachineRepresentation::kFloat64); |
| 776 if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this); |
| 777 } else { |
| 778 SetOutput(node, MachineRepresentation::kTagged); |
| 779 } |
| 780 break; |
| 781 } |
777 | 782 |
778 //------------------------------------------------------------------ | 783 //------------------------------------------------------------------ |
779 // Simplified operators. | 784 // Simplified operators. |
780 //------------------------------------------------------------------ | 785 //------------------------------------------------------------------ |
781 case IrOpcode::kBooleanNot: { | 786 case IrOpcode::kBooleanNot: { |
782 if (lower()) { | 787 if (lower()) { |
783 NodeInfo* input_info = GetInfo(node->InputAt(0)); | 788 NodeInfo* input_info = GetInfo(node->InputAt(0)); |
784 if (input_info->representation() == MachineRepresentation::kBit) { | 789 if (input_info->representation() == MachineRepresentation::kBit) { |
785 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 790 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
786 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 791 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 source_positions_(source_positions) {} | 1461 source_positions_(source_positions) {} |
1457 | 1462 |
1458 | 1463 |
1459 void SimplifiedLowering::LowerAllNodes() { | 1464 void SimplifiedLowering::LowerAllNodes() { |
1460 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); | 1465 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); |
1461 RepresentationSelector selector(jsgraph(), zone_, &changer, | 1466 RepresentationSelector selector(jsgraph(), zone_, &changer, |
1462 source_positions_); | 1467 source_positions_); |
1463 selector.Run(this); | 1468 selector.Run(this); |
1464 } | 1469 } |
1465 | 1470 |
| 1471 void SimplifiedLowering::DoJSToNumberTruncatesToFloat64( |
| 1472 Node* node, RepresentationSelector* selector) { |
| 1473 DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode()); |
| 1474 Node* value = node->InputAt(0); |
| 1475 Node* context = node->InputAt(1); |
| 1476 Node* frame_state = node->InputAt(2); |
| 1477 Node* effect = node->InputAt(3); |
| 1478 Node* control = node->InputAt(4); |
| 1479 Node* throwing; |
| 1480 |
| 1481 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 1482 Node* branch0 = |
| 1483 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
| 1484 |
| 1485 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1486 Node* etrue0 = effect; |
| 1487 Node* vtrue0; |
| 1488 { |
| 1489 vtrue0 = |
| 1490 graph()->NewNode(simplified()->ChangeTaggedSignedToWord32(), value); |
| 1491 vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0); |
| 1492 } |
| 1493 |
| 1494 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1495 Node* efalse0 = effect; |
| 1496 Node* vfalse0; |
| 1497 { |
| 1498 throwing = vfalse0 = efalse0 = |
| 1499 graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context, |
| 1500 frame_state, efalse0, if_false0); |
| 1501 if_false0 = graph()->NewNode(common()->IfSuccess(), throwing); |
| 1502 |
| 1503 Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0); |
| 1504 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); |
| 1505 |
| 1506 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1507 Node* etrue1 = efalse0; |
| 1508 Node* vtrue1; |
| 1509 { |
| 1510 vtrue1 = |
| 1511 graph()->NewNode(simplified()->ChangeTaggedSignedToWord32(), vfalse0); |
| 1512 vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1); |
| 1513 } |
| 1514 |
| 1515 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1516 Node* efalse1 = efalse0; |
| 1517 Node* vfalse1; |
| 1518 { |
| 1519 vfalse1 = efalse1 = graph()->NewNode( |
| 1520 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0, |
| 1521 efalse1, if_false1); |
| 1522 } |
| 1523 |
| 1524 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1525 efalse0 = |
| 1526 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
| 1527 vfalse0 = |
| 1528 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 1529 vtrue1, vfalse1, if_false0); |
| 1530 } |
| 1531 |
| 1532 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1533 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| 1534 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 1535 vtrue0, vfalse0, control); |
| 1536 |
| 1537 // Replace effect and control uses appropriately. |
| 1538 for (Edge edge : node->use_edges()) { |
| 1539 if (NodeProperties::IsControlEdge(edge)) { |
| 1540 if (edge.from()->opcode() == IrOpcode::kIfSuccess) { |
| 1541 edge.from()->ReplaceUses(control); |
| 1542 edge.from()->Kill(); |
| 1543 } else if (edge.from()->opcode() == IrOpcode::kIfException) { |
| 1544 edge.UpdateTo(throwing); |
| 1545 } else { |
| 1546 UNREACHABLE(); |
| 1547 } |
| 1548 } else if (NodeProperties::IsEffectEdge(edge)) { |
| 1549 edge.UpdateTo(effect); |
| 1550 } |
| 1551 } |
| 1552 |
| 1553 selector->DeferReplacement(node, value); |
| 1554 } |
| 1555 |
| 1556 void SimplifiedLowering::DoJSToNumberTruncatesToWord32( |
| 1557 Node* node, RepresentationSelector* selector) { |
| 1558 DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode()); |
| 1559 Node* value = node->InputAt(0); |
| 1560 Node* context = node->InputAt(1); |
| 1561 Node* frame_state = node->InputAt(2); |
| 1562 Node* effect = node->InputAt(3); |
| 1563 Node* control = node->InputAt(4); |
| 1564 Node* throwing; |
| 1565 |
| 1566 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value); |
| 1567 Node* branch0 = |
| 1568 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
| 1569 |
| 1570 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1571 Node* etrue0 = effect; |
| 1572 Node* vtrue0 = |
| 1573 graph()->NewNode(simplified()->ChangeTaggedSignedToWord32(), value); |
| 1574 |
| 1575 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1576 Node* efalse0 = effect; |
| 1577 Node* vfalse0; |
| 1578 { |
| 1579 throwing = vfalse0 = efalse0 = |
| 1580 graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context, |
| 1581 frame_state, efalse0, if_false0); |
| 1582 if_false0 = graph()->NewNode(common()->IfSuccess(), throwing); |
| 1583 |
| 1584 Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0); |
| 1585 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); |
| 1586 |
| 1587 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1588 Node* etrue1 = efalse0; |
| 1589 Node* vtrue1 = |
| 1590 graph()->NewNode(simplified()->ChangeTaggedSignedToWord32(), vfalse0); |
| 1591 |
| 1592 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1593 Node* efalse1 = efalse0; |
| 1594 Node* vfalse1; |
| 1595 { |
| 1596 vfalse1 = efalse1 = graph()->NewNode( |
| 1597 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0, |
| 1598 efalse1, if_false1); |
| 1599 vfalse1 = graph()->NewNode( |
| 1600 machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript), |
| 1601 vfalse1); |
| 1602 } |
| 1603 |
| 1604 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1605 efalse0 = |
| 1606 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
| 1607 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
| 1608 vtrue1, vfalse1, if_false0); |
| 1609 } |
| 1610 |
| 1611 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1612 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| 1613 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
| 1614 vtrue0, vfalse0, control); |
| 1615 |
| 1616 // Replace effect and control uses appropriately. |
| 1617 for (Edge edge : node->use_edges()) { |
| 1618 if (NodeProperties::IsControlEdge(edge)) { |
| 1619 if (edge.from()->opcode() == IrOpcode::kIfSuccess) { |
| 1620 edge.from()->ReplaceUses(control); |
| 1621 edge.from()->Kill(); |
| 1622 } else if (edge.from()->opcode() == IrOpcode::kIfException) { |
| 1623 edge.UpdateTo(throwing); |
| 1624 } else { |
| 1625 UNREACHABLE(); |
| 1626 } |
| 1627 } else if (NodeProperties::IsEffectEdge(edge)) { |
| 1628 edge.UpdateTo(effect); |
| 1629 } |
| 1630 } |
| 1631 |
| 1632 selector->DeferReplacement(node, value); |
| 1633 } |
1466 | 1634 |
1467 void SimplifiedLowering::DoLoadBuffer(Node* node, | 1635 void SimplifiedLowering::DoLoadBuffer(Node* node, |
1468 MachineRepresentation output_rep, | 1636 MachineRepresentation output_rep, |
1469 RepresentationChanger* changer) { | 1637 RepresentationChanger* changer) { |
1470 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); | 1638 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); |
1471 DCHECK_NE(MachineRepresentation::kNone, output_rep); | 1639 DCHECK_NE(MachineRepresentation::kNone, output_rep); |
1472 MachineType const access_type = BufferAccessOf(node->op()).machine_type(); | 1640 MachineType const access_type = BufferAccessOf(node->op()).machine_type(); |
1473 if (output_rep != access_type.representation()) { | 1641 if (output_rep != access_type.representation()) { |
1474 Node* const buffer = node->InputAt(0); | 1642 Node* const buffer = node->InputAt(0); |
1475 Node* const offset = node->InputAt(1); | 1643 Node* const offset = node->InputAt(1); |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 void SimplifiedLowering::DoShift(Node* node, Operator const* op, | 2344 void SimplifiedLowering::DoShift(Node* node, Operator const* op, |
2177 Type* rhs_type) { | 2345 Type* rhs_type) { |
2178 Node* const rhs = NodeProperties::GetValueInput(node, 1); | 2346 Node* const rhs = NodeProperties::GetValueInput(node, 1); |
2179 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { | 2347 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { |
2180 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, | 2348 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, |
2181 jsgraph()->Int32Constant(0x1f))); | 2349 jsgraph()->Int32Constant(0x1f))); |
2182 } | 2350 } |
2183 NodeProperties::ChangeOp(node, op); | 2351 NodeProperties::ChangeOp(node, op); |
2184 } | 2352 } |
2185 | 2353 |
| 2354 Node* SimplifiedLowering::ToNumberCode() { |
| 2355 if (!to_number_code_.is_set()) { |
| 2356 Callable callable = CodeFactory::ToNumber(isolate()); |
| 2357 to_number_code_.set(jsgraph()->HeapConstant(callable.code())); |
| 2358 } |
| 2359 return to_number_code_.get(); |
| 2360 } |
| 2361 |
| 2362 Operator const* SimplifiedLowering::ToNumberOperator() { |
| 2363 if (!to_number_operator_.is_set()) { |
| 2364 Callable callable = CodeFactory::ToNumber(isolate()); |
| 2365 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
| 2366 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 2367 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 2368 Operator::kIdempotent); |
| 2369 to_number_operator_.set(common()->Call(desc)); |
| 2370 } |
| 2371 return to_number_operator_.get(); |
| 2372 } |
| 2373 |
2186 } // namespace compiler | 2374 } // namespace compiler |
2187 } // namespace internal | 2375 } // namespace internal |
2188 } // namespace v8 | 2376 } // namespace v8 |
OLD | NEW |