From d75f736c11986979b3a2ccae263abfb3a18f7047 Mon Sep 17 00:00:00 2001 From: "jarin@chromium.org" Date: Tue, 14 Oct 2014 08:34:20 +0000 Subject: [PATCH] [turbofan] Use register for instruction operands when SameAsFirst is specified. As the register allocator cannot reuse spill slots, SameAsFirst constraint means that we would have to do an expensive move to a differen spill slot if we choose to spill. Forcing the operand to a register is cheaper. In zlib, we get >10% speed-up for ia32, >25% for x64. BUG= R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/650083003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24580 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/ia32/instruction-selector-ia32.cc | 8 ++++---- src/compiler/instruction-selector-impl.h | 8 ++++---- src/compiler/x64/instruction-selector-x64.cc | 18 +++++++++--------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index d3b1e00..d6edb45 100644 --- a/src/compiler/ia32/instruction-selector-ia32.cc +++ b/src/compiler/ia32/instruction-selector-ia32.cc @@ -260,7 +260,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, // TODO(turbofan): match complex addressing modes. if (g.CanBeImmediate(right)) { - inputs[input_count++] = g.Use(left); + inputs[input_count++] = g.UseRegister(left); inputs[input_count++] = g.UseImmediate(right); } else { if (node->op()->HasProperty(Operator::kCommutative) && @@ -315,7 +315,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) { IA32OperandGenerator g(this); Int32BinopMatcher m(node); if (m.right().Is(-1)) { - Emit(kIA32Not, g.DefineSameAsFirst(node), g.Use(m.left().node())); + Emit(kIA32Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); } else { VisitBinop(this, node, kIA32Xor); } @@ -330,7 +330,7 @@ static inline void VisitShift(InstructionSelector* selector, Node* node, Node* right = node->InputAt(1); if (g.CanBeImmediate(right)) { - selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), + selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), g.UseImmediate(right)); } else { Int32BinopMatcher m(node); @@ -340,7 +340,7 @@ static inline void VisitShift(InstructionSelector* selector, Node* node, right = mright.left().node(); } } - selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), + selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), g.UseFixed(right, ecx)); } } diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h index 1c8c175..f6a437d 100644 --- a/src/compiler/instruction-selector-impl.h +++ b/src/compiler/instruction-selector-impl.h @@ -55,9 +55,9 @@ class OperandGenerator { } InstructionOperand* Use(Node* node) { - return Use(node, - new (zone()) UnallocatedOperand( - UnallocatedOperand::ANY, UnallocatedOperand::USED_AT_START)); + return Use( + node, new (zone()) UnallocatedOperand( + UnallocatedOperand::NONE, UnallocatedOperand::USED_AT_START)); } InstructionOperand* UseRegister(Node* node) { @@ -69,7 +69,7 @@ class OperandGenerator { // Use register or operand for the node. If a register is chosen, it won't // alias any temporary or output registers. InstructionOperand* UseUnique(Node* node) { - return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::ANY)); + return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE)); } // Use a unique register for the node that does not alias any temporary or diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index 9540753..6a3d9c0 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -241,7 +241,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, // TODO(turbofan): match complex addressing modes. if (g.CanBeImmediate(right)) { - inputs[input_count++] = g.Use(left); + inputs[input_count++] = g.UseRegister(left); inputs[input_count++] = g.UseImmediate(right); } else { if (node->op()->HasProperty(Operator::kCommutative) && @@ -305,7 +305,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) { X64OperandGenerator g(this); Uint32BinopMatcher m(node); if (m.right().Is(-1)) { - Emit(kX64Not32, g.DefineSameAsFirst(node), g.Use(m.left().node())); + Emit(kX64Not32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); } else { VisitBinop(this, node, kX64Xor32); } @@ -316,7 +316,7 @@ void InstructionSelector::VisitWord64Xor(Node* node) { X64OperandGenerator g(this); Uint64BinopMatcher m(node); if (m.right().Is(-1)) { - Emit(kX64Not, g.DefineSameAsFirst(node), g.Use(m.left().node())); + Emit(kX64Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); } else { VisitBinop(this, node, kX64Xor); } @@ -332,7 +332,7 @@ static void VisitWord32Shift(InstructionSelector* selector, Node* node, Node* right = node->InputAt(1); if (g.CanBeImmediate(right)) { - selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), + selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), g.UseImmediate(right)); } else { Int32BinopMatcher m(node); @@ -342,7 +342,7 @@ static void VisitWord32Shift(InstructionSelector* selector, Node* node, right = mright.left().node(); } } - selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), + selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), g.UseFixed(right, rcx)); } } @@ -357,7 +357,7 @@ static void VisitWord64Shift(InstructionSelector* selector, Node* node, Node* right = node->InputAt(1); if (g.CanBeImmediate(right)) { - selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), + selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), g.UseImmediate(right)); } else { Int64BinopMatcher m(node); @@ -367,7 +367,7 @@ static void VisitWord64Shift(InstructionSelector* selector, Node* node, right = mright.left().node(); } } - selector->Emit(opcode, g.DefineSameAsFirst(node), g.Use(left), + selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), g.UseFixed(right, rcx)); } } @@ -472,7 +472,7 @@ void InstructionSelector::VisitInt32Sub(Node* node) { X64OperandGenerator g(this); Int32BinopMatcher m(node); if (m.left().Is(0)) { - Emit(kX64Neg32, g.DefineSameAsFirst(node), g.Use(m.right().node())); + Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); } else { VisitBinop(this, node, kX64Sub32); } @@ -483,7 +483,7 @@ void InstructionSelector::VisitInt64Sub(Node* node) { X64OperandGenerator g(this); Int64BinopMatcher m(node); if (m.left().Is(0)) { - Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); + Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); } else { VisitBinop(this, node, kX64Sub); } -- 2.7.4