| Index: src/compiler/x64/instruction-selector-x64.cc
|
| diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
|
| index 96501e686b3b7eb0a73ee519c4893d7b14e61af4..c9c1aac780db853b1bb172ed6998d5bdce7241d2 100644
|
| --- a/src/compiler/x64/instruction-selector-x64.cc
|
| +++ b/src/compiler/x64/instruction-selector-x64.cc
|
| @@ -52,6 +52,8 @@ class X64OperandGenerator FINAL : public OperandGenerator {
|
| return false;
|
| }
|
| }
|
| +
|
| + bool CanBeBetterLeftOperand(Node* node) { return !selector()->IsUsed(node); }
|
| };
|
|
|
|
|
| @@ -178,20 +180,24 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
|
| InstructionCode opcode, FlagsContinuation* cont) {
|
| X64OperandGenerator g(selector);
|
| Int32BinopMatcher m(node);
|
| + Node* left = m.left().node();
|
| + Node* right = m.right().node();
|
| InstructionOperand* inputs[4];
|
| size_t input_count = 0;
|
| InstructionOperand* outputs[2];
|
| size_t output_count = 0;
|
|
|
| // TODO(turbofan): match complex addressing modes.
|
| - // TODO(turbofan): if commutative, pick the non-live-in operand as the left as
|
| - // this might be the last use and therefore its register can be reused.
|
| - if (g.CanBeImmediate(m.right().node())) {
|
| - inputs[input_count++] = g.Use(m.left().node());
|
| - inputs[input_count++] = g.UseImmediate(m.right().node());
|
| + if (g.CanBeImmediate(right)) {
|
| + inputs[input_count++] = g.Use(left);
|
| + inputs[input_count++] = g.UseImmediate(right);
|
| } else {
|
| - inputs[input_count++] = g.UseRegister(m.left().node());
|
| - inputs[input_count++] = g.Use(m.right().node());
|
| + if (node->op()->HasProperty(Operator::kCommutative) &&
|
| + g.CanBeBetterLeftOperand(right)) {
|
| + std::swap(left, right);
|
| + }
|
| + inputs[input_count++] = g.UseRegister(left);
|
| + inputs[input_count++] = g.Use(right);
|
| }
|
|
|
| if (cont->IsBranch()) {
|
| @@ -392,16 +398,16 @@ void InstructionSelector::VisitInt64Sub(Node* node) {
|
| static void VisitMul(InstructionSelector* selector, Node* node,
|
| ArchOpcode opcode) {
|
| X64OperandGenerator g(selector);
|
| - Node* left = node->InputAt(0);
|
| - Node* right = node->InputAt(1);
|
| + Int32BinopMatcher m(node);
|
| + Node* left = m.left().node();
|
| + Node* right = m.right().node();
|
| if (g.CanBeImmediate(right)) {
|
| selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left),
|
| g.UseImmediate(right));
|
| - } else if (g.CanBeImmediate(left)) {
|
| - selector->Emit(opcode, g.DefineAsRegister(node), g.Use(right),
|
| - g.UseImmediate(left));
|
| } else {
|
| - // TODO(turbofan): select better left operand.
|
| + if (g.CanBeBetterLeftOperand(right)) {
|
| + std::swap(left, right);
|
| + }
|
| selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
|
| g.Use(right));
|
| }
|
|
|