Chromium Code Reviews| 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..63e742bedc6467b8cb740bedd4754ebbc9369c1c 100644 |
| --- a/src/compiler/ia32/instruction-selector-ia32.cc |
| +++ b/src/compiler/ia32/instruction-selector-ia32.cc |
| @@ -37,6 +37,8 @@ class IA32OperandGenerator FINAL : public OperandGenerator { |
| return false; |
| } |
| } |
| + |
| + bool CanBeBetterLeftOperand(Node* node) { return !selector()->IsUsed(node); } |
|
Benedikt Meurer
2014/09/23 04:56:31
Nit: method should be const.
Weiliang
2014/09/23 05:22:12
Done.
|
| }; |
| @@ -166,20 +168,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 +302,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), |
|
Benedikt Meurer
2014/09/23 04:57:37
There should be no need to use DefineSameAsFirst w
Weiliang
2014/09/23 05:22:12
My thought here is that three operand imul require
|
| g.Use(right)); |
| } |