Index: src/compiler/ia32/instruction-selector-ia32.cc |
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc |
index ce8cb0f6306410a2c5999553418d0388b011ad80..4a314ae46740abacc57d9dd6c88214b6751de30a 100644 |
--- a/src/compiler/ia32/instruction-selector-ia32.cc |
+++ b/src/compiler/ia32/instruction-selector-ia32.cc |
@@ -37,6 +37,10 @@ class IA32OperandGenerator FINAL : public OperandGenerator { |
return false; |
} |
} |
+ |
+ bool CanBeBetterLeftOperand(Node* node) const { |
+ return !selector()->IsLive(node); |
+ } |
}; |
@@ -166,20 +170,24 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
InstructionCode opcode, FlagsContinuation* cont) { |
IA32OperandGenerator 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()) { |
@@ -296,16 +304,16 @@ void InstructionSelector::VisitInt32Sub(Node* node) { |
void InstructionSelector::VisitInt32Mul(Node* node) { |
IA32OperandGenerator g(this); |
- 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)) { |
Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left), |
g.UseImmediate(right)); |
- } else if (g.CanBeImmediate(left)) { |
- Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(right), |
- g.UseImmediate(left)); |
} else { |
- // TODO(turbofan): select better left operand. |
+ if (g.CanBeBetterLeftOperand(right)) { |
+ std::swap(left, right); |
+ } |
Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), |
g.Use(right)); |
} |