| 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.h" | 5 #include "src/compiler/instruction-selector.h" | 
| 6 | 6 | 
| 7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" | 
| 8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" | 
| 9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" | 
| 10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" | 
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 291       buffer->output_nodes.push_back(call); | 291       buffer->output_nodes.push_back(call); | 
| 292     } else { | 292     } else { | 
| 293       buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL); | 293       buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL); | 
| 294       call->CollectProjections(&buffer->output_nodes); | 294       call->CollectProjections(&buffer->output_nodes); | 
| 295     } | 295     } | 
| 296 | 296 | 
| 297     // Filter out the outputs that aren't live because no projection uses them. | 297     // Filter out the outputs that aren't live because no projection uses them. | 
| 298     for (size_t i = 0; i < buffer->output_nodes.size(); i++) { | 298     for (size_t i = 0; i < buffer->output_nodes.size(); i++) { | 
| 299       if (buffer->output_nodes[i] != NULL) { | 299       if (buffer->output_nodes[i] != NULL) { | 
| 300         Node* output = buffer->output_nodes[i]; | 300         Node* output = buffer->output_nodes[i]; | 
|  | 301         MachineType type = | 
|  | 302             buffer->descriptor->GetReturnType(static_cast<int>(i)); | 
| 301         LinkageLocation location = | 303         LinkageLocation location = | 
| 302             buffer->descriptor->GetReturnLocation(static_cast<int>(i)); | 304             buffer->descriptor->GetReturnLocation(static_cast<int>(i)); | 
| 303         MarkAsRepresentation(location.representation(), output); | 305         MarkAsRepresentation(type, output); | 
| 304         buffer->outputs.push_back(g.DefineAsLocation(output, location)); | 306         buffer->outputs.push_back(g.DefineAsLocation(output, location, type)); | 
| 305       } | 307       } | 
| 306     } | 308     } | 
| 307   } | 309   } | 
| 308 | 310 | 
| 309   // The first argument is always the callee code. | 311   // The first argument is always the callee code. | 
| 310   Node* callee = call->InputAt(0); | 312   Node* callee = call->InputAt(0); | 
| 311   switch (buffer->descriptor->kind()) { | 313   switch (buffer->descriptor->kind()) { | 
| 312     case CallDescriptor::kCallCodeObject: | 314     case CallDescriptor::kCallCodeObject: | 
| 313       buffer->instruction_args.push_back( | 315       buffer->instruction_args.push_back( | 
| 314           (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) | 316           (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) | 
| 315               ? g.UseImmediate(callee) | 317               ? g.UseImmediate(callee) | 
| 316               : g.UseRegister(callee)); | 318               : g.UseRegister(callee)); | 
| 317       break; | 319       break; | 
| 318     case CallDescriptor::kCallAddress: | 320     case CallDescriptor::kCallAddress: | 
| 319       buffer->instruction_args.push_back( | 321       buffer->instruction_args.push_back( | 
| 320           (call_address_immediate && | 322           (call_address_immediate && | 
| 321            (callee->opcode() == IrOpcode::kInt32Constant || | 323            (callee->opcode() == IrOpcode::kInt32Constant || | 
| 322             callee->opcode() == IrOpcode::kInt64Constant)) | 324             callee->opcode() == IrOpcode::kInt64Constant)) | 
| 323               ? g.UseImmediate(callee) | 325               ? g.UseImmediate(callee) | 
| 324               : g.UseRegister(callee)); | 326               : g.UseRegister(callee)); | 
| 325       break; | 327       break; | 
| 326     case CallDescriptor::kCallJSFunction: | 328     case CallDescriptor::kCallJSFunction: | 
| 327       buffer->instruction_args.push_back( | 329       buffer->instruction_args.push_back( | 
| 328           g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); | 330           g.UseLocation(callee, buffer->descriptor->GetInputLocation(0), | 
|  | 331                         buffer->descriptor->GetInputType(0))); | 
| 329       break; | 332       break; | 
| 330   } | 333   } | 
| 331   DCHECK_EQ(1, buffer->instruction_args.size()); | 334   DCHECK_EQ(1, buffer->instruction_args.size()); | 
| 332 | 335 | 
| 333   // If the call needs a frame state, we insert the state information as | 336   // If the call needs a frame state, we insert the state information as | 
| 334   // follows (n is the number of value inputs to the frame state): | 337   // follows (n is the number of value inputs to the frame state): | 
| 335   // arg 1               : deoptimization id. | 338   // arg 1               : deoptimization id. | 
| 336   // arg 2 - arg (n + 1) : value inputs to the frame state. | 339   // arg 2 - arg (n + 1) : value inputs to the frame state. | 
| 337   if (buffer->frame_state_descriptor != NULL) { | 340   if (buffer->frame_state_descriptor != NULL) { | 
| 338     InstructionSequence::StateId state_id = | 341     InstructionSequence::StateId state_id = | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 353   // not appear as arguments to the call. Everything else ends up | 356   // not appear as arguments to the call. Everything else ends up | 
| 354   // as an InstructionOperand argument to the call. | 357   // as an InstructionOperand argument to the call. | 
| 355   InputIter iter(call->inputs().begin()); | 358   InputIter iter(call->inputs().begin()); | 
| 356   int pushed_count = 0; | 359   int pushed_count = 0; | 
| 357   for (int index = 0; index < input_count; ++iter, ++index) { | 360   for (int index = 0; index < input_count; ++iter, ++index) { | 
| 358     DCHECK(iter != call->inputs().end()); | 361     DCHECK(iter != call->inputs().end()); | 
| 359     DCHECK(index == iter.index()); | 362     DCHECK(index == iter.index()); | 
| 360     DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); | 363     DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); | 
| 361     if (index == 0) continue;  // The first argument (callee) is already done. | 364     if (index == 0) continue;  // The first argument (callee) is already done. | 
| 362     InstructionOperand* op = | 365     InstructionOperand* op = | 
| 363         g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index)); | 366         g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), | 
|  | 367                       buffer->descriptor->GetInputType(index)); | 
| 364     if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { | 368     if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { | 
| 365       int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; | 369       int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; | 
| 366       if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { | 370       if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { | 
| 367         buffer->pushed_nodes.resize(stack_index + 1, NULL); | 371         buffer->pushed_nodes.resize(stack_index + 1, NULL); | 
| 368       } | 372       } | 
| 369       DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); | 373       DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); | 
| 370       buffer->pushed_nodes[stack_index] = *iter; | 374       buffer->pushed_nodes[stack_index] = *iter; | 
| 371       pushed_count++; | 375       pushed_count++; | 
| 372     } else { | 376     } else { | 
| 373       buffer->instruction_args.push_back(op); | 377       buffer->instruction_args.push_back(op); | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 477     case IrOpcode::kBranch: | 481     case IrOpcode::kBranch: | 
| 478     case IrOpcode::kIfTrue: | 482     case IrOpcode::kIfTrue: | 
| 479     case IrOpcode::kIfFalse: | 483     case IrOpcode::kIfFalse: | 
| 480     case IrOpcode::kEffectPhi: | 484     case IrOpcode::kEffectPhi: | 
| 481     case IrOpcode::kMerge: | 485     case IrOpcode::kMerge: | 
| 482       // No code needed for these graph artifacts. | 486       // No code needed for these graph artifacts. | 
| 483       return; | 487       return; | 
| 484     case IrOpcode::kFinish: | 488     case IrOpcode::kFinish: | 
| 485       return VisitFinish(node); | 489       return VisitFinish(node); | 
| 486     case IrOpcode::kParameter: { | 490     case IrOpcode::kParameter: { | 
| 487       LinkageLocation location = | 491       MachineType type = linkage()->GetParameterType(OpParameter<int>(node)); | 
| 488           linkage()->GetParameterLocation(OpParameter<int>(node)); | 492       MarkAsRepresentation(type, node); | 
| 489       MarkAsRepresentation(location.representation(), node); |  | 
| 490       return VisitParameter(node); | 493       return VisitParameter(node); | 
| 491     } | 494     } | 
| 492     case IrOpcode::kPhi: | 495     case IrOpcode::kPhi: | 
| 493       return VisitPhi(node); | 496       return VisitPhi(node); | 
| 494     case IrOpcode::kProjection: | 497     case IrOpcode::kProjection: | 
| 495       return VisitProjection(node); | 498       return VisitProjection(node); | 
| 496     case IrOpcode::kInt32Constant: | 499     case IrOpcode::kInt32Constant: | 
| 497     case IrOpcode::kInt64Constant: | 500     case IrOpcode::kInt64Constant: | 
| 498     case IrOpcode::kExternalConstant: | 501     case IrOpcode::kExternalConstant: | 
| 499       return VisitConstant(node); | 502       return VisitConstant(node); | 
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 815 | 818 | 
| 816 void InstructionSelector::VisitFinish(Node* node) { | 819 void InstructionSelector::VisitFinish(Node* node) { | 
| 817   OperandGenerator g(this); | 820   OperandGenerator g(this); | 
| 818   Node* value = node->InputAt(0); | 821   Node* value = node->InputAt(0); | 
| 819   Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 822   Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 
| 820 } | 823 } | 
| 821 | 824 | 
| 822 | 825 | 
| 823 void InstructionSelector::VisitParameter(Node* node) { | 826 void InstructionSelector::VisitParameter(Node* node) { | 
| 824   OperandGenerator g(this); | 827   OperandGenerator g(this); | 
| 825   Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation( | 828   int index = OpParameter<int>(node); | 
| 826                                               OpParameter<int>(node)))); | 829   Emit(kArchNop, | 
|  | 830        g.DefineAsLocation(node, linkage()->GetParameterLocation(index), | 
|  | 831                           linkage()->GetParameterType(index))); | 
| 827 } | 832 } | 
| 828 | 833 | 
| 829 | 834 | 
| 830 void InstructionSelector::VisitPhi(Node* node) { | 835 void InstructionSelector::VisitPhi(Node* node) { | 
| 831   // TODO(bmeurer): Emit a PhiInstruction here. | 836   // TODO(bmeurer): Emit a PhiInstruction here. | 
| 832   for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { | 837   for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { | 
| 833     MarkAsUsed(*i); | 838     MarkAsUsed(*i); | 
| 834   } | 839   } | 
| 835 } | 840 } | 
| 836 | 841 | 
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 980   } | 985   } | 
| 981 | 986 | 
| 982   // Branch could not be combined with a compare, emit compare against 0. | 987   // Branch could not be combined with a compare, emit compare against 0. | 
| 983   VisitWord32Test(value, &cont); | 988   VisitWord32Test(value, &cont); | 
| 984 } | 989 } | 
| 985 | 990 | 
| 986 | 991 | 
| 987 void InstructionSelector::VisitReturn(Node* value) { | 992 void InstructionSelector::VisitReturn(Node* value) { | 
| 988   OperandGenerator g(this); | 993   OperandGenerator g(this); | 
| 989   if (value != NULL) { | 994   if (value != NULL) { | 
| 990     Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation())); | 995     Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(), | 
|  | 996                                        linkage()->GetReturnType())); | 
| 991   } else { | 997   } else { | 
| 992     Emit(kArchRet, NULL); | 998     Emit(kArchRet, NULL); | 
| 993   } | 999   } | 
| 994 } | 1000 } | 
| 995 | 1001 | 
| 996 | 1002 | 
| 997 void InstructionSelector::VisitThrow(Node* value) { | 1003 void InstructionSelector::VisitThrow(Node* value) { | 
| 998   UNIMPLEMENTED();  // TODO(titzer) | 1004   UNIMPLEMENTED();  // TODO(titzer) | 
| 999 } | 1005 } | 
| 1000 | 1006 | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1096 | 1102 | 
| 1097 | 1103 | 
| 1098 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1104 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 
| 1099                                     BasicBlock* deoptimization) {} | 1105                                     BasicBlock* deoptimization) {} | 
| 1100 | 1106 | 
| 1101 #endif  // !V8_TURBOFAN_BACKEND | 1107 #endif  // !V8_TURBOFAN_BACKEND | 
| 1102 | 1108 | 
| 1103 }  // namespace compiler | 1109 }  // namespace compiler | 
| 1104 }  // namespace internal | 1110 }  // namespace internal | 
| 1105 }  // namespace v8 | 1111 }  // namespace v8 | 
| OLD | NEW | 
|---|