| 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/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
| (...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 bool InstructionSelector::IsSourcePositionUsed(Node* node) { | 821 bool InstructionSelector::IsSourcePositionUsed(Node* node) { |
| 822 return (source_position_mode_ == kAllSourcePositions || | 822 return (source_position_mode_ == kAllSourcePositions || |
| 823 node->opcode() == IrOpcode::kCall || | 823 node->opcode() == IrOpcode::kCall || |
| 824 node->opcode() == IrOpcode::kTrapIf || | 824 node->opcode() == IrOpcode::kTrapIf || |
| 825 node->opcode() == IrOpcode::kTrapUnless); | 825 node->opcode() == IrOpcode::kTrapUnless); |
| 826 } | 826 } |
| 827 | 827 |
| 828 void InstructionSelector::VisitBlock(BasicBlock* block) { | 828 void InstructionSelector::VisitBlock(BasicBlock* block) { |
| 829 DCHECK(!current_block_); | 829 DCHECK(!current_block_); |
| 830 current_block_ = block; | 830 current_block_ = block; |
| 831 int current_block_end = static_cast<int>(instructions_.size()); | 831 auto current_num_instructions = [&] { |
| 832 DCHECK_GE(kMaxInt, instructions_.size()); |
| 833 return static_cast<int>(instructions_.size()); |
| 834 }; |
| 835 int current_block_end = current_num_instructions(); |
| 832 | 836 |
| 833 int effect_level = 0; | 837 int effect_level = 0; |
| 834 for (Node* const node : *block) { | 838 for (Node* const node : *block) { |
| 835 if (node->opcode() == IrOpcode::kStore || | 839 if (node->opcode() == IrOpcode::kStore || |
| 836 node->opcode() == IrOpcode::kUnalignedStore || | 840 node->opcode() == IrOpcode::kUnalignedStore || |
| 837 node->opcode() == IrOpcode::kCheckedStore || | 841 node->opcode() == IrOpcode::kCheckedStore || |
| 838 node->opcode() == IrOpcode::kCall) { | 842 node->opcode() == IrOpcode::kCall) { |
| 839 ++effect_level; | 843 ++effect_level; |
| 840 } | 844 } |
| 841 SetEffectLevel(node, effect_level); | 845 SetEffectLevel(node, effect_level); |
| 842 } | 846 } |
| 843 | 847 |
| 844 // We visit the control first, then the nodes in the block, so the block's | 848 // We visit the control first, then the nodes in the block, so the block's |
| 845 // control input should be on the same effect level as the last node. | 849 // control input should be on the same effect level as the last node. |
| 846 if (block->control_input() != nullptr) { | 850 if (block->control_input() != nullptr) { |
| 847 SetEffectLevel(block->control_input(), effect_level); | 851 SetEffectLevel(block->control_input(), effect_level); |
| 848 } | 852 } |
| 849 | 853 |
| 854 auto FinishEmittedInstructions = [&](Node* node, int instruction_start) { |
| 855 if (instruction_selection_failed()) return false; |
| 856 if (current_num_instructions() == instruction_start) return true; |
| 857 std::reverse(instructions_.begin() + instruction_start, |
| 858 instructions_.end()); |
| 859 if (!node) return true; |
| 860 SourcePosition source_position = source_positions_->GetSourcePosition(node); |
| 861 if (source_position.IsKnown() && IsSourcePositionUsed(node)) { |
| 862 sequence()->SetSourcePosition(instructions_[instruction_start], |
| 863 source_position); |
| 864 } |
| 865 return true; |
| 866 }; |
| 867 |
| 850 // Generate code for the block control "top down", but schedule the code | 868 // Generate code for the block control "top down", but schedule the code |
| 851 // "bottom up". | 869 // "bottom up". |
| 852 VisitControl(block); | 870 VisitControl(block); |
| 853 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); | 871 if (!FinishEmittedInstructions(block->control_input(), current_block_end)) |
| 872 return; |
| 854 | 873 |
| 855 // Visit code in reverse control flow order, because architecture-specific | 874 // Visit code in reverse control flow order, because architecture-specific |
| 856 // matching may cover more than one node at a time. | 875 // matching may cover more than one node at a time. |
| 857 for (auto node : base::Reversed(*block)) { | 876 for (auto node : base::Reversed(*block)) { |
| 858 // Skip nodes that are unused or already defined. | 877 // Skip nodes that are unused or already defined. |
| 859 if (!IsUsed(node) || IsDefined(node)) continue; | 878 if (!IsUsed(node) || IsDefined(node)) continue; |
| 860 // Generate code for this node "top down", but schedule the code "bottom | 879 // Generate code for this node "top down", but schedule the code "bottom |
| 861 // up". | 880 // up". |
| 862 size_t current_node_end = instructions_.size(); | 881 int current_node_end = current_num_instructions(); |
| 863 VisitNode(node); | 882 VisitNode(node); |
| 864 if (instruction_selection_failed()) return; | 883 if (!FinishEmittedInstructions(node, current_node_end)) return; |
| 865 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); | |
| 866 if (instructions_.size() == current_node_end) continue; | |
| 867 // Mark source position on first instruction emitted. | |
| 868 SourcePosition source_position = source_positions_->GetSourcePosition(node); | |
| 869 if (source_position.IsKnown() && IsSourcePositionUsed(node)) { | |
| 870 sequence()->SetSourcePosition(instructions_[current_node_end], | |
| 871 source_position); | |
| 872 } | |
| 873 } | 884 } |
| 874 | 885 |
| 875 // We're done with the block. | 886 // We're done with the block. |
| 876 InstructionBlock* instruction_block = | 887 InstructionBlock* instruction_block = |
| 877 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); | 888 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); |
| 878 instruction_block->set_code_start(static_cast<int>(instructions_.size())); | 889 instruction_block->set_code_start(static_cast<int>(instructions_.size())); |
| 879 instruction_block->set_code_end(current_block_end); | 890 instruction_block->set_code_end(current_block_end); |
| 880 | 891 |
| 881 current_block_ = nullptr; | 892 current_block_ = nullptr; |
| 882 } | 893 } |
| (...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2160 return new (instruction_zone()) FrameStateDescriptor( | 2171 return new (instruction_zone()) FrameStateDescriptor( |
| 2161 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2172 instruction_zone(), state_info.type(), state_info.bailout_id(), |
| 2162 state_info.state_combine(), parameters, locals, stack, | 2173 state_info.state_combine(), parameters, locals, stack, |
| 2163 state_info.shared_info(), outer_state); | 2174 state_info.shared_info(), outer_state); |
| 2164 } | 2175 } |
| 2165 | 2176 |
| 2166 | 2177 |
| 2167 } // namespace compiler | 2178 } // namespace compiler |
| 2168 } // namespace internal | 2179 } // namespace internal |
| 2169 } // namespace v8 | 2180 } // namespace v8 |
| OLD | NEW |