| 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 <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 18 matching lines...) Expand all Loading... |
| 29 } | 29 } |
| 30 case IrOpcode::kNumberConstant: { | 30 case IrOpcode::kNumberConstant: { |
| 31 const double value = OpParameter<double>(node); | 31 const double value = OpParameter<double>(node); |
| 32 return bit_cast<int64_t>(value) == 0; | 32 return bit_cast<int64_t>(value) == 0; |
| 33 } | 33 } |
| 34 default: | 34 default: |
| 35 return false; | 35 return false; |
| 36 } | 36 } |
| 37 } | 37 } |
| 38 | 38 |
| 39 bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input) { | 39 bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input, |
| 40 int effect_level) { |
| 40 if (input->opcode() != IrOpcode::kLoad || | 41 if (input->opcode() != IrOpcode::kLoad || |
| 41 !selector()->CanCover(node, input)) { | 42 !selector()->CanCover(node, input)) { |
| 42 return false; | 43 return false; |
| 43 } | 44 } |
| 45 if (effect_level != selector()->GetEffectLevel(input)) { |
| 46 return false; |
| 47 } |
| 44 MachineRepresentation rep = | 48 MachineRepresentation rep = |
| 45 LoadRepresentationOf(input->op()).representation(); | 49 LoadRepresentationOf(input->op()).representation(); |
| 46 switch (opcode) { | 50 switch (opcode) { |
| 47 case kX64Cmp: | 51 case kX64Cmp: |
| 48 case kX64Test: | 52 case kX64Test: |
| 49 return rep == MachineRepresentation::kWord64 || | 53 return rep == MachineRepresentation::kWord64 || |
| 50 rep == MachineRepresentation::kTagged; | 54 rep == MachineRepresentation::kTagged; |
| 51 case kX64Cmp32: | 55 case kX64Cmp32: |
| 52 case kX64Test32: | 56 case kX64Test32: |
| 53 return rep == MachineRepresentation::kWord32; | 57 return rep == MachineRepresentation::kWord32; |
| (...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 void VisitWordCompare(InstructionSelector* selector, Node* node, | 1542 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1539 InstructionCode opcode, FlagsContinuation* cont) { | 1543 InstructionCode opcode, FlagsContinuation* cont) { |
| 1540 X64OperandGenerator g(selector); | 1544 X64OperandGenerator g(selector); |
| 1541 Node* left = node->InputAt(0); | 1545 Node* left = node->InputAt(0); |
| 1542 Node* right = node->InputAt(1); | 1546 Node* right = node->InputAt(1); |
| 1543 | 1547 |
| 1544 opcode = TryNarrowOpcodeSize(opcode, left, right); | 1548 opcode = TryNarrowOpcodeSize(opcode, left, right); |
| 1545 | 1549 |
| 1546 // If one of the two inputs is an immediate, make sure it's on the right, or | 1550 // If one of the two inputs is an immediate, make sure it's on the right, or |
| 1547 // if one of the two inputs is a memory operand, make sure it's on the left. | 1551 // if one of the two inputs is a memory operand, make sure it's on the left. |
| 1552 int effect_level = selector->GetEffectLevel(node); |
| 1553 if (cont->IsBranch()) { |
| 1554 effect_level = selector->GetEffectLevel( |
| 1555 cont->true_block()->PredecessorAt(0)->control_input()); |
| 1556 } |
| 1557 |
| 1548 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || | 1558 if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || |
| 1549 (g.CanBeMemoryOperand(opcode, node, right) && | 1559 (g.CanBeMemoryOperand(opcode, node, right, effect_level) && |
| 1550 !g.CanBeMemoryOperand(opcode, node, left))) { | 1560 !g.CanBeMemoryOperand(opcode, node, left, effect_level))) { |
| 1551 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1561 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 1552 std::swap(left, right); | 1562 std::swap(left, right); |
| 1553 } | 1563 } |
| 1554 | 1564 |
| 1555 // Match immediates on right side of comparison. | 1565 // Match immediates on right side of comparison. |
| 1556 if (g.CanBeImmediate(right)) { | 1566 if (g.CanBeImmediate(right)) { |
| 1557 if (g.CanBeMemoryOperand(opcode, node, left)) { | 1567 if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) { |
| 1558 return VisitCompareWithMemoryOperand(selector, opcode, left, | 1568 return VisitCompareWithMemoryOperand(selector, opcode, left, |
| 1559 g.UseImmediate(right), cont); | 1569 g.UseImmediate(right), cont); |
| 1560 } | 1570 } |
| 1561 return VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), | 1571 return VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), |
| 1562 cont); | 1572 cont); |
| 1563 } | 1573 } |
| 1564 | 1574 |
| 1565 // Match memory operands on left side of comparison. | 1575 // Match memory operands on left side of comparison. |
| 1566 if (g.CanBeMemoryOperand(opcode, node, left)) { | 1576 if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) { |
| 1567 return VisitCompareWithMemoryOperand(selector, opcode, left, | 1577 return VisitCompareWithMemoryOperand(selector, opcode, left, |
| 1568 g.UseRegister(right), cont); | 1578 g.UseRegister(right), cont); |
| 1569 } | 1579 } |
| 1570 | 1580 |
| 1571 if (g.CanBeBetterLeftOperand(right)) { | 1581 if (g.CanBeBetterLeftOperand(right)) { |
| 1572 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); | 1582 if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); |
| 1573 std::swap(left, right); | 1583 std::swap(left, right); |
| 1574 } | 1584 } |
| 1575 | 1585 |
| 1576 return VisitCompare(selector, opcode, left, right, cont, | 1586 return VisitCompare(selector, opcode, left, right, cont, |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 MachineOperatorBuilder::kFloat64RoundTruncate | | 2057 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 2048 MachineOperatorBuilder::kFloat32RoundTiesEven | | 2058 MachineOperatorBuilder::kFloat32RoundTiesEven | |
| 2049 MachineOperatorBuilder::kFloat64RoundTiesEven; | 2059 MachineOperatorBuilder::kFloat64RoundTiesEven; |
| 2050 } | 2060 } |
| 2051 return flags; | 2061 return flags; |
| 2052 } | 2062 } |
| 2053 | 2063 |
| 2054 } // namespace compiler | 2064 } // namespace compiler |
| 2055 } // namespace internal | 2065 } // namespace internal |
| 2056 } // namespace v8 | 2066 } // namespace v8 |
| OLD | NEW |