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

Side by Side Diff: src/compiler/arm/instruction-selector-arm.cc

Issue 1721103003: [turbofan] Introduce DeoptimizeIf And DeoptimizeUnless common operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add comments Created 4 years, 9 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
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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/base/bits.h" 6 #include "src/base/bits.h"
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 if (cont->IsSet()) { 230 if (cont->IsSet()) {
231 outputs[output_count++] = g.DefineAsRegister(cont->result()); 231 outputs[output_count++] = g.DefineAsRegister(cont->result());
232 } 232 }
233 233
234 DCHECK_NE(0u, input_count); 234 DCHECK_NE(0u, input_count);
235 DCHECK_NE(0u, output_count); 235 DCHECK_NE(0u, output_count);
236 DCHECK_GE(arraysize(inputs), input_count); 236 DCHECK_GE(arraysize(inputs), input_count);
237 DCHECK_GE(arraysize(outputs), output_count); 237 DCHECK_GE(arraysize(outputs), output_count);
238 DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); 238 DCHECK_NE(kMode_None, AddressingModeField::decode(opcode));
239 239
240 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, 240 opcode = cont->Encode(opcode);
241 inputs); 241 if (cont->IsDeoptimize()) {
242 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
243 cont->frame_state());
244 } else {
245 selector->Emit(opcode, output_count, outputs, input_count, inputs);
246 }
242 } 247 }
243 248
244 249
245 void VisitBinop(InstructionSelector* selector, Node* node, 250 void VisitBinop(InstructionSelector* selector, Node* node,
246 InstructionCode opcode, InstructionCode reverse_opcode) { 251 InstructionCode opcode, InstructionCode reverse_opcode) {
247 FlagsContinuation cont; 252 FlagsContinuation cont;
248 VisitBinop(selector, node, opcode, reverse_opcode, &cont); 253 VisitBinop(selector, node, opcode, reverse_opcode, &cont);
249 } 254 }
250 255
251 256
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 if (cont->IsSet()) { 689 if (cont->IsSet()) {
685 outputs[output_count++] = g.DefineAsRegister(cont->result()); 690 outputs[output_count++] = g.DefineAsRegister(cont->result());
686 } 691 }
687 692
688 DCHECK_NE(0u, input_count); 693 DCHECK_NE(0u, input_count);
689 DCHECK_NE(0u, output_count); 694 DCHECK_NE(0u, output_count);
690 DCHECK_GE(arraysize(inputs), input_count); 695 DCHECK_GE(arraysize(inputs), input_count);
691 DCHECK_GE(arraysize(outputs), output_count); 696 DCHECK_GE(arraysize(outputs), output_count);
692 DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); 697 DCHECK_NE(kMode_None, AddressingModeField::decode(opcode));
693 698
694 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, 699 opcode = cont->Encode(opcode);
695 inputs); 700 if (cont->IsDeoptimize()) {
701 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
702 cont->frame_state());
703 } else {
704 selector->Emit(opcode, output_count, outputs, input_count, inputs);
705 }
696 } 706 }
697 707
698 708
699 template <typename TryMatchShift> 709 template <typename TryMatchShift>
700 void VisitShift(InstructionSelector* selector, Node* node, 710 void VisitShift(InstructionSelector* selector, Node* node,
701 TryMatchShift try_match_shift) { 711 TryMatchShift try_match_shift) {
702 FlagsContinuation cont; 712 FlagsContinuation cont;
703 VisitShift(selector, node, try_match_shift, &cont); 713 VisitShift(selector, node, try_match_shift, &cont);
704 } 714 }
705 715
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 1287
1278 // Shared routine for multiple compare operations. 1288 // Shared routine for multiple compare operations.
1279 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1289 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1280 InstructionOperand left, InstructionOperand right, 1290 InstructionOperand left, InstructionOperand right,
1281 FlagsContinuation* cont) { 1291 FlagsContinuation* cont) {
1282 ArmOperandGenerator g(selector); 1292 ArmOperandGenerator g(selector);
1283 opcode = cont->Encode(opcode); 1293 opcode = cont->Encode(opcode);
1284 if (cont->IsBranch()) { 1294 if (cont->IsBranch()) {
1285 selector->Emit(opcode, g.NoOutput(), left, right, 1295 selector->Emit(opcode, g.NoOutput(), left, right,
1286 g.Label(cont->true_block()), g.Label(cont->false_block())); 1296 g.Label(cont->true_block()), g.Label(cont->false_block()));
1297 } else if (cont->IsDeoptimize()) {
1298 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right,
1299 cont->frame_state());
1287 } else { 1300 } else {
1288 DCHECK(cont->IsSet()); 1301 DCHECK(cont->IsSet());
1289 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 1302 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
1290 } 1303 }
1291 } 1304 }
1292 1305
1293 1306
1294 // Shared routine for multiple float32 compare operations. 1307 // Shared routine for multiple float32 compare operations.
1295 void VisitFloat32Compare(InstructionSelector* selector, Node* node, 1308 void VisitFloat32Compare(InstructionSelector* selector, Node* node,
1296 FlagsContinuation* cont) { 1309 FlagsContinuation* cont) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 input_count++; 1363 input_count++;
1351 } else { 1364 } else {
1352 opcode |= AddressingModeField::encode(kMode_Operand2_R); 1365 opcode |= AddressingModeField::encode(kMode_Operand2_R);
1353 inputs[input_count++] = g.UseRegister(m.left().node()); 1366 inputs[input_count++] = g.UseRegister(m.left().node());
1354 inputs[input_count++] = g.UseRegister(m.right().node()); 1367 inputs[input_count++] = g.UseRegister(m.right().node());
1355 } 1368 }
1356 1369
1357 if (cont->IsBranch()) { 1370 if (cont->IsBranch()) {
1358 inputs[input_count++] = g.Label(cont->true_block()); 1371 inputs[input_count++] = g.Label(cont->true_block());
1359 inputs[input_count++] = g.Label(cont->false_block()); 1372 inputs[input_count++] = g.Label(cont->false_block());
1360 } else { 1373 } else if (cont->IsSet()) {
1361 DCHECK(cont->IsSet());
1362 outputs[output_count++] = g.DefineAsRegister(cont->result()); 1374 outputs[output_count++] = g.DefineAsRegister(cont->result());
1363 } 1375 }
1364 1376
1365 DCHECK_NE(0u, input_count); 1377 DCHECK_NE(0u, input_count);
1366 DCHECK_GE(arraysize(inputs), input_count); 1378 DCHECK_GE(arraysize(inputs), input_count);
1367 DCHECK_GE(arraysize(outputs), output_count); 1379 DCHECK_GE(arraysize(outputs), output_count);
1368 1380
1369 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, 1381 opcode = cont->Encode(opcode);
1370 inputs); 1382 if (cont->IsDeoptimize()) {
1383 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
1384 cont->frame_state());
1385 } else {
1386 selector->Emit(opcode, output_count, outputs, input_count, inputs);
1387 }
1371 } 1388 }
1372 1389
1373 1390
1374 void VisitWordCompare(InstructionSelector* selector, Node* node, 1391 void VisitWordCompare(InstructionSelector* selector, Node* node,
1375 FlagsContinuation* cont) { 1392 FlagsContinuation* cont) {
1376 VisitWordCompare(selector, node, kArmCmp, cont); 1393 VisitWordCompare(selector, node, kArmCmp, cont);
1377 } 1394 }
1378 1395
1379 1396
1380 // Shared routine for word comparisons against zero. 1397 // Shared routine for word comparisons against zero.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 } 1492 }
1476 1493
1477 // Continuation could not be combined with a compare, emit compare against 0. 1494 // Continuation could not be combined with a compare, emit compare against 0.
1478 ArmOperandGenerator g(selector); 1495 ArmOperandGenerator g(selector);
1479 InstructionCode const opcode = 1496 InstructionCode const opcode =
1480 cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R); 1497 cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R);
1481 InstructionOperand const value_operand = g.UseRegister(value); 1498 InstructionOperand const value_operand = g.UseRegister(value);
1482 if (cont->IsBranch()) { 1499 if (cont->IsBranch()) {
1483 selector->Emit(opcode, g.NoOutput(), value_operand, value_operand, 1500 selector->Emit(opcode, g.NoOutput(), value_operand, value_operand,
1484 g.Label(cont->true_block()), g.Label(cont->false_block())); 1501 g.Label(cont->true_block()), g.Label(cont->false_block()));
1502 } else if (cont->IsDeoptimize()) {
1503 selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, value_operand,
1504 cont->frame_state());
1485 } else { 1505 } else {
1506 DCHECK(cont->IsSet());
1486 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, 1507 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
1487 value_operand); 1508 value_operand);
1488 } 1509 }
1489 } 1510 }
1490 1511
1491 } // namespace 1512 } // namespace
1492 1513
1493
1494 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 1514 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
1495 BasicBlock* fbranch) { 1515 BasicBlock* fbranch) {
1496 FlagsContinuation cont(kNotEqual, tbranch, fbranch); 1516 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
1497 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); 1517 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
1498 } 1518 }
1499 1519
1520 void InstructionSelector::VisitDeoptimizeIf(Node* node) {
1521 FlagsContinuation cont =
1522 FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
1523 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
1524 }
1525
1526 void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
1527 FlagsContinuation cont =
1528 FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
1529 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
1530 }
1500 1531
1501 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { 1532 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
1502 ArmOperandGenerator g(this); 1533 ArmOperandGenerator g(this);
1503 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); 1534 InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
1504 1535
1505 // Emit either ArchTableSwitch or ArchLookupSwitch. 1536 // Emit either ArchTableSwitch or ArchLookupSwitch.
1506 size_t table_space_cost = 4 + sw.value_range; 1537 size_t table_space_cost = 4 + sw.value_range;
1507 size_t table_time_cost = 3; 1538 size_t table_time_cost = 3;
1508 size_t lookup_space_cost = 3 + 2 * sw.case_count; 1539 size_t lookup_space_cost = 3 + 2 * sw.case_count;
1509 size_t lookup_time_cost = sw.case_count; 1540 size_t lookup_time_cost = sw.case_count;
(...skipping 10 matching lines...) Expand all
1520 // Generate a table lookup. 1551 // Generate a table lookup.
1521 return EmitTableSwitch(sw, index_operand); 1552 return EmitTableSwitch(sw, index_operand);
1522 } 1553 }
1523 1554
1524 // Generate a sequence of conditional jumps. 1555 // Generate a sequence of conditional jumps.
1525 return EmitLookupSwitch(sw, value_operand); 1556 return EmitLookupSwitch(sw, value_operand);
1526 } 1557 }
1527 1558
1528 1559
1529 void InstructionSelector::VisitWord32Equal(Node* const node) { 1560 void InstructionSelector::VisitWord32Equal(Node* const node) {
1530 FlagsContinuation cont(kEqual, node); 1561 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1531 Int32BinopMatcher m(node); 1562 Int32BinopMatcher m(node);
1532 if (m.right().Is(0)) { 1563 if (m.right().Is(0)) {
1533 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); 1564 return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
1534 } 1565 }
1535 VisitWordCompare(this, node, &cont); 1566 VisitWordCompare(this, node, &cont);
1536 } 1567 }
1537 1568
1538 1569
1539 void InstructionSelector::VisitInt32LessThan(Node* node) { 1570 void InstructionSelector::VisitInt32LessThan(Node* node) {
1540 FlagsContinuation cont(kSignedLessThan, node); 1571 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
1541 VisitWordCompare(this, node, &cont); 1572 VisitWordCompare(this, node, &cont);
1542 } 1573 }
1543 1574
1544 1575
1545 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { 1576 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
1546 FlagsContinuation cont(kSignedLessThanOrEqual, node); 1577 FlagsContinuation cont =
1578 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
1547 VisitWordCompare(this, node, &cont); 1579 VisitWordCompare(this, node, &cont);
1548 } 1580 }
1549 1581
1550 1582
1551 void InstructionSelector::VisitUint32LessThan(Node* node) { 1583 void InstructionSelector::VisitUint32LessThan(Node* node) {
1552 FlagsContinuation cont(kUnsignedLessThan, node); 1584 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1553 VisitWordCompare(this, node, &cont); 1585 VisitWordCompare(this, node, &cont);
1554 } 1586 }
1555 1587
1556 1588
1557 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { 1589 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
1558 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 1590 FlagsContinuation cont =
1591 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1559 VisitWordCompare(this, node, &cont); 1592 VisitWordCompare(this, node, &cont);
1560 } 1593 }
1561 1594
1562 1595
1563 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { 1596 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
1564 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 1597 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1565 FlagsContinuation cont(kOverflow, ovf); 1598 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1566 return VisitBinop(this, node, kArmAdd, kArmAdd, &cont); 1599 return VisitBinop(this, node, kArmAdd, kArmAdd, &cont);
1567 } 1600 }
1568 FlagsContinuation cont; 1601 FlagsContinuation cont;
1569 VisitBinop(this, node, kArmAdd, kArmAdd, &cont); 1602 VisitBinop(this, node, kArmAdd, kArmAdd, &cont);
1570 } 1603 }
1571 1604
1572 1605
1573 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { 1606 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
1574 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 1607 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1575 FlagsContinuation cont(kOverflow, ovf); 1608 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1576 return VisitBinop(this, node, kArmSub, kArmRsb, &cont); 1609 return VisitBinop(this, node, kArmSub, kArmRsb, &cont);
1577 } 1610 }
1578 FlagsContinuation cont; 1611 FlagsContinuation cont;
1579 VisitBinop(this, node, kArmSub, kArmRsb, &cont); 1612 VisitBinop(this, node, kArmSub, kArmRsb, &cont);
1580 } 1613 }
1581 1614
1582 1615
1583 void InstructionSelector::VisitFloat32Equal(Node* node) { 1616 void InstructionSelector::VisitFloat32Equal(Node* node) {
1584 FlagsContinuation cont(kEqual, node); 1617 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1585 VisitFloat32Compare(this, node, &cont); 1618 VisitFloat32Compare(this, node, &cont);
1586 } 1619 }
1587 1620
1588 1621
1589 void InstructionSelector::VisitFloat32LessThan(Node* node) { 1622 void InstructionSelector::VisitFloat32LessThan(Node* node) {
1590 FlagsContinuation cont(kFloatLessThan, node); 1623 FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
1591 VisitFloat32Compare(this, node, &cont); 1624 VisitFloat32Compare(this, node, &cont);
1592 } 1625 }
1593 1626
1594 1627
1595 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { 1628 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
1596 FlagsContinuation cont(kFloatLessThanOrEqual, node); 1629 FlagsContinuation cont =
1630 FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
1597 VisitFloat32Compare(this, node, &cont); 1631 VisitFloat32Compare(this, node, &cont);
1598 } 1632 }
1599 1633
1600 1634
1601 void InstructionSelector::VisitFloat64Equal(Node* node) { 1635 void InstructionSelector::VisitFloat64Equal(Node* node) {
1602 FlagsContinuation cont(kEqual, node); 1636 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1603 VisitFloat64Compare(this, node, &cont); 1637 VisitFloat64Compare(this, node, &cont);
1604 } 1638 }
1605 1639
1606 1640
1607 void InstructionSelector::VisitFloat64LessThan(Node* node) { 1641 void InstructionSelector::VisitFloat64LessThan(Node* node) {
1608 FlagsContinuation cont(kFloatLessThan, node); 1642 FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
1609 VisitFloat64Compare(this, node, &cont); 1643 VisitFloat64Compare(this, node, &cont);
1610 } 1644 }
1611 1645
1612 1646
1613 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 1647 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1614 FlagsContinuation cont(kFloatLessThanOrEqual, node); 1648 FlagsContinuation cont =
1649 FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
1615 VisitFloat64Compare(this, node, &cont); 1650 VisitFloat64Compare(this, node, &cont);
1616 } 1651 }
1617 1652
1618 1653
1619 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { 1654 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
1620 VisitRR(this, kArmVmovLowU32F64, node); 1655 VisitRR(this, kArmVmovLowU32F64, node);
1621 } 1656 }
1622 1657
1623 1658
1624 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { 1659 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 MachineOperatorBuilder::kFloat64RoundTiesAway | 1712 MachineOperatorBuilder::kFloat64RoundTiesAway |
1678 MachineOperatorBuilder::kFloat32RoundTiesEven | 1713 MachineOperatorBuilder::kFloat32RoundTiesEven |
1679 MachineOperatorBuilder::kFloat64RoundTiesEven; 1714 MachineOperatorBuilder::kFloat64RoundTiesEven;
1680 } 1715 }
1681 return flags; 1716 return flags;
1682 } 1717 }
1683 1718
1684 } // namespace compiler 1719 } // namespace compiler
1685 } // namespace internal 1720 } // namespace internal
1686 } // namespace v8 1721 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm/code-generator-arm.cc ('k') | src/compiler/arm64/instruction-selector-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698