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

Side by Side Diff: src/compiler/ia32/instruction-selector-ia32.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: 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
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "src/compiler/node-properties-inl.h" 7 #include "src/compiler/node-properties-inl.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 19 matching lines...) Expand all
30 case IrOpcode::kHeapConstant: { 30 case IrOpcode::kHeapConstant: {
31 // Constants in new space cannot be used as immediates in V8 because 31 // Constants in new space cannot be used as immediates in V8 because
32 // the GC does not scan code objects when collecting the new generation. 32 // the GC does not scan code objects when collecting the new generation.
33 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node); 33 Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node);
34 return !isolate()->heap()->InNewSpace(*value.handle()); 34 return !isolate()->heap()->InNewSpace(*value.handle());
35 } 35 }
36 default: 36 default:
37 return false; 37 return false;
38 } 38 }
39 } 39 }
40
41 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.
40 }; 42 };
41 43
42 44
43 void InstructionSelector::VisitLoad(Node* node) { 45 void InstructionSelector::VisitLoad(Node* node) {
44 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); 46 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
45 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); 47 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
46 IA32OperandGenerator g(this); 48 IA32OperandGenerator g(this);
47 Node* base = node->InputAt(0); 49 Node* base = node->InputAt(0);
48 Node* index = node->InputAt(1); 50 Node* index = node->InputAt(1);
49 51
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 161 }
160 // TODO(turbofan): addressing modes [r+r*{2,4,8}+K] 162 // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
161 } 163 }
162 164
163 165
164 // Shared routine for multiple binary operations. 166 // Shared routine for multiple binary operations.
165 static void VisitBinop(InstructionSelector* selector, Node* node, 167 static void VisitBinop(InstructionSelector* selector, Node* node,
166 InstructionCode opcode, FlagsContinuation* cont) { 168 InstructionCode opcode, FlagsContinuation* cont) {
167 IA32OperandGenerator g(selector); 169 IA32OperandGenerator g(selector);
168 Int32BinopMatcher m(node); 170 Int32BinopMatcher m(node);
171 Node* left = m.left().node();
172 Node* right = m.right().node();
169 InstructionOperand* inputs[4]; 173 InstructionOperand* inputs[4];
170 size_t input_count = 0; 174 size_t input_count = 0;
171 InstructionOperand* outputs[2]; 175 InstructionOperand* outputs[2];
172 size_t output_count = 0; 176 size_t output_count = 0;
173 177
174 // TODO(turbofan): match complex addressing modes. 178 // TODO(turbofan): match complex addressing modes.
175 // TODO(turbofan): if commutative, pick the non-live-in operand as the left as 179 if (g.CanBeImmediate(right)) {
176 // this might be the last use and therefore its register can be reused. 180 inputs[input_count++] = g.Use(left);
177 if (g.CanBeImmediate(m.right().node())) { 181 inputs[input_count++] = g.UseImmediate(right);
178 inputs[input_count++] = g.Use(m.left().node());
179 inputs[input_count++] = g.UseImmediate(m.right().node());
180 } else { 182 } else {
181 inputs[input_count++] = g.UseRegister(m.left().node()); 183 if (node->op()->HasProperty(Operator::kCommutative) &&
182 inputs[input_count++] = g.Use(m.right().node()); 184 g.CanBeBetterLeftOperand(right)) {
185 std::swap(left, right);
186 }
187 inputs[input_count++] = g.UseRegister(left);
188 inputs[input_count++] = g.Use(right);
183 } 189 }
184 190
185 if (cont->IsBranch()) { 191 if (cont->IsBranch()) {
186 inputs[input_count++] = g.Label(cont->true_block()); 192 inputs[input_count++] = g.Label(cont->true_block());
187 inputs[input_count++] = g.Label(cont->false_block()); 193 inputs[input_count++] = g.Label(cont->false_block());
188 } 194 }
189 195
190 outputs[output_count++] = g.DefineSameAsFirst(node); 196 outputs[output_count++] = g.DefineSameAsFirst(node);
191 if (cont->IsSet()) { 197 if (cont->IsSet()) {
192 // TODO(turbofan): Use byte register here. 198 // TODO(turbofan): Use byte register here.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 if (m.left().Is(0)) { 295 if (m.left().Is(0)) {
290 Emit(kIA32Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); 296 Emit(kIA32Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
291 } else { 297 } else {
292 VisitBinop(this, node, kIA32Sub); 298 VisitBinop(this, node, kIA32Sub);
293 } 299 }
294 } 300 }
295 301
296 302
297 void InstructionSelector::VisitInt32Mul(Node* node) { 303 void InstructionSelector::VisitInt32Mul(Node* node) {
298 IA32OperandGenerator g(this); 304 IA32OperandGenerator g(this);
299 Node* left = node->InputAt(0); 305 Int32BinopMatcher m(node);
300 Node* right = node->InputAt(1); 306 Node* left = m.left().node();
307 Node* right = m.right().node();
301 if (g.CanBeImmediate(right)) { 308 if (g.CanBeImmediate(right)) {
302 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left), 309 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left),
303 g.UseImmediate(right)); 310 g.UseImmediate(right));
304 } else if (g.CanBeImmediate(left)) {
305 Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(right),
306 g.UseImmediate(left));
307 } else { 311 } else {
308 // TODO(turbofan): select better left operand. 312 if (g.CanBeBetterLeftOperand(right)) {
313 std::swap(left, right);
314 }
309 Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left), 315 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
310 g.Use(right)); 316 g.Use(right));
311 } 317 }
312 } 318 }
313 319
314 320
315 static inline void VisitDiv(InstructionSelector* selector, Node* node, 321 static inline void VisitDiv(InstructionSelector* selector, Node* node,
316 ArchOpcode opcode) { 322 ArchOpcode opcode) {
317 IA32OperandGenerator g(selector); 323 IA32OperandGenerator g(selector);
318 InstructionOperand* temps[] = {g.TempRegister(edx)}; 324 InstructionOperand* temps[] = {g.TempRegister(edx)};
319 size_t temp_count = arraysize(temps); 325 size_t temp_count = arraysize(temps);
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 call_instr->MarkAsCall(); 554 call_instr->MarkAsCall();
549 if (deoptimization != NULL) { 555 if (deoptimization != NULL) {
550 DCHECK(continuation != NULL); 556 DCHECK(continuation != NULL);
551 call_instr->MarkAsControl(); 557 call_instr->MarkAsControl();
552 } 558 }
553 } 559 }
554 560
555 } // namespace compiler 561 } // namespace compiler
556 } // namespace internal 562 } // namespace internal
557 } // namespace v8 563 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/ia32/instruction-selector-ia32-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698