Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 591343002: [turbofan] IA: support better left operand for commutative binops (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 case IrOpcode::kHeapConstant: { 45 case IrOpcode::kHeapConstant: {
46 // Constants in new space cannot be used as immediates in V8 because 46 // Constants in new space cannot be used as immediates in V8 because
47 // the GC does not scan code objects when collecting the new generation. 47 // the GC does not scan code objects when collecting the new generation.
48 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node); 48 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node);
49 return !isolate()->heap()->InNewSpace(*value.handle()); 49 return !isolate()->heap()->InNewSpace(*value.handle());
50 } 50 }
51 default: 51 default:
52 return false; 52 return false;
53 } 53 }
54 } 54 }
55
56 bool CanBeBetterLeftOperand(Node* node) const {
57 return !selector()->IsLive(node);
58 }
55 }; 59 };
56 60
57 61
58 void InstructionSelector::VisitLoad(Node* node) { 62 void InstructionSelector::VisitLoad(Node* node) {
59 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); 63 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
60 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); 64 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
61 X64OperandGenerator g(this); 65 X64OperandGenerator g(this);
62 Node* base = node->InputAt(0); 66 Node* base = node->InputAt(0);
63 Node* index = node->InputAt(1); 67 Node* index = node->InputAt(1);
64 68
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 } 175 }
172 // TODO(turbofan): addressing modes [r+r*{2,4,8}+K] 176 // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
173 } 177 }
174 178
175 179
176 // Shared routine for multiple binary operations. 180 // Shared routine for multiple binary operations.
177 static void VisitBinop(InstructionSelector* selector, Node* node, 181 static void VisitBinop(InstructionSelector* selector, Node* node,
178 InstructionCode opcode, FlagsContinuation* cont) { 182 InstructionCode opcode, FlagsContinuation* cont) {
179 X64OperandGenerator g(selector); 183 X64OperandGenerator g(selector);
180 Int32BinopMatcher m(node); 184 Int32BinopMatcher m(node);
185 Node* left = m.left().node();
186 Node* right = m.right().node();
181 InstructionOperand* inputs[4]; 187 InstructionOperand* inputs[4];
182 size_t input_count = 0; 188 size_t input_count = 0;
183 InstructionOperand* outputs[2]; 189 InstructionOperand* outputs[2];
184 size_t output_count = 0; 190 size_t output_count = 0;
185 191
186 // TODO(turbofan): match complex addressing modes. 192 // TODO(turbofan): match complex addressing modes.
187 // TODO(turbofan): if commutative, pick the non-live-in operand as the left as 193 if (g.CanBeImmediate(right)) {
188 // this might be the last use and therefore its register can be reused. 194 inputs[input_count++] = g.Use(left);
189 if (g.CanBeImmediate(m.right().node())) { 195 inputs[input_count++] = g.UseImmediate(right);
190 inputs[input_count++] = g.Use(m.left().node());
191 inputs[input_count++] = g.UseImmediate(m.right().node());
192 } else { 196 } else {
193 inputs[input_count++] = g.UseRegister(m.left().node()); 197 if (node->op()->HasProperty(Operator::kCommutative) &&
194 inputs[input_count++] = g.Use(m.right().node()); 198 g.CanBeBetterLeftOperand(right)) {
199 std::swap(left, right);
200 }
201 inputs[input_count++] = g.UseRegister(left);
202 inputs[input_count++] = g.Use(right);
195 } 203 }
196 204
197 if (cont->IsBranch()) { 205 if (cont->IsBranch()) {
198 inputs[input_count++] = g.Label(cont->true_block()); 206 inputs[input_count++] = g.Label(cont->true_block());
199 inputs[input_count++] = g.Label(cont->false_block()); 207 inputs[input_count++] = g.Label(cont->false_block());
200 } 208 }
201 209
202 outputs[output_count++] = g.DefineSameAsFirst(node); 210 outputs[output_count++] = g.DefineSameAsFirst(node);
203 if (cont->IsSet()) { 211 if (cont->IsSet()) {
204 outputs[output_count++] = g.DefineAsRegister(cont->result()); 212 outputs[output_count++] = g.DefineAsRegister(cont->result());
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); 393 Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
386 } else { 394 } else {
387 VisitBinop(this, node, kX64Sub); 395 VisitBinop(this, node, kX64Sub);
388 } 396 }
389 } 397 }
390 398
391 399
392 static void VisitMul(InstructionSelector* selector, Node* node, 400 static void VisitMul(InstructionSelector* selector, Node* node,
393 ArchOpcode opcode) { 401 ArchOpcode opcode) {
394 X64OperandGenerator g(selector); 402 X64OperandGenerator g(selector);
395 Node* left = node->InputAt(0); 403 Int32BinopMatcher m(node);
396 Node* right = node->InputAt(1); 404 Node* left = m.left().node();
405 Node* right = m.right().node();
397 if (g.CanBeImmediate(right)) { 406 if (g.CanBeImmediate(right)) {
398 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left), 407 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left),
399 g.UseImmediate(right)); 408 g.UseImmediate(right));
400 } else if (g.CanBeImmediate(left)) {
401 selector->Emit(opcode, g.DefineAsRegister(node), g.Use(right),
402 g.UseImmediate(left));
403 } else { 409 } else {
404 // TODO(turbofan): select better left operand. 410 if (g.CanBeBetterLeftOperand(right)) {
411 std::swap(left, right);
412 }
405 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), 413 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
406 g.Use(right)); 414 g.Use(right));
407 } 415 }
408 } 416 }
409 417
410 418
411 void InstructionSelector::VisitInt32Mul(Node* node) { 419 void InstructionSelector::VisitInt32Mul(Node* node) {
412 VisitMul(this, node, kX64Imul32); 420 VisitMul(this, node, kX64Imul32);
413 } 421 }
414 422
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 call_instr->MarkAsCall(); 716 call_instr->MarkAsCall();
709 if (deoptimization != NULL) { 717 if (deoptimization != NULL) {
710 DCHECK(continuation != NULL); 718 DCHECK(continuation != NULL);
711 call_instr->MarkAsControl(); 719 call_instr->MarkAsControl();
712 } 720 }
713 } 721 }
714 722
715 } // namespace compiler 723 } // namespace compiler
716 } // namespace internal 724 } // namespace internal
717 } // namespace v8 725 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/x64/instruction-selector-x64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698