| OLD | NEW | 
|---|
| 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  Loading... | 
| 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) { return !selector()->IsUsed(node); } | 
| 55 }; | 57 }; | 
| 56 | 58 | 
| 57 | 59 | 
| 58 void InstructionSelector::VisitLoad(Node* node) { | 60 void InstructionSelector::VisitLoad(Node* node) { | 
| 59   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 61   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 
| 60   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 62   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 
| 61   X64OperandGenerator g(this); | 63   X64OperandGenerator g(this); | 
| 62   Node* base = node->InputAt(0); | 64   Node* base = node->InputAt(0); | 
| 63   Node* index = node->InputAt(1); | 65   Node* index = node->InputAt(1); | 
| 64 | 66 | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 171   } | 173   } | 
| 172   // TODO(turbofan): addressing modes [r+r*{2,4,8}+K] | 174   // TODO(turbofan): addressing modes [r+r*{2,4,8}+K] | 
| 173 } | 175 } | 
| 174 | 176 | 
| 175 | 177 | 
| 176 // Shared routine for multiple binary operations. | 178 // Shared routine for multiple binary operations. | 
| 177 static void VisitBinop(InstructionSelector* selector, Node* node, | 179 static void VisitBinop(InstructionSelector* selector, Node* node, | 
| 178                        InstructionCode opcode, FlagsContinuation* cont) { | 180                        InstructionCode opcode, FlagsContinuation* cont) { | 
| 179   X64OperandGenerator g(selector); | 181   X64OperandGenerator g(selector); | 
| 180   Int32BinopMatcher m(node); | 182   Int32BinopMatcher m(node); | 
|  | 183   Node* left = m.left().node(); | 
|  | 184   Node* right = m.right().node(); | 
| 181   InstructionOperand* inputs[4]; | 185   InstructionOperand* inputs[4]; | 
| 182   size_t input_count = 0; | 186   size_t input_count = 0; | 
| 183   InstructionOperand* outputs[2]; | 187   InstructionOperand* outputs[2]; | 
| 184   size_t output_count = 0; | 188   size_t output_count = 0; | 
| 185 | 189 | 
| 186   // TODO(turbofan): match complex addressing modes. | 190   // TODO(turbofan): match complex addressing modes. | 
| 187   // TODO(turbofan): if commutative, pick the non-live-in operand as the left as | 191   if (g.CanBeImmediate(right)) { | 
| 188   // this might be the last use and therefore its register can be reused. | 192     inputs[input_count++] = g.Use(left); | 
| 189   if (g.CanBeImmediate(m.right().node())) { | 193     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 { | 194   } else { | 
| 193     inputs[input_count++] = g.UseRegister(m.left().node()); | 195     if (node->op()->HasProperty(Operator::kCommutative) && | 
| 194     inputs[input_count++] = g.Use(m.right().node()); | 196         g.CanBeBetterLeftOperand(right)) { | 
|  | 197       std::swap(left, right); | 
|  | 198     } | 
|  | 199     inputs[input_count++] = g.UseRegister(left); | 
|  | 200     inputs[input_count++] = g.Use(right); | 
| 195   } | 201   } | 
| 196 | 202 | 
| 197   if (cont->IsBranch()) { | 203   if (cont->IsBranch()) { | 
| 198     inputs[input_count++] = g.Label(cont->true_block()); | 204     inputs[input_count++] = g.Label(cont->true_block()); | 
| 199     inputs[input_count++] = g.Label(cont->false_block()); | 205     inputs[input_count++] = g.Label(cont->false_block()); | 
| 200   } | 206   } | 
| 201 | 207 | 
| 202   outputs[output_count++] = g.DefineSameAsFirst(node); | 208   outputs[output_count++] = g.DefineSameAsFirst(node); | 
| 203   if (cont->IsSet()) { | 209   if (cont->IsSet()) { | 
| 204     outputs[output_count++] = g.DefineAsRegister(cont->result()); | 210     outputs[output_count++] = g.DefineAsRegister(cont->result()); | 
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 385     Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); | 391     Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node())); | 
| 386   } else { | 392   } else { | 
| 387     VisitBinop(this, node, kX64Sub); | 393     VisitBinop(this, node, kX64Sub); | 
| 388   } | 394   } | 
| 389 } | 395 } | 
| 390 | 396 | 
| 391 | 397 | 
| 392 static void VisitMul(InstructionSelector* selector, Node* node, | 398 static void VisitMul(InstructionSelector* selector, Node* node, | 
| 393                      ArchOpcode opcode) { | 399                      ArchOpcode opcode) { | 
| 394   X64OperandGenerator g(selector); | 400   X64OperandGenerator g(selector); | 
| 395   Node* left = node->InputAt(0); | 401   Int32BinopMatcher m(node); | 
| 396   Node* right = node->InputAt(1); | 402   Node* left = m.left().node(); | 
|  | 403   Node* right = m.right().node(); | 
| 397   if (g.CanBeImmediate(right)) { | 404   if (g.CanBeImmediate(right)) { | 
| 398     selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left), | 405     selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left), | 
| 399                    g.UseImmediate(right)); | 406                    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 { | 407   } else { | 
| 404     // TODO(turbofan): select better left operand. | 408     if (g.CanBeBetterLeftOperand(right)) { | 
|  | 409       std::swap(left, right); | 
|  | 410     } | 
| 405     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 411     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | 
| 406                    g.Use(right)); | 412                    g.Use(right)); | 
| 407   } | 413   } | 
| 408 } | 414 } | 
| 409 | 415 | 
| 410 | 416 | 
| 411 void InstructionSelector::VisitInt32Mul(Node* node) { | 417 void InstructionSelector::VisitInt32Mul(Node* node) { | 
| 412   VisitMul(this, node, kX64Imul32); | 418   VisitMul(this, node, kX64Imul32); | 
| 413 } | 419 } | 
| 414 | 420 | 
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 708   call_instr->MarkAsCall(); | 714   call_instr->MarkAsCall(); | 
| 709   if (deoptimization != NULL) { | 715   if (deoptimization != NULL) { | 
| 710     DCHECK(continuation != NULL); | 716     DCHECK(continuation != NULL); | 
| 711     call_instr->MarkAsControl(); | 717     call_instr->MarkAsControl(); | 
| 712   } | 718   } | 
| 713 } | 719 } | 
| 714 | 720 | 
| 715 }  // namespace compiler | 721 }  // namespace compiler | 
| 716 }  // namespace internal | 722 }  // namespace internal | 
| 717 }  // namespace v8 | 723 }  // namespace v8 | 
| OLD | NEW | 
|---|