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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 } | 48 } |
49 | 49 |
50 // Visit each basic block in post order. | 50 // Visit each basic block in post order. |
51 for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) { | 51 for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) { |
52 VisitBlock(*i); | 52 VisitBlock(*i); |
53 } | 53 } |
54 | 54 |
55 // Schedule the selected instructions. | 55 // Schedule the selected instructions. |
56 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { | 56 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { |
57 BasicBlock* block = *i; | 57 BasicBlock* block = *i; |
58 size_t end = block->code_end_; | 58 size_t end = block->code_end(); |
59 size_t start = block->code_start_; | 59 size_t start = block->code_start(); |
60 sequence()->StartBlock(block); | 60 sequence()->StartBlock(block); |
61 while (start-- > end) { | 61 while (start-- > end) { |
62 sequence()->AddInstruction(instructions_[start], block); | 62 sequence()->AddInstruction(instructions_[start], block); |
63 } | 63 } |
64 sequence()->EndBlock(block); | 64 sequence()->EndBlock(block); |
65 } | 65 } |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 Instruction* InstructionSelector::Emit(InstructionCode opcode, | 69 Instruction* InstructionSelector::Emit(InstructionCode opcode, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 Instruction* InstructionSelector::Emit(Instruction* instr) { | 137 Instruction* InstructionSelector::Emit(Instruction* instr) { |
138 instructions_.push_back(instr); | 138 instructions_.push_back(instr); |
139 return instr; | 139 return instr; |
140 } | 140 } |
141 | 141 |
142 | 142 |
143 bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const { | 143 bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const { |
144 return block->rpo_number_ == (current_block_->rpo_number_ + 1) && | 144 return block->rpo_number() == (current_block_->rpo_number() + 1) && |
145 block->deferred_ == current_block_->deferred_; | 145 block->deferred() == current_block_->deferred(); |
146 } | 146 } |
147 | 147 |
148 | 148 |
149 bool InstructionSelector::CanCover(Node* user, Node* node) const { | 149 bool InstructionSelector::CanCover(Node* user, Node* node) const { |
150 return node->OwnedBy(user) && | 150 return node->OwnedBy(user) && |
151 schedule()->block(node) == schedule()->block(user); | 151 schedule()->block(node) == schedule()->block(user); |
152 } | 152 } |
153 | 153 |
154 | 154 |
155 bool InstructionSelector::IsDefined(Node* node) const { | 155 bool InstructionSelector::IsDefined(Node* node) const { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 if (!IsUsed(node) || IsDefined(node)) continue; | 376 if (!IsUsed(node) || IsDefined(node)) continue; |
377 // Generate code for this node "top down", but schedule the code "bottom | 377 // Generate code for this node "top down", but schedule the code "bottom |
378 // up". | 378 // up". |
379 size_t current_node_end = instructions_.size(); | 379 size_t current_node_end = instructions_.size(); |
380 VisitNode(node); | 380 VisitNode(node); |
381 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); | 381 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); |
382 } | 382 } |
383 | 383 |
384 // We're done with the block. | 384 // We're done with the block. |
385 // TODO(bmeurer): We should not mutate the schedule. | 385 // TODO(bmeurer): We should not mutate the schedule. |
386 block->code_end_ = current_block_end; | 386 block->set_code_start(static_cast<int>(instructions_.size())); |
387 block->code_start_ = static_cast<int>(instructions_.size()); | 387 block->set_code_end(current_block_end); |
388 | 388 |
389 current_block_ = NULL; | 389 current_block_ = NULL; |
390 } | 390 } |
391 | 391 |
392 | 392 |
393 static inline void CheckNoPhis(const BasicBlock* block) { | 393 static inline void CheckNoPhis(const BasicBlock* block) { |
394 #ifdef DEBUG | 394 #ifdef DEBUG |
395 // Branch targets should not have phis. | 395 // Branch targets should not have phis. |
396 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) { | 396 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) { |
397 const Node* node = *i; | 397 const Node* node = *i; |
398 CHECK_NE(IrOpcode::kPhi, node->opcode()); | 398 CHECK_NE(IrOpcode::kPhi, node->opcode()); |
399 } | 399 } |
400 #endif | 400 #endif |
401 } | 401 } |
402 | 402 |
403 | 403 |
404 void InstructionSelector::VisitControl(BasicBlock* block) { | 404 void InstructionSelector::VisitControl(BasicBlock* block) { |
405 Node* input = block->control_input_; | 405 Node* input = block->control_input(); |
406 switch (block->control_) { | 406 switch (block->control()) { |
407 case BasicBlockData::kGoto: | 407 case BasicBlock::kGoto: |
408 return VisitGoto(block->SuccessorAt(0)); | 408 return VisitGoto(block->SuccessorAt(0)); |
409 case BasicBlockData::kBranch: { | 409 case BasicBlock::kBranch: { |
410 DCHECK_EQ(IrOpcode::kBranch, input->opcode()); | 410 DCHECK_EQ(IrOpcode::kBranch, input->opcode()); |
411 BasicBlock* tbranch = block->SuccessorAt(0); | 411 BasicBlock* tbranch = block->SuccessorAt(0); |
412 BasicBlock* fbranch = block->SuccessorAt(1); | 412 BasicBlock* fbranch = block->SuccessorAt(1); |
413 // SSA deconstruction requires targets of branches not to have phis. | 413 // SSA deconstruction requires targets of branches not to have phis. |
414 // Edge split form guarantees this property, but is more strict. | 414 // Edge split form guarantees this property, but is more strict. |
415 CheckNoPhis(tbranch); | 415 CheckNoPhis(tbranch); |
416 CheckNoPhis(fbranch); | 416 CheckNoPhis(fbranch); |
417 if (tbranch == fbranch) return VisitGoto(tbranch); | 417 if (tbranch == fbranch) return VisitGoto(tbranch); |
418 return VisitBranch(input, tbranch, fbranch); | 418 return VisitBranch(input, tbranch, fbranch); |
419 } | 419 } |
420 case BasicBlockData::kReturn: { | 420 case BasicBlock::kReturn: { |
421 // If the result itself is a return, return its input. | 421 // If the result itself is a return, return its input. |
422 Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) | 422 Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) |
423 ? input->InputAt(0) | 423 ? input->InputAt(0) |
424 : input; | 424 : input; |
425 return VisitReturn(value); | 425 return VisitReturn(value); |
426 } | 426 } |
427 case BasicBlockData::kThrow: | 427 case BasicBlock::kThrow: |
428 return VisitThrow(input); | 428 return VisitThrow(input); |
429 case BasicBlockData::kNone: { | 429 case BasicBlock::kNone: { |
430 // TODO(titzer): exit block doesn't have control. | 430 // TODO(titzer): exit block doesn't have control. |
431 DCHECK(input == NULL); | 431 DCHECK(input == NULL); |
432 break; | 432 break; |
433 } | 433 } |
434 default: | 434 default: |
435 UNREACHABLE(); | 435 UNREACHABLE(); |
436 break; | 436 break; |
437 } | 437 } |
438 } | 438 } |
439 | 439 |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 | 1098 |
1099 | 1099 |
1100 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1100 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
1101 BasicBlock* deoptimization) {} | 1101 BasicBlock* deoptimization) {} |
1102 | 1102 |
1103 #endif // !V8_TURBOFAN_BACKEND | 1103 #endif // !V8_TURBOFAN_BACKEND |
1104 | 1104 |
1105 } // namespace compiler | 1105 } // namespace compiler |
1106 } // namespace internal | 1106 } // namespace internal |
1107 } // namespace v8 | 1107 } // namespace v8 |
OLD | NEW |