| Index: src/compiler/instruction-selector.cc
|
| diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
|
| index bd3bfd73c9a7969a9dca3412945bb486d507b27d..b8d2fca76ce6f2420e3bf9c9af8589a0797aa2a0 100644
|
| --- a/src/compiler/instruction-selector.cc
|
| +++ b/src/compiler/instruction-selector.cc
|
| @@ -13,13 +13,17 @@ namespace v8 {
|
| namespace internal {
|
| namespace compiler {
|
|
|
| -InstructionSelector::InstructionSelector(InstructionSequence* sequence,
|
| +InstructionSelector::InstructionSelector(Zone* local_zone, Linkage* linkage,
|
| + InstructionSequence* sequence,
|
| + Schedule* schedule,
|
| SourcePositionTable* source_positions,
|
| Features features)
|
| - : zone_(sequence->isolate()),
|
| + : zone_(local_zone),
|
| + linkage_(linkage),
|
| sequence_(sequence),
|
| source_positions_(source_positions),
|
| features_(features),
|
| + schedule_(schedule),
|
| current_block_(NULL),
|
| instructions_(zone()),
|
| defined_(sequence->node_count(), false, zone()),
|
| @@ -55,8 +59,10 @@ void InstructionSelector::SelectInstructions() {
|
| // Schedule the selected instructions.
|
| for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
|
| BasicBlock* block = *i;
|
| - size_t end = sequence()->code_end(block);
|
| - size_t start = sequence()->code_start(block);
|
| + InstructionBlock* instruction_block =
|
| + sequence()->InstructionBlockAt(block->GetRpoNumber());
|
| + size_t end = instruction_block->code_end();
|
| + size_t start = instruction_block->code_start();
|
| sequence()->StartBlock(block);
|
| while (start-- > end) {
|
| sequence()->AddInstruction(instructions_[start]);
|
| @@ -141,7 +147,7 @@ Instruction* InstructionSelector::Emit(Instruction* instr) {
|
|
|
|
|
| bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
|
| - return current_block_->GetRpoNumber().IsNext(block->GetRpoNumber());
|
| + return current_block_->GetAoNumber().IsNext(block->GetAoNumber());
|
| }
|
|
|
|
|
| @@ -213,6 +219,23 @@ void InstructionSelector::MarkAsReference(Node* node) {
|
| }
|
|
|
|
|
| +void InstructionSelector::MarkAsRepresentation(MachineType rep,
|
| + InstructionOperand* op) {
|
| + UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
|
| + switch (RepresentationOf(rep)) {
|
| + case kRepFloat32:
|
| + case kRepFloat64:
|
| + sequence()->MarkAsDouble(unalloc->virtual_register());
|
| + break;
|
| + case kRepTagged:
|
| + sequence()->MarkAsReference(unalloc->virtual_register());
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
|
| DCHECK_NOT_NULL(node);
|
| switch (RepresentationOf(rep)) {
|
| @@ -268,15 +291,27 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
|
| }
|
|
|
| // Filter out the outputs that aren't live because no projection uses them.
|
| + size_t outputs_needed_by_framestate =
|
| + buffer->frame_state_descriptor == NULL
|
| + ? 0
|
| + : buffer->frame_state_descriptor->state_combine()
|
| + .ConsumedOutputCount();
|
| for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
|
| - if (buffer->output_nodes[i] != NULL) {
|
| - Node* output = buffer->output_nodes[i];
|
| + bool output_is_live =
|
| + buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate;
|
| + if (output_is_live) {
|
| MachineType type =
|
| buffer->descriptor->GetReturnType(static_cast<int>(i));
|
| LinkageLocation location =
|
| buffer->descriptor->GetReturnLocation(static_cast<int>(i));
|
| - MarkAsRepresentation(type, output);
|
| - buffer->outputs.push_back(g.DefineAsLocation(output, location, type));
|
| +
|
| + Node* output = buffer->output_nodes[i];
|
| + InstructionOperand* op =
|
| + output == NULL ? g.TempLocation(location, type)
|
| + : g.DefineAsLocation(output, location, type);
|
| + MarkAsRepresentation(type, op);
|
| +
|
| + buffer->outputs.push_back(op);
|
| }
|
| }
|
| }
|
| @@ -383,8 +418,10 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
|
| }
|
|
|
| // We're done with the block.
|
| - sequence()->set_code_start(block, static_cast<int>(instructions_.size()));
|
| - sequence()->set_code_end(block, current_block_end);
|
| + InstructionBlock* instruction_block =
|
| + sequence()->InstructionBlockAt(block->GetRpoNumber());
|
| + instruction_block->set_code_start(static_cast<int>(instructions_.size()));
|
| + instruction_block->set_code_end(current_block_end);
|
|
|
| current_block_ = NULL;
|
| }
|
| @@ -449,6 +486,7 @@ MachineType InstructionSelector::GetMachineType(Node* node) {
|
| case IrOpcode::kIfFalse:
|
| case IrOpcode::kEffectPhi:
|
| case IrOpcode::kMerge:
|
| + case IrOpcode::kTerminate:
|
| // No code needed for these graph artifacts.
|
| return kMachNone;
|
| case IrOpcode::kFinish:
|
| @@ -853,8 +891,15 @@ void InstructionSelector::VisitParameter(Node* node) {
|
|
|
| void InstructionSelector::VisitPhi(Node* node) {
|
| // TODO(bmeurer): Emit a PhiInstruction here.
|
| - for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
|
| - MarkAsUsed(*i);
|
| + PhiInstruction* phi = new (instruction_zone())
|
| + PhiInstruction(instruction_zone(), sequence()->GetVirtualRegister(node));
|
| + sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi);
|
| + const int input_count = node->op()->InputCount();
|
| + phi->operands().reserve(static_cast<size_t>(input_count));
|
| + for (int i = 0; i < input_count; ++i) {
|
| + Node* const input = node->InputAt(i);
|
| + MarkAsUsed(input);
|
| + phi->operands().push_back(sequence()->GetVirtualRegister(input));
|
| }
|
| }
|
|
|
| @@ -1026,6 +1071,13 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
|
| UNIMPLEMENTED();
|
| }
|
|
|
| +
|
| +// static
|
| +MachineOperatorBuilder::Flags
|
| +InstructionSelector::SupportedMachineOperatorFlags() {
|
| + return MachineOperatorBuilder::Flag::kNoFlags;
|
| +}
|
| +
|
| #endif // !V8_TURBOFAN_BACKEND
|
|
|
| } // namespace compiler
|
|
|