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..00e27e9b815d04ba76558212d5644ed7e098f22f 100644 |
--- a/src/compiler/x64/instruction-selector-x64.cc |
+++ b/src/compiler/x64/instruction-selector-x64.cc |
@@ -52,6 +52,10 @@ class X64OperandGenerator FINAL : public OperandGenerator { |
return false; |
} |
} |
+ |
+ bool CanBeBetterLeftOperand(Node* node) const { |
+ return !selector()->IsLive(node); |
+ } |
}; |
@@ -178,20 +182,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 +400,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)); |
} |