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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.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, 10 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/verifier.cc ('k') | test/mjsunit/mjsunit.status » ('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 <algorithm> 5 #include <algorithm>
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/compiler/instruction-selector-impl.h" 8 #include "src/compiler/instruction-selector-impl.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 outputs[output_count++] = g.DefineSameAsFirst(node); 392 outputs[output_count++] = g.DefineSameAsFirst(node);
393 if (cont->IsSet()) { 393 if (cont->IsSet()) {
394 outputs[output_count++] = g.DefineAsRegister(cont->result()); 394 outputs[output_count++] = g.DefineAsRegister(cont->result());
395 } 395 }
396 396
397 DCHECK_NE(0u, input_count); 397 DCHECK_NE(0u, input_count);
398 DCHECK_NE(0u, output_count); 398 DCHECK_NE(0u, output_count);
399 DCHECK_GE(arraysize(inputs), input_count); 399 DCHECK_GE(arraysize(inputs), input_count);
400 DCHECK_GE(arraysize(outputs), output_count); 400 DCHECK_GE(arraysize(outputs), output_count);
401 401
402 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, 402 opcode = cont->Encode(opcode);
403 inputs); 403 if (cont->IsDeoptimize()) {
404 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
405 cont->frame_state());
406 } else {
407 selector->Emit(opcode, output_count, outputs, input_count, inputs);
408 }
404 } 409 }
405 410
406 411
407 // Shared routine for multiple binary operations. 412 // Shared routine for multiple binary operations.
408 static void VisitBinop(InstructionSelector* selector, Node* node, 413 static void VisitBinop(InstructionSelector* selector, Node* node,
409 InstructionCode opcode) { 414 InstructionCode opcode) {
410 FlagsContinuation cont; 415 FlagsContinuation cont;
411 VisitBinop(selector, node, opcode, &cont); 416 VisitBinop(selector, node, opcode, &cont);
412 } 417 }
413 418
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 } 666 }
662 667
663 668
664 void InstructionSelector::VisitInt64Add(Node* node) { 669 void InstructionSelector::VisitInt64Add(Node* node) {
665 VisitBinop(this, node, kX64Add); 670 VisitBinop(this, node, kX64Add);
666 } 671 }
667 672
668 673
669 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { 674 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
670 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 675 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
671 FlagsContinuation cont(kOverflow, ovf); 676 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
672 VisitBinop(this, node, kX64Add, &cont); 677 VisitBinop(this, node, kX64Add, &cont);
673 } 678 }
674 FlagsContinuation cont; 679 FlagsContinuation cont;
675 VisitBinop(this, node, kX64Add, &cont); 680 VisitBinop(this, node, kX64Add, &cont);
676 } 681 }
677 682
678 683
679 void InstructionSelector::VisitInt32Sub(Node* node) { 684 void InstructionSelector::VisitInt32Sub(Node* node) {
680 X64OperandGenerator g(this); 685 X64OperandGenerator g(this);
681 Int32BinopMatcher m(node); 686 Int32BinopMatcher m(node);
(...skipping 19 matching lines...) Expand all
701 if (m.left().Is(0)) { 706 if (m.left().Is(0)) {
702 Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); 707 Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
703 } else { 708 } else {
704 VisitBinop(this, node, kX64Sub); 709 VisitBinop(this, node, kX64Sub);
705 } 710 }
706 } 711 }
707 712
708 713
709 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { 714 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
710 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 715 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
711 FlagsContinuation cont(kOverflow, ovf); 716 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
712 return VisitBinop(this, node, kX64Sub, &cont); 717 return VisitBinop(this, node, kX64Sub, &cont);
713 } 718 }
714 FlagsContinuation cont; 719 FlagsContinuation cont;
715 VisitBinop(this, node, kX64Sub, &cont); 720 VisitBinop(this, node, kX64Sub, &cont);
716 } 721 }
717 722
718 723
719 namespace { 724 namespace {
720 725
721 void VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 726 void VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 AddressingMode addressing_mode = 1354 AddressingMode addressing_mode =
1350 g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count); 1355 g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count);
1351 opcode |= AddressingModeField::encode(addressing_mode); 1356 opcode |= AddressingModeField::encode(addressing_mode);
1352 opcode = cont->Encode(opcode); 1357 opcode = cont->Encode(opcode);
1353 inputs[input_count++] = right; 1358 inputs[input_count++] = right;
1354 1359
1355 if (cont->IsBranch()) { 1360 if (cont->IsBranch()) {
1356 inputs[input_count++] = g.Label(cont->true_block()); 1361 inputs[input_count++] = g.Label(cont->true_block());
1357 inputs[input_count++] = g.Label(cont->false_block()); 1362 inputs[input_count++] = g.Label(cont->false_block());
1358 selector->Emit(opcode, 0, nullptr, input_count, inputs); 1363 selector->Emit(opcode, 0, nullptr, input_count, inputs);
1364 } else if (cont->IsDeoptimize()) {
1365 selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs,
1366 cont->frame_state());
1359 } else { 1367 } else {
1360 DCHECK(cont->IsSet()); 1368 DCHECK(cont->IsSet());
1361 InstructionOperand output = g.DefineAsRegister(cont->result()); 1369 InstructionOperand output = g.DefineAsRegister(cont->result());
1362 selector->Emit(opcode, 1, &output, input_count, inputs); 1370 selector->Emit(opcode, 1, &output, input_count, inputs);
1363 } 1371 }
1364 } 1372 }
1365 1373
1366 // Determines if {input} of {node} can be replaced by a memory operand. 1374 // Determines if {input} of {node} can be replaced by a memory operand.
1367 bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode, 1375 bool CanUseMemoryOperand(InstructionSelector* selector, InstructionCode opcode,
1368 Node* node, Node* input) { 1376 Node* node, Node* input) {
(...skipping 13 matching lines...) Expand all
1382 1390
1383 // Shared routine for multiple compare operations. 1391 // Shared routine for multiple compare operations.
1384 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1392 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1385 InstructionOperand left, InstructionOperand right, 1393 InstructionOperand left, InstructionOperand right,
1386 FlagsContinuation* cont) { 1394 FlagsContinuation* cont) {
1387 X64OperandGenerator g(selector); 1395 X64OperandGenerator g(selector);
1388 opcode = cont->Encode(opcode); 1396 opcode = cont->Encode(opcode);
1389 if (cont->IsBranch()) { 1397 if (cont->IsBranch()) {
1390 selector->Emit(opcode, g.NoOutput(), left, right, 1398 selector->Emit(opcode, g.NoOutput(), left, right,
1391 g.Label(cont->true_block()), g.Label(cont->false_block())); 1399 g.Label(cont->true_block()), g.Label(cont->false_block()));
1400 } else if (cont->IsDeoptimize()) {
1401 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right,
1402 cont->frame_state());
1392 } else { 1403 } else {
1393 DCHECK(cont->IsSet()); 1404 DCHECK(cont->IsSet());
1394 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 1405 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
1395 } 1406 }
1396 } 1407 }
1397 1408
1398 1409
1399 // Shared routine for multiple compare operations. 1410 // Shared routine for multiple compare operations.
1400 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1411 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1401 Node* left, Node* right, FlagsContinuation* cont, 1412 Node* left, Node* right, FlagsContinuation* cont,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); 1463 LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
1453 ExternalReference js_stack_limit = 1464 ExternalReference js_stack_limit =
1454 ExternalReference::address_of_stack_limit(selector->isolate()); 1465 ExternalReference::address_of_stack_limit(selector->isolate());
1455 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { 1466 if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) {
1456 // Compare(Load(js_stack_limit), LoadStackPointer) 1467 // Compare(Load(js_stack_limit), LoadStackPointer)
1457 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); 1468 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
1458 InstructionCode opcode = cont->Encode(kX64StackCheck); 1469 InstructionCode opcode = cont->Encode(kX64StackCheck);
1459 if (cont->IsBranch()) { 1470 if (cont->IsBranch()) {
1460 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), 1471 selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
1461 g.Label(cont->false_block())); 1472 g.Label(cont->false_block()));
1473 } else if (cont->IsDeoptimize()) {
1474 selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr,
1475 cont->frame_state());
1462 } else { 1476 } else {
1463 DCHECK(cont->IsSet()); 1477 DCHECK(cont->IsSet());
1464 selector->Emit(opcode, g.DefineAsRegister(cont->result())); 1478 selector->Emit(opcode, g.DefineAsRegister(cont->result()));
1465 } 1479 }
1466 return; 1480 return;
1467 } 1481 }
1468 } 1482 }
1469 VisitWordCompare(selector, node, kX64Cmp, cont); 1483 VisitWordCompare(selector, node, kX64Cmp, cont);
1470 } 1484 }
1471 1485
(...skipping 20 matching lines...) Expand all
1492 // Shared routine for multiple float64 compare operations (inputs commuted). 1506 // Shared routine for multiple float64 compare operations (inputs commuted).
1493 void VisitFloat64Compare(InstructionSelector* selector, Node* node, 1507 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
1494 FlagsContinuation* cont) { 1508 FlagsContinuation* cont) {
1495 Node* const left = node->InputAt(0); 1509 Node* const left = node->InputAt(0);
1496 Node* const right = node->InputAt(1); 1510 Node* const right = node->InputAt(1);
1497 InstructionCode const opcode = 1511 InstructionCode const opcode =
1498 selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp; 1512 selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp;
1499 VisitCompare(selector, opcode, right, left, cont, false); 1513 VisitCompare(selector, opcode, right, left, cont, false);
1500 } 1514 }
1501 1515
1502 } // namespace 1516 // Shared routine for word comparison against zero.
1503 1517 void VisitWordCompareZero(InstructionSelector* selector, Node* user,
1504 1518 Node* value, FlagsContinuation* cont) {
1505 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 1519 while (selector->CanCover(user, value)) {
1506 BasicBlock* fbranch) {
1507 X64OperandGenerator g(this);
1508 Node* user = branch;
1509 Node* value = branch->InputAt(0);
1510
1511 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
1512
1513 // Try to combine with comparisons against 0 by simply inverting the branch.
1514 while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
1515 Int32BinopMatcher m(value);
1516 if (m.right().Is(0)) {
1517 user = value;
1518 value = m.left().node();
1519 cont.Negate();
1520 } else {
1521 break;
1522 }
1523 }
1524
1525 // Try to combine the branch with a comparison.
1526 if (CanCover(user, value)) {
1527 switch (value->opcode()) { 1520 switch (value->opcode()) {
1528 case IrOpcode::kWord32Equal: 1521 case IrOpcode::kWord32Equal: {
1529 cont.OverwriteAndNegateIfEqual(kEqual); 1522 // Combine with comparisons against 0 by simply inverting the
1530 return VisitWordCompare(this, value, kX64Cmp32, &cont); 1523 // continuation.
1524 Int32BinopMatcher m(value);
1525 if (m.right().Is(0)) {
1526 user = value;
1527 value = m.left().node();
1528 cont->Negate();
1529 continue;
1530 }
1531 cont->OverwriteAndNegateIfEqual(kEqual);
1532 return VisitWordCompare(selector, value, kX64Cmp32, cont);
1533 }
1531 case IrOpcode::kInt32LessThan: 1534 case IrOpcode::kInt32LessThan:
1532 cont.OverwriteAndNegateIfEqual(kSignedLessThan); 1535 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1533 return VisitWordCompare(this, value, kX64Cmp32, &cont); 1536 return VisitWordCompare(selector, value, kX64Cmp32, cont);
1534 case IrOpcode::kInt32LessThanOrEqual: 1537 case IrOpcode::kInt32LessThanOrEqual:
1535 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 1538 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1536 return VisitWordCompare(this, value, kX64Cmp32, &cont); 1539 return VisitWordCompare(selector, value, kX64Cmp32, cont);
1537 case IrOpcode::kUint32LessThan: 1540 case IrOpcode::kUint32LessThan:
1538 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); 1541 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1539 return VisitWordCompare(this, value, kX64Cmp32, &cont); 1542 return VisitWordCompare(selector, value, kX64Cmp32, cont);
1540 case IrOpcode::kUint32LessThanOrEqual: 1543 case IrOpcode::kUint32LessThanOrEqual:
1541 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1544 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1542 return VisitWordCompare(this, value, kX64Cmp32, &cont); 1545 return VisitWordCompare(selector, value, kX64Cmp32, cont);
1543 case IrOpcode::kWord64Equal: { 1546 case IrOpcode::kWord64Equal: {
1544 cont.OverwriteAndNegateIfEqual(kEqual); 1547 cont->OverwriteAndNegateIfEqual(kEqual);
1545 Int64BinopMatcher m(value); 1548 Int64BinopMatcher m(value);
1546 if (m.right().Is(0)) { 1549 if (m.right().Is(0)) {
1547 // Try to combine the branch with a comparison. 1550 // Try to combine the branch with a comparison.
1548 Node* const user = m.node(); 1551 Node* const user = m.node();
1549 Node* const value = m.left().node(); 1552 Node* const value = m.left().node();
1550 if (CanCover(user, value)) { 1553 if (selector->CanCover(user, value)) {
1551 switch (value->opcode()) { 1554 switch (value->opcode()) {
1552 case IrOpcode::kInt64Sub: 1555 case IrOpcode::kInt64Sub:
1553 return VisitWord64Compare(this, value, &cont); 1556 return VisitWord64Compare(selector, value, cont);
1554 case IrOpcode::kWord64And: 1557 case IrOpcode::kWord64And:
1555 return VisitWordCompare(this, value, kX64Test, &cont); 1558 return VisitWordCompare(selector, value, kX64Test, cont);
1556 default: 1559 default:
1557 break; 1560 break;
1558 } 1561 }
1559 } 1562 }
1560 return VisitCompareZero(this, value, kX64Cmp, &cont); 1563 return VisitCompareZero(selector, value, kX64Cmp, cont);
1561 } 1564 }
1562 return VisitWord64Compare(this, value, &cont); 1565 return VisitWord64Compare(selector, value, cont);
1563 } 1566 }
1564 case IrOpcode::kInt64LessThan: 1567 case IrOpcode::kInt64LessThan:
1565 cont.OverwriteAndNegateIfEqual(kSignedLessThan); 1568 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1566 return VisitWord64Compare(this, value, &cont); 1569 return VisitWord64Compare(selector, value, cont);
1567 case IrOpcode::kInt64LessThanOrEqual: 1570 case IrOpcode::kInt64LessThanOrEqual:
1568 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 1571 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1569 return VisitWord64Compare(this, value, &cont); 1572 return VisitWord64Compare(selector, value, cont);
1570 case IrOpcode::kUint64LessThan: 1573 case IrOpcode::kUint64LessThan:
1571 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); 1574 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1572 return VisitWord64Compare(this, value, &cont); 1575 return VisitWord64Compare(selector, value, cont);
1573 case IrOpcode::kUint64LessThanOrEqual: 1576 case IrOpcode::kUint64LessThanOrEqual:
1574 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1577 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1575 return VisitWord64Compare(this, value, &cont); 1578 return VisitWord64Compare(selector, value, cont);
1576 case IrOpcode::kFloat32Equal: 1579 case IrOpcode::kFloat32Equal:
1577 cont.OverwriteAndNegateIfEqual(kUnorderedEqual); 1580 cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
1578 return VisitFloat32Compare(this, value, &cont); 1581 return VisitFloat32Compare(selector, value, cont);
1579 case IrOpcode::kFloat32LessThan: 1582 case IrOpcode::kFloat32LessThan:
1580 cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan); 1583 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
1581 return VisitFloat32Compare(this, value, &cont); 1584 return VisitFloat32Compare(selector, value, cont);
1582 case IrOpcode::kFloat32LessThanOrEqual: 1585 case IrOpcode::kFloat32LessThanOrEqual:
1583 cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); 1586 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
1584 return VisitFloat32Compare(this, value, &cont); 1587 return VisitFloat32Compare(selector, value, cont);
1585 case IrOpcode::kFloat64Equal: 1588 case IrOpcode::kFloat64Equal:
1586 cont.OverwriteAndNegateIfEqual(kUnorderedEqual); 1589 cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
1587 return VisitFloat64Compare(this, value, &cont); 1590 return VisitFloat64Compare(selector, value, cont);
1588 case IrOpcode::kFloat64LessThan: 1591 case IrOpcode::kFloat64LessThan:
1589 cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan); 1592 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
1590 return VisitFloat64Compare(this, value, &cont); 1593 return VisitFloat64Compare(selector, value, cont);
1591 case IrOpcode::kFloat64LessThanOrEqual: 1594 case IrOpcode::kFloat64LessThanOrEqual:
1592 cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); 1595 cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
1593 return VisitFloat64Compare(this, value, &cont); 1596 return VisitFloat64Compare(selector, value, cont);
1594 case IrOpcode::kProjection: 1597 case IrOpcode::kProjection:
1595 // Check if this is the overflow output projection of an 1598 // Check if this is the overflow output projection of an
1596 // <Operation>WithOverflow node. 1599 // <Operation>WithOverflow node.
1597 if (ProjectionIndexOf(value->op()) == 1u) { 1600 if (ProjectionIndexOf(value->op()) == 1u) {
1598 // We cannot combine the <Operation>WithOverflow with this branch 1601 // We cannot combine the <Operation>WithOverflow with this branch
1599 // unless the 0th projection (the use of the actual value of the 1602 // unless the 0th projection (the use of the actual value of the
1600 // <Operation> is either nullptr, which means there's no use of the 1603 // <Operation> is either nullptr, which means there's no use of the
1601 // actual value, or was already defined, which means it is scheduled 1604 // actual value, or was already defined, which means it is scheduled
1602 // *AFTER* this branch). 1605 // *AFTER* this branch).
1603 Node* const node = value->InputAt(0); 1606 Node* const node = value->InputAt(0);
1604 Node* const result = NodeProperties::FindProjection(node, 0); 1607 Node* const result = NodeProperties::FindProjection(node, 0);
1605 if (result == nullptr || IsDefined(result)) { 1608 if (result == nullptr || selector->IsDefined(result)) {
1606 switch (node->opcode()) { 1609 switch (node->opcode()) {
1607 case IrOpcode::kInt32AddWithOverflow: 1610 case IrOpcode::kInt32AddWithOverflow:
1608 cont.OverwriteAndNegateIfEqual(kOverflow); 1611 cont->OverwriteAndNegateIfEqual(kOverflow);
1609 return VisitBinop(this, node, kX64Add32, &cont); 1612 return VisitBinop(selector, node, kX64Add32, cont);
1610 case IrOpcode::kInt32SubWithOverflow: 1613 case IrOpcode::kInt32SubWithOverflow:
1611 cont.OverwriteAndNegateIfEqual(kOverflow); 1614 cont->OverwriteAndNegateIfEqual(kOverflow);
1612 return VisitBinop(this, node, kX64Sub32, &cont); 1615 return VisitBinop(selector, node, kX64Sub32, cont);
1613 case IrOpcode::kInt64AddWithOverflow: 1616 case IrOpcode::kInt64AddWithOverflow:
1614 cont.OverwriteAndNegateIfEqual(kOverflow); 1617 cont->OverwriteAndNegateIfEqual(kOverflow);
1615 return VisitBinop(this, node, kX64Add, &cont); 1618 return VisitBinop(selector, node, kX64Add, cont);
1616 case IrOpcode::kInt64SubWithOverflow: 1619 case IrOpcode::kInt64SubWithOverflow:
1617 cont.OverwriteAndNegateIfEqual(kOverflow); 1620 cont->OverwriteAndNegateIfEqual(kOverflow);
1618 return VisitBinop(this, node, kX64Sub, &cont); 1621 return VisitBinop(selector, node, kX64Sub, cont);
1619 default: 1622 default:
1620 break; 1623 break;
1621 } 1624 }
1622 } 1625 }
1623 } 1626 }
1624 break; 1627 break;
1625 case IrOpcode::kInt32Sub: 1628 case IrOpcode::kInt32Sub:
1626 return VisitWordCompare(this, value, kX64Cmp32, &cont); 1629 return VisitWordCompare(selector, value, kX64Cmp32, cont);
1627 case IrOpcode::kInt64Sub: 1630 case IrOpcode::kInt64Sub:
1628 return VisitWord64Compare(this, value, &cont); 1631 return VisitWord64Compare(selector, value, cont);
1629 case IrOpcode::kWord32And: 1632 case IrOpcode::kWord32And:
1630 return VisitWordCompare(this, value, kX64Test32, &cont); 1633 return VisitWordCompare(selector, value, kX64Test32, cont);
1631 case IrOpcode::kWord64And: 1634 case IrOpcode::kWord64And:
1632 return VisitWordCompare(this, value, kX64Test, &cont); 1635 return VisitWordCompare(selector, value, kX64Test, cont);
1633 default: 1636 default:
1634 break; 1637 break;
1635 } 1638 }
1639 break;
1636 } 1640 }
1637 1641
1638 // Branch could not be combined with a compare, emit compare against 0. 1642 // Branch could not be combined with a compare, emit compare against 0.
1639 VisitCompareZero(this, value, kX64Cmp32, &cont); 1643 VisitCompareZero(selector, value, kX64Cmp32, cont);
1640 } 1644 }
1641 1645
1646 } // namespace
1647
1648 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
1649 BasicBlock* fbranch) {
1650 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
1651 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
1652 }
1653
1654 void InstructionSelector::VisitDeoptimizeIf(Node* node) {
1655 FlagsContinuation cont =
1656 FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
1657 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
1658 }
1659
1660 void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
1661 FlagsContinuation cont =
1662 FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
1663 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
1664 }
1642 1665
1643 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { 1666 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
1644 X64OperandGenerator g(this); 1667 X64OperandGenerator g(this);
1645 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); 1668 InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
1646 1669
1647 // Emit either ArchTableSwitch or ArchLookupSwitch. 1670 // Emit either ArchTableSwitch or ArchLookupSwitch.
1648 size_t table_space_cost = 4 + sw.value_range; 1671 size_t table_space_cost = 4 + sw.value_range;
1649 size_t table_time_cost = 3; 1672 size_t table_time_cost = 3;
1650 size_t lookup_space_cost = 3 + 2 * sw.case_count; 1673 size_t lookup_space_cost = 3 + 2 * sw.case_count;
1651 size_t lookup_time_cost = sw.case_count; 1674 size_t lookup_time_cost = sw.case_count;
(...skipping 14 matching lines...) Expand all
1666 return EmitTableSwitch(sw, index_operand); 1689 return EmitTableSwitch(sw, index_operand);
1667 } 1690 }
1668 1691
1669 // Generate a sequence of conditional jumps. 1692 // Generate a sequence of conditional jumps.
1670 return EmitLookupSwitch(sw, value_operand); 1693 return EmitLookupSwitch(sw, value_operand);
1671 } 1694 }
1672 1695
1673 1696
1674 void InstructionSelector::VisitWord32Equal(Node* const node) { 1697 void InstructionSelector::VisitWord32Equal(Node* const node) {
1675 Node* user = node; 1698 Node* user = node;
1676 FlagsContinuation cont(kEqual, node); 1699 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1677 Int32BinopMatcher m(user); 1700 Int32BinopMatcher m(user);
1678 if (m.right().Is(0)) { 1701 if (m.right().Is(0)) {
1679 Node* value = m.left().node(); 1702 Node* value = m.left().node();
1680 1703
1681 // Try to combine with comparisons against 0 by simply inverting the branch. 1704 // Try to combine with comparisons against 0 by simply inverting the branch.
1682 while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) { 1705 while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
1683 Int32BinopMatcher m(value); 1706 Int32BinopMatcher m(value);
1684 if (m.right().Is(0)) { 1707 if (m.right().Is(0)) {
1685 user = value; 1708 user = value;
1686 value = m.left().node(); 1709 value = m.left().node();
(...skipping 14 matching lines...) Expand all
1701 break; 1724 break;
1702 } 1725 }
1703 } 1726 }
1704 return VisitCompareZero(this, value, kX64Cmp32, &cont); 1727 return VisitCompareZero(this, value, kX64Cmp32, &cont);
1705 } 1728 }
1706 VisitWordCompare(this, node, kX64Cmp32, &cont); 1729 VisitWordCompare(this, node, kX64Cmp32, &cont);
1707 } 1730 }
1708 1731
1709 1732
1710 void InstructionSelector::VisitInt32LessThan(Node* node) { 1733 void InstructionSelector::VisitInt32LessThan(Node* node) {
1711 FlagsContinuation cont(kSignedLessThan, node); 1734 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
1712 VisitWordCompare(this, node, kX64Cmp32, &cont); 1735 VisitWordCompare(this, node, kX64Cmp32, &cont);
1713 } 1736 }
1714 1737
1715 1738
1716 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { 1739 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
1717 FlagsContinuation cont(kSignedLessThanOrEqual, node); 1740 FlagsContinuation cont =
1741 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
1718 VisitWordCompare(this, node, kX64Cmp32, &cont); 1742 VisitWordCompare(this, node, kX64Cmp32, &cont);
1719 } 1743 }
1720 1744
1721 1745
1722 void InstructionSelector::VisitUint32LessThan(Node* node) { 1746 void InstructionSelector::VisitUint32LessThan(Node* node) {
1723 FlagsContinuation cont(kUnsignedLessThan, node); 1747 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1724 VisitWordCompare(this, node, kX64Cmp32, &cont); 1748 VisitWordCompare(this, node, kX64Cmp32, &cont);
1725 } 1749 }
1726 1750
1727 1751
1728 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { 1752 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
1729 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 1753 FlagsContinuation cont =
1754 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1730 VisitWordCompare(this, node, kX64Cmp32, &cont); 1755 VisitWordCompare(this, node, kX64Cmp32, &cont);
1731 } 1756 }
1732 1757
1733 1758
1734 void InstructionSelector::VisitWord64Equal(Node* const node) { 1759 void InstructionSelector::VisitWord64Equal(Node* const node) {
1735 FlagsContinuation cont(kEqual, node); 1760 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1736 Int64BinopMatcher m(node); 1761 Int64BinopMatcher m(node);
1737 if (m.right().Is(0)) { 1762 if (m.right().Is(0)) {
1738 // Try to combine the equality check with a comparison. 1763 // Try to combine the equality check with a comparison.
1739 Node* const user = m.node(); 1764 Node* const user = m.node();
1740 Node* const value = m.left().node(); 1765 Node* const value = m.left().node();
1741 if (CanCover(user, value)) { 1766 if (CanCover(user, value)) {
1742 switch (value->opcode()) { 1767 switch (value->opcode()) {
1743 case IrOpcode::kInt64Sub: 1768 case IrOpcode::kInt64Sub:
1744 return VisitWord64Compare(this, value, &cont); 1769 return VisitWord64Compare(this, value, &cont);
1745 case IrOpcode::kWord64And: 1770 case IrOpcode::kWord64And:
1746 return VisitWordCompare(this, value, kX64Test, &cont); 1771 return VisitWordCompare(this, value, kX64Test, &cont);
1747 default: 1772 default:
1748 break; 1773 break;
1749 } 1774 }
1750 } 1775 }
1751 } 1776 }
1752 VisitWord64Compare(this, node, &cont); 1777 VisitWord64Compare(this, node, &cont);
1753 } 1778 }
1754 1779
1755 1780
1756 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { 1781 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
1757 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 1782 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1758 FlagsContinuation cont(kOverflow, ovf); 1783 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1759 VisitBinop(this, node, kX64Add32, &cont); 1784 VisitBinop(this, node, kX64Add32, &cont);
1760 } 1785 }
1761 FlagsContinuation cont; 1786 FlagsContinuation cont;
1762 VisitBinop(this, node, kX64Add32, &cont); 1787 VisitBinop(this, node, kX64Add32, &cont);
1763 } 1788 }
1764 1789
1765 1790
1766 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { 1791 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
1767 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 1792 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1768 FlagsContinuation cont(kOverflow, ovf); 1793 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1769 return VisitBinop(this, node, kX64Sub32, &cont); 1794 return VisitBinop(this, node, kX64Sub32, &cont);
1770 } 1795 }
1771 FlagsContinuation cont; 1796 FlagsContinuation cont;
1772 VisitBinop(this, node, kX64Sub32, &cont); 1797 VisitBinop(this, node, kX64Sub32, &cont);
1773 } 1798 }
1774 1799
1775 1800
1776 void InstructionSelector::VisitInt64LessThan(Node* node) { 1801 void InstructionSelector::VisitInt64LessThan(Node* node) {
1777 FlagsContinuation cont(kSignedLessThan, node); 1802 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
1778 VisitWord64Compare(this, node, &cont); 1803 VisitWord64Compare(this, node, &cont);
1779 } 1804 }
1780 1805
1781 1806
1782 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { 1807 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
1783 FlagsContinuation cont(kSignedLessThanOrEqual, node); 1808 FlagsContinuation cont =
1809 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
1784 VisitWord64Compare(this, node, &cont); 1810 VisitWord64Compare(this, node, &cont);
1785 } 1811 }
1786 1812
1787 1813
1788 void InstructionSelector::VisitUint64LessThan(Node* node) { 1814 void InstructionSelector::VisitUint64LessThan(Node* node) {
1789 FlagsContinuation cont(kUnsignedLessThan, node); 1815 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1790 VisitWord64Compare(this, node, &cont); 1816 VisitWord64Compare(this, node, &cont);
1791 } 1817 }
1792 1818
1793 1819
1794 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { 1820 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
1795 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 1821 FlagsContinuation cont =
1822 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1796 VisitWord64Compare(this, node, &cont); 1823 VisitWord64Compare(this, node, &cont);
1797 } 1824 }
1798 1825
1799 1826
1800 void InstructionSelector::VisitFloat32Equal(Node* node) { 1827 void InstructionSelector::VisitFloat32Equal(Node* node) {
1801 FlagsContinuation cont(kUnorderedEqual, node); 1828 FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node);
1802 VisitFloat32Compare(this, node, &cont); 1829 VisitFloat32Compare(this, node, &cont);
1803 } 1830 }
1804 1831
1805 1832
1806 void InstructionSelector::VisitFloat32LessThan(Node* node) { 1833 void InstructionSelector::VisitFloat32LessThan(Node* node) {
1807 FlagsContinuation cont(kUnsignedGreaterThan, node); 1834 FlagsContinuation cont =
1835 FlagsContinuation::ForSet(kUnsignedGreaterThan, node);
1808 VisitFloat32Compare(this, node, &cont); 1836 VisitFloat32Compare(this, node, &cont);
1809 } 1837 }
1810 1838
1811 1839
1812 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { 1840 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
1813 FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); 1841 FlagsContinuation cont =
1842 FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node);
1814 VisitFloat32Compare(this, node, &cont); 1843 VisitFloat32Compare(this, node, &cont);
1815 } 1844 }
1816 1845
1817 1846
1818 void InstructionSelector::VisitFloat64Equal(Node* node) { 1847 void InstructionSelector::VisitFloat64Equal(Node* node) {
1819 FlagsContinuation cont(kUnorderedEqual, node); 1848 FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node);
1820 VisitFloat64Compare(this, node, &cont); 1849 VisitFloat64Compare(this, node, &cont);
1821 } 1850 }
1822 1851
1823 1852
1824 void InstructionSelector::VisitFloat64LessThan(Node* node) { 1853 void InstructionSelector::VisitFloat64LessThan(Node* node) {
1825 FlagsContinuation cont(kUnsignedGreaterThan, node); 1854 FlagsContinuation cont =
1855 FlagsContinuation::ForSet(kUnsignedGreaterThan, node);
1826 VisitFloat64Compare(this, node, &cont); 1856 VisitFloat64Compare(this, node, &cont);
1827 } 1857 }
1828 1858
1829 1859
1830 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 1860 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1831 FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node); 1861 FlagsContinuation cont =
1862 FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node);
1832 VisitFloat64Compare(this, node, &cont); 1863 VisitFloat64Compare(this, node, &cont);
1833 } 1864 }
1834 1865
1835 1866
1836 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { 1867 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
1837 X64OperandGenerator g(this); 1868 X64OperandGenerator g(this);
1838 Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node), 1869 Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node),
1839 g.Use(node->InputAt(0))); 1870 g.Use(node->InputAt(0)));
1840 } 1871 }
1841 1872
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 MachineOperatorBuilder::kFloat64RoundTruncate | 1924 MachineOperatorBuilder::kFloat64RoundTruncate |
1894 MachineOperatorBuilder::kFloat32RoundTiesEven | 1925 MachineOperatorBuilder::kFloat32RoundTiesEven |
1895 MachineOperatorBuilder::kFloat64RoundTiesEven; 1926 MachineOperatorBuilder::kFloat64RoundTiesEven;
1896 } 1927 }
1897 return flags; 1928 return flags;
1898 } 1929 }
1899 1930
1900 } // namespace compiler 1931 } // namespace compiler
1901 } // namespace internal 1932 } // namespace internal
1902 } // namespace v8 1933 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/verifier.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698