| 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));
|
| }
|
|
|