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 <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 linkage_(linkage), | 27 linkage_(linkage), |
28 sequence_(sequence), | 28 sequence_(sequence), |
29 source_positions_(source_positions), | 29 source_positions_(source_positions), |
30 source_position_mode_(source_position_mode), | 30 source_position_mode_(source_position_mode), |
31 features_(features), | 31 features_(features), |
32 schedule_(schedule), | 32 schedule_(schedule), |
33 current_block_(nullptr), | 33 current_block_(nullptr), |
34 instructions_(zone), | 34 instructions_(zone), |
35 defined_(node_count, false, zone), | 35 defined_(node_count, false, zone), |
36 used_(node_count, false, zone), | 36 used_(node_count, false, zone), |
| 37 effect_level_(node_count, 0, zone), |
37 virtual_registers_(node_count, | 38 virtual_registers_(node_count, |
38 InstructionOperand::kInvalidVirtualRegister, zone), | 39 InstructionOperand::kInvalidVirtualRegister, zone), |
39 scheduler_(nullptr), | 40 scheduler_(nullptr), |
40 frame_(frame) { | 41 frame_(frame) { |
41 instructions_.reserve(node_count); | 42 instructions_.reserve(node_count); |
42 } | 43 } |
43 | 44 |
44 | 45 |
45 void InstructionSelector::SelectInstructions() { | 46 void InstructionSelector::SelectInstructions() { |
46 // Mark the inputs of all phis in loop headers as used. | 47 // Mark the inputs of all phis in loop headers as used. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 | 212 |
212 | 213 |
213 Instruction* InstructionSelector::Emit(Instruction* instr) { | 214 Instruction* InstructionSelector::Emit(Instruction* instr) { |
214 instructions_.push_back(instr); | 215 instructions_.push_back(instr); |
215 return instr; | 216 return instr; |
216 } | 217 } |
217 | 218 |
218 | 219 |
219 bool InstructionSelector::CanCover(Node* user, Node* node) const { | 220 bool InstructionSelector::CanCover(Node* user, Node* node) const { |
220 return node->OwnedBy(user) && | 221 return node->OwnedBy(user) && |
221 schedule()->block(node) == schedule()->block(user); | 222 schedule()->block(node) == schedule()->block(user) && |
| 223 (node->op()->HasProperty(Operator::kPure) || |
| 224 GetEffectLevel(node) == GetEffectLevel(user)); |
222 } | 225 } |
223 | 226 |
224 | |
225 int InstructionSelector::GetVirtualRegister(const Node* node) { | 227 int InstructionSelector::GetVirtualRegister(const Node* node) { |
226 DCHECK_NOT_NULL(node); | 228 DCHECK_NOT_NULL(node); |
227 size_t const id = node->id(); | 229 size_t const id = node->id(); |
228 DCHECK_LT(id, virtual_registers_.size()); | 230 DCHECK_LT(id, virtual_registers_.size()); |
229 int virtual_register = virtual_registers_[id]; | 231 int virtual_register = virtual_registers_[id]; |
230 if (virtual_register == InstructionOperand::kInvalidVirtualRegister) { | 232 if (virtual_register == InstructionOperand::kInvalidVirtualRegister) { |
231 virtual_register = sequence()->NextVirtualRegister(); | 233 virtual_register = sequence()->NextVirtualRegister(); |
232 virtual_registers_[id] = virtual_register; | 234 virtual_registers_[id] = virtual_register; |
233 } | 235 } |
234 return virtual_register; | 236 return virtual_register; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 } | 275 } |
274 | 276 |
275 | 277 |
276 void InstructionSelector::MarkAsUsed(Node* node) { | 278 void InstructionSelector::MarkAsUsed(Node* node) { |
277 DCHECK_NOT_NULL(node); | 279 DCHECK_NOT_NULL(node); |
278 size_t const id = node->id(); | 280 size_t const id = node->id(); |
279 DCHECK_LT(id, used_.size()); | 281 DCHECK_LT(id, used_.size()); |
280 used_[id] = true; | 282 used_[id] = true; |
281 } | 283 } |
282 | 284 |
| 285 int InstructionSelector::GetEffectLevel(Node* node) const { |
| 286 DCHECK_NOT_NULL(node); |
| 287 size_t const id = node->id(); |
| 288 DCHECK_LT(id, effect_level_.size()); |
| 289 return effect_level_[id]; |
| 290 } |
| 291 |
| 292 void InstructionSelector::SetEffectLevel(Node* node, int effect_level) { |
| 293 DCHECK_NOT_NULL(node); |
| 294 size_t const id = node->id(); |
| 295 DCHECK_LT(id, effect_level_.size()); |
| 296 effect_level_[id] = effect_level; |
| 297 } |
283 | 298 |
284 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, | 299 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, |
285 const InstructionOperand& op) { | 300 const InstructionOperand& op) { |
286 UnallocatedOperand unalloc = UnallocatedOperand::cast(op); | 301 UnallocatedOperand unalloc = UnallocatedOperand::cast(op); |
287 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register()); | 302 sequence()->MarkAsRepresentation(rep, unalloc.virtual_register()); |
288 } | 303 } |
289 | 304 |
290 | 305 |
291 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, | 306 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, |
292 Node* node) { | 307 Node* node) { |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 buffer->instruction_args.push_back(return_address); | 677 buffer->instruction_args.push_back(return_address); |
663 } | 678 } |
664 } | 679 } |
665 | 680 |
666 | 681 |
667 void InstructionSelector::VisitBlock(BasicBlock* block) { | 682 void InstructionSelector::VisitBlock(BasicBlock* block) { |
668 DCHECK(!current_block_); | 683 DCHECK(!current_block_); |
669 current_block_ = block; | 684 current_block_ = block; |
670 int current_block_end = static_cast<int>(instructions_.size()); | 685 int current_block_end = static_cast<int>(instructions_.size()); |
671 | 686 |
| 687 int effect_level = 0; |
| 688 for (Node* const node : *block) { |
| 689 if (node->opcode() == IrOpcode::kStore || |
| 690 node->opcode() == IrOpcode::kCheckedStore || |
| 691 node->opcode() == IrOpcode::kCall) { |
| 692 ++effect_level; |
| 693 } |
| 694 SetEffectLevel(node, effect_level); |
| 695 } |
| 696 |
672 // Generate code for the block control "top down", but schedule the code | 697 // Generate code for the block control "top down", but schedule the code |
673 // "bottom up". | 698 // "bottom up". |
674 VisitControl(block); | 699 VisitControl(block); |
675 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); | 700 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); |
676 | 701 |
677 // Visit code in reverse control flow order, because architecture-specific | 702 // Visit code in reverse control flow order, because architecture-specific |
678 // matching may cover more than one node at a time. | 703 // matching may cover more than one node at a time. |
679 for (auto node : base::Reversed(*block)) { | 704 for (auto node : base::Reversed(*block)) { |
680 // Skip nodes that are unused or already defined. | 705 // Skip nodes that are unused or already defined. |
681 if (!IsUsed(node) || IsDefined(node)) continue; | 706 if (!IsUsed(node) || IsDefined(node)) continue; |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 return new (instruction_zone()) FrameStateDescriptor( | 1690 return new (instruction_zone()) FrameStateDescriptor( |
1666 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1691 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1667 state_info.state_combine(), parameters, locals, stack, | 1692 state_info.state_combine(), parameters, locals, stack, |
1668 state_info.shared_info(), outer_state); | 1693 state_info.shared_info(), outer_state); |
1669 } | 1694 } |
1670 | 1695 |
1671 | 1696 |
1672 } // namespace compiler | 1697 } // namespace compiler |
1673 } // namespace internal | 1698 } // namespace internal |
1674 } // namespace v8 | 1699 } // namespace v8 |
OLD | NEW |