Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1901803002: [turbofan] Remove phase ordering problem in JSToNumber lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comment Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 = graph()->NewNode(simplified()->ChangeSmiToInt32(), value);
1490 vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
1491 }
1492
1493 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1494 Node* efalse0 = effect;
1495 Node* vfalse0;
1496 {
1497 throwing = vfalse0 = efalse0 =
1498 graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
1499 frame_state, efalse0, if_false0);
1500 if_false0 = graph()->NewNode(common()->IfSuccess(), throwing);
1501
1502 Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
1503 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
1504
1505 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1506 Node* etrue1 = efalse0;
1507 Node* vtrue1;
1508 {
1509 vtrue1 = graph()->NewNode(simplified()->ChangeSmiToInt32(), vfalse0);
1510 vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
1511 }
1512
1513 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1514 Node* efalse1 = efalse0;
1515 Node* vfalse1;
1516 {
1517 vfalse1 = efalse1 = graph()->NewNode(
1518 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
1519 efalse1, if_false1);
1520 }
1521
1522 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1523 efalse0 =
1524 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1525 vfalse0 =
1526 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1527 vtrue1, vfalse1, if_false0);
1528 }
1529
1530 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1531 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1532 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1533 vtrue0, vfalse0, control);
1534
1535 // Replace effect and control uses appropriately.
1536 for (Edge edge : node->use_edges()) {
1537 if (NodeProperties::IsControlEdge(edge)) {
1538 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
1539 edge.from()->ReplaceUses(control);
1540 edge.from()->Kill();
1541 } else if (edge.from()->opcode() == IrOpcode::kIfException) {
1542 edge.UpdateTo(throwing);
1543 } else {
1544 UNREACHABLE();
1545 }
1546 } else if (NodeProperties::IsEffectEdge(edge)) {
1547 edge.UpdateTo(effect);
1548 }
1549 }
1550
1551 selector->DeferReplacement(node, value);
1552 }
1553
1554 void SimplifiedLowering::DoJSToNumberTruncatesToWord32(
1555 Node* node, RepresentationSelector* selector) {
1556 DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
1557 Node* value = node->InputAt(0);
1558 Node* context = node->InputAt(1);
1559 Node* frame_state = node->InputAt(2);
1560 Node* effect = node->InputAt(3);
1561 Node* control = node->InputAt(4);
1562 Node* throwing;
1563
1564 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
1565 Node* branch0 =
1566 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1567
1568 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1569 Node* etrue0 = effect;
1570 Node* vtrue0 = graph()->NewNode(simplified()->ChangeSmiToInt32(), value);
1571
1572 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1573 Node* efalse0 = effect;
1574 Node* vfalse0;
1575 {
1576 throwing = vfalse0 = efalse0 =
1577 graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
1578 frame_state, efalse0, if_false0);
1579 if_false0 = graph()->NewNode(common()->IfSuccess(), throwing);
1580
1581 Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
1582 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
1583
1584 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1585 Node* etrue1 = efalse0;
1586 Node* vtrue1 = graph()->NewNode(simplified()->ChangeSmiToInt32(), vfalse0);
1587
1588 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1589 Node* efalse1 = efalse0;
1590 Node* vfalse1;
1591 {
1592 vfalse1 = efalse1 = graph()->NewNode(
1593 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
1594 efalse1, if_false1);
1595 vfalse1 = graph()->NewNode(
1596 machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript),
1597 vfalse1);
1598 }
1599
1600 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1601 efalse0 =
1602 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1603 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1604 vtrue1, vfalse1, if_false0);
1605 }
1606
1607 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1608 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1609 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1610 vtrue0, vfalse0, control);
1611
1612 // Replace effect and control uses appropriately.
1613 for (Edge edge : node->use_edges()) {
1614 if (NodeProperties::IsControlEdge(edge)) {
1615 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
1616 edge.from()->ReplaceUses(control);
1617 edge.from()->Kill();
1618 } else if (edge.from()->opcode() == IrOpcode::kIfException) {
1619 edge.UpdateTo(throwing);
1620 } else {
1621 UNREACHABLE();
1622 }
1623 } else if (NodeProperties::IsEffectEdge(edge)) {
1624 edge.UpdateTo(effect);
1625 }
1626 }
1627
1628 selector->DeferReplacement(node, value);
1629 }
1466 1630
1467 void SimplifiedLowering::DoLoadBuffer(Node* node, 1631 void SimplifiedLowering::DoLoadBuffer(Node* node,
1468 MachineRepresentation output_rep, 1632 MachineRepresentation output_rep,
1469 RepresentationChanger* changer) { 1633 RepresentationChanger* changer) {
1470 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); 1634 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
1471 DCHECK_NE(MachineRepresentation::kNone, output_rep); 1635 DCHECK_NE(MachineRepresentation::kNone, output_rep);
1472 MachineType const access_type = BufferAccessOf(node->op()).machine_type(); 1636 MachineType const access_type = BufferAccessOf(node->op()).machine_type();
1473 if (output_rep != access_type.representation()) { 1637 if (output_rep != access_type.representation()) {
1474 Node* const buffer = node->InputAt(0); 1638 Node* const buffer = node->InputAt(0);
1475 Node* const offset = node->InputAt(1); 1639 Node* const offset = node->InputAt(1);
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
2176 void SimplifiedLowering::DoShift(Node* node, Operator const* op, 2340 void SimplifiedLowering::DoShift(Node* node, Operator const* op,
2177 Type* rhs_type) { 2341 Type* rhs_type) {
2178 Node* const rhs = NodeProperties::GetValueInput(node, 1); 2342 Node* const rhs = NodeProperties::GetValueInput(node, 1);
2179 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { 2343 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) {
2180 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, 2344 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
2181 jsgraph()->Int32Constant(0x1f))); 2345 jsgraph()->Int32Constant(0x1f)));
2182 } 2346 }
2183 NodeProperties::ChangeOp(node, op); 2347 NodeProperties::ChangeOp(node, op);
2184 } 2348 }
2185 2349
2350 Node* SimplifiedLowering::ToNumberCode() {
2351 if (!to_number_code_.is_set()) {
2352 Callable callable = CodeFactory::ToNumber(isolate());
2353 to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
2354 }
2355 return to_number_code_.get();
2356 }
2357
2358 Operator const* SimplifiedLowering::ToNumberOperator() {
2359 if (!to_number_operator_.is_set()) {
2360 Callable callable = CodeFactory::ToNumber(isolate());
2361 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
2362 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
2363 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
2364 Operator::kNoProperties);
2365 to_number_operator_.set(common()->Call(desc));
2366 }
2367 return to_number_operator_.get();
2368 }
2369
2186 } // namespace compiler 2370 } // namespace compiler
2187 } // namespace internal 2371 } // namespace internal
2188 } // namespace v8 2372 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698